diff options
46 files changed, 1199 insertions, 446 deletions
@@ -222,13 +222,13 @@ invokes cmake commands as needed. HAVE_DOT=YES doxygen Doxyfile -#### On the Raspberry Pi 2 +#### On the Raspberry Pi -Tested on a Raspberry Pi 2 with a clean install of minimal Debian Jessie from https://www.raspberrypi.org/downloads/raspbian/ +Tested on a Raspberry Pi Zero with a clean install of minimal Raspbian Stretch (2017-09-07 or later) from https://www.raspberrypi.org/downloads/raspbian/. If you are using Raspian Jessie, [please see note in the following section](#note-for-raspbian-jessie-users). * `apt-get update && apt-get upgrade` to install all of the latest software -* Install the dependencies for Monero except libunwind and libboost-all-dev +* Install the dependencies for Monero from the 'Debian' column in the table above. * Increase the system swap size: ``` @@ -237,6 +237,41 @@ Tested on a Raspberry Pi 2 with a clean install of minimal Debian Jessie from ht CONF_SWAPSIZE=1024 sudo /etc/init.d/dphys-swapfile start ``` +* Clone monero and checkout most recent release version: +``` + git clone https://github.com/monero-project/monero.git + cd monero + git checkout tags/v0.11.0.0 +``` +* Build: +``` + make release +``` +* Wait 4-6 hours + +* The resulting executables can be found in `build/release/bin` + +* Add `PATH="$PATH:$HOME/monero/build/release/bin"` to `.profile` + +* Run Monero with `monerod --detach` + +* You may wish to reduce the size of the swap file after the build has finished, and delete the boost directory from your home directory + +#### *Note for Raspbian Jessie Users:* + +If you are using the older Raspbian Jessie image, compiling Monero is a bit more complicated. The version of Boost available in the Debian Jessie repositories is too old to use with Monero, and thus you must compile a newer version yourself. The following explains the extra steps, and has been tested on a Raspberry Pi 2 with a clean install of minimal Raspbian Jessie. + +* As before, `apt-get update && apt-get upgrade` to install all of the latest software, and increase the system swap size + +``` + sudo /etc/init.d/dphys-swapfile stop + sudo nano /etc/dphys-swapfile + CONF_SWAPSIZE=1024 + sudo /etc/init.d/dphys-swapfile start +``` + +* Then, install the dependencies for Monero except `libunwind` and `libboost-all-dev` + * Install the latest version of boost (this may first require invoking `apt-get remove --purge libboost*` to remove a previous version if you're not using a clean install): ``` cd @@ -252,20 +287,7 @@ Tested on a Raspberry Pi 2 with a clean install of minimal Debian Jessie from ht ``` * Wait ~4 hours -* Change to the root of the source code directory and build: -``` - cd monero - make release -``` -* Wait ~4 hours - -* The resulting executables can be found in `build/release/bin` - -* Add `PATH="$PATH:$HOME/monero/build/release/bin"` to `.profile` - -* Run Monero with `monerod --detach` - -* You may wish to reduce the size of the swap file after the build has finished, and delete the boost directory from your home directory +* From here, follow the [general Raspberry Pi instructions](#on-the-raspberry-pi) from the "Clone monero and checkout most recent release version" step. #### On Windows: @@ -350,11 +372,11 @@ To build: `env CC=egcc CXX=eg++ CPP=ecpp DEVELOPER_LOCAL_TOOLS=1 BOOST_ROOT=/pat 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: -* ```make release-static-64``` builds binaries on Linux on x86_64 portable across POSIX systems on x86_64 processors -* ```make release-static-32``` builds binaries on Linux on x86_64 or i686 portable across POSIX systems on i686 processors -* ```make release-static-armv8``` builds binaries on Linux portable across POSIX systems on armv8 processors -* ```make release-static-armv7``` builds binaries on Linux portable across POSIX systems on armv7 processors -* ```make release-static-armv6``` builds binaries on Linux portable across POSIX systems on armv6 processors +* ```make release-static-linux-x86_64``` builds binaries on Linux on x86_64 portable across POSIX systems on x86_64 processors +* ```make release-static-linux-i686``` builds binaries on Linux on x86_64 or i686 portable across POSIX systems on i686 processors +* ```make release-static-linux-armv8``` builds binaries on Linux portable across POSIX systems on armv8 processors +* ```make release-static-linux-armv7``` builds binaries on Linux portable across POSIX systems on armv7 processors +* ```make release-static-linux-armv6``` builds binaries on Linux portable across POSIX systems on armv6 processors * ```make release-static-win64``` builds binaries on 64-bit Windows portable across 64-bit Windows systems * ```make release-static-win32``` builds binaries on 64-bit or 32-bit Windows portable across 32-bit Windows systems diff --git a/contrib/epee/include/copyable_atomic.h b/contrib/epee/include/copyable_atomic.h index 410b4b4ff..00a5f484b 100644 --- a/contrib/epee/include/copyable_atomic.h +++ b/contrib/epee/include/copyable_atomic.h @@ -35,6 +35,8 @@ namespace epee public: copyable_atomic() {}; + copyable_atomic(uint32_t value) + { store(value); } copyable_atomic(const copyable_atomic& a):std::atomic<uint32_t>(a.load()) {} copyable_atomic& operator= (const copyable_atomic& a) diff --git a/contrib/epee/include/misc_log_ex.h b/contrib/epee/include/misc_log_ex.h index d351b024d..982aaea06 100644 --- a/contrib/epee/include/misc_log_ex.h +++ b/contrib/epee/include/misc_log_ex.h @@ -126,6 +126,7 @@ std::string mlog_get_default_log_path(const char *default_filename); void mlog_configure(const std::string &filename_base, bool console, const std::size_t max_log_file_size = MAX_LOG_FILE_SIZE); void mlog_set_categories(const char *categories); +std::string mlog_get_categories(); void mlog_set_log_level(int level); void mlog_set_log(const char *log); diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl index 76988a26e..94ef7c3b3 100644 --- a/contrib/epee/include/net/abstract_tcp_server2.inl +++ b/contrib/epee/include/net/abstract_tcp_server2.inl @@ -137,14 +137,14 @@ PRAGMA_WARNING_DISABLE_VS(4355) CHECK_AND_NO_ASSERT_MES(!ec, false, "Failed to get local endpoint: " << ec.message() << ':' << ec.value()); context = boost::value_initialized<t_connection_context>(); - long ip_ = boost::asio::detail::socket_ops::host_to_network_long(remote_ep.address().to_v4().to_ulong()); + const unsigned long ip_{boost::asio::detail::socket_ops::host_to_network_long(remote_ep.address().to_v4().to_ulong())}; // create a random uuid boost::uuids::uuid random_uuid; // that stuff turns out to be included, even though it's from src... Taking advantage random_uuid = crypto::rand<boost::uuids::uuid>(); - context.set_details(random_uuid, new epee::net_utils::ipv4_network_address(ip_, remote_ep.port()), is_income); + context.set_details(random_uuid, epee::net_utils::ipv4_network_address(ip_, remote_ep.port()), is_income); _dbg3("[sock " << socket_.native_handle() << "] new connection from " << print_connection_context_short(context) << " to " << local_ep.address().to_string() << ':' << local_ep.port() << ", total sockets objects " << m_ref_sock_count); diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/net/levin_protocol_handler_async.h index 60a667690..779f4e78f 100644 --- a/contrib/epee/include/net/levin_protocol_handler_async.h +++ b/contrib/epee/include/net/levin_protocol_handler_async.h @@ -740,9 +740,15 @@ void async_protocol_handler_config<t_connection_context>::del_out_connections(si shuffle(out_connections.begin(), out_connections.end(), std::default_random_engine(seed)); while (count > 0 && out_connections.size() > 0) { - close(*out_connections.begin()); - del_connection(m_connects.at(*out_connections.begin())); + boost::uuids::uuid connection_id = *out_connections.begin(); + async_protocol_handler<t_connection_context> *connection = find_connection(connection_id); + // we temporarily ref the connection so it doesn't drop from the m_connects table + // when we close it + connection->start_outer_call(); + close(connection_id); + del_connection(m_connects.at(connection_id)); out_connections.erase(out_connections.begin()); + connection->finish_outer_call(); --count; } diff --git a/contrib/epee/include/net/net_utils_base.h b/contrib/epee/include/net/net_utils_base.h index ef3a1d146..0e31ee86f 100644 --- a/contrib/epee/include/net/net_utils_base.h +++ b/contrib/epee/include/net/net_utils_base.h @@ -29,11 +29,12 @@ #ifndef _NET_UTILS_BASE_H_ #define _NET_UTILS_BASE_H_ -#include <typeinfo> #include <boost/asio/io_service.hpp> #include <boost/uuid/uuid.hpp> +#include <memory> +#include <typeinfo> +#include <type_traits> #include "serialization/keyvalue_serialization.h" -#include "net/local_ip.h" #include "string_tools.h" #include "misc_log_ex.h" @@ -49,75 +50,119 @@ namespace epee { namespace net_utils { - struct network_address_base + class ipv4_network_address { - public: - bool operator==(const network_address_base &other) const { return m_full_id == other.m_full_id; } - bool operator!=(const network_address_base &other) const { return !operator==(other); } - bool operator<(const network_address_base &other) const { return m_full_id < other.m_full_id; } - bool is_same_host(const network_address_base &other) const { return m_host_id == other.m_host_id; } - virtual std::string str() const = 0; - virtual std::string host_str() const = 0; - virtual bool is_loopback() const = 0; - virtual bool is_local() const = 0; - virtual uint8_t get_type_id() const = 0; - protected: - // A very simple non cryptographic hash function by Fowler, Noll, Vo - uint64_t fnv1a(const uint8_t *data, size_t len) const { - uint64_t h = 0xcbf29ce484222325; - while (len--) - h = (h ^ *data++) * 0x100000001b3; - return h; - } - uint64_t m_host_id; - uint64_t m_full_id; - }; - struct ipv4_network_address: public network_address_base - { - void init_ids() - { - m_host_id = fnv1a((const uint8_t*)&m_ip, sizeof(m_ip)); - m_full_id = fnv1a((const uint8_t*)&m_ip, sizeof(m_ip) + sizeof(m_port)); - } - public: - ipv4_network_address(uint32_t ip, uint16_t port): network_address_base(), m_ip(ip), m_port(port) { init_ids(); } - uint32_t ip() const { return m_ip; } - uint16_t port() const { return m_port; } - virtual std::string str() const { return epee::string_tools::get_ip_string_from_int32(m_ip) + ":" + std::to_string(m_port); } - virtual std::string host_str() const { return epee::string_tools::get_ip_string_from_int32(m_ip); } - virtual bool is_loopback() const { return epee::net_utils::is_ip_loopback(m_ip); } - virtual bool is_local() const { return epee::net_utils::is_ip_local(m_ip); } - virtual uint8_t get_type_id() const { return ID; } - public: // serialization - static const uint8_t ID = 1; -#pragma pack(push) -#pragma pack(1) uint32_t m_ip; uint16_t m_port; -#pragma pack(pop) + + public: + constexpr ipv4_network_address(uint32_t ip, uint16_t port) noexcept + : m_ip(ip), m_port(port) {} + + bool equal(const ipv4_network_address& other) const noexcept; + bool less(const ipv4_network_address& other) const noexcept; + constexpr bool is_same_host(const ipv4_network_address& other) const noexcept + { return ip() == other.ip(); } + + constexpr uint32_t ip() const noexcept { return m_ip; } + constexpr uint16_t port() const noexcept { return m_port; } + std::string str() const; + std::string host_str() const; + bool is_loopback() const; + bool is_local() const; + static constexpr uint8_t get_type_id() noexcept { return ID; } + + static const uint8_t ID = 1; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(m_ip) KV_SERIALIZE(m_port) - if (!is_store) - const_cast<ipv4_network_address&>(this_ref).init_ids(); END_KV_SERIALIZE_MAP() }; - class network_address: public boost::shared_ptr<network_address_base> + + inline bool operator==(const ipv4_network_address& lhs, const ipv4_network_address& rhs) noexcept + { return lhs.equal(rhs); } + inline bool operator!=(const ipv4_network_address& lhs, const ipv4_network_address& rhs) noexcept + { return !lhs.equal(rhs); } + inline bool operator<(const ipv4_network_address& lhs, const ipv4_network_address& rhs) noexcept + { return lhs.less(rhs); } + inline bool operator<=(const ipv4_network_address& lhs, const ipv4_network_address& rhs) noexcept + { return !rhs.less(lhs); } + inline bool operator>(const ipv4_network_address& lhs, const ipv4_network_address& rhs) noexcept + { return rhs.less(lhs); } + inline bool operator>=(const ipv4_network_address& lhs, const ipv4_network_address& rhs) noexcept + { return !lhs.less(rhs); } + + class network_address { + struct interface + { + virtual ~interface() {}; + + virtual bool equal(const interface&) const = 0; + virtual bool less(const interface&) const = 0; + virtual bool is_same_host(const interface&) const = 0; + + virtual std::string str() const = 0; + virtual std::string host_str() const = 0; + virtual bool is_loopback() const = 0; + virtual bool is_local() const = 0; + virtual uint8_t get_type_id() const = 0; + }; + + template<typename T> + struct implementation final : interface + { + T value; + + implementation(const T& src) : value(src) {} + ~implementation() = default; + + // Type-checks for cast are done in cpp + static const T& cast(const interface& src) noexcept + { return static_cast<const implementation<T>&>(src).value; } + + virtual bool equal(const interface& other) const override + { return value.equal(cast(other)); } + + virtual bool less(const interface& other) const override + { return value.less(cast(other)); } + + virtual bool is_same_host(const interface& other) const override + { return value.is_same_host(cast(other)); } + + virtual std::string str() const override { return value.str(); } + virtual std::string host_str() const override { return value.host_str(); } + virtual bool is_loopback() const override { return value.is_loopback(); } + virtual bool is_local() const override { return value.is_local(); } + virtual uint8_t get_type_id() const override { return value.get_type_id(); } + }; + + std::shared_ptr<interface> self; + + template<typename Type> + Type& as_mutable() const + { + // types `implmentation<Type>` and `implementation<const Type>` are unique + using Type_ = typename std::remove_const<Type>::type; + network_address::interface* const self_ = self.get(); // avoid clang warning in typeid + if (!self_ || typeid(implementation<Type_>) != typeid(*self_)) + throw std::bad_cast{}; + return static_cast<implementation<Type_>*>(self_)->value; + } public: - network_address() {} - network_address(ipv4_network_address *address): boost::shared_ptr<network_address_base>(address) {} - bool operator==(const network_address &other) const { return (*this)->operator==(*other); } - bool operator!=(const network_address &other) const { return (*this)->operator!=(*other); } - bool operator<(const network_address &other) const { return (*this)->operator<(*other); } - bool is_same_host(const network_address &other) const { return (*this)->is_same_host(*other); } - std::string str() const { return (*this) ? (*this)->str() : "<none>"; } - std::string host_str() const { return (*this) ? (*this)->host_str() : "<none>"; } - bool is_loopback() const { return (*this)->is_loopback(); } - bool is_local() const { return (*this)->is_local(); } - uint8_t get_type_id() const { return (*this)->get_type_id(); } - template<typename Type> Type &as() { if (get_type_id() != Type::ID) throw std::runtime_error("Bad type"); return *(Type*)get(); } - template<typename Type> const Type &as() const { if (get_type_id() != Type::ID) throw std::runtime_error("Bad type"); return *(const Type*)get(); } + network_address() : self(nullptr) {} + template<typename T> + network_address(const T& src) + : self(std::make_shared<implementation<T>>(src)) {} + bool equal(const network_address &other) const; + bool less(const network_address &other) const; + bool is_same_host(const network_address &other) const; + std::string str() const { return self ? self->str() : "<none>"; } + std::string host_str() const { return self ? self->host_str() : "<none>"; } + bool is_loopback() const { return self ? self->is_loopback() : false; } + bool is_local() const { return self ? self->is_local() : false; } + uint8_t get_type_id() const { return self ? self->get_type_id() : 0; } + template<typename Type> const Type &as() const { return as_mutable<const Type>(); } BEGIN_KV_SERIALIZE_MAP() uint8_t type = is_store ? this_ref.get_type_id() : 0; @@ -126,13 +171,27 @@ namespace net_utils { case ipv4_network_address::ID: if (!is_store) - const_cast<network_address&>(this_ref).reset(new ipv4_network_address(0, 0)); - KV_SERIALIZE(template as<ipv4_network_address>()); + const_cast<network_address&>(this_ref) = ipv4_network_address{0, 0}; + KV_SERIALIZE(template as_mutable<ipv4_network_address>()); break; default: MERROR("Unsupported network address type: " << type); return false; } END_KV_SERIALIZE_MAP() }; + + inline bool operator==(const network_address& lhs, const network_address& rhs) + { return lhs.equal(rhs); } + inline bool operator!=(const network_address& lhs, const network_address& rhs) + { return !lhs.equal(rhs); } + inline bool operator<(const network_address& lhs, const network_address& rhs) + { return lhs.less(rhs); } + inline bool operator<=(const network_address& lhs, const network_address& rhs) + { return !rhs.less(lhs); } + inline bool operator>(const network_address& lhs, const network_address& rhs) + { return rhs.less(lhs); } + inline bool operator>=(const network_address& lhs, const network_address& rhs) + { return !lhs.less(rhs); } + inline bool create_network_address(network_address &address, const std::string &string, uint16_t default_port = 0) { uint32_t ip; @@ -141,7 +200,7 @@ namespace net_utils { if (default_port && !port) port = default_port; - address.reset(new ipv4_network_address(ip, port)); + address = ipv4_network_address{ip, port}; return true; } return false; @@ -179,7 +238,7 @@ namespace net_utils {} connection_context_base(): m_connection_id(), - m_remote_address(new ipv4_network_address(0,0)), + m_remote_address(ipv4_network_address{0,0}), m_is_income(false), m_started(time(NULL)), m_last_recv(0), @@ -232,7 +291,7 @@ namespace net_utils std::string print_connection_context(const connection_context_base& ctx) { std::stringstream ss; - ss << ctx.m_remote_address->str() << " " << epee::string_tools::get_str_from_guid_a(ctx.m_connection_id) << (ctx.m_is_income ? " INC":" OUT"); + ss << ctx.m_remote_address.str() << " " << epee::string_tools::get_str_from_guid_a(ctx.m_connection_id) << (ctx.m_is_income ? " INC":" OUT"); return ss.str(); } @@ -240,7 +299,7 @@ namespace net_utils std::string print_connection_context_short(const connection_context_base& ctx) { std::stringstream ss; - ss << ctx.m_remote_address->str() << (ctx.m_is_income ? " INC":" OUT"); + ss << ctx.m_remote_address.str() << (ctx.m_is_income ? " INC":" OUT"); return ss.str(); } diff --git a/contrib/epee/src/CMakeLists.txt b/contrib/epee/src/CMakeLists.txt index c61a6e684..294515f83 100644 --- a/contrib/epee/src/CMakeLists.txt +++ b/contrib/epee/src/CMakeLists.txt @@ -27,9 +27,9 @@ # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. if (USE_READLINE AND GNU_READLINE_FOUND) - add_library(epee STATIC hex.cpp http_auth.cpp mlog.cpp string_tools.cpp readline_buffer.cpp) + add_library(epee STATIC hex.cpp http_auth.cpp mlog.cpp net_utils_base.cpp string_tools.cpp readline_buffer.cpp) else() - add_library(epee STATIC hex.cpp http_auth.cpp mlog.cpp string_tools.cpp) + add_library(epee STATIC hex.cpp http_auth.cpp mlog.cpp net_utils_base.cpp string_tools.cpp) endif() # Build and install libepee if we're building for GUI diff --git a/contrib/epee/src/mlog.cpp b/contrib/epee/src/mlog.cpp index 964ba41df..cfb2b7b15 100644 --- a/contrib/epee/src/mlog.cpp +++ b/contrib/epee/src/mlog.cpp @@ -144,16 +144,52 @@ void mlog_configure(const std::string &filename_base, bool console, const std::s void mlog_set_categories(const char *categories) { - el::Loggers::setCategories(categories); - MLOG_LOG("New log categories: " << categories); + std::string new_categories; + if (*categories) + { + if (*categories == '+') + { + ++categories; + new_categories = mlog_get_categories(); + if (*categories) + { + if (!new_categories.empty()) + new_categories += ","; + new_categories += categories; + } + } + else if (*categories == '-') + { + ++categories; + new_categories = mlog_get_categories(); + std::vector<std::string> single_categories; + boost::split(single_categories, categories, boost::is_any_of(","), boost::token_compress_on); + for (const std::string &s: single_categories) + { + size_t pos = new_categories.find(s); + if (pos != std::string::npos) + new_categories = new_categories.erase(pos, s.size()); + } + } + else + { + new_categories = categories; + } + } + el::Loggers::setCategories(new_categories.c_str(), true); + MLOG_LOG("New log categories: " << el::Loggers::getCategories()); +} + +std::string mlog_get_categories() +{ + return el::Loggers::getCategories(); } // maps epee style log level to new logging system void mlog_set_log_level(int level) { const char *categories = get_default_categories(level); - el::Loggers::setCategories(categories); - MLOG_LOG("New log categories: " << categories); + mlog_set_categories(categories); } void mlog_set_log(const char *log) diff --git a/contrib/epee/src/net_utils_base.cpp b/contrib/epee/src/net_utils_base.cpp new file mode 100644 index 000000000..22afcf819 --- /dev/null +++ b/contrib/epee/src/net_utils_base.cpp @@ -0,0 +1,60 @@ + +#include "net/net_utils_base.h" + +#include <cstring> +#include <typeindex> +#include "net/local_ip.h" + +namespace epee { namespace net_utils +{ + const uint8_t ipv4_network_address::ID; + + bool ipv4_network_address::equal(const ipv4_network_address& other) const noexcept + { return is_same_host(other) && port() == other.port(); } + + bool ipv4_network_address::less(const ipv4_network_address& other) const noexcept + { return is_same_host(other) ? port() < other.port() : ip() < other.ip(); } + + std::string ipv4_network_address::str() const + { return string_tools::get_ip_string_from_int32(ip()) + ":" + std::to_string(port()); } + + std::string ipv4_network_address::host_str() const { return string_tools::get_ip_string_from_int32(ip()); } + bool ipv4_network_address::is_loopback() const { return net_utils::is_ip_loopback(ip()); } + bool ipv4_network_address::is_local() const { return net_utils::is_ip_local(ip()); } + + + bool network_address::equal(const network_address& other) const + { + // clang typeid workaround + network_address::interface const* const self_ = self.get(); + network_address::interface const* const other_self = other.self.get(); + if (self_ == other_self) return true; + if (!self_ || !other_self) return false; + if (typeid(*self_) != typeid(*other_self)) return false; + return self_->equal(*other_self); + } + + bool network_address::less(const network_address& other) const + { + // clang typeid workaround + network_address::interface const* const self_ = self.get(); + network_address::interface const* const other_self = other.self.get(); + if (self_ == other_self) return false; + if (!self_ || !other_self) return self == nullptr; + if (typeid(*self_) != typeid(*other_self)) + return self_->get_type_id() < other_self->get_type_id(); + return self_->less(*other_self); + } + + bool network_address::is_same_host(const network_address& other) const + { + // clang typeid workaround + network_address::interface const* const self_ = self.get(); + network_address::interface const* const other_self = other.self.get(); + if (self_ == other_self) return true; + if (!self_ || !other_self) return false; + if (typeid(*self_) != typeid(*other_self)) return false; + return self_->is_same_host(*other_self); + } +}} + diff --git a/external/db_drivers/liblmdb/mdb_load.1 b/external/db_drivers/liblmdb/mdb_load.1 index 712ed0540..ede3702d9 100644 --- a/external/db_drivers/liblmdb/mdb_load.1 +++ b/external/db_drivers/liblmdb/mdb_load.1 @@ -37,6 +37,13 @@ option below. .BR \-V Write the library version number to the standard output, and exit. .TP +.BR \-a +Append all records in the order they appear in the input. The input is assumed to already be +in correctly sorted order and no sorting or checking for redundant values will be performed. +This option must be used to reload data that was produced by running +.B mdb_dump +on a database that uses custom compare functions. +.TP .BR \-f \ file Read from the specified file instead of from the standard input. .TP diff --git a/external/db_drivers/liblmdb/mdb_load.c b/external/db_drivers/liblmdb/mdb_load.c index d1fda4bf5..797c2f979 100644 --- a/external/db_drivers/liblmdb/mdb_load.c +++ b/external/db_drivers/liblmdb/mdb_load.c @@ -37,6 +37,7 @@ static int Eof; static MDB_envinfo info; static MDB_val kbuf, dbuf; +static MDB_val k0buf; #ifdef _WIN32 #define Z "I" @@ -285,10 +286,15 @@ badend: static void usage(void) { - fprintf(stderr, "usage: %s [-V] [-f input] [-n] [-s name] [-N] [-T] dbpath\n", prog); + fprintf(stderr, "usage: %s [-V] [-a] [-f input] [-n] [-s name] [-N] [-T] dbpath\n", prog); exit(EXIT_FAILURE); } +static int greater(const MDB_val *a, const MDB_val *b) +{ + return 1; +} + int main(int argc, char *argv[]) { int i, rc; @@ -298,7 +304,8 @@ int main(int argc, char *argv[]) MDB_dbi dbi; char *envname; int envflags = 0, putflags = 0; - int dohdr = 0; + int dohdr = 0, append = 0; + MDB_val prevk; prog = argv[0]; @@ -306,19 +313,23 @@ int main(int argc, char *argv[]) usage(); } - /* -f: load file instead of stdin + /* -a: append records in input order + * -f: load file instead of stdin * -n: use NOSUBDIR flag on env_open * -s: load into named subDB * -N: use NOOVERWRITE on puts * -T: read plaintext * -V: print version and exit */ - while ((i = getopt(argc, argv, "f:ns:NTV")) != EOF) { + while ((i = getopt(argc, argv, "af:ns:NTV")) != EOF) { switch(i) { case 'V': printf("%s\n", MDB_VERSION_STRING); exit(0); break; + case 'a': + append = 1; + break; case 'f': if (freopen(optarg, "r", stdin) == NULL) { fprintf(stderr, "%s: %s: reopen: %s\n", @@ -377,12 +388,17 @@ int main(int argc, char *argv[]) } kbuf.mv_size = mdb_env_get_maxkeysize(env) * 2 + 2; - kbuf.mv_data = malloc(kbuf.mv_size); + kbuf.mv_data = malloc(kbuf.mv_size * 2); + k0buf.mv_size = kbuf.mv_size; + k0buf.mv_data = (char *)kbuf.mv_data + kbuf.mv_size; + prevk.mv_size = 0; + prevk.mv_data = k0buf.mv_data; while(!Eof) { MDB_val key, data; int batch = 0; flags = 0; + int appflag; if (!dohdr) { dohdr = 1; @@ -400,6 +416,11 @@ int main(int argc, char *argv[]) fprintf(stderr, "mdb_open failed, error %d %s\n", rc, mdb_strerror(rc)); goto txn_abort; } + if (append) { + mdb_set_compare(txn, dbi, greater); + if (flags & MDB_DUPSORT) + mdb_set_dupsort(txn, dbi, greater); + } rc = mdb_cursor_open(txn, dbi, &mc); if (rc) { @@ -418,7 +439,20 @@ int main(int argc, char *argv[]) goto txn_abort; } - rc = mdb_cursor_put(mc, &key, &data, putflags); + if (append) { + appflag = MDB_APPEND; + if (flags & MDB_DUPSORT) { + if (prevk.mv_size == key.mv_size && !memcmp(prevk.mv_data, key.mv_data, key.mv_size)) + appflag = MDB_APPENDDUP; + else { + memcpy(prevk.mv_data, key.mv_data, key.mv_size); + prevk.mv_size = key.mv_size; + } + } + } else { + appflag = 0; + } + rc = mdb_cursor_put(mc, &key, &data, putflags|appflag); if (rc == MDB_KEYEXIST && putflags) continue; if (rc) { diff --git a/external/easylogging++/easylogging++.cc b/external/easylogging++/easylogging++.cc index 721b2af15..6bc6b2619 100644 --- a/external/easylogging++/easylogging++.cc +++ b/external/easylogging++/easylogging++.cc @@ -1961,8 +1961,13 @@ void VRegistry::setCategories(const char* categories, bool clear) { m_categories.push_back(std::make_pair(ss.str(), level)); }; - if (clear) + if (clear) { m_categories.clear(); + m_categoriesString.clear(); + } + if (!m_categoriesString.empty()) + m_categoriesString += ","; + m_categoriesString += categories; if (!categories) return; @@ -2001,6 +2006,11 @@ void VRegistry::setCategories(const char* categories, bool clear) { } } +std::string VRegistry::getCategories() { + base::threading::ScopedLock scopedLock(lock()); + return m_categoriesString; +} + // Log levels are sorted in a weird way... static int priority(Level level) { if (level == Level::Fatal) return 0; @@ -3073,6 +3083,10 @@ void Loggers::setCategories(const char* categories, bool clear) { ELPP->vRegistry()->setCategories(categories, clear); } +std::string Loggers::getCategories() { + return ELPP->vRegistry()->getCategories(); +} + void Loggers::clearCategories(void) { ELPP->vRegistry()->clearCategories(); } diff --git a/external/easylogging++/easylogging++.h b/external/easylogging++/easylogging++.h index 8f592899e..c55cce755 100644 --- a/external/easylogging++/easylogging++.h +++ b/external/easylogging++/easylogging++.h @@ -2488,6 +2488,8 @@ class VRegistry : base::NoCopy, public base::threading::ThreadSafe { void setCategories(const char* categories, bool clear = true); + std::string getCategories(); + void setModules(const char* modules); bool allowed(Level level, const char* category); @@ -2518,6 +2520,7 @@ class VRegistry : base::NoCopy, public base::threading::ThreadSafe { base::type::EnumType* m_pFlags; std::map<std::string, base::type::VerboseLevel> m_modules; std::deque<std::pair<std::string, Level>> m_categories; + std::string m_categoriesString; std::string m_filenameCommonPrefix; }; } // namespace base @@ -3953,6 +3956,8 @@ class Loggers : base::StaticClass { static void setVModules(const char* modules); /// @brief Sets categories as specified (on the fly) static void setCategories(const char* categories, bool clear = true); + /// @brief Gets current categories + static std::string getCategories(); /// @brief Clears vmodules static void clearVModules(void); /// @brief Clears categories diff --git a/src/common/dns_utils.cpp b/src/common/dns_utils.cpp index 9c306505e..1310b8bfd 100644 --- a/src/common/dns_utils.cpp +++ b/src/common/dns_utils.cpp @@ -443,19 +443,28 @@ bool load_txt_records_from_dns(std::vector<std::string> &good_records, const std std::uniform_int_distribution<int> dis(0, dns_urls.size() - 1); size_t first_index = dis(gen); - bool avail, valid; + // send all requests in parallel + std::vector<boost::thread> threads(dns_urls.size()); + std::deque<bool> avail(dns_urls.size(), false), valid(dns_urls.size(), false); + for (size_t n = 0; n < dns_urls.size(); ++n) + { + threads[n] = boost::thread([n, dns_urls, &records, &avail, &valid](){ + records[n] = tools::DNSResolver::instance().get_txt_record(dns_urls[n], avail[n], valid[n]); + }); + } + for (size_t n = 0; n < dns_urls.size(); ++n) + threads[n].join(); + size_t cur_index = first_index; do { - std::string url = dns_urls[cur_index]; - - records[cur_index] = tools::DNSResolver::instance().get_txt_record(url, avail, valid); - if (!avail) + const std::string &url = dns_urls[cur_index]; + if (!avail[cur_index]) { records[cur_index].clear(); LOG_PRINT_L2("DNSSEC not available for checkpoint update at URL: " << url << ", skipping."); } - if (!valid) + if (!valid[cur_index]) { records[cur_index].clear(); LOG_PRINT_L2("DNSSEC validation failed for checkpoint update at URL: " << url << ", skipping."); diff --git a/src/cryptonote_basic/connection_context.h b/src/cryptonote_basic/connection_context.h index da4b6512e..e173348db 100644 --- a/src/cryptonote_basic/connection_context.h +++ b/src/cryptonote_basic/connection_context.h @@ -40,7 +40,7 @@ namespace cryptonote struct cryptonote_connection_context: public epee::net_utils::connection_context_base { cryptonote_connection_context(): m_state(state_before_handshake), m_remote_blockchain_height(0), m_last_response_height(0), - m_last_known_hash(crypto::null_hash) {} + m_callback_request_count(0), m_last_known_hash(crypto::null_hash) {} enum state { diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 0b09d503c..3e0ffc409 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -1444,7 +1444,7 @@ bool Blockchain::get_blocks(uint64_t start_offset, size_t count, std::list<std:: { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); - if(start_offset > m_db->height()) + if(start_offset >= m_db->height()) return false; if (!get_blocks(start_offset, count, blocks)) @@ -1466,7 +1466,7 @@ bool Blockchain::get_blocks(uint64_t start_offset, size_t count, std::list<std:: { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); - if(start_offset > m_db->height()) + if(start_offset >= m_db->height()) return false; for(size_t i = start_offset; i < start_offset + count && i < m_db->height();i++) @@ -2383,26 +2383,6 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context } } - // from v7, sorted outs - if (m_hardfork->get_current_version() >= 7) { - const crypto::public_key *last_key = NULL; - for (size_t n = 0; n < tx.vout.size(); ++n) - { - const tx_out &o = tx.vout[n]; - if (o.target.type() == typeid(txout_to_key)) - { - const txout_to_key& out_to_key = boost::get<txout_to_key>(o.target); - if (last_key && memcmp(&out_to_key.key, last_key, sizeof(*last_key)) >= 0) - { - MERROR_VER("transaction has unsorted outputs"); - tvc.m_invalid_output = true; - return false; - } - last_key = &out_to_key.key; - } - } - } - return true; } //------------------------------------------------------------------ diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 57347fdbc..c1a5ae324 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -1298,11 +1298,12 @@ namespace cryptonote bool core::check_updates() { static const char software[] = "monero"; - static const char subdir[] = "cli"; // because it can never be simple #ifdef BUILD_TAG static const char buildtag[] = BOOST_PP_STRINGIZE(BUILD_TAG); + static const char subdir[] = "cli"; // because it can never be simple #else static const char buildtag[] = "source"; + static const char subdir[] = "source"; // because it can never be simple #endif if (check_updates_level == UPDATES_DISABLED) diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp index 19ed57aba..fd647a356 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.cpp +++ b/src/cryptonote_core/cryptonote_tx_utils.cpp @@ -157,7 +157,7 @@ namespace cryptonote return destinations[0].addr.m_view_public_key; } //--------------------------------------------------------------- - bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, std::vector<tx_source_entry> sources, const std::vector<tx_destination_entry>& destinations, std::vector<uint8_t> extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, bool rct) + bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, std::vector<tx_source_entry>& sources, const std::vector<tx_destination_entry>& destinations, std::vector<uint8_t> extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, bool rct) { std::vector<rct::key> amount_keys; tx.set_null(); @@ -245,7 +245,7 @@ namespace cryptonote { LOG_ERROR("derived public key mismatch with output public key at index " << idx << ", real out " << src_entr.real_output << "! "<< ENDL << "derived_key:" << string_tools::pod_to_hex(in_ephemeral.pub) << ENDL << "real output_public_key:" - << string_tools::pod_to_hex(src_entr.outputs[src_entr.real_output].second) ); + << string_tools::pod_to_hex(src_entr.outputs[src_entr.real_output].second.dest) ); LOG_ERROR("amount " << src_entr.amount << ", rct " << src_entr.rct); LOG_ERROR("tx pubkey " << src_entr.real_out_tx_key << ", real_output_in_tx_index " << src_entr.real_output_in_tx_index); return false; @@ -264,6 +264,10 @@ namespace cryptonote tx.vin.push_back(input_to_key); } + // "Shuffle" outs + std::vector<tx_destination_entry> shuffled_dsts(destinations); + std::random_shuffle(shuffled_dsts.begin(), shuffled_dsts.end(), [](unsigned int i) { return crypto::rand<unsigned int>() % i; }); + // sort ins by their key image std::vector<size_t> ins_order(sources.size()); for (size_t n = 0; n < sources.size(); ++n) @@ -309,23 +313,6 @@ namespace cryptonote summary_outs_money += dst_entr.amount; } -#if 0 - // sort outs by their public key - std::vector<size_t> outs_order(tx.vout.size()); - for (size_t n = 0; n < tx.vout.size(); ++n) - outs_order[n] = n; - std::sort(outs_order.begin(), outs_order.end(), [&](size_t i0, size_t i1) { - const txout_to_key &tk0 = boost::get<txout_to_key>(tx.vout[i0].target); - const txout_to_key &tk1 = boost::get<txout_to_key>(tx.vout[i1].target); - return memcmp(&tk0.key, &tk1.key, sizeof(tk0.key)) < 0; - }); - tools::apply_permutation(outs_order, [&] (size_t i0, size_t i1) { - std::swap(tx.vout[i0], tx.vout[i1]); - if (!amount_keys.empty()) - std::swap(amount_keys[i0], amount_keys[i1]); - }); -#endif - //check money if(summary_outs_money > summary_inputs_money ) { @@ -488,7 +475,7 @@ namespace cryptonote return true; } //--------------------------------------------------------------- - bool construct_tx(const account_keys& sender_account_keys, const std::vector<tx_source_entry>& sources, const std::vector<tx_destination_entry>& destinations, std::vector<uint8_t> extra, transaction& tx, uint64_t unlock_time) + bool construct_tx(const account_keys& sender_account_keys, std::vector<tx_source_entry>& sources, const std::vector<tx_destination_entry>& destinations, std::vector<uint8_t> extra, transaction& tx, uint64_t unlock_time) { crypto::secret_key tx_key; return construct_tx_and_get_tx_key(sender_account_keys, sources, destinations, extra, tx, unlock_time, tx_key); diff --git a/src/cryptonote_core/cryptonote_tx_utils.h b/src/cryptonote_core/cryptonote_tx_utils.h index 69254fb5f..f2cc73545 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.h +++ b/src/cryptonote_core/cryptonote_tx_utils.h @@ -70,8 +70,8 @@ namespace cryptonote //--------------------------------------------------------------- crypto::public_key get_destination_view_key_pub(const std::vector<tx_destination_entry> &destinations, const account_keys &sender_keys); - bool construct_tx(const account_keys& sender_account_keys, const std::vector<tx_source_entry>& sources, const std::vector<tx_destination_entry>& destinations, std::vector<uint8_t> extra, transaction& tx, uint64_t unlock_time); - bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, std::vector<tx_source_entry> sources, const std::vector<tx_destination_entry>& destinations, std::vector<uint8_t> extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, bool rct = false); + bool construct_tx(const account_keys& sender_account_keys, std::vector<tx_source_entry>& sources, const std::vector<tx_destination_entry>& destinations, std::vector<uint8_t> extra, transaction& tx, uint64_t unlock_time); + bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, std::vector<tx_source_entry>& sources, const std::vector<tx_destination_entry>& destinations, std::vector<uint8_t> extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, bool rct = false); bool generate_genesis_block( block& bl diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp index d949a57b1..af46453cd 100644 --- a/src/daemon/command_parser_executor.cpp +++ b/src/daemon/command_parser_executor.cpp @@ -125,12 +125,17 @@ bool t_command_parser_executor::print_blockchain_info(const std::vector<std::str bool t_command_parser_executor::set_log_level(const std::vector<std::string>& args) { - if(args.size() != 1) + if(args.size() > 1) { std::cout << "use: set_log [<log_level_number_0-4> | <categories>]" << std::endl; return true; } + if (args.empty()) + { + return m_executor.set_log_categories("+"); + } + uint16_t l = 0; if(epee::string_tools::get_xtype_from_string(l, args[0])) { @@ -334,17 +339,18 @@ bool t_command_parser_executor::set_limit(const std::vector<std::string>& args) if(args.size()==0) { return m_executor.get_limit(); } - int limit; + int64_t limit; try { - limit = std::stoi(args[0]); + limit = std::stoll(args[0]); } - catch(std::invalid_argument& ex) { + catch(const std::invalid_argument& ex) { + std::cout << "failed to parse argument" << std::endl; return false; } - if (limit==-1) limit=128; - limit *= 1024; + if (limit > 0) + limit *= 1024; - return m_executor.set_limit(limit); + return m_executor.set_limit(limit, limit); } bool t_command_parser_executor::set_limit_up(const std::vector<std::string>& args) @@ -353,17 +359,18 @@ bool t_command_parser_executor::set_limit_up(const std::vector<std::string>& arg if(args.size()==0) { return m_executor.get_limit_up(); } - int limit; + int64_t limit; try { - limit = std::stoi(args[0]); + limit = std::stoll(args[0]); } - catch(std::invalid_argument& ex) { + catch(const std::invalid_argument& ex) { + std::cout << "failed to parse argument" << std::endl; return false; } - if (limit==-1) limit=128; - limit *= 1024; + if (limit > 0) + limit *= 1024; - return m_executor.set_limit_up(limit); + return m_executor.set_limit(0, limit); } bool t_command_parser_executor::set_limit_down(const std::vector<std::string>& args) @@ -372,17 +379,18 @@ bool t_command_parser_executor::set_limit_down(const std::vector<std::string>& a if(args.size()==0) { return m_executor.get_limit_down(); } - int limit; + int64_t limit; try { - limit = std::stoi(args[0]); + limit = std::stoll(args[0]); } - catch(std::invalid_argument& ex) { + catch(const std::invalid_argument& ex) { + std::cout << "failed to parse argument" << std::endl; return false; } - if (limit==-1) limit=128; - limit *= 1024; + if (limit > 0) + limit *= 1024; - return m_executor.set_limit_down(limit); + return m_executor.set_limit(limit, 0); } bool t_command_parser_executor::out_peers(const std::vector<std::string>& args) diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp index b9f503c6b..3f1543857 100644 --- a/src/daemon/command_server.cpp +++ b/src/daemon/command_server.cpp @@ -141,7 +141,7 @@ t_command_server::t_command_server( m_command_lookup.set_handler( "set_log" , std::bind(&t_command_parser_executor::set_log_level, &m_parser, p::_1) - , "set_log <level>|<categories> - Change current loglevel, <level> is a number 0-4" + , "set_log <level>|<{+,-,}categories> - Change current log level/categories, <level> is a number 0-4" ); m_command_lookup.set_handler( "diff" diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index 11e3a2252..ef593237c 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -599,7 +599,7 @@ bool t_rpc_command_executor::set_log_categories(const std::string &categories) { } } - tools::success_msg_writer() << "Log categories are now " << categories; + tools::success_msg_writer() << "Log categories are now " << res.categories; return true; } @@ -1130,48 +1130,115 @@ bool t_rpc_command_executor::print_status() bool t_rpc_command_executor::get_limit() { - int limit_down = epee::net_utils::connection_basic::get_rate_down_limit( ); - int limit_up = epee::net_utils::connection_basic::get_rate_up_limit( ); - std::cout << "limit-down is " << limit_down/1024 << " kB/s" << std::endl; - std::cout << "limit-up is " << limit_up/1024 << " kB/s" << std::endl; - return true; + cryptonote::COMMAND_RPC_GET_LIMIT::request req; + cryptonote::COMMAND_RPC_GET_LIMIT::response res; + + std::string failure_message = "Couldn't get limit"; + + if (m_is_rpc) + { + if (!m_rpc_client->rpc_request(req, res, "/get_limit", failure_message.c_str())) + { + return true; + } + } + else + { + if (!m_rpc_server->on_get_limit(req, res) || res.status != CORE_RPC_STATUS_OK) + { + tools::fail_msg_writer() << make_error(failure_message, res.status); + return true; + } + } + + tools::msg_writer() << "limit-down is " << res.limit_down/1024 << " kB/s"; + tools::msg_writer() << "limit-up is " << res.limit_up/1024 << " kB/s"; + return true; } -bool t_rpc_command_executor::set_limit(int limit) +bool t_rpc_command_executor::set_limit(int64_t limit_down, int64_t limit_up) { - epee::net_utils::connection_basic::set_rate_down_limit( limit ); - epee::net_utils::connection_basic::set_rate_up_limit( limit ); - std::cout << "Set limit-down to " << limit/1024 << " kB/s" << std::endl; - std::cout << "Set limit-up to " << limit/1024 << " kB/s" << std::endl; - return true; + cryptonote::COMMAND_RPC_SET_LIMIT::request req; + cryptonote::COMMAND_RPC_SET_LIMIT::response res; + + req.limit_down = limit_down; + req.limit_up = limit_up; + + std::string failure_message = "Couldn't set limit"; + + if (m_is_rpc) + { + if (!m_rpc_client->rpc_request(req, res, "/set_limit", failure_message.c_str())) + { + return true; + } + } + else + { + if (!m_rpc_server->on_set_limit(req, res) || res.status != CORE_RPC_STATUS_OK) + { + tools::fail_msg_writer() << make_error(failure_message, res.status); + return true; + } + } + + tools::msg_writer() << "Set limit-down to " << res.limit_down/1024 << " kB/s"; + tools::msg_writer() << "Set limit-up to " << res.limit_up/1024 << " kB/s"; + return true; } bool t_rpc_command_executor::get_limit_up() { - int limit_up = epee::net_utils::connection_basic::get_rate_up_limit( ); - std::cout << "limit-up is " << limit_up/1024 << " kB/s" << std::endl; - return true; -} + cryptonote::COMMAND_RPC_GET_LIMIT::request req; + cryptonote::COMMAND_RPC_GET_LIMIT::response res; -bool t_rpc_command_executor::set_limit_up(int limit) -{ - epee::net_utils::connection_basic::set_rate_up_limit( limit ); - std::cout << "Set limit-up to " << limit/1024 << " kB/s" << std::endl; - return true; + std::string failure_message = "Couldn't get limit"; + + if (m_is_rpc) + { + if (!m_rpc_client->rpc_request(req, res, "/get_limit", failure_message.c_str())) + { + return true; + } + } + else + { + if (!m_rpc_server->on_get_limit(req, res) || res.status != CORE_RPC_STATUS_OK) + { + tools::fail_msg_writer() << make_error(failure_message, res.status); + return true; + } + } + + tools::msg_writer() << "limit-up is " << res.limit_up/1024 << " kB/s"; + return true; } bool t_rpc_command_executor::get_limit_down() { - int limit_down = epee::net_utils::connection_basic::get_rate_down_limit( ); - std::cout << "limit-down is " << limit_down/1024 << " kB/s" << std::endl; - return true; -} + cryptonote::COMMAND_RPC_GET_LIMIT::request req; + cryptonote::COMMAND_RPC_GET_LIMIT::response res; -bool t_rpc_command_executor::set_limit_down(int limit) -{ - epee::net_utils::connection_basic::set_rate_down_limit( limit ); - std::cout << "Set limit-down to " << limit/1024 << " kB/s" << std::endl; - return true; + std::string failure_message = "Couldn't get limit"; + + if (m_is_rpc) + { + if (!m_rpc_client->rpc_request(req, res, "/get_limit", failure_message.c_str())) + { + return true; + } + } + else + { + if (!m_rpc_server->on_get_limit(req, res) || res.status != CORE_RPC_STATUS_OK) + { + tools::fail_msg_writer() << make_error(failure_message, res.status); + return true; + } + } + + tools::msg_writer() << "limit-down is " << res.limit_down/1024 << " kB/s"; + return true; } bool t_rpc_command_executor::out_peers(uint64_t limit) diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h index fc0b39654..d79707a6f 100644 --- a/src/daemon/rpc_command_executor.h +++ b/src/daemon/rpc_command_executor.h @@ -119,11 +119,7 @@ public: bool get_limit_down(); - bool set_limit(int limit); - - bool set_limit_up(int limit); - - bool set_limit_down(int limit); + bool set_limit(int64_t limit_down, int64_t limit_up); bool out_peers(uint64_t limit); diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index f1ca50f76..6162d649b 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -390,7 +390,7 @@ namespace nodetool ip::tcp::endpoint endpoint = *i; if (endpoint.address().is_v4()) { - epee::net_utils::network_address na(new epee::net_utils::ipv4_network_address(boost::asio::detail::socket_ops::host_to_network_long(endpoint.address().to_v4().to_ulong()), endpoint.port())); + epee::net_utils::network_address na{epee::net_utils::ipv4_network_address{boost::asio::detail::socket_ops::host_to_network_long(endpoint.address().to_v4().to_ulong()), endpoint.port()}}; seed_nodes.push_back(na); MINFO("Added seed node: " << na.str()); } @@ -1521,7 +1521,7 @@ namespace nodetool return false; std::string ip = epee::string_tools::get_ip_string_from_int32(actual_ip); std::string port = epee::string_tools::num_to_string_fast(node_data.my_port); - epee::net_utils::network_address address(new epee::net_utils::ipv4_network_address(actual_ip, node_data.my_port)); + epee::net_utils::network_address address{epee::net_utils::ipv4_network_address(actual_ip, node_data.my_port)}; peerid_type pr = node_data.peer_id; bool r = m_net_server.connect_async(ip, port, m_config.m_net_config.ping_connection_timeout, [cb, /*context,*/ address, pr, this]( const typename net_server::t_connection_context& ping_context, @@ -1669,7 +1669,7 @@ namespace nodetool if(arg.node_data.peer_id != m_config.m_peer_id && arg.node_data.my_port) { peerid_type peer_id_l = arg.node_data.peer_id; - uint32_t port_l = arg.node_data.my_port; + uint32_t port_l = arg.node_data.my_port; //try ping to be sure that we can add this peer to peer_list try_ping(arg.node_data, context, [peer_id_l, port_l, context, this]() { @@ -1678,7 +1678,7 @@ namespace nodetool //called only(!) if success pinged, update local peerlist peerlist_entry pe; const epee::net_utils::network_address na = context.m_remote_address; - pe.adr.reset(new epee::net_utils::ipv4_network_address(na.as<epee::net_utils::ipv4_network_address>().ip(), port_l)); + pe.adr = epee::net_utils::ipv4_network_address(na.as<epee::net_utils::ipv4_network_address>().ip(), port_l); time_t last_seen; time(&last_seen); pe.last_seen = static_cast<int64_t>(last_seen); diff --git a/src/p2p/net_peerlist_boost_serialization.h b/src/p2p/net_peerlist_boost_serialization.h index 6ea2d48fd..079524aa1 100644 --- a/src/p2p/net_peerlist_boost_serialization.h +++ b/src/p2p/net_peerlist_boost_serialization.h @@ -31,11 +31,19 @@ #pragma once #include "net/net_utils_base.h" +#include "p2p/p2p_protocol_defs.h" namespace boost { namespace serialization { + template <class T, class Archive> + inline void do_serialize(Archive &a, epee::net_utils::network_address& na, T local) + { + if (typename Archive::is_saving()) local = na.as<T>(); + a & local; + if (!typename Archive::is_saving()) na = local; + } template <class Archive, class ver_type> inline void serialize(Archive &a, epee::net_utils::network_address& na, const ver_type ver) { @@ -46,10 +54,8 @@ namespace boost switch (type) { case epee::net_utils::ipv4_network_address::ID: - if (!typename Archive::is_saving()) - na.reset(new epee::net_utils::ipv4_network_address(0, 0)); - a & na.as<epee::net_utils::ipv4_network_address>(); - break; + do_serialize(a, na, epee::net_utils::ipv4_network_address{0, 0}); + break; default: throw std::runtime_error("Unsupported network address type"); } @@ -57,13 +63,14 @@ namespace boost template <class Archive, class ver_type> inline void serialize(Archive &a, epee::net_utils::ipv4_network_address& na, const ver_type ver) { - a & na.m_ip; - a & na.m_port; + uint32_t ip{na.ip()}; + uint16_t port{na.port()}; + a & ip; + a & port; if (!typename Archive::is_saving()) - na.init_ids(); + na = epee::net_utils::ipv4_network_address{ip, port}; } - template <class Archive, class ver_type> inline void serialize(Archive &a, nodetool::peerlist_entry& pl, const ver_type ver) { diff --git a/src/p2p/p2p_protocol_defs.h b/src/p2p/p2p_protocol_defs.h index f2b2cd1da..d49d83989 100644 --- a/src/p2p/p2p_protocol_defs.h +++ b/src/p2p/p2p_protocol_defs.h @@ -120,7 +120,7 @@ namespace nodetool ss << std::setfill ('0') << std::setw (8) << std::hex << std::noshowbase; for(const peerlist_entry& pe: pl) { - ss << pe.id << "\t" << pe.adr->str() << " \tlast_seen: " << epee::misc_utils::get_time_interval_string(now_time - pe.last_seen) << std::endl; + ss << pe.id << "\t" << pe.adr.str() << " \tlast_seen: " << epee::misc_utils::get_time_interval_string(now_time - pe.last_seen) << std::endl; } return ss.str(); } @@ -216,7 +216,7 @@ namespace nodetool std::list<peerlist_entry_base<network_address_old>> local_peerlist; epee::serialization::selector<is_store>::serialize_stl_container_pod_val_as_blob(local_peerlist, stg, hparent_section, "local_peerlist"); for (const auto &p: local_peerlist) - ((response&)this_ref).local_peerlist_new.push_back(peerlist_entry({new epee::net_utils::ipv4_network_address(p.adr.ip, p.adr.port), p.id, p.last_seen})); + ((response&)this_ref).local_peerlist_new.push_back(peerlist_entry({epee::net_utils::ipv4_network_address(p.adr.ip, p.adr.port), p.id, p.last_seen})); } } END_KV_SERIALIZE_MAP() @@ -275,7 +275,7 @@ namespace nodetool std::list<peerlist_entry_base<network_address_old>> local_peerlist; epee::serialization::selector<is_store>::serialize_stl_container_pod_val_as_blob(local_peerlist, stg, hparent_section, "local_peerlist"); for (const auto &p: local_peerlist) - ((response&)this_ref).local_peerlist_new.push_back(peerlist_entry({new epee::net_utils::ipv4_network_address(p.adr.ip, p.adr.port), p.id, p.last_seen})); + ((response&)this_ref).local_peerlist_new.push_back(peerlist_entry({epee::net_utils::ipv4_network_address(p.adr.ip, p.adr.port), p.id, p.last_seen})); } } END_KV_SERIALIZE_MAP() diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index e814dcc1e..b9678f414 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -831,6 +831,7 @@ namespace cryptonote bool core_rpc_server::on_set_log_categories(const COMMAND_RPC_SET_LOG_CATEGORIES::request& req, COMMAND_RPC_SET_LOG_CATEGORIES::response& res) { mlog_set_log(req.categories.c_str()); + res.categories = mlog_get_categories(); res.status = CORE_RPC_STATUS_OK; return true; } @@ -1394,7 +1395,7 @@ namespace cryptonote } else { - na.reset(new epee::net_utils::ipv4_network_address(i->ip, 0)); + na = epee::net_utils::ipv4_network_address{i->ip, 0}; } if (i->ban) m_p2p.block_host(na, i->seconds); @@ -1533,6 +1534,53 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool core_rpc_server::on_get_limit(const COMMAND_RPC_GET_LIMIT::request& req, COMMAND_RPC_GET_LIMIT::response& res) + { + res.limit_down = epee::net_utils::connection_basic::get_rate_down_limit(); + res.limit_up = epee::net_utils::connection_basic::get_rate_up_limit(); + res.status = CORE_RPC_STATUS_OK; + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ + bool core_rpc_server::on_set_limit(const COMMAND_RPC_SET_LIMIT::request& req, COMMAND_RPC_SET_LIMIT::response& res) + { + // -1 = reset to default + // 0 = do not modify + + if (req.limit_down > 0) + { + epee::net_utils::connection_basic::set_rate_down_limit(req.limit_down); + } + else if (req.limit_down < 0) + { + if (req.limit_down != -1) + { + res.status = CORE_RPC_ERROR_CODE_WRONG_PARAM; + return false; + } + epee::net_utils::connection_basic::set_rate_down_limit(nodetool::default_limit_down * 1024); + } + + if (req.limit_up > 0) + { + epee::net_utils::connection_basic::set_rate_up_limit(req.limit_up); + } + else if (req.limit_up < 0) + { + if (req.limit_up != -1) + { + res.status = CORE_RPC_ERROR_CODE_WRONG_PARAM; + return false; + } + epee::net_utils::connection_basic::set_rate_up_limit(nodetool::default_limit_up * 1024); + } + + res.limit_down = epee::net_utils::connection_basic::get_rate_down_limit(); + res.limit_up = epee::net_utils::connection_basic::get_rate_up_limit(); + res.status = CORE_RPC_STATUS_OK; + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ bool core_rpc_server::on_out_peers(const COMMAND_RPC_OUT_PEERS::request& req, COMMAND_RPC_OUT_PEERS::response& res) { // TODO @@ -1571,8 +1619,10 @@ namespace cryptonote static const char software[] = "monero"; #ifdef BUILD_TAG static const char buildtag[] = BOOST_PP_STRINGIZE(BUILD_TAG); + static const char subdir[] = "cli"; #else static const char buildtag[] = "source"; + static const char subdir[] = "source"; #endif if (req.command != "check" && req.command != "download" && req.command != "update") @@ -1595,8 +1645,8 @@ namespace cryptonote } res.update = true; res.version = version; - res.user_uri = tools::get_update_url(software, "cli", buildtag, version, true); - res.auto_uri = tools::get_update_url(software, "cli", buildtag, version, false); + res.user_uri = tools::get_update_url(software, subdir, buildtag, version, true); + res.auto_uri = tools::get_update_url(software, subdir, buildtag, version, false); res.hash = hash; if (req.command == "check") { diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index dbbe07972..73a308a72 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -97,6 +97,8 @@ namespace cryptonote MAP_URI_AUTO_JON2("/get_transaction_pool_stats", on_get_transaction_pool_stats, COMMAND_RPC_GET_TRANSACTION_POOL_STATS) MAP_URI_AUTO_JON2_IF("/stop_daemon", on_stop_daemon, COMMAND_RPC_STOP_DAEMON, !m_restricted) MAP_URI_AUTO_JON2("/getinfo", on_get_info, COMMAND_RPC_GET_INFO) + MAP_URI_AUTO_JON2("/get_limit", on_get_limit, COMMAND_RPC_GET_LIMIT) + MAP_URI_AUTO_JON2_IF("/set_limit", on_set_limit, COMMAND_RPC_SET_LIMIT, !m_restricted) MAP_URI_AUTO_JON2_IF("/out_peers", on_out_peers, COMMAND_RPC_OUT_PEERS, !m_restricted) MAP_URI_AUTO_JON2_IF("/start_save_graph", on_start_save_graph, COMMAND_RPC_START_SAVE_GRAPH, !m_restricted) MAP_URI_AUTO_JON2_IF("/stop_save_graph", on_stop_save_graph, COMMAND_RPC_STOP_SAVE_GRAPH, !m_restricted) @@ -155,6 +157,8 @@ namespace cryptonote bool on_get_transaction_pool_hashes(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::response& res); bool on_get_transaction_pool_stats(const COMMAND_RPC_GET_TRANSACTION_POOL_STATS::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_STATS::response& res); bool on_stop_daemon(const COMMAND_RPC_STOP_DAEMON::request& req, COMMAND_RPC_STOP_DAEMON::response& res); + bool on_get_limit(const COMMAND_RPC_GET_LIMIT::request& req, COMMAND_RPC_GET_LIMIT::response& res); + bool on_set_limit(const COMMAND_RPC_SET_LIMIT::request& req, COMMAND_RPC_SET_LIMIT::response& res); bool on_out_peers(const COMMAND_RPC_OUT_PEERS::request& req, COMMAND_RPC_OUT_PEERS::response& res); bool on_start_save_graph(const COMMAND_RPC_START_SAVE_GRAPH::request& req, COMMAND_RPC_START_SAVE_GRAPH::response& res); bool on_stop_save_graph(const COMMAND_RPC_STOP_SAVE_GRAPH::request& req, COMMAND_RPC_STOP_SAVE_GRAPH::response& res); diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 99430bf20..85ac2ca30 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -981,8 +981,11 @@ namespace cryptonote struct response { std::string status; + std::string categories; + BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(status) + KV_SERIALIZE(categories) END_KV_SERIALIZE_MAP() }; }; @@ -1244,6 +1247,55 @@ namespace cryptonote }; }; + struct COMMAND_RPC_GET_LIMIT + { + struct request + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::string status; + uint64_t limit_up; + uint64_t limit_down; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(status) + KV_SERIALIZE(limit_up) + KV_SERIALIZE(limit_down) + END_KV_SERIALIZE_MAP() + }; + }; + + struct COMMAND_RPC_SET_LIMIT + { + struct request + { + int64_t limit_down; + int64_t limit_up; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(limit_down) + KV_SERIALIZE(limit_up) + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::string status; + uint64_t limit_up; + uint64_t limit_down; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(status) + KV_SERIALIZE(limit_up) + KV_SERIALIZE(limit_down) + END_KV_SERIALIZE_MAP() + }; + }; + struct COMMAND_RPC_OUT_PEERS { struct request diff --git a/src/serialization/json_object.cpp b/src/serialization/json_object.cpp index e35389f9c..a40821d19 100644 --- a/src/serialization/json_object.cpp +++ b/src/serialization/json_object.cpp @@ -776,6 +776,7 @@ void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::tx_in_pool& tx) GET_FROM_JSON_OBJECT(val, tx.receive_time, receive_time); GET_FROM_JSON_OBJECT(val, tx.last_relayed_time, last_relayed_time); GET_FROM_JSON_OBJECT(val, tx.relayed, relayed); + GET_FROM_JSON_OBJECT(val, tx.do_not_relay, do_not_relay); } void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::hard_fork_info& info, rapidjson::Value& val) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 937403c66..314670327 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -735,6 +735,24 @@ bool simple_wallet::set_confirm_backlog(const std::vector<std::string> &args/* = return true; } +bool simple_wallet::set_confirm_backlog_threshold(const std::vector<std::string> &args/* = std::vector<std::string>()*/) +{ + uint32_t threshold; + if (!string_tools::get_xtype_from_string(threshold, args[1])) + { + fail_msg_writer() << tr("invalid count: must be an unsigned integer"); + return true; + } + + const auto pwd_container = get_and_verify_password(); + if (pwd_container) + { + m_wallet->set_confirm_backlog_threshold(threshold); + m_wallet->rewrite(m_wallet_file, pwd_container->password()); + } + return true; +} + bool simple_wallet::help(const std::vector<std::string> &args/* = std::vector<std::string>()*/) { success_msg_writer() << get_commands_str(); @@ -766,7 +784,7 @@ simple_wallet::simple_wallet() 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>)")); + 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>)")); m_cmd_binder.set_handler("address", boost::bind(&simple_wallet::print_address, this, _1), tr("Show current wallet public address")); m_cmd_binder.set_handler("integrated_address", boost::bind(&simple_wallet::print_integrated_address, this, _1), tr("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")); m_cmd_binder.set_handler("address_book", boost::bind(&simple_wallet::address_book, this, _1), tr("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")); @@ -775,7 +793,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-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; confirm-backlog <1|0> - whether to warn if there is transaction backlog")); + 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; confirm-backlog <1|0> - whether to warn if there is transaction backlog; confirm-backlog-threshold [n] - sets a threshold for confirm-backlog to only warn if the transaction backlog is greater than n blocks")); m_cmd_binder.set_handler("encrypted_seed", boost::bind(&simple_wallet::encrypted_seed, this, _1), tr("Display encrypted Electrum-style mnemonic seed")); 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>")); @@ -821,6 +839,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args) success_msg_writer() << "min-outputs-value = " << cryptonote::print_money(m_wallet->get_min_output_value()); success_msg_writer() << "merge-destinations = " << m_wallet->merge_destinations(); success_msg_writer() << "confirm-backlog = " << m_wallet->confirm_backlog(); + success_msg_writer() << "confirm-backlog-threshold = " << m_wallet->get_confirm_backlog_threshold(); return true; } else @@ -867,6 +886,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args) CHECK_SIMPLE_VARIABLE("min-outputs-value", set_min_output_value, tr("amount")); CHECK_SIMPLE_VARIABLE("merge-destinations", set_merge_destinations, tr("0 or 1")); CHECK_SIMPLE_VARIABLE("confirm-backlog", set_confirm_backlog, tr("0 or 1")); + CHECK_SIMPLE_VARIABLE("confirm-backlog-threshold", set_confirm_backlog_threshold, tr("unsigned integer")); } fail_msg_writer() << tr("set: unrecognized argument(s)"); return true; @@ -875,12 +895,14 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args) //---------------------------------------------------------------------------------------------------- bool simple_wallet::set_log(const std::vector<std::string> &args) { - if(args.size() != 1) + if(args.size() > 1) { fail_msg_writer() << tr("usage: set_log <log_level_number_0-4> | <categories>"); return true; } - mlog_set_log(args[0].c_str()); + if (!args.empty()) + mlog_set_log(args[0].c_str()); + success_msg_writer() << "New log categories: " << mlog_get_categories(); return true; } //---------------------------------------------------------------------------------------------------- @@ -1424,6 +1446,9 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) } catch (const std::exception &e) { } + if (!m_trusted_daemon) + message_writer() << (boost::format(tr("Warning: using an untrusted daemon at %s, privacy will be lessened")) % m_wallet->get_daemon_address()).str(); + m_http_client.set_server(m_wallet->get_daemon_address(), m_wallet->get_daemon_login()); m_wallet->callback(this); @@ -2562,7 +2587,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri } else { - if (nblocks[0].first > 0) + if (nblocks[0].first > m_wallet->get_confirm_backlog_threshold()) prompt << (boost::format(tr("There is currently a %u block backlog at that fee level. Is this okay? (Y/Yes/N/No)")) % nblocks[0].first).str(); } } diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 3b29e3ca2..6c6d0cf05 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -122,6 +122,7 @@ namespace cryptonote bool set_min_output_value(const std::vector<std::string> &args = std::vector<std::string>()); bool set_merge_destinations(const std::vector<std::string> &args = std::vector<std::string>()); bool set_confirm_backlog(const std::vector<std::string> &args = std::vector<std::string>()); + bool set_confirm_backlog_threshold(const std::vector<std::string> &args = std::vector<std::string>()); bool help(const std::vector<std::string> &args = std::vector<std::string>()); bool start_mining(const std::vector<std::string> &args); bool stop_mining(const std::vector<std::string> &args); diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt index fe87d0de1..b62c084be 100644 --- a/src/wallet/CMakeLists.txt +++ b/src/wallet/CMakeLists.txt @@ -125,7 +125,16 @@ endif() # build and install libwallet_merged only if we building for GUI if (BUILD_GUI_DEPS) - set(libs_to_merge wallet cryptonote_core cryptonote_basic mnemonics common cncrypto ringct) + set(libs_to_merge + wallet + cryptonote_core + cryptonote_basic + mnemonics + common + cncrypto + ringct + checkpoints + version) foreach(lib ${libs_to_merge}) list(APPEND objlibs $<TARGET_OBJECTS:obj_${lib}>) # matches naming convention in src/CMakeLists.txt diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 4ad8ea2c1..dc4f4879b 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -33,6 +33,7 @@ #include <boost/format.hpp> #include <boost/optional/optional.hpp> #include <boost/utility/value_init.hpp> +#include <boost/algorithm/string/join.hpp> #include "include_base_utils.h" using namespace epee; @@ -430,6 +431,20 @@ static void throw_on_rpc_response_error(const boost::optional<std::string> &stat THROW_WALLET_EXCEPTION_IF(*status != CORE_RPC_STATUS_OK, tools::error::wallet_generic_rpc_error, method, *status); } +std::string strjoin(const std::vector<size_t> &V, const char *sep) +{ + std::stringstream ss; + bool first = true; + for (const auto &v: V) + { + if (!first) + ss << sep; + ss << std::to_string(v); + first = false; + } + return ss.str(); +} + } //namespace namespace tools @@ -643,16 +658,10 @@ static uint64_t decodeRct(const rct::rctSig & rv, const crypto::public_key &pub, } } //---------------------------------------------------------------------------------------------------- -bool wallet2::wallet_generate_key_image_helper(const cryptonote::account_keys& ack, const crypto::public_key& tx_public_key, size_t real_output_index, cryptonote::keypair& in_ephemeral, crypto::key_image& ki) -{ - if (!cryptonote::generate_key_image_helper(ack, tx_public_key, real_output_index, in_ephemeral, ki)) - return false; - return true; -} -//---------------------------------------------------------------------------------------------------- void wallet2::scan_output(const cryptonote::account_keys &keys, const cryptonote::transaction &tx, const crypto::public_key &tx_pub_key, size_t i, tx_scan_info_t &tx_scan_info, int &num_vouts_received, uint64_t &tx_money_got_in_outs, std::vector<size_t> &outs) { - wallet_generate_key_image_helper(keys, tx_pub_key, i, tx_scan_info.in_ephemeral, tx_scan_info.ki); + bool r = cryptonote::generate_key_image_helper(keys, tx_pub_key, i, tx_scan_info.in_ephemeral, tx_scan_info.ki); + THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to generate key image"); THROW_WALLET_EXCEPTION_IF(tx_scan_info.in_ephemeral.pub != boost::get<cryptonote::txout_to_key>(tx.vout[i].target).key, error::wallet_internal_error, "key_image generated ephemeral public key not matched with output_key"); @@ -1100,7 +1109,10 @@ void wallet2::get_short_chain_history(std::list<crypto::hash>& ids) const size_t current_multiplier = 1; size_t sz = m_blockchain.size() - m_blockchain.offset(); if(!sz) + { + ids.push_back(m_blockchain.genesis()); return; + } size_t current_back_offset = 1; bool base_included = false; while(current_back_offset < sz) @@ -1205,6 +1217,7 @@ void wallet2::process_blocks(uint64_t start_height, const std::list<cryptonote:: size_t tx_o_indices_idx = 0; THROW_WALLET_EXCEPTION_IF(blocks.size() != o_indices.size(), error::wallet_internal_error, "size mismatch"); + THROW_WALLET_EXCEPTION_IF(!m_blockchain.is_in_bounds(current_index), error::wallet_internal_error, "Index out of bounds of hashchain"); tools::threadpool& tpool = tools::threadpool::getInstance(); int threads = tpool.get_max_concurrency(); @@ -1920,6 +1933,9 @@ bool wallet2::store_keys(const std::string& keys_file_name, const std::string& p value2.SetInt(m_confirm_backlog ? 1 :0); json.AddMember("confirm_backlog", value2, json.GetAllocator()); + value2.SetUint(m_confirm_backlog_threshold); + json.AddMember("confirm_backlog_threshold", value2, json.GetAllocator()); + value2.SetInt(m_testnet ? 1 :0); json.AddMember("testnet", value2, json.GetAllocator()); @@ -1995,6 +2011,7 @@ bool wallet2::load_keys(const std::string& keys_file_name, const std::string& pa m_min_output_value = 0; m_merge_destinations = false; m_confirm_backlog = true; + m_confirm_backlog_threshold = 0; } else { @@ -2067,6 +2084,8 @@ bool wallet2::load_keys(const std::string& keys_file_name, const std::string& pa m_merge_destinations = field_merge_destinations; GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, confirm_backlog, int, Int, false, true); m_confirm_backlog = field_confirm_backlog; + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, confirm_backlog_threshold, uint32_t, Uint, false, 0); + m_confirm_backlog_threshold = field_confirm_backlog_threshold; 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"); @@ -2547,7 +2566,30 @@ void wallet2::load(const std::string& wallet_, const std::string& password) void wallet2::trim_hashchain() { uint64_t height = m_checkpoints.get_max_height(); - if (height > 0) + if (!m_blockchain.empty() && m_blockchain.size() == m_blockchain.offset()) + { + MINFO("Fixing empty hashchain"); + epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::request> req = AUTO_VAL_INIT(req); + epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::response, std::string> res = AUTO_VAL_INIT(res); + m_daemon_rpc_mutex.lock(); + req.jsonrpc = "2.0"; + req.id = epee::serialization::storage_entry(0); + req.method = "getblockheaderbyheight"; + req.params.height = m_blockchain.size() - 1; + bool r = net_utils::invoke_http_json("/json_rpc", req, res, m_http_client, rpc_timeout); + m_daemon_rpc_mutex.unlock(); + if (r && res.result.status == CORE_RPC_STATUS_OK) + { + crypto::hash hash; + epee::string_tools::hex_to_pod(res.result.block_header.hash, hash); + m_blockchain.refill(hash); + } + else + { + MERROR("Failed to request block header from daemon, hash chain may be unable to sync till the wallet is loaded with a usable daemon"); + } + } + if (height > 0 && m_blockchain.size() > height) { --height; MDEBUG("trimming to " << height << ", offset " << m_blockchain.offset()); @@ -3292,7 +3334,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, const std::string &signed_f signed_tx_set signed_txes; for (size_t n = 0; n < exported_txs.txes.size(); ++n) { - const tools::wallet2::tx_construction_data &sd = exported_txs.txes[n]; + tools::wallet2::tx_construction_data &sd = exported_txs.txes[n]; 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(); @@ -4331,7 +4373,8 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp } else { - THROW_WALLET_EXCEPTION_IF(original_output_index > dsts.size(), error::wallet_internal_error, "original_output_index too large"); + THROW_WALLET_EXCEPTION_IF(original_output_index > dsts.size(), error::wallet_internal_error, + std::string("original_output_index too large: ") + std::to_string(original_output_index) + " > " + std::to_string(dsts.size())); if (original_output_index == dsts.size()) dsts.push_back(tx_destination_entry(0,addr)); THROW_WALLET_EXCEPTION_IF(memcmp(&dsts[original_output_index].addr, &addr, sizeof(addr)), error::wallet_internal_error, "Mismatched destination address"); @@ -4430,12 +4473,8 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp TX &tx = txes.back(); LOG_PRINT_L2("Start of loop with " << unused_transfers_indices.size() << " " << unused_dust_indices.size()); - LOG_PRINT_L2("unused_transfers_indices:"); - for (auto t: unused_transfers_indices) - LOG_PRINT_L2(" " << t); - LOG_PRINT_L2("unused_dust_indices:"); - for (auto t: unused_dust_indices) - LOG_PRINT_L2(" " << t); + LOG_PRINT_L2("unused_transfers_indices: " << strjoin(unused_transfers_indices, " ")); + LOG_PRINT_L2("unused_dust_indices:" << strjoin(unused_dust_indices, " ")); LOG_PRINT_L2("dsts size " << dsts.size() << ", first " << (dsts.empty() ? -1 : dsts[0].amount)); LOG_PRINT_L2("adding_fee " << adding_fee << ", use_rct " << use_rct); @@ -4609,6 +4648,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp { LOG_PRINT_L2("We have more to pay, starting another tx"); txes.push_back(TX()); + original_output_index = 0; } } } @@ -5222,7 +5262,8 @@ std::vector<std::pair<crypto::key_image, crypto::signature>> wallet2::export_key // generate ephemeral secret key crypto::key_image ki; cryptonote::keypair in_ephemeral; - cryptonote::generate_key_image_helper(m_account.get_keys(), tx_pub_key, td.m_internal_output_index, in_ephemeral, ki); + bool r = cryptonote::generate_key_image_helper(m_account.get_keys(), tx_pub_key, td.m_internal_output_index, in_ephemeral, ki); + THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to generate key image"); THROW_WALLET_EXCEPTION_IF(td.m_key_image_known && ki != td.m_key_image, error::wallet_internal_error, "key_image generated not matched with cached key image"); @@ -5618,7 +5659,8 @@ size_t wallet2::import_outputs(const std::vector<tools::wallet2::transfer_detail "Transaction extra has unsupported format at index " + boost::lexical_cast<std::string>(i)); crypto::public_key tx_pub_key = get_tx_pub_key_from_received_outs(td); - cryptonote::generate_key_image_helper(m_account.get_keys(), tx_pub_key, td.m_internal_output_index, in_ephemeral, td.m_key_image); + bool r = cryptonote::generate_key_image_helper(m_account.get_keys(), tx_pub_key, td.m_internal_output_index, in_ephemeral, td.m_key_image); + THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to generate key image"); td.m_key_image_known = true; THROW_WALLET_EXCEPTION_IF(in_ephemeral.pub != boost::get<cryptonote::txout_to_key>(td.m_tx.vout[td.m_internal_output_index].target).key, error::wallet_internal_error, "key_image generated ephemeral public key not matched with output_key at index " + boost::lexical_cast<std::string>(i)); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 83863ca54..e31ad5dc8 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -108,7 +108,8 @@ namespace tools void crop(size_t height) { m_blockchain.resize(height - m_offset); } void clear() { m_offset = 0; m_blockchain.clear(); } bool empty() const { return m_blockchain.empty() && m_offset == 0; } - void trim(size_t height) { while (height > m_offset && !m_blockchain.empty()) { m_blockchain.pop_front(); ++m_offset; } m_blockchain.shrink_to_fit(); } + void trim(size_t height) { while (height > m_offset+1 && m_blockchain.size() > 1) { m_blockchain.pop_front(); ++m_offset; } m_blockchain.shrink_to_fit(); } + void refill(const crypto::hash &hash) { m_blockchain.push_back(hash); --m_offset; } template <class t_archive> inline void serialize(t_archive &a, const unsigned int ver) @@ -599,6 +600,8 @@ namespace tools bool merge_destinations() const { return m_merge_destinations; } bool confirm_backlog() const { return m_confirm_backlog; } void confirm_backlog(bool always) { m_confirm_backlog = always; } + void set_confirm_backlog_threshold(uint32_t threshold) { m_confirm_backlog_threshold = threshold; }; + uint32_t get_confirm_backlog_threshold() const { return m_confirm_backlog_threshold; }; bool get_tx_key(const crypto::hash &txid, crypto::secret_key &tx_key) const; @@ -718,7 +721,6 @@ namespace tools void set_spent(size_t idx, uint64_t height); void set_unspent(size_t idx); void get_outs(std::vector<std::vector<get_outs_entry>> &outs, const std::list<size_t> &selected_transfers, size_t fake_outputs_count); - bool wallet_generate_key_image_helper(const cryptonote::account_keys& ack, const crypto::public_key& tx_public_key, size_t real_output_index, cryptonote::keypair& in_ephemeral, crypto::key_image& ki); crypto::public_key get_tx_pub_key_from_received_outs(const tools::wallet2::transfer_details &td) const; bool should_pick_a_second_output(bool use_rct, size_t n_transfers, const std::vector<size_t> &unused_transfers_indices, const std::vector<size_t> &unused_dust_indices) const; std::vector<size_t> get_only_rct(const std::vector<size_t> &unused_dust_indices, const std::vector<size_t> &unused_transfers_indices) const; @@ -772,6 +774,7 @@ namespace tools uint64_t m_min_output_value; bool m_merge_destinations; bool m_confirm_backlog; + uint32_t m_confirm_backlog_threshold; bool m_is_initialized; NodeRPCProxy m_node_rpc_proxy; std::unordered_set<crypto::hash> m_scanned_pool_txs[2]; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 85763f8b5..a5f5335db 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -30,6 +30,7 @@ # The docs say this only affects grouping in IDEs set(folder "tests") +set(TEST_DATA_DIR "${CMAKE_CURRENT_LIST_DIR}/data") if (WIN32 AND STATIC) add_definitions(-DSTATICLIB) diff --git a/tests/performance_tests/construct_tx.h b/tests/performance_tests/construct_tx.h index 0610c86ed..90e4cf76e 100644 --- a/tests/performance_tests/construct_tx.h +++ b/tests/performance_tests/construct_tx.h @@ -43,7 +43,7 @@ class test_construct_tx : private multi_tx_test_base<a_in_count> static_assert(0 < a_out_count, "out_count must be greater than 0"); public: - static const size_t loop_count = (a_in_count + a_out_count < 100) ? 100 : 10; + static const size_t loop_count = (a_in_count + a_out_count < 10) ? (a_rct ? 10 : 200) : (a_in_count + a_out_count) < 100 ? (a_rct ? 5 : 25) : 5; static const size_t in_count = a_in_count; static const size_t out_count = a_out_count; static const bool rct = a_rct; diff --git a/tests/performance_tests/derive_secret_key.h b/tests/performance_tests/derive_secret_key.h index 1a2945a77..f97deb974 100644 --- a/tests/performance_tests/derive_secret_key.h +++ b/tests/performance_tests/derive_secret_key.h @@ -38,7 +38,7 @@ class test_derive_secret_key : public single_tx_test_base { public: - static const size_t loop_count = 1000000; + static const size_t loop_count = 10000; bool init() { diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt index 53d93fcce..1dac92bed 100644 --- a/tests/unit_tests/CMakeLists.txt +++ b/tests/unit_tests/CMakeLists.txt @@ -100,4 +100,4 @@ endif () add_test( NAME unit_tests - COMMAND unit_tests) + COMMAND unit_tests "${TEST_DATA_DIR}") diff --git a/tests/unit_tests/ban.cpp b/tests/unit_tests/ban.cpp index b8d57452e..d15716a42 100644 --- a/tests/unit_tests/ban.cpp +++ b/tests/unit_tests/ban.cpp @@ -33,7 +33,7 @@ #include "p2p/net_node.h" #include "cryptonote_protocol/cryptonote_protocol_handler.h" -#define MAKE_IPV4_ADDRESS(a,b,c,d) new epee::net_utils::ipv4_network_address(MAKE_IP(a,b,c,d),0) +#define MAKE_IPV4_ADDRESS(a,b,c,d) epee::net_utils::ipv4_network_address{MAKE_IP(a,b,c,d),0} namespace cryptonote { class blockchain_storage; diff --git a/tests/unit_tests/epee_utils.cpp b/tests/unit_tests/epee_utils.cpp index e8ddbe3f5..f6cb0c163 100644 --- a/tests/unit_tests/epee_utils.cpp +++ b/tests/unit_tests/epee_utils.cpp @@ -27,6 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <array> +#include <boost/endian/conversion.hpp> #include <boost/range/algorithm/equal.hpp> #include <boost/range/algorithm_ext/iota.hpp> #include <cstdint> @@ -42,7 +43,11 @@ # include <arpa/inet.h> #endif +#include "boost/archive/portable_binary_iarchive.hpp" +#include "boost/archive/portable_binary_oarchive.hpp" #include "hex.h" +#include "net/net_utils_base.h" +#include "p2p/net_peerlist_boost_serialization.h" #include "span.h" #include "string_tools.h" @@ -100,6 +105,40 @@ namespace boost::range::iota(out, 0); return out; } + + #define CHECK_EQUAL(lhs, rhs) \ + EXPECT_TRUE( lhs == rhs ); \ + EXPECT_TRUE( rhs == lhs ); \ + EXPECT_FALSE( lhs != rhs ); \ + EXPECT_FALSE( rhs != lhs ); \ + EXPECT_FALSE( lhs < rhs ); \ + EXPECT_FALSE( rhs < lhs ); \ + EXPECT_TRUE( lhs <= rhs ); \ + EXPECT_TRUE( rhs <= lhs ); \ + EXPECT_FALSE( lhs > rhs ); \ + EXPECT_FALSE( rhs > lhs ); \ + EXPECT_TRUE( lhs >= rhs ); \ + EXPECT_TRUE( rhs >= lhs ) + + #define CHECK_LESS(lhs, rhs) \ + EXPECT_FALSE( lhs == rhs ); \ + EXPECT_FALSE( rhs == lhs ); \ + EXPECT_TRUE( lhs != rhs ); \ + EXPECT_TRUE( rhs != lhs ); \ + EXPECT_TRUE( lhs < rhs ); \ + EXPECT_FALSE( rhs < lhs ); \ + EXPECT_TRUE( lhs <= rhs ); \ + EXPECT_FALSE( rhs <= lhs ); \ + EXPECT_FALSE( lhs > rhs ); \ + EXPECT_TRUE( rhs > lhs ); \ + EXPECT_FALSE( lhs >= rhs ); \ + EXPECT_TRUE( rhs >= lhs ) + + #ifdef BOOST_LITTLE_ENDIAN + #define CHECK_LESS_ENDIAN(lhs, rhs) CHECK_LESS( rhs , lhs ) + #else + #define CHECK_LESS_ENDIAN(lhs, rhs) CHECK_LESS( lhs , rhs ) + #endif } TEST(Span, Traits) @@ -419,3 +458,195 @@ TEST(StringTools, GetIpInt32) EXPECT_EQ(htonl(0xff0aff00), ip); } +TEST(NetUtils, IPv4NetworkAddress) +{ + const auto ip1 = boost::endian::native_to_big(0x330012FFu); + const auto ip_loopback = boost::endian::native_to_big(0x7F000001u); + const auto ip_local = boost::endian::native_to_big(0x0A000000u); + + epee::net_utils::ipv4_network_address address1{ip1, 65535}; + CHECK_EQUAL(address1, address1); + EXPECT_STREQ("51.0.18.255:65535", address1.str().c_str()); + EXPECT_STREQ("51.0.18.255", address1.host_str().c_str()); + EXPECT_FALSE(address1.is_loopback()); + EXPECT_FALSE(address1.is_local()); + EXPECT_EQ(epee::net_utils::ipv4_network_address::ID, address1.get_type_id()); + EXPECT_EQ(ip1, address1.ip()); + EXPECT_EQ(65535, address1.port()); + EXPECT_TRUE(epee::net_utils::ipv4_network_address{std::move(address1)} == address1); + EXPECT_TRUE(epee::net_utils::ipv4_network_address{address1} == address1); + + const epee::net_utils::ipv4_network_address loopback{ip_loopback, 0}; + CHECK_EQUAL(loopback, loopback); + CHECK_LESS_ENDIAN(address1, loopback); + EXPECT_STREQ("127.0.0.1:0", loopback.str().c_str()); + EXPECT_STREQ("127.0.0.1", loopback.host_str().c_str()); + EXPECT_TRUE(loopback.is_loopback()); + EXPECT_FALSE(loopback.is_local()); + EXPECT_EQ(epee::net_utils::ipv4_network_address::ID, address1.get_type_id()); + EXPECT_EQ(ip_loopback, loopback.ip()); + EXPECT_EQ(0, loopback.port()); + + const epee::net_utils::ipv4_network_address local{ip_local, 8080}; + CHECK_EQUAL(local, local); + CHECK_LESS(local, address1); + CHECK_LESS(local, loopback); + EXPECT_FALSE(local.is_loopback()); + EXPECT_TRUE(local.is_local()); + + epee::net_utils::ipv4_network_address address2{ip1, 55}; + CHECK_EQUAL(address2, address2); + CHECK_LESS_ENDIAN(address2, loopback); + CHECK_LESS(local, address2); + EXPECT_STREQ("51.0.18.255:55", address2.str().c_str()); + EXPECT_STREQ("51.0.18.255", address2.host_str().c_str()); + + + address2 = std::move(address1); + CHECK_EQUAL(address2, address1); + + address2 = local; + CHECK_EQUAL(address2, local); + CHECK_LESS(address2, address1); + + { + std::stringstream stream; + { + boost::archive::portable_binary_oarchive ostream{stream}; + ostream << address1; + } + { + boost::archive::portable_binary_iarchive istream{stream}; + istream >> address2; + } + } + CHECK_EQUAL(address1, address2); + EXPECT_EQ(ip1, address2.ip()); + EXPECT_EQ(65535, address2.port()); +} + +TEST(NetUtils, NetworkAddress) +{ + const auto ip1 = boost::endian::native_to_big(0x330012FFu); + const auto ip_loopback = boost::endian::native_to_big(0x7F000001u); + const auto ip_local = boost::endian::native_to_big(0x0A000000u); + + struct custom_address { + constexpr static bool equal(const custom_address&) noexcept { return false; } + constexpr static bool less(const custom_address&) noexcept { return false; } + constexpr static bool is_same_host(const custom_address&) noexcept { return false; } + constexpr static bool is_loopback() noexcept { return false; } + constexpr static bool is_local() noexcept { return false; } + static std::string str() { return {}; } + static std::string host_str() { return {}; } + constexpr static uint8_t get_type_id() noexcept { return uint8_t(-1); } + }; + + const epee::net_utils::network_address empty; + CHECK_EQUAL(empty, empty); + EXPECT_TRUE(empty.is_same_host(empty)); + EXPECT_STREQ("<none>", empty.str().c_str()); + EXPECT_STREQ("<none>", empty.host_str().c_str()); + EXPECT_FALSE(empty.is_loopback()); + EXPECT_FALSE(empty.is_local()); + EXPECT_EQ(0, empty.get_type_id()); + EXPECT_THROW(empty.as<custom_address>(), std::bad_cast); + + epee::net_utils::network_address address1{ + epee::net_utils::ipv4_network_address{ip1, 65535} + }; + CHECK_EQUAL(address1, address1); + CHECK_EQUAL(epee::net_utils::network_address{address1}, address1); + CHECK_LESS(empty, address1); + EXPECT_TRUE(address1.is_same_host(address1)); + EXPECT_FALSE(empty.is_same_host(address1)); + EXPECT_FALSE(address1.is_same_host(empty)); + EXPECT_STREQ("51.0.18.255:65535", address1.str().c_str()); + EXPECT_STREQ("51.0.18.255", address1.host_str().c_str()); + EXPECT_FALSE(address1.is_loopback()); + EXPECT_FALSE(address1.is_local()); + EXPECT_EQ(epee::net_utils::ipv4_network_address::ID, address1.get_type_id()); + EXPECT_NO_THROW(address1.as<epee::net_utils::ipv4_network_address>()); + EXPECT_THROW(address1.as<custom_address>(), std::bad_cast); + + const epee::net_utils::network_address loopback{ + epee::net_utils::ipv4_network_address{ip_loopback, 0} + }; + CHECK_EQUAL(loopback, loopback); + CHECK_LESS(empty, loopback); + CHECK_LESS_ENDIAN(address1, loopback); + EXPECT_TRUE(loopback.is_same_host(loopback)); + EXPECT_FALSE(loopback.is_same_host(address1)); + EXPECT_FALSE(address1.is_same_host(loopback)); + EXPECT_STREQ("127.0.0.1:0", loopback.str().c_str()); + EXPECT_STREQ("127.0.0.1", loopback.host_str().c_str()); + EXPECT_TRUE(loopback.is_loopback()); + EXPECT_FALSE(loopback.is_local()); + EXPECT_EQ(epee::net_utils::ipv4_network_address::ID, address1.get_type_id()); + + const epee::net_utils::network_address local{ + epee::net_utils::ipv4_network_address{ip_local, 8080} + }; + CHECK_EQUAL(local, local); + CHECK_LESS(local, loopback); + CHECK_LESS(local, address1); + EXPECT_FALSE(local.is_loopback()); + EXPECT_TRUE(local.is_local()); + + epee::net_utils::network_address address2{ + epee::net_utils::ipv4_network_address{ip1, 55} + }; + CHECK_EQUAL(address2, address2); + CHECK_LESS(address2, address1); + CHECK_LESS(local, address2); + CHECK_LESS_ENDIAN(address2, loopback); + EXPECT_TRUE(address1.is_same_host(address2)); + EXPECT_TRUE(address2.is_same_host(address1)); + EXPECT_STREQ("51.0.18.255:55", address2.str().c_str()); + EXPECT_STREQ("51.0.18.255", address2.host_str().c_str()); + + address2 = std::move(address1); + CHECK_EQUAL(address1, address1); + CHECK_EQUAL(empty, address1); + CHECK_LESS(address1, address2); + EXPECT_FALSE(address1.is_same_host(address2)); + EXPECT_FALSE(address2.is_same_host(address1)); + EXPECT_STREQ("51.0.18.255:65535", address2.str().c_str()); + EXPECT_STREQ("51.0.18.255", address2.host_str().c_str()); + EXPECT_FALSE(address1.is_loopback()); + EXPECT_FALSE(address1.is_local()); + EXPECT_THROW(address1.as<epee::net_utils::ipv4_network_address>(), std::bad_cast); + EXPECT_NO_THROW(address2.as<epee::net_utils::ipv4_network_address>()); + + address2 = local; + CHECK_EQUAL(address2, local); + CHECK_LESS(address1, address2); + EXPECT_TRUE(address2.is_same_host(local)); + EXPECT_TRUE(local.is_same_host(address2)); + EXPECT_FALSE(address2.is_same_host(address1)); + EXPECT_FALSE(address1.is_same_host(address2)); + + { + std::stringstream stream; + { + boost::archive::portable_binary_oarchive ostream{stream}; + ostream << address2; + } + { + boost::archive::portable_binary_iarchive istream{stream}; + istream >> address1; + } + } + CHECK_EQUAL(address1, address2); + EXPECT_TRUE(address1.is_same_host(address2)); + EXPECT_TRUE(address2.is_same_host(address1)); + EXPECT_NO_THROW(address1.as<epee::net_utils::ipv4_network_address>()); + + address1 = custom_address{}; + CHECK_EQUAL(address1, address1); + CHECK_LESS(address2, address1); + EXPECT_FALSE(address1.is_same_host(loopback)); + EXPECT_FALSE(loopback.is_same_host(address1)); + EXPECT_THROW(address1.as<epee::net_utils::ipv4_network_address>(), std::bad_cast); + EXPECT_NO_THROW(address1.as<custom_address>()); +} diff --git a/tests/unit_tests/main.cpp b/tests/unit_tests/main.cpp index b470249a3..b2abad942 100644 --- a/tests/unit_tests/main.cpp +++ b/tests/unit_tests/main.cpp @@ -30,14 +30,32 @@ #include "gtest/gtest.h" +#include <boost/filesystem.hpp> + #include "include_base_utils.h" +#include "unit_tests_utils.h" + +boost::filesystem::path unit_test::data_dir; int main(int argc, char** argv) { - epee::string_tools::set_module_name_and_folder(argv[0]); mlog_configure(mlog_get_default_log_path("unit_tests.log"), true); epee::debug::get_set_enable_assert(true, false); ::testing::InitGoogleTest(&argc, argv); + + // Process remaining arguments + if (argc == 2 && argv[1] != NULL) { // one arg: path to dir with test data + unit_test::data_dir = argv[1]; + } else if (argc == 1) { // legacy: assume test binaries in 'build/release' + epee::string_tools::set_module_name_and_folder(argv[0]); + unit_test::data_dir = boost::filesystem::path(epee::string_tools::get_current_module_folder()) + .parent_path().parent_path().parent_path().parent_path() + .append("tests").append("data"); + } else { + std::cerr << "Usage: " << argv[0] << " [<path-to-test-data-dir>]" << std::endl; + return 1; + } + return RUN_ALL_TESTS(); } diff --git a/tests/unit_tests/serialization.cpp b/tests/unit_tests/serialization.cpp index 6f9fe7d11..e701a53ce 100644 --- a/tests/unit_tests/serialization.cpp +++ b/tests/unit_tests/serialization.cpp @@ -47,6 +47,7 @@ #include "serialization/binary_utils.h" #include "wallet/wallet2.h" #include "gtest/gtest.h" +#include "unit_tests_utils.h" using namespace std; struct Struct @@ -671,12 +672,12 @@ TEST(Serialization, portability_wallet) const bool testnet = true; const bool restricted = false; tools::wallet2 w(testnet, restricted); - string wallet_file = epee::string_tools::get_current_module_folder() + "/../../../../tests/data/wallet_9svHk1"; + const boost::filesystem::path wallet_file = unit_test::data_dir / "wallet_9svHk1"; string password = "test"; bool r = false; try { - w.load(wallet_file, password); + w.load(wallet_file.native(), password); r = true; } catch (const exception& e) @@ -791,9 +792,9 @@ TEST(Serialization, portability_wallet) TEST(Serialization, portability_outputs) { // read file - const std::string filename = epee::string_tools::get_current_module_folder() + "/../../../../tests/data/outputs"; + const boost::filesystem::path filename = unit_test::data_dir / "outputs"; std::string data; - bool r = epee::file_io_utils::load_file_to_string(filename, data); + bool r = epee::file_io_utils::load_file_to_string(filename.native(), data); ASSERT_TRUE(r); const size_t magiclen = strlen(OUTPUT_EXPORT_FILE_MAGIC); ASSERT_FALSE(data.size() < magiclen || memcmp(data.data(), OUTPUT_EXPORT_FILE_MAGIC, magiclen)); @@ -906,10 +907,10 @@ TEST(Serialization, portability_outputs) #define UNSIGNED_TX_PREFIX "Monero unsigned tx set\003" TEST(Serialization, portability_unsigned_tx) { - const string filename = epee::string_tools::get_current_module_folder() + "/../../../../tests/data/unsigned_monero_tx"; + const boost::filesystem::path filename = unit_test::data_dir / "unsigned_monero_tx"; std::string s; const bool testnet = true; - bool r = epee::file_io_utils::load_file_to_string(filename, s); + bool r = epee::file_io_utils::load_file_to_string(filename.native(), s); ASSERT_TRUE(r); const size_t magiclen = strlen(UNSIGNED_TX_PREFIX); ASSERT_FALSE(strncmp(s.c_str(), UNSIGNED_TX_PREFIX, magiclen)); @@ -1054,10 +1055,10 @@ TEST(Serialization, portability_unsigned_tx) #define SIGNED_TX_PREFIX "Monero signed tx set\003" TEST(Serialization, portability_signed_tx) { - const string filename = epee::string_tools::get_current_module_folder() + "/../../../../tests/data/signed_monero_tx"; + const boost::filesystem::path filename = unit_test::data_dir / "signed_monero_tx"; const bool testnet = true; std::string s; - bool r = epee::file_io_utils::load_file_to_string(filename, s); + bool r = epee::file_io_utils::load_file_to_string(filename.native(), s); ASSERT_TRUE(r); const size_t magiclen = strlen(SIGNED_TX_PREFIX); ASSERT_FALSE(strncmp(s.c_str(), SIGNED_TX_PREFIX, magiclen)); diff --git a/tests/unit_tests/test_peerlist.cpp b/tests/unit_tests/test_peerlist.cpp index 4a546b50d..849020d25 100644 --- a/tests/unit_tests/test_peerlist.cpp +++ b/tests/unit_tests/test_peerlist.cpp @@ -38,7 +38,7 @@ TEST(peer_list, peer_list_general) { nodetool::peerlist_manager plm; plm.init(false); -#define MAKE_IPV4_ADDRESS(a,b,c,d,e) new epee::net_utils::ipv4_network_address(MAKE_IP(a,b,c,d),e) +#define MAKE_IPV4_ADDRESS(a,b,c,d,e) epee::net_utils::ipv4_network_address{MAKE_IP(a,b,c,d),e} #define ADD_GRAY_NODE(addr_, id_, last_seen_) { nodetool::peerlist_entry ple; ple.last_seen=last_seen_;ple.adr = addr_; ple.id = id_;plm.append_with_peer_gray(ple);} #define ADD_WHITE_NODE(addr_, id_, last_seen_) { nodetool::peerlist_entry ple;ple.last_seen=last_seen_; ple.adr = addr_; ple.id = id_;plm.append_with_peer_white(ple);} diff --git a/tests/unit_tests/unit_tests_utils.h b/tests/unit_tests/unit_tests_utils.h index 11230c0db..a07eaf02b 100644 --- a/tests/unit_tests/unit_tests_utils.h +++ b/tests/unit_tests/unit_tests_utils.h @@ -31,9 +31,12 @@ #pragma once #include <atomic> +#include <boost/filesystem.hpp> namespace unit_test { + extern boost::filesystem::path data_dir; + class call_counter { public: diff --git a/translations/monero_it.ts b/translations/monero_it.ts index c30413219..10c1599df 100644 --- a/translations/monero_it.ts +++ b/translations/monero_it.ts @@ -6,17 +6,17 @@ <message> <location filename="../src/wallet/api/address_book.cpp" line="55"/> <source>Invalid destination address</source> - <translation>Indirizzo destinatario invalido</translation> + <translation>Indirizzo destinatario non valido</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> + <translation>ID pagamento non valido. 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> + <translation>ID pagamento non valido</translation> </message> <message> <location filename="../src/wallet/api/address_book.cpp" line="79"/> @@ -54,7 +54,7 @@ <message> <location filename="../src/wallet/api/pending_transaction.cpp" line="126"/> <source>. Reason: </source> - <translation>Motivo: </translation> + <translation>. Motivo: </translation> </message> <message> <location filename="../src/wallet/api/pending_transaction.cpp" line="128"/> @@ -93,12 +93,12 @@ <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> + <translation>Il cambiamento ha effetto su più di un 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> + <translation>inviando %s a %s</translation> </message> <message> <location filename="../src/wallet/api/unsigned_transaction.cpp" line="170"/> @@ -113,12 +113,12 @@ <message> <location filename="../src/wallet/api/unsigned_transaction.cpp" line="179"/> <source>no change</source> - <translation>nessun cambiamento</translation> + <translation>nessuna modifica</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> + <translation>Caricato %lu transazioni, per %s, commissione %s, %s, %s, %s, con mixin %lu. %s</translation> </message> </context> <context> @@ -154,53 +154,53 @@ <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> + <translation>impossibile recuperare 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> + <translation>non hai abbastanza fondi 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> + <translation>parsing indirizzo fallito</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> + <translation>impossibile fare il parsing della chiave segreta di spesa</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> + <translation>Non è stata fornita nessuna chiave di 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> + <translation>impossibile fare il parsing della chiave segreta di 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> + <translation>impossibile verificare chiave segreta di spesa</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> + <translation>la chiave di spesa 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> + <translation>verifica chiave segreta di 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> + <translation>la chiave di visualizzazione non corrisponde all'indirizzo</translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="477"/> @@ -241,7 +241,7 @@ <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> + <translation>non hai abbastanza fondi da trasferire, disponibili solo %s, ammontare transazione %s = %s + %s (commissione)</translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="1012"/> @@ -301,7 +301,7 @@ <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> + <translation>errore inaspettato: </translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="1045"/> @@ -312,7 +312,7 @@ <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> + <translation>"Riscannerizza spesi" può essere utilizzato solo da un daemon fidato</translation> </message> </context> <context> @@ -320,38 +320,38 @@ <message> <location filename="../src/wallet/api/wallet_manager.cpp" line="192"/> <source>failed to parse txid</source> - <translation>analisi(parse) txid fallita</translation> + <translation>analisi 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> + <translation>parsing chiave tx fallito</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> + <translation>parsing indirizzo fallito</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> + <translation>impossibile recuperare la transazione dal 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> + <translation>impossibile fare il parsing della 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> + <translation>convalida transazione dal 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> + <translation>impossibile recuperare la giusta transazione dal daemon</translation> </message> <message> <location filename="../src/wallet/api/wallet_manager.cpp" line="257"/> @@ -376,7 +376,7 @@ <message> <location filename="../src/wallet/api/wallet_manager.cpp" line="323"/> <source>received nothing in txid</source> - <translation>ricevuto nulla in txid</translation> + <translation>nulla ricevuto in txid</translation> </message> </context> <context> @@ -384,17 +384,17 @@ <message> <location filename="../src/wallet/api/wallet.cpp" line="212"/> <source>Failed to parse address</source> - <translation>Analisi(parse) indirizzo fallita</translation> + <translation>Parsing indirizzo fallito</translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="219"/> <source>Failed to parse key</source> - <translation>Analisi(parse) key fallita</translation> + <translation>Parsing chiave fallito</translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="227"/> <source>failed to verify key</source> - <translation>verifica key fallita</translation> + <translation>verifica chiave fallita</translation> </message> <message> <location filename="../src/wallet/api/wallet.cpp" line="237"/> @@ -430,7 +430,7 @@ <message> <location filename="../src/rpc/rpc_args.cpp" line="66"/> <source>Invalid IP address given for --</source> - <translation>Invalido indirizzo IP dato per --</translation> + <translation>Indirizzo IP non valido dato per --</translation> </message> <message> <location filename="../src/rpc/rpc_args.cpp" line="74"/> @@ -445,7 +445,7 @@ <message> <location filename="../src/rpc/rpc_args.cpp" line="89"/> <source> cannot be empty</source> - <translation> non puoò essere vuoto</translation> + <translation> non può essere vuoto</translation> </message> </context> <context> @@ -458,7 +458,7 @@ <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1557"/> <source>failed to read wallet password</source> - <translation>impossibile leggere password portafoglio</translation> + <translation>impossibile leggere la password del portafoglio</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1325"/> @@ -468,12 +468,12 @@ <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> + <translation>start_mining [<number_of_threads>] - Avvia mining 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> + <translation>Interrompi mining nel daemon</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="699"/> @@ -493,7 +493,7 @@ <message> <location filename="../src/simplewallet/simplewallet.cpp" line="715"/> <source>Show current wallet public address</source> - <translation>Mostra indirizzo pubblico del corrente portafoglio</translation> + <translation>Mostra indirizzo pubblico del portafoglio corrente</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="744"/> @@ -503,7 +503,7 @@ <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> + <translation>imposta seed: richiede una definizione. opzioni disponibili: lingua</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="811"/> @@ -538,12 +538,12 @@ <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> + <translation>Verifica prova tx per pagamento inviato a <indirizzo> in <txid></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> + <translation>Genera un nuovo id pagamento casuale di dimensione completa - queste non saranno criptate nel blockchain, considera integrated_address per payment ids corti crittati</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="774"/> @@ -564,7 +564,7 @@ <message> <location filename="../src/simplewallet/simplewallet.cpp" line="800"/> <source>integer >= 2</source> - <translation type="unfinished"></translation> + <translation>integrale >= 2</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="803"/> @@ -585,12 +585,12 @@ <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> + <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> + <translation>impossibile connettere il portafoglio al daemon: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1269"/> @@ -600,7 +600,7 @@ <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> + <translation>Lista delle lingue disponibili per il seed del tuo portafoglio:</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1297"/> @@ -611,7 +611,7 @@ <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> + <translation>Hai usato una versione obsoleta del portafoglio. Per favore usa il nuovo seed che ti abbiamo fornito.</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1368"/> @@ -666,12 +666,12 @@ <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1613"/> <source>Mining started in daemon</source> - <translation>Mining partito nel daemon</translation> + <translation>Mining avviato 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> + <translation>il mining NON è stato avviato: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1634"/> @@ -681,7 +681,7 @@ <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1636"/> <source>mining has NOT been stopped: </source> - <translation>Il mining NON è stato interrotto: </translation> + <translation>il mining NON è stato interrotto: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1655"/> @@ -710,7 +710,7 @@ <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1689"/> <source>spent </source> - <translation>speso/i</translation> + <translation>speso/i </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1701"/> @@ -720,7 +720,7 @@ <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1718"/> <source>Starting refresh...</source> - <translation>Iniziando refresh...</translation> + <translation>Sto iniziando il refresh...</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1731"/> @@ -736,7 +736,7 @@ <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2201"/> <source>bad locked_blocks parameter:</source> - <translation>parametro locked_blocks difettoso:</translation> + <translation>parametro locked_blocks non corretto:</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2228"/> @@ -762,17 +762,17 @@ <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2323"/> <source>Sending %s. </source> - <translation>Inviando %s. </translation> + <translation>Sto 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> + <translation>La tua transazione deve essere divisa in %llu transazioni. Una commissione verrà applicata per ogni transazione, per un totale di %s commissioni</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> + <translation>La commissione per la transazione è %s</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2335"/> @@ -793,7 +793,8 @@ <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> + <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"/> @@ -823,7 +824,7 @@ This transaction will unlock on block %llu, in approximately %s days (assuming 2 <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> + <translation>Impossibile creare transazioni. Questo succede di solito perchè l'ammontare di polvere è così piccolo da non poter pagare le proprie commissioni, oppure stai provando a mandare più fondi di quelli che possiedi nel bilancio sbloccato, o non hai aggiunto abbastanza commissioni</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2435"/> @@ -837,7 +838,7 @@ This transaction will unlock on block %llu, in approximately %s days (assuming 2 <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> + <translation>impossibile trovare un modo adatto per dividere le transazioni</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2503"/> @@ -862,7 +863,7 @@ This transaction will unlock on block %llu, in approximately %s days (assuming 2 <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3035"/> <source>sending %s to %s</source> - <translation>mandando %s a %s</translation> + <translation>sto mandando %s a %s</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3041"/> @@ -882,7 +883,7 @@ This transaction will unlock on block %llu, in approximately %s days (assuming 2 <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3120"/> <source>Failed to load transaction from file</source> - <translation>caricamento transazione da file fallito</translation> + <translation>Caricamento transazione da file fallito</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3137"/> @@ -902,7 +903,7 @@ This transaction will unlock on block %llu, in approximately %s days (assuming 2 <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> + <translation>il portafoglio è solo-vista e non ha una chiave di spesa</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="390"/> @@ -998,7 +999,7 @@ This transaction will unlock on block %llu, in approximately %s days (assuming 2 <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> + <translation>parametro m_restore_height non corretto: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1162"/> @@ -1008,18 +1009,18 @@ This transaction will unlock on block %llu, in approximately %s days (assuming 2 <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1175"/> <source>Restore height is: </source> - <translation>ripristina altezza è: </translation> + <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> + <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> + <translation>Il daemon è locale, viene considerato fidato</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1553"/> @@ -1100,12 +1101,12 @@ This transaction will unlock on block %llu, in approximately %s days (assuming 2 <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1868"/> <source>No incoming transfers</source> - <translation>nessun trasferimento in entrata</translation> + <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> + <translation>Nessun trasferimento in entrata disponibile</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1876"/> @@ -1130,7 +1131,7 @@ This transaction will unlock on block %llu, in approximately %s days (assuming 2 <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> <source>height</source> - <translation>blocco</translation> + <translation>altezza</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> @@ -1140,14 +1141,14 @@ This transaction will unlock on block %llu, in approximately %s days (assuming 2 <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1908"/> <source>No payments with id </source> - <translation>nessun pagamento con id </translation> + <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> + <translation>impossibile recuperare altezza blockchain: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2016"/> @@ -1158,7 +1159,8 @@ This transaction will unlock on block %llu, in approximately %s days (assuming 2 <location filename="../src/simplewallet/simplewallet.cpp" line="2034"/> <source> Transaction %llu/%llu: txid=%s</source> - <translation>Transazione %llu/%llu: txid=%s</translation> + <translation> +Transazione %llu/%llu: txid=%s</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2044"/> @@ -1174,13 +1176,14 @@ Input %llu/%llu: amount=%s</source> <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> + <translation>l'altezza del blocco di origine della chiave di output non dovrebbe essere più alta dell'altezza della blockchain</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2072"/> <source> Originating block heights: </source> - <translation>Originando blocchi: </translation> + <translation> +Originando blocchi: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2087"/> @@ -1201,24 +1204,25 @@ Originating block heights: </source> <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> + <translation> +Avviso: 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> + <translation>, che potrebbe compromettere l'anonimità della ring signature. 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> + <translation>numero di argomenti errato</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> + <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"/> @@ -1238,12 +1242,12 @@ Warning: Some input keys being spent are from </source> <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> + <translation>Sto eseguendo lo sweep di %s nelle transazioni %llu per un totale commissioni 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> + <translation>Sto eseguendo lo sweep di %s per un totale commissioni di %s. Va bene? (S/Sì/N/No): </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2969"/> @@ -1253,12 +1257,12 @@ Warning: Some input keys being spent are from </source> <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> + <translation>Caricate %lu transazioni, per %s, commissioni %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> + <translation>Questo è un portafoglio solo-vista</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4443"/> @@ -1278,19 +1282,19 @@ Warning: Some input keys being spent are from </source> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="266"/> <source>failed to parse refresh type</source> - <translation>impossibile analizzare (parse) tipo di refresh</translation> + <translation>impossibile fare il parsing del 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> + <translation>il portafoglio è solo-vista e non possiede un seed</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> + <translation>il portafoglio è non-deterministico e non possiede un seed</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="450"/> @@ -1308,7 +1312,7 @@ Warning: Some input keys being spent are from </source> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="501"/> <source>could not change default mixin</source> - <translation>impossibile cambiare mixxaggio standard</translation> + <translation>impossibile cambiare mixin standard</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="545"/> @@ -1338,7 +1342,7 @@ Warning: Some input keys being spent are from </source> <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> + <translation>locked_transfer [<mixin_count>] <addr> <amount> <lockblocks>(Numero di blocchi durante i quali bloccare la transazione, max 1000000) [<payment_id>]</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="708"/> @@ -1353,12 +1357,12 @@ Warning: Some input keys being spent are from </source> <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> + <translation>Invia una transazione firmata 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> + <translation>integrated_address [PID] - Codifica un ID pagamento in un indirizzo integrato per l'indirizzo pubblico del portafoglio corrente (nessun parametro usa un payment ID casuale), oppure decodifica un indirizzo integrato in indirizzo standard e payment ID</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="718"/> @@ -1378,22 +1382,22 @@ Warning: Some input keys being spent are from </source> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="721"/> <source>Display private spend key</source> - <translation>Visualizza chiave privata spendibile</translation> + <translation>Visualizza chiave di spesa privata</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> + <translation>Visualizza il seed 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> + <translation>Opzioni disponibili: seed language - seleziona lingua del seed per il portafoglio; always-confirm-transfers <1|0> - se confermare unsplit txes; print-ring-members <1|0> - se mostrare informazioni dettagliate sui ring members durante le conferme; store-tx-info <1|0> - se salvare le informazioni tx in uscita (indirizzo di destinazione, payment ID, chiave tx segreta) per riferimento futuro; default-mixin <n> - imposta default mixin (default è 4); auto-refresh <1|0> - se sincronizzare automaticamente i nuovi blocchi dal daemon; refresh-type <full|optimize-coinbase|no-coinbase|default> - imposta modalità wallet refresh; 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> - imposta default monero (sub-)unit; min-outputs-count [n] - cerca di mantenere come minimo tanti outputs quanti il valore di min-outputs-value; min-outputs-value [n] - cerca di mantenere i min-outputs-count outputs come minimo a questo valore; merge-destinations <1|0> - se fondere pagamenti multipli allo stessp indirizzo di destinazione</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> + <translation>Riscannerizza blockchain in cerca di outputs spesi</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="725"/> @@ -1408,12 +1412,12 @@ Warning: Some input keys being spent are from </source> <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> + <translation>unspent_outputs [<min_amount> <max_amount>] - Mostra gli outputs non spesi entro un intervallo di valori opzionale</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="731"/> <source>Rescan blockchain from scratch</source> - <translation>Riscannerizza blockchain dal principio</translation> + <translation>Avvia scansione blockchain dal principio</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="732"/> @@ -1423,7 +1427,7 @@ Warning: Some input keys being spent are from </source> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="733"/> <source>Get a string note for a txid</source> - <translation type="unfinished"></translation> + <translation>Ricevi una stringa di annotazione per un txid</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="734"/> @@ -1463,12 +1467,12 @@ Warning: Some input keys being spent are from </source> <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> + <translation>completo (più lento, nessuna ipotesi); optimize-coinbase (veloce, ipotizza che l'intero coinbase viene pagato ad un indirizzo singolo); no-coinbase (il più veloce, ipotizza di non ricevere una transazione coinbase), default (come optimize-coinbase)</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="806"/> <source>monero, millinero, micronero, nanonero, piconero</source> - <translation type="unfinished"></translation> + <translation>monero, millinero, micronero, nanonero, piconero</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="851"/> @@ -1478,12 +1482,12 @@ Warning: Some input keys being spent are from </source> <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> + <translation>Portafoglio e chiavi trovate, 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> + <translation>Ho trovato la chiave ma non il portafoglio. Sto rigenerando...</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="880"/> @@ -1535,25 +1539,25 @@ Warning: Some input keys being spent are from </source> <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> + <translation>impossibile fare il parsing dell'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> + <translation>impossibile fare il parsing chiave di 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> + <translation>impossibile verificare chiave di visualizzazione chiave segreta</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> + <translation>la chiave di visualizzazione non corrisponde all'indirizzo standard</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1036"/> @@ -1565,22 +1569,22 @@ Warning: Some input keys being spent are from </source> <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> + <translation>impossibile fare il parsing chiave di spesa 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> + <translation>impossibile verificare chiave di spesa 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> + <translation>la chiave di spesa 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> + <translation>specifica un percorso per il portafoglio con --generate-new-wallet (non --wallet-file)</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1199"/> @@ -1611,7 +1615,7 @@ Warning: Some input keys being spent are from </source> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1370"/> <source>View key: </source> - <translation>Chiave per visualizzazione: </translation> + <translation>Chiave di visualizzazione: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1385"/> @@ -1648,7 +1652,7 @@ di nuovo il tuo portafoglio (le chiavi del tuo portafoglio NON sono a rischio in <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1657"/> <source>blockchain can't be saved: </source> - <translation>impossibile salvare blockchain: </translation> + <translation>impossibile salvare la blockchain: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1736"/> @@ -1671,7 +1675,7 @@ di nuovo il tuo portafoglio (le chiavi del tuo portafoglio NON sono a rischio in <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1750"/> <source>refresh error: </source> - <translation>refresh errore: </translation> + <translation>errore refresh: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="1794"/> @@ -1737,17 +1741,17 @@ di nuovo il tuo portafoglio (le chiavi del tuo portafoglio NON sono a rischio in <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2105"/> <source>the same transaction</source> - <translation type="unfinished"></translation> + <translation>la stessa transazione</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2105"/> <source>blocks that are temporally very close</source> - <translation type="unfinished"></translation> + <translation>i blocchi che sono temporalmente molto vicini</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> + <translation>I blocchi bloccati sono troppo alti, max 1000000 (˜4 anni)</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2921"/> @@ -1772,7 +1776,7 @@ di nuovo il tuo portafoglio (le chiavi del tuo portafoglio NON sono a rischio in <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3289"/> <source>failed to parse tx_key</source> - <translation>impossibile analizzare (parse) tx_key</translation> + <translation>impossibile fare il parsing del tx_key</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3298"/> @@ -1797,7 +1801,7 @@ di nuovo il tuo portafoglio (le chiavi del tuo portafoglio NON sono a rischio in <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3539"/> <source>Signature header check error</source> - <translation>errore controllo firma intestazione</translation> + <translation>Errore controllo firma intestazione</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3550"/> @@ -1844,7 +1848,7 @@ di nuovo il tuo portafoglio (le chiavi del tuo portafoglio NON sono a rischio in <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> + <translation>impossibile fare il parsing di ID pagamento o indirizzo</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4038"/> @@ -1854,12 +1858,12 @@ di nuovo il tuo portafoglio (le chiavi del tuo portafoglio NON sono a rischio in <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4070"/> <source>failed to parse payment ID</source> - <translation>impossibile analizzare (parse) ID pagamento</translation> + <translation>impossibile fare il parsing di 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> + <translation>impossibile fare il parsing dell'indice</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4096"/> @@ -1899,7 +1903,7 @@ di nuovo il tuo portafoglio (le chiavi del tuo portafoglio NON sono a rischio in <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4193"/> <source>usage: sign <filename></source> - <translation type="unfinished"></translation> + <translation>uso: sign <filename></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4198"/> @@ -1911,7 +1915,7 @@ di nuovo il tuo portafoglio (le chiavi del tuo portafoglio NON sono a rischio in <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> + <translation>impossibile leggere il file </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4219"/> @@ -1921,7 +1925,7 @@ di nuovo il tuo portafoglio (le chiavi del tuo portafoglio NON sono a rischio in <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4246"/> <source>Bad signature from </source> - <translation>Firma invalida da </translation> + <translation>Firma non valida da </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4250"/> @@ -1957,7 +1961,7 @@ di nuovo il tuo portafoglio (le chiavi del tuo portafoglio NON sono a rischio in <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4323"/> <source>usage: export_outputs <filename></source> - <translation>usage: export_outputs <filename></translation> + <translation>uso: export_outputs <filename></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="4357"/> @@ -1973,7 +1977,7 @@ di nuovo il tuo portafoglio (le chiavi del tuo portafoglio NON sono a rischio in <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> + <translation>l'ammontare non è corretto: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2247"/> @@ -2042,7 +2046,7 @@ di nuovo il tuo portafoglio (le chiavi del tuo portafoglio NON sono a rischio in <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> + <translation>Impossibile trovare un modo corretto per dividere le transazioni</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2452"/> @@ -2055,19 +2059,19 @@ di nuovo il tuo portafoglio (le chiavi del tuo portafoglio NON sono a rischio in <message> <location filename="../src/simplewallet/simplewallet.cpp" line="2516"/> <source>Sweeping </source> - <translation>Pulendo (sweeping) </translation> + <translation>Eseguendo lo 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> + <translation>Eseguendo lo sweeping di %s per un totale commissioni 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> + <translation>Fondi inviati con successo, transazione: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3047"/> @@ -2098,7 +2102,7 @@ di nuovo il tuo portafoglio (le chiavi del tuo portafoglio NON sono a rischio in <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> + <translation>parsing txid fallito</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3245"/> @@ -2119,19 +2123,19 @@ di nuovo il tuo portafoglio (le chiavi del tuo portafoglio NON sono a rischio in <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> + <translation>impossibile fare il parsing della 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> + <translation>impossibile 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> + <translation>impossibile fare il parsing della transazione dal daemon</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3418"/> @@ -2168,12 +2172,12 @@ di nuovo il tuo portafoglio (le chiavi del tuo portafoglio NON sono a rischio in <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3481"/> <source>received nothing in txid</source> - <translation>ricevuto niente in txid</translation> + <translation>nulla ricevuto 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> + <translation>AVVISO: questa transazione non è ancora inclusa nella blockchain!</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3494"/> @@ -2183,7 +2187,7 @@ di nuovo il tuo portafoglio (le chiavi del tuo portafoglio NON sono a rischio in <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> + <translation>AVVISO: impossibile determinare il numero di conferme!</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3661"/> @@ -2193,12 +2197,12 @@ di nuovo il tuo portafoglio (le chiavi del tuo portafoglio NON sono a rischio in <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3700"/> <source>bad min_height parameter:</source> - <translation>parametro min_height scorretto:</translation> + <translation>parametro min_height non corretto:</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3712"/> <source>bad max_height parameter:</source> - <translation>parametro max_height scorretto:</translation> + <translation>parametro max_height non corretto:</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3760"/> @@ -2235,7 +2239,8 @@ di nuovo il tuo portafoglio (le chiavi del tuo portafoglio NON sono a rischio in <location filename="../src/simplewallet/simplewallet.cpp" line="3856"/> <source> Amount: </source> - <translation>Ammontare: </translation> + <translation> +Ammontare: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3856"/> @@ -2251,43 +2256,49 @@ Amount: </source> <location filename="../src/simplewallet/simplewallet.cpp" line="3866"/> <source> Min block height: </source> - <translation>Altezza minima blocco: </translation> + <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> + <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> + <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> + <translation> +Ammontare massimo trovato: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3870"/> <source> Total count: </source> - <translation>Conto totale: </translation> + <translation> +Conto totale: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3910"/> <source> Bin size: </source> - <translation>Dimensione Bin</translation> + <translation> +Dimensione Bin: </translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3911"/> <source> Outputs per *: </source> - <translation></translation> + <translation type="unfinished"></translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="3913"/> @@ -2356,7 +2367,7 @@ Outputs per *: </source> <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> + <translation>Genera un portafoglio solo-ricezione da chiave di visualizzazione</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="118"/> @@ -2366,17 +2377,17 @@ Outputs per *: </source> <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> + <translation>Specifica il seed 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> + <translation>Recupera portafoglio usando il seed 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> + <translation>Crea chiavi di visualizzione e chiavi di spesa non-deterministiche</translation> </message> <message> <location filename="../src/simplewallet/simplewallet.cpp" line="123"/> @@ -2424,7 +2435,7 @@ Outputs per *: </source> <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> + <translation>AVVISO: convalida DNSSEC fallita, questo indirizzo potrebbe non essere corretto!</translation> </message> <message> <location filename="../src/common/dns_utils.cpp" line="437"/> @@ -2434,7 +2445,7 @@ Outputs per *: </source> <message> <location filename="../src/common/dns_utils.cpp" line="439"/> <source> Monero Address = </source> - <translation>Indirizzo Monero = </translation> + <translation> Indirizzo Monero = </translation> </message> <message> <location filename="../src/common/dns_utils.cpp" line="441"/> @@ -2444,7 +2455,7 @@ Outputs per *: </source> <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> + <translation>hai cancellato la richiesta di transferimento</translation> </message> </context> <context> @@ -2477,12 +2488,12 @@ Outputs per *: </source> <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> + <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> + <translation>Restringi a comandi di tipo solo-vista</translation> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="152"/> @@ -2517,7 +2528,7 @@ Outputs per *: </source> <message> <location filename="../src/wallet/wallet2.cpp" line="108"/> <source>Wallet password (escape/quote as needed)</source> - <translation type="unfinished"></translation> + <translation>Wallet password (escape/quote se necessario)</translation> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="111"/> @@ -2527,46 +2538,46 @@ Outputs per *: </source> <message> <location filename="../src/wallet/wallet2.cpp" line="233"/> <source>Failed to parse JSON</source> - <translation>Impossibile analizzare (parse) JSON</translation> + <translation>Impossibile fare il parsing di 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> + <translation>La versione %u è troppo recente, possiamo comprendere solo fino alla versione %u</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> + <translation>impossibile fare il parsing di chiave di 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> + <translation>impossibile verificare chiave di 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> + <translation>impossibile fare il parsing chiave di spesa 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> + <translation>impossibile verificare chiave di spesa 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> + <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> + <translation>Almeno una parola della lista stile-Electrum e una chiave privata di visualizzazione devono essere specificate</translation> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="311"/> @@ -2581,12 +2592,12 @@ Outputs per *: </source> <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> + <translation>la chiave di 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> + <translation>la chiave di spesa non corrisponde all'indirizzo standard</translation> </message> <message> <location filename="../src/wallet/wallet2.cpp" line="356"/> @@ -2609,7 +2620,7 @@ Outputs per *: </source> <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> + <translation>Il daemon è locale, viene considerato fidato</translation> </message> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="171"/> @@ -2639,7 +2650,7 @@ Outputs per *: </source> <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> + <translation>Username/password RPC conservato nel file </translation> </message> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="1748"/> @@ -2654,19 +2665,19 @@ Outputs per *: </source> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="1764"/> <source>Loading wallet...</source> - <translation>Caricando il portafoglio...</translation> + <translation>Sto 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> + <translation>Sto salvando 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> + <translation>Salvato con successo</translation> </message> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="1794"/> @@ -2686,7 +2697,7 @@ Outputs per *: </source> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="1809"/> <source>Starting wallet rpc server</source> - <translation>Server RPC portafoglio in partenza</translation> + <translation>Server RPC portafoglio in avvio</translation> </message> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="1811"/> @@ -2696,7 +2707,7 @@ Outputs per *: </source> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="1820"/> <source>Failed to store wallet: </source> - <translation>Impossibile conservare portafoglio: </translation> + <translation>Impossibile salvare portafoglio: </translation> </message> </context> <context> @@ -2725,7 +2736,7 @@ Outputs per *: </source> <message> <location filename="../src/wallet/wallet_args.cpp" line="88"/> <source>Specify log file</source> - <translation>Specificare log file</translation> + <translation>Specificare file di log</translation> </message> <message> <location filename="../src/wallet/wallet_args.cpp" line="89"/> @@ -2745,12 +2756,12 @@ Outputs per *: </source> <message> <location filename="../src/wallet/wallet_args.cpp" line="172"/> <source>Logging to: </source> - <translation>Loggando in: </translation> + <translation>Sto salvando il Log in: </translation> </message> <message> <location filename="../src/wallet/wallet_args.cpp" line="173"/> <source>Logging to %s</source> - <translation>Loggando in %s</translation> + <translation>Sto salvando il Log in %s</translation> </message> <message> <location filename="../src/wallet/wallet_args.cpp" line="153"/> |