diff options
201 files changed, 29019 insertions, 11388 deletions
diff --git a/ANONYMITY_NETWORKS.md b/ANONYMITY_NETWORKS.md new file mode 100644 index 000000000..6ac8cd999 --- /dev/null +++ b/ANONYMITY_NETWORKS.md @@ -0,0 +1,179 @@ +# Anonymity Networks with Monero + +Currently only Tor has been integrated into Monero. Providing support for +Kovri/I2P should be minimal, but has not yet been attempted. The usage of +these networks is still considered experimental - there are a few pessimistic +cases where privacy is leaked. The design is intended to maximize privacy of +the source of a transaction by broadcasting it over an anonymity network, while +relying on IPv4 for the remainder of messages to make surrounding node attacks +(via sybil) more difficult. + + +## Behavior + +If _any_ anonymity network is enabled, transactions being broadcast that lack +a valid "context" (i.e. the transaction did not come from a p2p connection), +will only be sent to peers on anonymity networks. If an anonymity network is +enabled but no peers over an anonymity network are available, an error is +logged and the transaction is kept for future broadcasting over an anonymity +network. The transaction will not be broadcast unless an anonymity connection +is made or until `monerod` is shutdown and restarted with only public +connections enabled. + + +## P2P Commands + +Only handshakes, peer timed syncs, and transaction broadcast messages are +supported over anonymity networks. If one `--add-exclusive-node` onion address +is specified, then no syncing will take place and only transaction broadcasting +can occur. It is therefore recommended that `--add-exclusive-node` be combined +with additional exclusive IPv4 address(es). + + +## Usage + +Anonymity networks have no seed nodes (the feature is still considered +experimental), so a user must specify an address. If configured properly, +additional peers can be found through typical p2p peerlist sharing. + +### Outbound Connections + +Connecting to an anonymous address requires the command line option +`--proxy` which tells `monerod` the ip/port of a socks proxy provided by a +separate process. On most systems the configuration will look like: + +> `--proxy tor,127.0.0.1:9050,10` +> `--proxy i2p,127.0.0.1:9000` + +which tells `monerod` that ".onion" p2p addresses can be forwarded to a socks +proxy at IP 127.0.0.1 port 9050 with a max of 10 outgoing connections and +".i2p" p2p addresses can be forwarded to a socks proxy at IP 127.0.0.1 port 9000 +with the default max outgoing connections. Since there are no seed nodes for +anonymity connections, peers must be manually specified: + +> `--add-exclusive-node rveahdfho7wo4b2m.onion:28083` +> `--add-peer rveahdfho7wo4b2m.onion:28083` + +Either option can be listed multiple times, and can specify any mix of Tor, +I2P, and IPv4 addresses. Using `--add-exclusive-node` will prevent the usage of +seed nodes on ALL networks, which will typically be undesireable. + +### Inbound Connections + +Receiving anonymity connections is done through the option +`--anonymous-inbound`. This option tells `monerod` the inbound address, network +type, and max connections: + +> `--anonymous-inbound rveahdfho7wo4b2m.onion:28083,127.0.0.28083,25` +> `--anonymous-inbound foobar.i2p:5000,127.0.0.1:30000` + +which tells `monerod` that a max of 25 inbound Tor connections are being +received at address "rveahdfho7wo4b2m.onion:28083" and forwarded to `monerod` +localhost port 28083, and a default max I2P connections are being received at +address "foobar.i2p:5000" and forwarded to `monerod` localhost port 30000. +These addresses will be shared with outgoing peers, over the same network type, +otherwise the peer will not be notified of the peer address by the proxy. + +### Network Types + +#### Tor + +Options `--add-exclusive-node` and `--add-peer` recognize ".onion" addresses, +and will properly forward those addresses to the proxy provided with +`--proxy tor,...`. + +Option `--anonymous-inbound` also recognizes ".onion" addresses, and will +automatically be sent out to outgoing Tor connections so the peer can +distribute the address to its other peers. + +##### Configuration + +Tor must be configured for hidden services. An example configuration ("torrc") +might look like: + +> HiddenServiceDir /var/lib/tor/data/monero +> HiddenServicePort 28083 127.0.0.1:28083 + +This will store key information in `/var/lib/tor/data/monero` and will forward +"Tor port" 28083 to port 28083 of ip 127.0.0.1. The file +`/usr/lib/tor/data/monero/hostname` will contain the ".onion" address for use +with `--anonymous-inbound`. + +#### Kovri/I2P + +Support for this network has not been implemented. Using ".i2p" addresses or +specifying "i2p" will currently generate an error. + + +## Privacy Limitations + +There are currently some techniques that could be used to _possibly_ identify +the machine that broadcast a transaction over an anonymity network. + +### Timestamps + +The peer timed sync command sends the current time in the message. This value +can be used to link an onion address to an IPv4/IPv6 address. If a peer first +sees a transaction over Tor, it could _assume_ (possibly incorrectly) that the +transaction originated from the peer. If both the Tor connection and an +IPv4/IPv6 connection have timestamps that are approximately close in value they +could be used to link the two connections. This is less likely to happen if the +system clock is fairly accurate - many peers on the Monero network should have +similar timestamps. + +#### Mitigation + +Keep the system clock accurate so that fingerprinting is more difficult. In +the future a random offset might be applied to anonymity networks so that if +the system clock is noticeably off (and therefore more fingerprintable), +linking the public IPv4/IPv6 connections with the anonymity networks will be +more difficult. + +### Bandwidth Usage + +An ISP can passively monitor `monerod` connections from a node and observe when +a transaction is sent over a Tor/Kovri connection via timing analysis + size of +data sent during that timeframe. Kovri should provide better protection against +this attack - its connections are not circuit based. However, if a node is +only using Kovri for broadcasting Monero transactions, the total aggregate of +Kovri/I2P data would also leak information. + +#### Mitigation + +There is no current mitigation for the user right now. This attack is fairly +sophisticated, and likely requires support from the internet host of a Monero +user. + +In the near future, "whitening" the amount of data sent over anonymity network +connections will be performed. An attempt will be made to make a transaction +broadcast indistinguishable from a peer timed sync command. + +### Intermittent Monero Syncing + +If a user only runs `monerod` to send a transaction then quit, this can also +be used by an ISP to link a user to a transaction. + +#### Mitigation + +Run `monerod` as often as possible to conceal when transactions are being sent. +Future versions will also have peers that first receive a transaction over an +anonymity network delay the broadcast to public peers by a randomized amount. +This will not completetely mitigate a user who syncs up sends then quits, in +part because this rule is not enforceable, so this mitigation strategy is +simply a best effort attempt. + +### Active Bandwidth Shaping + +An attacker could attempt to bandwidth shape traffic in an attempt to determine +the source of a Tor/Kovri/I2P connection. There isn't great mitigation against +this, but Kovri/I2P should provide better protection against this attack since +the connections are not circuit based. + +#### Mitigation + +The best mitigiation is to use Kovri/I2P instead of Tor. However, Kovri/I2P +has a smaller set of users (less cover traffic) and academic reviews, so there +is a tradeoff in potential isses. Also, anyone attempting this strategy really +wants to uncover a user, it seems unlikely that this would be performed against +every Tor/Kovri/I2P user. + diff --git a/CMakeLists.txt b/CMakeLists.txt index 31c3dbd21..9515885d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,8 @@ message(STATUS "CMake version ${CMAKE_VERSION}") project(monero) +enable_language(C ASM) + function (die msg) if (NOT WIN32) string(ASCII 27 Esc) @@ -398,7 +398,7 @@ You will have to add the serialization, date_time, and regex modules to Boost wh To build: `env CC=egcc CXX=eg++ CPP=ecpp DEVELOPER_LOCAL_TOOLS=1 BOOST_ROOT=/path/to/the/boost/you/built make release-static-64` -#### OpenBSD >= 6.2 +#### OpenBSD 6.2 and 6.3 You will need to add a few packages to your system. `pkg_add cmake zeromq libiconv`. @@ -443,8 +443,6 @@ echo 'using clang : : c++ : <cxxflags>"-fvisibility=hidden -fPIC" <linkflags>"" doas ./b2 -d0 runtime-link=shared threadapi=pthread threading=multi link=static variant=release --layout=tagged --build-type=complete --user-config=user-config.jam -sNO_BZIP2=1 -sICONV_PATH=/usr/local --prefix=/usr/local install ``` -Build cppzmq - Build the cppzmq bindings. We assume you are compiling with a non-root user and you have `doas` enabled. @@ -471,6 +469,23 @@ doas make install Build monero: `env DEVELOPER_LOCAL_TOOLS=1 BOOST_ROOT=/usr/local make release-static` +#### OpenBSD >= 6.4 + +You will need to add a few packages to your system. `pkg_add cmake gmake zeromq cppzmq libiconv boost`. + +The doxygen and graphviz packages are optional and require the xbase set. + +Build monero: `env DEVELOPER_LOCAL_TOOLS=1 BOOST_ROOT=/usr/local gmake release-static` + +Note: you may encounter the following error, when compiling the latest version of monero as a normal user: + +``` +LLVM ERROR: out of memory +c++: error: unable to execute command: Abort trap (core dumped) +``` + +Then you need to increase the data ulimit size to 2GB and try again: `ulimit -d 2000000` + ### On Solaris: The default Solaris linker can't be used, you have to install GNU ld, then run cmake manually with the path to your copy of GNU ld: @@ -600,6 +615,12 @@ See [README.i18n.md](README.i18n.md). ## Using Tor +> There is a new, still experimental, [integration with Tor](ANONYMITY_NETWORKS.md). The +> feature allows connecting over IPv4 and Tor simulatenously - IPv4 is used for +> relaying blocks and relaying transactions received by peers whereas Tor is +> used solely for relaying transactions received over local RPC. This provides +> privacy and better protection against surrounding node (sybil) attacks. + While Monero isn't made to integrate with Tor, it can be used wrapped with torsocks, by setting the following configuration parameters and environment variables: diff --git a/contrib/depends/packages/sodium-darwin.mk b/contrib/depends/packages/sodium-darwin.mk index d8e3de352..8b6ee3f1d 100644 --- a/contrib/depends/packages/sodium-darwin.mk +++ b/contrib/depends/packages/sodium-darwin.mk @@ -1,8 +1,8 @@ package=sodium-darwin -$(package)_version=1.0.15 +$(package)_version=1.0.16 $(package)_download_path=https://download.libsodium.org/libsodium/releases/ $(package)_file_name=libsodium-$($(package)_version).tar.gz -$(package)_sha256_hash=fb6a9e879a2f674592e4328c5d9f79f082405ee4bb05cb6e679b90afe9e178f4 +$(package)_sha256_hash=eeadc7e1e1bcef09680fb4837d448fbdf57224978f865ac1c16745868fbd0533 define $(package)_set_vars $(package)_build_opts_darwin=OS=Darwin LIBTOOL="$($(package)_libtool)" diff --git a/contrib/depends/packages/sodium.mk b/contrib/depends/packages/sodium.mk index 35f444fd5..06aa8f874 100644 --- a/contrib/depends/packages/sodium.mk +++ b/contrib/depends/packages/sodium.mk @@ -1,8 +1,8 @@ package=sodium -$(package)_version=1.0.15 +$(package)_version=1.0.16 $(package)_download_path=https://download.libsodium.org/libsodium/releases/ $(package)_file_name=libsodium-$($(package)_version).tar.gz -$(package)_sha256_hash=fb6a9e879a2f674592e4328c5d9f79f082405ee4bb05cb6e679b90afe9e178f4 +$(package)_sha256_hash=eeadc7e1e1bcef09680fb4837d448fbdf57224978f865ac1c16745868fbd0533 $(package)_patches=fix-whitespace.patch define $(package)_set_vars diff --git a/contrib/depends/patches/sodium/fix-whitespace.patch b/contrib/depends/patches/sodium/fix-whitespace.patch index c11838611..efbfe4e83 100644 --- a/contrib/depends/patches/sodium/fix-whitespace.patch +++ b/contrib/depends/patches/sodium/fix-whitespace.patch @@ -5,8 +5,8 @@ index b29f769..ca008ae 100755 @@ -591,7 +591,7 @@ MAKEFLAGS= PACKAGE_NAME='libsodium' PACKAGE_TARNAME='libsodium' - PACKAGE_VERSION='1.0.15' --PACKAGE_STRING='libsodium 1.0.15' + PACKAGE_VERSION='1.0.16' +-PACKAGE_STRING='libsodium 1.0.16' +PACKAGE_STRING='libsodium' PACKAGE_BUGREPORT='https://github.com/jedisct1/libsodium/issues' PACKAGE_URL='https://github.com/jedisct1/libsodium' diff --git a/contrib/epee/include/misc_log_ex.h b/contrib/epee/include/misc_log_ex.h index 1ff9da3a7..602b6a371 100644 --- a/contrib/epee/include/misc_log_ex.h +++ b/contrib/epee/include/misc_log_ex.h @@ -85,6 +85,16 @@ #define MGINFO_MAGENTA(x) MCLOG_MAGENTA(el::Level::Info, "global",x) #define MGINFO_CYAN(x) MCLOG_CYAN(el::Level::Info, "global",x) +#define IFLOG(level, cat, type, init, x) \ + do { \ + if (ELPP->vRegistry()->allowed(level, cat)) { \ + init; \ + el::base::Writer(level, __FILE__, __LINE__, ELPP_FUNC, type).construct(cat) << x; \ + } \ + } while(0) +#define MIDEBUG(init, x) IFLOG(el::Level::Debug, MONERO_DEFAULT_LOG_CATEGORY, el::base::DispatchAction::NormalLog, init, x) + + #define LOG_ERROR(x) MERROR(x) #define LOG_PRINT_L0(x) MWARNING(x) #define LOG_PRINT_L1(x) MINFO(x) diff --git a/contrib/epee/include/net/abstract_tcp_server2.h b/contrib/epee/include/net/abstract_tcp_server2.h index e6b2755af..643b93b87 100644 --- a/contrib/epee/include/net/abstract_tcp_server2.h +++ b/contrib/epee/include/net/abstract_tcp_server2.h @@ -41,10 +41,12 @@ #include <boost/noncopyable.hpp> #include <boost/shared_ptr.hpp> #include <atomic> +#include <cassert> #include <map> #include <memory> #include <boost/asio.hpp> +#include <boost/asio/ssl.hpp> #include <boost/array.hpp> #include <boost/noncopyable.hpp> #include <boost/shared_ptr.hpp> @@ -87,22 +89,40 @@ namespace net_utils { public: typedef typename t_protocol_handler::connection_context t_connection_context; + + struct shared_state : socket_stats + { + shared_state() + : socket_stats(), pfilter(nullptr), config() + {} + + i_connection_filter* pfilter; + typename t_protocol_handler::config_type config; + }; + /// Construct a connection with the given io_service. - explicit connection( boost::asio::io_service& io_service, - typename t_protocol_handler::config_type& config, - std::atomic<long> &ref_sock_count, // the ++/-- counter - std::atomic<long> &sock_number, // the only increasing ++ number generator - i_connection_filter * &pfilter - ,t_connection_type connection_type); + boost::shared_ptr<shared_state> state, + t_connection_type connection_type, + epee::net_utils::ssl_support_t ssl_support, + ssl_context_t &ssl_context); + + explicit connection( boost::asio::ip::tcp::socket&& sock, + boost::shared_ptr<shared_state> state, + t_connection_type connection_type, + epee::net_utils::ssl_support_t ssl_support, + ssl_context_t &ssl_context); + + virtual ~connection() noexcept(false); - /// Get the socket associated with the connection. - boost::asio::ip::tcp::socket& socket(); /// Start the first asynchronous operation for the connection. bool start(bool is_income, bool is_multithreaded); + // `real_remote` is the actual endpoint (if connection is to proxy, etc.) + bool start(bool is_income, bool is_multithreaded, network_address real_remote); + void get_context(t_connection_context& context_){context_ = context;} void call_back_starter(); @@ -128,6 +148,10 @@ namespace net_utils //------------------------------------------------------ boost::shared_ptr<connection<t_protocol_handler> > safe_shared_from_this(); bool shutdown(); + /// Handle completion of a receive operation. + void handle_receive(const boost::system::error_code& e, + std::size_t bytes_transferred); + /// Handle completion of a read operation. void handle_read(const boost::system::error_code& e, std::size_t bytes_transferred); @@ -145,10 +169,9 @@ namespace net_utils /// Buffer for incoming data. boost::array<char, 8192> buffer_; - //boost::array<char, 1024> buffer_; + size_t buffer_ssl_init_fill; t_connection_context context; - i_connection_filter* &m_pfilter; // TODO what do they mean about wait on destructor?? --rfree : //this should be the last one, because it could be wait on destructor, while other activities possible on other threads @@ -185,6 +208,13 @@ namespace net_utils class boosted_tcp_server : private boost::noncopyable { + enum try_connect_result_t + { + CONNECT_SUCCESS, + CONNECT_FAILURE, + CONNECT_NO_SSL, + }; + public: typedef boost::shared_ptr<connection<t_protocol_handler> > connection_ptr; typedef typename t_protocol_handler::connection_context t_connection_context; @@ -198,8 +228,8 @@ namespace net_utils std::map<std::string, t_connection_type> server_type_map; void create_server_type_map(); - bool init_server(uint32_t port, const std::string address = "0.0.0.0"); - bool init_server(const std::string port, const std::string& address = "0.0.0.0"); + bool init_server(uint32_t port, const std::string address = "0.0.0.0", epee::net_utils::ssl_support_t ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_autodetect, const std::pair<std::string, std::string> &private_key_and_certificate_path = std::make_pair(std::string(), std::string()), const std::list<std::string> &allowed_certificates = {}, bool allow_any_cert = false); + bool init_server(const std::string port, const std::string& address = "0.0.0.0", epee::net_utils::ssl_support_t ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_autodetect, const std::pair<std::string, std::string> &private_key_and_certificate_path = std::make_pair(std::string(), std::string()), const std::list<std::string> &allowed_certificates = {}, bool allow_any_cert = false); /// Run the server's io_service loop. bool run_server(size_t threads_count, bool wait = true, const boost::thread::attributes& attrs = boost::thread::attributes()); @@ -210,7 +240,9 @@ namespace net_utils /// Stop the server. void send_stop_signal(); - bool is_stop_signal_sent(); + bool is_stop_signal_sent() const noexcept { return m_stop_signal_sent; }; + + const std::atomic<bool>& get_stop_signal() const noexcept { return m_stop_signal_sent; } void set_threads_prefix(const std::string& prefix_name); @@ -220,17 +252,29 @@ namespace net_utils void set_connection_filter(i_connection_filter* pfilter); - bool connect(const std::string& adr, const std::string& port, uint32_t conn_timeot, t_connection_context& cn, const std::string& bind_ip = "0.0.0.0"); + void set_default_remote(epee::net_utils::network_address remote) + { + default_remote = std::move(remote); + } + + bool add_connection(t_connection_context& out, boost::asio::ip::tcp::socket&& sock, network_address real_remote, epee::net_utils::ssl_support_t ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_autodetect); + try_connect_result_t try_connect(connection_ptr new_connection_l, const std::string& adr, const std::string& port, boost::asio::ip::tcp::socket &sock_, const boost::asio::ip::tcp::endpoint &remote_endpoint, const std::string &bind_ip, uint32_t conn_timeout, epee::net_utils::ssl_support_t ssl_support); + bool connect(const std::string& adr, const std::string& port, uint32_t conn_timeot, t_connection_context& cn, const std::string& bind_ip = "0.0.0.0", epee::net_utils::ssl_support_t ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_autodetect); template<class t_callback> - bool connect_async(const std::string& adr, const std::string& port, uint32_t conn_timeot, const t_callback &cb, const std::string& bind_ip = "0.0.0.0"); + bool connect_async(const std::string& adr, const std::string& port, uint32_t conn_timeot, const t_callback &cb, const std::string& bind_ip = "0.0.0.0", epee::net_utils::ssl_support_t ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_autodetect); - typename t_protocol_handler::config_type& get_config_object(){return m_config;} + typename t_protocol_handler::config_type& get_config_object() + { + assert(m_state != nullptr); // always set in constructor + return m_state->config; + } int get_binded_port(){return m_port;} long get_connections_count() const { - auto connections_count = (m_sock_count > 0) ? (m_sock_count - 1) : 0; // Socket count minus listening socket + assert(m_state != nullptr); // always set in constructor + auto connections_count = m_state->sock_count > 0 ? (m_state->sock_count - 1) : 0; // Socket count minus listening socket return connections_count; } @@ -292,9 +336,6 @@ namespace net_utils return true; } - protected: - typename t_protocol_handler::config_type m_config; - private: /// Run the server's io_service loop. bool worker_thread(); @@ -303,21 +344,21 @@ namespace net_utils bool is_thread_worker(); + const boost::shared_ptr<typename connection<t_protocol_handler>::shared_state> m_state; + /// The io_service used to perform asynchronous operations. std::unique_ptr<boost::asio::io_service> m_io_service_local_instance; boost::asio::io_service& io_service_; /// Acceptor used to listen for incoming connections. boost::asio::ip::tcp::acceptor acceptor_; + epee::net_utils::network_address default_remote; std::atomic<bool> m_stop_signal_sent; uint32_t m_port; - std::atomic<long> m_sock_count; - std::atomic<long> m_sock_number; std::string m_address; std::string m_thread_name_prefix; //TODO: change to enum server_type, now used size_t m_threads_count; - i_connection_filter* m_pfilter; std::vector<boost::shared_ptr<boost::thread> > m_threads; boost::thread::id m_main_thread_id; critical_section m_threads_lock; @@ -331,6 +372,9 @@ namespace net_utils boost::mutex connections_mutex; std::set<connection_ptr> connections_; + ssl_context_t m_ssl_context; + std::list<std::string> m_allowed_certificates; + }; // class <>boosted_tcp_server diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl index d8779f372..7a3abe9e9 100644 --- a/contrib/epee/include/net/abstract_tcp_server2.inl +++ b/contrib/epee/include/net/abstract_tcp_server2.inl @@ -40,6 +40,7 @@ #include <boost/asio/deadline_timer.hpp> #include <boost/date_time/posix_time/posix_time.hpp> // TODO #include <boost/thread/condition_variable.hpp> // TODO +#include <boost/make_shared.hpp> #include "warnings.h" #include "string_tools.h" #include "misc_language.h" @@ -62,6 +63,13 @@ namespace epee { namespace net_utils { + template<typename T> + T& check_and_get(boost::shared_ptr<T>& ptr) + { + CHECK_AND_ASSERT_THROW_MES(bool(ptr), "shared_state cannot be null"); + return *ptr; + } + /************************************************************************/ /* */ /************************************************************************/ @@ -69,25 +77,35 @@ PRAGMA_WARNING_DISABLE_VS(4355) template<class t_protocol_handler> connection<t_protocol_handler>::connection( boost::asio::io_service& io_service, - typename t_protocol_handler::config_type& config, - std::atomic<long> &ref_sock_count, // the ++/-- counter - std::atomic<long> &sock_number, // the only increasing ++ number generator - i_connection_filter* &pfilter - ,t_connection_type connection_type + boost::shared_ptr<shared_state> state, + t_connection_type connection_type, + epee::net_utils::ssl_support_t ssl_support, + ssl_context_t &ssl_context + ) + : connection(boost::asio::ip::tcp::socket{io_service}, std::move(state), connection_type, ssl_support, ssl_context) + { + } + + template<class t_protocol_handler> + connection<t_protocol_handler>::connection( boost::asio::ip::tcp::socket&& sock, + boost::shared_ptr<shared_state> state, + t_connection_type connection_type, + epee::net_utils::ssl_support_t ssl_support, + ssl_context_t &ssl_context ) : - connection_basic(io_service, ref_sock_count, sock_number), - m_protocol_handler(this, config, context), - m_pfilter( pfilter ), + connection_basic(std::move(sock), state, ssl_support, ssl_context), + m_protocol_handler(this, check_and_get(state).config, context), m_connection_type( connection_type ), m_throttle_speed_in("speed_in", "throttle_speed_in"), m_throttle_speed_out("speed_out", "throttle_speed_out"), - m_timer(io_service), + m_timer(socket_.get_io_service()), m_local(false), m_ready_to_close(false) { MDEBUG("test, connection constructor set m_connection_type="<<m_connection_type); } + PRAGMA_WARNING_DISABLE_VS(4355) //--------------------------------------------------------------------------------- template<class t_protocol_handler> @@ -95,17 +113,11 @@ PRAGMA_WARNING_DISABLE_VS(4355) { if(!m_was_shutdown) { - _dbg3("[sock " << socket_.native_handle() << "] Socket destroyed without shutdown."); + _dbg3("[sock " << socket().native_handle() << "] Socket destroyed without shutdown."); shutdown(); } - _dbg3("[sock " << socket_.native_handle() << "] Socket destroyed"); - } - //--------------------------------------------------------------------------------- - template<class t_protocol_handler> - boost::asio::ip::tcp::socket& connection<t_protocol_handler>::socket() - { - return socket_; + _dbg3("[sock " << socket().native_handle() << "] Socket destroyed"); } //--------------------------------------------------------------------------------- template<class t_protocol_handler> @@ -127,36 +139,47 @@ PRAGMA_WARNING_DISABLE_VS(4355) { TRY_ENTRY(); + boost::system::error_code ec; + auto remote_ep = socket().remote_endpoint(ec); + CHECK_AND_NO_ASSERT_MES(!ec, false, "Failed to get remote endpoint: " << ec.message() << ':' << ec.value()); + CHECK_AND_NO_ASSERT_MES(remote_ep.address().is_v4(), false, "IPv6 not supported here"); + + const unsigned long ip_{boost::asio::detail::socket_ops::host_to_network_long(remote_ep.address().to_v4().to_ulong())}; + return start(is_income, is_multithreaded, ipv4_network_address{uint32_t(ip_), remote_ep.port()}); + CATCH_ENTRY_L0("connection<t_protocol_handler>::start()", false); + } + //--------------------------------------------------------------------------------- + template<class t_protocol_handler> + bool connection<t_protocol_handler>::start(bool is_income, bool is_multithreaded, network_address real_remote) + { + TRY_ENTRY(); + // Use safe_shared_from_this, because of this is public method and it can be called on the object being deleted auto self = safe_shared_from_this(); if(!self) return false; m_is_multithreaded = is_multithreaded; - - boost::system::error_code ec; - auto remote_ep = socket_.remote_endpoint(ec); - CHECK_AND_NO_ASSERT_MES(!ec, false, "Failed to get remote endpoint: " << ec.message() << ':' << ec.value()); - CHECK_AND_NO_ASSERT_MES(remote_ep.address().is_v4(), false, "IPv6 not supported here"); - - auto local_ep = socket_.local_endpoint(ec); - CHECK_AND_NO_ASSERT_MES(!ec, false, "Failed to get local endpoint: " << ec.message() << ':' << ec.value()); - - context = boost::value_initialized<t_connection_context>(); - const unsigned long ip_{boost::asio::detail::socket_ops::host_to_network_long(remote_ep.address().to_v4().to_ulong())}; - m_local = epee::net_utils::is_ip_loopback(ip_) || epee::net_utils::is_ip_local(ip_); + m_local = real_remote.is_loopback() || real_remote.is_local(); // create a random uuid, we don't need crypto strength here const boost::uuids::uuid random_uuid = boost::uuids::random_generator()(); - context.set_details(random_uuid, epee::net_utils::ipv4_network_address(ip_, remote_ep.port()), is_income); + context = t_connection_context{}; + bool ssl = m_ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled; + context.set_details(random_uuid, std::move(real_remote), is_income, ssl); + + boost::system::error_code ec; + auto local_ep = socket().local_endpoint(ec); + CHECK_AND_NO_ASSERT_MES(!ec, false, "Failed to get local endpoint: " << ec.message() << ':' << ec.value()); + _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); + ", total sockets objects " << get_stats().sock_count); - if(m_pfilter && !m_pfilter->is_remote_host_allowed(context.m_remote_address)) + if(static_cast<shared_state&>(get_stats()).pfilter && !static_cast<shared_state&>(get_stats()).pfilter->is_remote_host_allowed(context.m_remote_address)) { - _dbg2("[sock " << socket_.native_handle() << "] host denied " << context.m_remote_address.host_str() << ", shutdowning connection"); + _dbg2("[sock " << socket().native_handle() << "] host denied " << context.m_remote_address.host_str() << ", shutdowning connection"); close(); return false; } @@ -168,11 +191,21 @@ PRAGMA_WARNING_DISABLE_VS(4355) reset_timer(get_default_timeout(), false); - socket_.async_read_some(boost::asio::buffer(buffer_), - strand_.wrap( - boost::bind(&connection<t_protocol_handler>::handle_read, self, - boost::asio::placeholders::error, - boost::asio::placeholders::bytes_transferred))); + // first read on the raw socket to detect SSL for the server + buffer_ssl_init_fill = 0; + if (is_income && m_ssl_support != epee::net_utils::ssl_support_t::e_ssl_support_disabled) + socket().async_receive(boost::asio::buffer(buffer_), + boost::asio::socket_base::message_peek, + strand_.wrap( + boost::bind(&connection<t_protocol_handler>::handle_receive, self, + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred))); + else + async_read_some(boost::asio::buffer(buffer_), + strand_.wrap( + boost::bind(&connection<t_protocol_handler>::handle_read, self, + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred))); #if !defined(_WIN32) || !defined(__i686) // not supported before Windows7, too lazy for runtime check // Just exclude for 32bit windows builds @@ -180,12 +213,12 @@ PRAGMA_WARNING_DISABLE_VS(4355) int tos = get_tos_flag(); boost::asio::detail::socket_option::integer< IPPROTO_IP, IP_TOS > optionTos( tos ); - socket_.set_option( optionTos ); + socket().set_option( optionTos ); //_dbg1("Set ToS flag to " << tos); #endif boost::asio::ip::tcp::no_delay noDelayOption(false); - socket_.set_option(noDelayOption); + socket().set_option(noDelayOption); return true; @@ -210,7 +243,7 @@ PRAGMA_WARNING_DISABLE_VS(4355) template<class t_protocol_handler> boost::asio::io_service& connection<t_protocol_handler>::get_io_service() { - return socket_.get_io_service(); + return socket().get_io_service(); } //--------------------------------------------------------------------------------- template<class t_protocol_handler> @@ -222,9 +255,9 @@ PRAGMA_WARNING_DISABLE_VS(4355) auto self = safe_shared_from_this(); if(!self) return false; - //_dbg3("[sock " << socket_.native_handle() << "] add_ref, m_peer_number=" << mI->m_peer_number); + //_dbg3("[sock " << socket().native_handle() << "] add_ref, m_peer_number=" << mI->m_peer_number); CRITICAL_REGION_LOCAL(self->m_self_refs_lock); - //_dbg3("[sock " << socket_.native_handle() << "] add_ref 2, m_peer_number=" << mI->m_peer_number); + //_dbg3("[sock " << socket().native_handle() << "] add_ref 2, m_peer_number=" << mI->m_peer_number); if(m_was_shutdown) return false; ++m_reference_count; @@ -238,9 +271,9 @@ PRAGMA_WARNING_DISABLE_VS(4355) { TRY_ENTRY(); boost::shared_ptr<connection<t_protocol_handler> > back_connection_copy; - LOG_TRACE_CC(context, "[sock " << socket_.native_handle() << "] release"); + LOG_TRACE_CC(context, "[sock " << socket().native_handle() << "] release"); CRITICAL_REGION_BEGIN(m_self_refs_lock); - CHECK_AND_ASSERT_MES(m_reference_count, false, "[sock " << socket_.native_handle() << "] m_reference_count already at 0 at connection<t_protocol_handler>::release() call"); + CHECK_AND_ASSERT_MES(m_reference_count, false, "[sock " << socket().native_handle() << "] m_reference_count already at 0 at connection<t_protocol_handler>::release() call"); // is this the last reference? if (--m_reference_count == 0) { // move the held reference to a local variable, keeping the object alive until the function terminates @@ -266,7 +299,7 @@ PRAGMA_WARNING_DISABLE_VS(4355) std::string address, port; boost::system::error_code e; - boost::asio::ip::tcp::endpoint endpoint = socket_.remote_endpoint(e); + boost::asio::ip::tcp::endpoint endpoint = socket().remote_endpoint(e); if (e) { address = "<not connected>"; @@ -278,8 +311,8 @@ PRAGMA_WARNING_DISABLE_VS(4355) port = boost::lexical_cast<std::string>(endpoint.port()); } MDEBUG(" connection type " << to_string( m_connection_type ) << " " - << socket_.local_endpoint().address().to_string() << ":" << socket_.local_endpoint().port() - << " <--> " << address << ":" << port); + << socket().local_endpoint().address().to_string() << ":" << socket().local_endpoint().port() + << " <--> " << context.m_remote_address.str() << " (via " << address << ":" << port << ")"); } //--------------------------------------------------------------------------------- template<class t_protocol_handler> @@ -287,7 +320,7 @@ PRAGMA_WARNING_DISABLE_VS(4355) std::size_t bytes_transferred) { TRY_ENTRY(); - //_info("[sock " << socket_.native_handle() << "] Async read calledback."); + //_info("[sock " << socket().native_handle() << "] Async read calledback."); if (!e) { @@ -295,6 +328,7 @@ PRAGMA_WARNING_DISABLE_VS(4355) CRITICAL_REGION_LOCAL(m_throttle_speed_in_mutex); m_throttle_speed_in.handle_trafic_exact(bytes_transferred); context.m_current_speed_down = m_throttle_speed_in.get_current_speed(); + context.m_max_speed_down = std::max(context.m_max_speed_down, context.m_current_speed_down); } { @@ -322,7 +356,7 @@ PRAGMA_WARNING_DISABLE_VS(4355) } while(delay > 0); } // any form of sleeping - //_info("[sock " << socket_.native_handle() << "] RECV " << bytes_transferred); + //_info("[sock " << socket().native_handle() << "] RECV " << bytes_transferred); logger_handle_net_read(bytes_transferred); context.m_last_recv = time(NULL); context.m_recv_cnt += bytes_transferred; @@ -330,7 +364,7 @@ PRAGMA_WARNING_DISABLE_VS(4355) bool recv_res = m_protocol_handler.handle_recv(buffer_.data(), bytes_transferred); if(!recv_res) { - //_info("[sock " << socket_.native_handle() << "] protocol_want_close"); + //_info("[sock " << socket().native_handle() << "] protocol_want_close"); //some error in protocol, protocol handler ask to close connection boost::interprocess::ipcdetail::atomic_write32(&m_want_close_connection, 1); @@ -344,24 +378,24 @@ PRAGMA_WARNING_DISABLE_VS(4355) }else { reset_timer(get_timeout_from_bytes_read(bytes_transferred), false); - socket_.async_read_some(boost::asio::buffer(buffer_), + async_read_some(boost::asio::buffer(buffer_), strand_.wrap( boost::bind(&connection<t_protocol_handler>::handle_read, connection<t_protocol_handler>::shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred))); - //_info("[sock " << socket_.native_handle() << "]Async read requested."); + //_info("[sock " << socket().native_handle() << "]Async read requested."); } }else { - _dbg3("[sock " << socket_.native_handle() << "] Some not success at read: " << e.message() << ':' << e.value()); + _dbg3("[sock " << socket().native_handle() << "] Some not success at read: " << e.message() << ':' << e.value()); if(e.value() != 2) { - _dbg3("[sock " << socket_.native_handle() << "] Some problems at read: " << e.message() << ':' << e.value()); + _dbg3("[sock " << socket().native_handle() << "] Some problems at read: " << e.message() << ':' << e.value()); shutdown(); } else { - _dbg3("[sock " << socket_.native_handle() << "] peer closed connection"); + _dbg3("[sock " << socket().native_handle() << "] peer closed connection"); if (m_ready_to_close) shutdown(); } @@ -375,13 +409,85 @@ PRAGMA_WARNING_DISABLE_VS(4355) } //--------------------------------------------------------------------------------- template<class t_protocol_handler> + void connection<t_protocol_handler>::handle_receive(const boost::system::error_code& e, + std::size_t bytes_transferred) + { + TRY_ENTRY(); + if (e) + { + // offload the error case + handle_read(e, bytes_transferred); + return; + } + + reset_timer(get_timeout_from_bytes_read(bytes_transferred), false); + + buffer_ssl_init_fill += bytes_transferred; + if (buffer_ssl_init_fill <= get_ssl_magic_size()) + { + socket().async_receive(boost::asio::buffer(buffer_.data() + buffer_ssl_init_fill, buffer_.size() - buffer_ssl_init_fill), + boost::asio::socket_base::message_peek, + strand_.wrap( + boost::bind(&connection<t_protocol_handler>::handle_receive, connection<t_protocol_handler>::shared_from_this(), + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred))); + return; + } + + // detect SSL + if (m_ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect) + { + if (is_ssl((const unsigned char*)buffer_.data(), buffer_ssl_init_fill)) + { + MDEBUG("That looks like SSL"); + m_ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_enabled; // read/write to the SSL socket + } + else + { + MDEBUG("That does not look like SSL"); + m_ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_disabled; // read/write to the raw socket + } + } + + if (m_ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled) + { + // Handshake + if (!handshake(boost::asio::ssl::stream_base::server)) + { + MERROR("SSL handshake failed"); + boost::interprocess::ipcdetail::atomic_write32(&m_want_close_connection, 1); + bool do_shutdown = false; + CRITICAL_REGION_BEGIN(m_send_que_lock); + if(!m_send_que.size()) + do_shutdown = true; + CRITICAL_REGION_END(); + if(do_shutdown) + shutdown(); + return; + } + } + + async_read_some(boost::asio::buffer(buffer_), + strand_.wrap( + boost::bind(&connection<t_protocol_handler>::handle_read, connection<t_protocol_handler>::shared_from_this(), + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred))); + + // If an error occurs then no new asynchronous operations are started. This + // means that all shared_ptr references to the connection object will + // disappear and the object will be destroyed automatically after this + // handler returns. The connection class's destructor closes the socket. + CATCH_ENTRY_L0("connection<t_protocol_handler>::handle_receive", void()); + } + //--------------------------------------------------------------------------------- + template<class t_protocol_handler> bool connection<t_protocol_handler>::call_run_once_service_io() { TRY_ENTRY(); if(!m_is_multithreaded) { //single thread model, we can wait in blocked call - size_t cnt = socket_.get_io_service().run_one(); + size_t cnt = socket().get_io_service().run_one(); if(!cnt)//service is going to quit return false; }else @@ -391,7 +497,7 @@ PRAGMA_WARNING_DISABLE_VS(4355) //if no handlers were called //TODO: Maybe we need to have have critical section + event + callback to upper protocol to //ask it inside(!) critical region if we still able to go in event wait... - size_t cnt = socket_.get_io_service().poll_one(); + size_t cnt = socket().get_io_service().poll_one(); if(!cnt) misc_utils::sleep_no_w(1); } @@ -497,9 +603,10 @@ PRAGMA_WARNING_DISABLE_VS(4355) CRITICAL_REGION_LOCAL(m_throttle_speed_out_mutex); m_throttle_speed_out.handle_trafic_exact(cb); context.m_current_speed_up = m_throttle_speed_out.get_current_speed(); + context.m_max_speed_up = std::max(context.m_max_speed_up, context.m_current_speed_up); } - //_info("[sock " << socket_.native_handle() << "] SEND " << cb); + //_info("[sock " << socket().native_handle() << "] SEND " << cb); context.m_last_send = time(NULL); context.m_send_cnt += cb; //some data should be wrote to stream @@ -544,7 +651,7 @@ PRAGMA_WARNING_DISABLE_VS(4355) MDEBUG("do_send_chunk() NOW just queues: packet="<<size_now<<" B, is added to queue-size="<<m_send_que.size()); //do_send_handler_delayed( ptr , size_now ); // (((H))) // empty function - LOG_TRACE_CC(context, "[sock " << socket_.native_handle() << "] Async send requested " << m_send_que.front().size()); + LOG_TRACE_CC(context, "[sock " << socket().native_handle() << "] Async send requested " << m_send_que.front().size()); } else { // no active operation @@ -562,14 +669,14 @@ PRAGMA_WARNING_DISABLE_VS(4355) CHECK_AND_ASSERT_MES( size_now == m_send_que.front().size(), false, "Unexpected queue size"); reset_timer(get_default_timeout(), false); - boost::asio::async_write(socket_, boost::asio::buffer(m_send_que.front().data(), size_now ) , + async_write(boost::asio::buffer(m_send_que.front().data(), size_now ) , //strand_.wrap( boost::bind(&connection<t_protocol_handler>::handle_write, self, _1, _2) //) ); //_dbg3("(chunk): " << size_now); //logger_handle_net_write(size_now); - //_info("[sock " << socket_.native_handle() << "] Async send requested " << m_send_que.front().size()); + //_info("[sock " << socket().native_handle() << "] Async send requested " << m_send_que.front().size()); } //do_send_handler_stop( ptr , cb ); // empty function @@ -654,7 +761,8 @@ PRAGMA_WARNING_DISABLE_VS(4355) // Initiate graceful connection closure. m_timer.cancel(); boost::system::error_code ignored_ec; - socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec); + socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec); + socket().close(); if (!m_host.empty()) { try { host_count(m_host, -1); } catch (...) { /* ignore */ } @@ -672,7 +780,7 @@ PRAGMA_WARNING_DISABLE_VS(4355) auto self = safe_shared_from_this(); if(!self) return false; - //_info("[sock " << socket_.native_handle() << "] Que Shutdown called."); + //_info("[sock " << socket().native_handle() << "] Que Shutdown called."); m_timer.cancel(); size_t send_que_size = 0; CRITICAL_REGION_BEGIN(m_send_que_lock); @@ -707,11 +815,11 @@ PRAGMA_WARNING_DISABLE_VS(4355) void connection<t_protocol_handler>::handle_write(const boost::system::error_code& e, size_t cb) { TRY_ENTRY(); - LOG_TRACE_CC(context, "[sock " << socket_.native_handle() << "] Async send calledback " << cb); + LOG_TRACE_CC(context, "[sock " << socket().native_handle() << "] Async send calledback " << cb); if (e) { - _dbg1("[sock " << socket_.native_handle() << "] Some problems at write: " << e.message() << ':' << e.value()); + _dbg1("[sock " << socket().native_handle() << "] Some problems at write: " << e.message() << ':' << e.value()); shutdown(); return; } @@ -726,7 +834,7 @@ PRAGMA_WARNING_DISABLE_VS(4355) CRITICAL_REGION_BEGIN(m_send_que_lock); if(m_send_que.empty()) { - _erro("[sock " << socket_.native_handle() << "] m_send_que.size() == 0 at handle_write!"); + _erro("[sock " << socket().native_handle() << "] m_send_que.size() == 0 at handle_write!"); return; } @@ -746,11 +854,11 @@ PRAGMA_WARNING_DISABLE_VS(4355) if (speed_limit_is_enabled()) do_send_handler_write_from_queue(e, m_send_que.front().size() , m_send_que.size()); // (((H))) CHECK_AND_ASSERT_MES( size_now == m_send_que.front().size(), void(), "Unexpected queue size"); - boost::asio::async_write(socket_, boost::asio::buffer(m_send_que.front().data(), size_now) , - // strand_.wrap( - boost::bind(&connection<t_protocol_handler>::handle_write, connection<t_protocol_handler>::shared_from_this(), _1, _2) - // ) - ); + async_write(boost::asio::buffer(m_send_que.front().data(), size_now) , + // strand_.wrap( + boost::bind(&connection<t_protocol_handler>::handle_write, connection<t_protocol_handler>::shared_from_this(), _1, _2) + // ) + ); //_dbg3("(normal)" << size_now); } CRITICAL_REGION_END(); @@ -782,14 +890,17 @@ PRAGMA_WARNING_DISABLE_VS(4355) template<class t_protocol_handler> boosted_tcp_server<t_protocol_handler>::boosted_tcp_server( t_connection_type connection_type ) : + m_state(boost::make_shared<typename connection<t_protocol_handler>::shared_state>()), m_io_service_local_instance(new boost::asio::io_service()), io_service_(*m_io_service_local_instance.get()), acceptor_(io_service_), + default_remote(), m_stop_signal_sent(false), m_port(0), - m_sock_count(0), m_sock_number(0), m_threads_count(0), - m_pfilter(NULL), m_thread_index(0), + m_threads_count(0), + m_thread_index(0), m_connection_type( connection_type ), - new_connection_() + new_connection_(), + m_ssl_context({boost::asio::ssl::context(boost::asio::ssl::context::sslv23), {}}) { create_server_type_map(); m_thread_name_prefix = "NET"; @@ -797,13 +908,16 @@ PRAGMA_WARNING_DISABLE_VS(4355) template<class t_protocol_handler> boosted_tcp_server<t_protocol_handler>::boosted_tcp_server(boost::asio::io_service& extarnal_io_service, t_connection_type connection_type) : + m_state(boost::make_shared<typename connection<t_protocol_handler>::shared_state>()), io_service_(extarnal_io_service), acceptor_(io_service_), - m_stop_signal_sent(false), m_port(0), - m_sock_count(0), m_sock_number(0), m_threads_count(0), - m_pfilter(NULL), m_thread_index(0), + default_remote(), + m_stop_signal_sent(false), m_port(0), + m_threads_count(0), + m_thread_index(0), m_connection_type(connection_type), - new_connection_() + new_connection_(), + m_ssl_context({boost::asio::ssl::context(boost::asio::ssl::context::sslv23), {}}) { create_server_type_map(); m_thread_name_prefix = "NET"; @@ -825,12 +939,14 @@ PRAGMA_WARNING_DISABLE_VS(4355) } //--------------------------------------------------------------------------------- template<class t_protocol_handler> - bool boosted_tcp_server<t_protocol_handler>::init_server(uint32_t port, const std::string address) + bool boosted_tcp_server<t_protocol_handler>::init_server(uint32_t port, const std::string address, epee::net_utils::ssl_support_t ssl_support, const std::pair<std::string, std::string> &private_key_and_certificate_path, const std::list<std::string> &allowed_certificates, bool allow_any_cert) { TRY_ENTRY(); m_stop_signal_sent = false; m_port = port; m_address = address; + if (ssl_support != epee::net_utils::ssl_support_t::e_ssl_support_disabled) + m_ssl_context = create_ssl_context(private_key_and_certificate_path, allowed_certificates, allow_any_cert); // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR). boost::asio::ip::tcp::resolver resolver(io_service_); boost::asio::ip::tcp::resolver::query query(address, boost::lexical_cast<std::string>(port), boost::asio::ip::tcp::resolver::query::canonical_name); @@ -842,7 +958,7 @@ PRAGMA_WARNING_DISABLE_VS(4355) boost::asio::ip::tcp::endpoint binded_endpoint = acceptor_.local_endpoint(); m_port = binded_endpoint.port(); MDEBUG("start accept"); - new_connection_.reset(new connection<t_protocol_handler>(io_service_, m_config, m_sock_count, m_sock_number, m_pfilter, m_connection_type)); + new_connection_.reset(new connection<t_protocol_handler>(io_service_, m_state, m_connection_type, ssl_support, m_ssl_context)); acceptor_.async_accept(new_connection_->socket(), boost::bind(&boosted_tcp_server<t_protocol_handler>::handle_accept, this, boost::asio::placeholders::error)); @@ -864,7 +980,7 @@ PRAGMA_WARNING_DISABLE_VS(4355) PUSH_WARNINGS DISABLE_GCC_WARNING(maybe-uninitialized) template<class t_protocol_handler> - bool boosted_tcp_server<t_protocol_handler>::init_server(const std::string port, const std::string& address) + bool boosted_tcp_server<t_protocol_handler>::init_server(const std::string port, const std::string& address, epee::net_utils::ssl_support_t ssl_support, const std::pair<std::string, std::string> &private_key_and_certificate_path, const std::list<std::string> &allowed_certificates, bool allow_any_cert) { uint32_t p = 0; @@ -872,7 +988,7 @@ DISABLE_GCC_WARNING(maybe-uninitialized) MERROR("Failed to convert port no = " << port); return false; } - return this->init_server(p, address); + return this->init_server(p, address, ssl_support, private_key_and_certificate_path, allowed_certificates, allow_any_cert); } POP_WARNINGS //--------------------------------------------------------------------------------- @@ -920,7 +1036,8 @@ POP_WARNINGS template<class t_protocol_handler> void boosted_tcp_server<t_protocol_handler>::set_connection_filter(i_connection_filter* pfilter) { - m_pfilter = pfilter; + assert(m_state != nullptr); // always set in constructor + m_state->pfilter = pfilter; } //--------------------------------------------------------------------------------- template<class t_protocol_handler> @@ -1028,12 +1145,6 @@ POP_WARNINGS } //--------------------------------------------------------------------------------- template<class t_protocol_handler> - bool boosted_tcp_server<t_protocol_handler>::is_stop_signal_sent() - { - return m_stop_signal_sent; - } - //--------------------------------------------------------------------------------- - template<class t_protocol_handler> void boosted_tcp_server<t_protocol_handler>::handle_accept(const boost::system::error_code& e) { MDEBUG("handle_accept"); @@ -1042,11 +1153,18 @@ POP_WARNINGS if (!e) { if (m_connection_type == e_connection_type_RPC) { - MDEBUG("New server for RPC connections"); + const char *ssl_message = "unknown"; + switch (new_connection_->get_ssl_support()) + { + case epee::net_utils::ssl_support_t::e_ssl_support_disabled: ssl_message = "disabled"; break; + case epee::net_utils::ssl_support_t::e_ssl_support_enabled: ssl_message = "enabled"; break; + case epee::net_utils::ssl_support_t::e_ssl_support_autodetect: ssl_message = "autodetection"; break; + } + MDEBUG("New server for RPC connections, SSL " << ssl_message); new_connection_->setRpcStation(); // hopefully this is not needed actually } connection_ptr conn(std::move(new_connection_)); - new_connection_.reset(new connection<t_protocol_handler>(io_service_, m_config, m_sock_count, m_sock_number, m_pfilter, m_connection_type)); + new_connection_.reset(new connection<t_protocol_handler>(io_service_, m_state, m_connection_type, conn->get_ssl_support(), m_ssl_context)); acceptor_.async_accept(new_connection_->socket(), boost::bind(&boosted_tcp_server<t_protocol_handler>::handle_accept, this, boost::asio::placeholders::error)); @@ -1054,7 +1172,16 @@ POP_WARNINGS boost::asio::socket_base::keep_alive opt(true); conn->socket().set_option(opt); - conn->start(true, 1 < m_threads_count); + bool res; + if (default_remote.get_type_id() == net_utils::address_type::invalid) + res = conn->start(true, 1 < m_threads_count); + else + res = conn->start(true, 1 < m_threads_count, default_remote); + if (!res) + { + conn->cancel(); + return; + } conn->save_dbg_log(); return; } @@ -1069,43 +1196,40 @@ POP_WARNINGS } // error path, if e or exception - _erro("Some problems at accept: " << e.message() << ", connections_count = " << m_sock_count); + assert(m_state != nullptr); // always set in constructor + _erro("Some problems at accept: " << e.message() << ", connections_count = " << m_state->sock_count); misc_utils::sleep_no_w(100); - new_connection_.reset(new connection<t_protocol_handler>(io_service_, m_config, m_sock_count, m_sock_number, m_pfilter, m_connection_type)); + new_connection_.reset(new connection<t_protocol_handler>(io_service_, m_state, m_connection_type, new_connection_->get_ssl_support(), m_ssl_context)); acceptor_.async_accept(new_connection_->socket(), boost::bind(&boosted_tcp_server<t_protocol_handler>::handle_accept, this, boost::asio::placeholders::error)); } //--------------------------------------------------------------------------------- template<class t_protocol_handler> - bool boosted_tcp_server<t_protocol_handler>::connect(const std::string& adr, const std::string& port, uint32_t conn_timeout, t_connection_context& conn_context, const std::string& bind_ip) + bool boosted_tcp_server<t_protocol_handler>::add_connection(t_connection_context& out, boost::asio::ip::tcp::socket&& sock, network_address real_remote, epee::net_utils::ssl_support_t ssl_support) { - TRY_ENTRY(); - - connection_ptr new_connection_l(new connection<t_protocol_handler>(io_service_, m_config, m_sock_count, m_sock_number, m_pfilter, m_connection_type) ); - connections_mutex.lock(); - connections_.insert(new_connection_l); - MDEBUG("connections_ size now " << connections_.size()); - connections_mutex.unlock(); - epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler([&](){ CRITICAL_REGION_LOCAL(connections_mutex); connections_.erase(new_connection_l); }); - boost::asio::ip::tcp::socket& sock_ = new_connection_l->socket(); - - ////////////////////////////////////////////////////////////////////////// - boost::asio::ip::tcp::resolver resolver(io_service_); - boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), adr, port, boost::asio::ip::tcp::resolver::query::canonical_name); - boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query); - boost::asio::ip::tcp::resolver::iterator end; - if(iterator == end) + if(std::addressof(get_io_service()) == std::addressof(sock.get_io_service())) { - _erro("Failed to resolve " << adr); - return false; + connection_ptr conn(new connection<t_protocol_handler>(std::move(sock), m_state, m_connection_type, ssl_support, m_ssl_context)); + if(conn->start(false, 1 < m_threads_count, std::move(real_remote))) + { + conn->get_context(out); + conn->save_dbg_log(); + return true; + } } - ////////////////////////////////////////////////////////////////////////// - + else + { + MWARNING(out << " was not added, socket/io_service mismatch"); + } + return false; + } + //--------------------------------------------------------------------------------- + template<class t_protocol_handler> + typename boosted_tcp_server<t_protocol_handler>::try_connect_result_t boosted_tcp_server<t_protocol_handler>::try_connect(connection_ptr new_connection_l, const std::string& adr, const std::string& port, boost::asio::ip::tcp::socket &sock_, const boost::asio::ip::tcp::endpoint &remote_endpoint, const std::string &bind_ip, uint32_t conn_timeout, epee::net_utils::ssl_support_t ssl_support) + { + TRY_ENTRY(); - //boost::asio::ip::tcp::endpoint remote_endpoint(boost::asio::ip::address::from_string(addr.c_str()), port); - boost::asio::ip::tcp::endpoint remote_endpoint(*iterator); - sock_.open(remote_endpoint.protocol()); if(bind_ip != "0.0.0.0" && bind_ip != "0" && bind_ip != "" ) { @@ -1117,7 +1241,7 @@ POP_WARNINGS MERROR("Error binding to " << bind_ip << ": " << ec.message()); if (sock_.is_open()) sock_.close(); - return false; + return CONNECT_FAILURE; } } @@ -1151,14 +1275,14 @@ POP_WARNINGS { if (sock_.is_open()) sock_.close(); - return false; + return CONNECT_FAILURE; } if(local_shared_context->ec == boost::asio::error::would_block && !r) { //timeout sock_.close(); _dbg3("Failed to connect to " << adr << ":" << port << ", because of timeout (" << conn_timeout << ")"); - return false; + return CONNECT_FAILURE; } } ec = local_shared_context->ec; @@ -1168,11 +1292,79 @@ POP_WARNINGS _dbg3("Some problems at connect, message: " << ec.message()); if (sock_.is_open()) sock_.close(); - return false; + return CONNECT_FAILURE; } _dbg3("Connected success to " << adr << ':' << port); + const epee::net_utils::ssl_support_t ssl_support = new_connection_l->get_ssl_support(); + if (ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled || ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect) + { + // Handshake + MDEBUG("Handshaking SSL..."); + if (!new_connection_l->handshake(boost::asio::ssl::stream_base::client)) + { + if (ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect) + { + boost::system::error_code ignored_ec; + sock_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec); + sock_.close(); + return CONNECT_NO_SSL; + } + MERROR("SSL handshake failed"); + if (sock_.is_open()) + sock_.close(); + return CONNECT_FAILURE; + } + } + + return CONNECT_SUCCESS; + + CATCH_ENTRY_L0("boosted_tcp_server<t_protocol_handler>::try_connect", CONNECT_FAILURE); + } + //--------------------------------------------------------------------------------- + template<class t_protocol_handler> + bool boosted_tcp_server<t_protocol_handler>::connect(const std::string& adr, const std::string& port, uint32_t conn_timeout, t_connection_context& conn_context, const std::string& bind_ip, epee::net_utils::ssl_support_t ssl_support) + { + TRY_ENTRY(); + + connection_ptr new_connection_l(new connection<t_protocol_handler>(io_service_, m_state, m_connection_type, ssl_support, m_ssl_context) ); + connections_mutex.lock(); + connections_.insert(new_connection_l); + MDEBUG("connections_ size now " << connections_.size()); + connections_mutex.unlock(); + epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler([&](){ CRITICAL_REGION_LOCAL(connections_mutex); connections_.erase(new_connection_l); }); + boost::asio::ip::tcp::socket& sock_ = new_connection_l->socket(); + + ////////////////////////////////////////////////////////////////////////// + boost::asio::ip::tcp::resolver resolver(io_service_); + boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), adr, port, boost::asio::ip::tcp::resolver::query::canonical_name); + boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query); + boost::asio::ip::tcp::resolver::iterator end; + if(iterator == end) + { + _erro("Failed to resolve " << adr); + return false; + } + ////////////////////////////////////////////////////////////////////////// + + + //boost::asio::ip::tcp::endpoint remote_endpoint(boost::asio::ip::address::from_string(addr.c_str()), port); + boost::asio::ip::tcp::endpoint remote_endpoint(*iterator); + + auto try_connect_result = try_connect(new_connection_l, adr, port, sock_, remote_endpoint, bind_ip, conn_timeout, ssl_support); + if (try_connect_result == CONNECT_FAILURE) + return false; + if (ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect && try_connect_result == CONNECT_NO_SSL) + { + // we connected, but could not connect with SSL, try without + MERROR("SSL handshake failed on an autodetect connection, reconnecting without SSL"); + new_connection_l->disable_ssl(); + try_connect_result = try_connect(new_connection_l, adr, port, sock_, remote_endpoint, bind_ip, conn_timeout, epee::net_utils::ssl_support_t::e_ssl_support_disabled); + if (try_connect_result != CONNECT_SUCCESS) + return false; + } + // start adds the connection to the config object's list, so we don't need to have it locally anymore connections_mutex.lock(); connections_.erase(new_connection_l); @@ -1185,7 +1377,8 @@ POP_WARNINGS } else { - _erro("[sock " << new_connection_l->socket().native_handle() << "] Failed to start connection, connections_count = " << m_sock_count); + assert(m_state != nullptr); // always set in constructor + _erro("[sock " << new_connection_l->socket().native_handle() << "] Failed to start connection, connections_count = " << m_state->sock_count); } new_connection_l->save_dbg_log(); @@ -1196,10 +1389,10 @@ POP_WARNINGS } //--------------------------------------------------------------------------------- template<class t_protocol_handler> template<class t_callback> - bool boosted_tcp_server<t_protocol_handler>::connect_async(const std::string& adr, const std::string& port, uint32_t conn_timeout, const t_callback &cb, const std::string& bind_ip) + bool boosted_tcp_server<t_protocol_handler>::connect_async(const std::string& adr, const std::string& port, uint32_t conn_timeout, const t_callback &cb, const std::string& bind_ip, epee::net_utils::ssl_support_t ssl_support) { TRY_ENTRY(); - connection_ptr new_connection_l(new connection<t_protocol_handler>(io_service_, m_config, m_sock_count, m_sock_number, m_pfilter, m_connection_type) ); + connection_ptr new_connection_l(new connection<t_protocol_handler>(io_service_, m_state, m_connection_type, ssl_support, m_ssl_context) ); connections_mutex.lock(); connections_.insert(new_connection_l); MDEBUG("connections_ size now " << connections_.size()); diff --git a/contrib/epee/include/net/connection_basic.hpp b/contrib/epee/include/net/connection_basic.hpp index 9b6fc14a7..328f9afbf 100644 --- a/contrib/epee/include/net/connection_basic.hpp +++ b/contrib/epee/include/net/connection_basic.hpp @@ -47,14 +47,25 @@ #include <memory> #include <boost/asio.hpp> +#include <boost/asio/ssl.hpp> #include "net/net_utils_base.h" +#include "net/net_ssl.h" #include "syncobj.h" namespace epee { namespace net_utils { + struct socket_stats + { + socket_stats() + : sock_count(0), sock_number(0) + {} + + std::atomic<long> sock_count; + std::atomic<long> sock_number; + }; /************************************************************************/ /* */ @@ -72,6 +83,8 @@ class connection_basic_pimpl; // PIMPL for this class std::string to_string(t_connection_type type); class connection_basic { // not-templated base class for rapid developmet of some code parts + // beware of removing const, net_utils::connection is sketchily doing a cast to prevent storing ptr twice + const boost::shared_ptr<socket_stats> m_stats; public: std::unique_ptr< connection_basic_pimpl > mI; // my Implementation @@ -84,15 +97,57 @@ class connection_basic { // not-templated base class for rapid developmet of som /// Strand to ensure the connection's handlers are not called concurrently. boost::asio::io_service::strand strand_; /// Socket for the connection. - boost::asio::ip::tcp::socket socket_; + ssl_context_t &m_ssl_context; + ssl_support_t m_ssl_support; + boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_; - std::atomic<long> &m_ref_sock_count; // reference to external counter of existing sockets that we will ++/-- public: // first counter is the ++/-- count of current sockets, the other socket_number is only-increasing ++ number generator - connection_basic(boost::asio::io_service& io_service, std::atomic<long> &ref_sock_count, std::atomic<long> &sock_number); + connection_basic(boost::asio::ip::tcp::socket&& socket, boost::shared_ptr<socket_stats> stats, ssl_support_t ssl_support, ssl_context_t &ssl_context); + connection_basic(boost::asio::io_service &io_service, boost::shared_ptr<socket_stats> stats, ssl_support_t ssl_support, ssl_context_t &ssl_context); virtual ~connection_basic() noexcept(false); + //! \return `socket_stats` object passed in construction (ptr never changes). + socket_stats& get_stats() noexcept { return *m_stats; /* verified in constructor */ } + connection_basic(boost::asio::io_service& io_service, std::atomic<long> &ref_sock_count, std::atomic<long> &sock_number, ssl_support_t ssl, ssl_context_t &ssl_context); + + boost::asio::ip::tcp::socket& socket() { return socket_.next_layer(); } + ssl_support_t get_ssl_support() const { return m_ssl_support; } + void disable_ssl() { m_ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_disabled; } + + bool handshake(boost::asio::ssl::stream_base::handshake_type type) + { + return ssl_handshake(socket_, type, m_ssl_context); + } + + template<typename MutableBufferSequence, typename ReadHandler> + void async_read_some(const MutableBufferSequence &buffers, ReadHandler &&handler) + { + if (m_ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled) + socket_.async_read_some(buffers, std::forward<ReadHandler>(handler)); + else + socket().async_read_some(buffers, std::forward<ReadHandler>(handler)); + } + + template<typename ConstBufferSequence, typename WriteHandler> + void async_write_some(const ConstBufferSequence &buffers, WriteHandler &&handler) + { + if (m_ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled) + socket_.async_write_some(buffers, std::forward<WriteHandler>(handler)); + else + socket().async_write_some(buffers, std::forward<WriteHandler>(handler)); + } + + template<typename ConstBufferSequence, typename WriteHandler> + void async_write(const ConstBufferSequence &buffers, WriteHandler &&handler) + { + if (m_ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled) + boost::asio::async_write(socket_, buffers, std::forward<WriteHandler>(handler)); + else + boost::asio::async_write(socket(), buffers, std::forward<WriteHandler>(handler)); + } + // various handlers to be called from connection class: void do_send_handler_write(const void * ptr , size_t cb); void do_send_handler_write_from_queue(const boost::system::error_code& e, size_t cb , int q_len); // from handle_write, sending next part diff --git a/contrib/epee/include/net/enums.h b/contrib/epee/include/net/enums.h new file mode 100644 index 000000000..078a4b274 --- /dev/null +++ b/contrib/epee/include/net/enums.h @@ -0,0 +1,65 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include <boost/utility/string_ref.hpp> +#include <cstdint> + +namespace epee +{ +namespace net_utils +{ + enum class address_type : std::uint8_t + { + // Do not change values, this will break serialization + invalid = 0, + ipv4 = 1, + ipv6 = 2, + i2p = 3, + tor = 4 + }; + + enum class zone : std::uint8_t + { + invalid = 0, + public_ = 1, // public is keyword + i2p = 2, + tor = 3 + }; + + // implementations in src/net_utils_base.cpp + + //! \return String name of zone or "invalid" on error. + const char* zone_to_string(zone value) noexcept; + + //! \return `zone` enum of `value` or `zone::invalid` on error. + zone zone_from_string(boost::string_ref value) noexcept; +} // net_utils +} // epee + diff --git a/contrib/epee/include/net/http_client.h b/contrib/epee/include/net/http_client.h index e01691794..34b3ac06c 100644 --- a/contrib/epee/include/net/http_client.h +++ b/contrib/epee/include/net/http_client.h @@ -275,7 +275,10 @@ namespace net_utils chunked_state m_chunked_state; std::string m_chunked_cache; critical_section m_lock; - bool m_ssl; + epee::net_utils::ssl_support_t m_ssl_support; + std::pair<std::string, std::string> m_ssl_private_key_and_certificate_path; + std::list<std::string> m_ssl_allowed_certificates; + bool m_ssl_allow_any_cert; public: explicit http_simple_client_template() @@ -293,35 +296,39 @@ namespace net_utils , m_chunked_state() , m_chunked_cache() , m_lock() - , m_ssl(false) + , m_ssl_support(epee::net_utils::ssl_support_t::e_ssl_support_autodetect) {} const std::string &get_host() const { return m_host_buff; }; const std::string &get_port() const { return m_port; }; - bool set_server(const std::string& address, boost::optional<login> user, bool ssl = false) + bool set_server(const std::string& address, boost::optional<login> user, epee::net_utils::ssl_support_t ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_autodetect, const std::pair<std::string, std::string> &private_key_and_certificate_path = {}, const std::list<std::string> &allowed_ssl_certificates = {}, bool allow_any_cert = false) { http::url_content parsed{}; const bool r = parse_url(address, parsed); CHECK_AND_ASSERT_MES(r, false, "failed to parse url: " << address); - set_server(std::move(parsed.host), std::to_string(parsed.port), std::move(user), ssl); + set_server(std::move(parsed.host), std::to_string(parsed.port), std::move(user), ssl_support, private_key_and_certificate_path, allowed_ssl_certificates, allow_any_cert); return true; } - void set_server(std::string host, std::string port, boost::optional<login> user, bool ssl = false) + void set_server(std::string host, std::string port, boost::optional<login> user, epee::net_utils::ssl_support_t ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_autodetect, const std::pair<std::string, std::string> &private_key_and_certificate_path = {}, const std::list<std::string> &allowed_ssl_certificates = {}, bool allow_any_cert = false) { CRITICAL_REGION_LOCAL(m_lock); disconnect(); m_host_buff = std::move(host); m_port = std::move(port); m_auth = user ? http_client_auth{std::move(*user)} : http_client_auth{}; - m_ssl = ssl; + m_ssl_support = ssl_support; + m_ssl_private_key_and_certificate_path = private_key_and_certificate_path; + m_ssl_allowed_certificates = allowed_ssl_certificates; + m_ssl_allow_any_cert = allow_any_cert; + m_net_client.set_ssl(m_ssl_support, m_ssl_private_key_and_certificate_path, m_ssl_allowed_certificates, m_ssl_allow_any_cert); } bool connect(std::chrono::milliseconds timeout) { CRITICAL_REGION_LOCAL(m_lock); - return m_net_client.connect(m_host_buff, m_port, timeout, m_ssl); + return m_net_client.connect(m_host_buff, m_port, timeout, "0.0.0.0"); } //--------------------------------------------------------------------------- bool disconnect() @@ -330,10 +337,10 @@ namespace net_utils return m_net_client.disconnect(); } //--------------------------------------------------------------------------- - bool is_connected() + bool is_connected(bool *ssl = NULL) { CRITICAL_REGION_LOCAL(m_lock); - return m_net_client.is_connected(); + return m_net_client.is_connected(ssl); } //--------------------------------------------------------------------------- virtual bool handle_target_data(std::string& piece_of_transfer) diff --git a/contrib/epee/include/net/http_server_handlers_map2.h b/contrib/epee/include/net/http_server_handlers_map2.h index 64d035df9..4b2053091 100644 --- a/contrib/epee/include/net/http_server_handlers_map2.h +++ b/contrib/epee/include/net/http_server_handlers_map2.h @@ -54,7 +54,7 @@ bool handled = false; \ if(false) return true; //just a stub to have "else if" -#define MAP_URI2(pattern, callback) else if(std::string::npos != query_info.m_URI.find(pattern)) return callback(query_info, response_info, m_conn_context); +#define MAP_URI2(pattern, callback) else if(std::string::npos != query_info.m_URI.find(pattern)) return callback(query_info, response_info, &m_conn_context); #define MAP_URI_AUTO_XML2(s_pattern, callback_f, command_type) //TODO: don't think i ever again will use xml - ambiguous and "overtagged" format @@ -69,7 +69,7 @@ uint64_t ticks1 = epee::misc_utils::get_tick_count(); \ boost::value_initialized<command_type::response> resp;\ MINFO(m_conn_context << "calling " << s_pattern); \ - if(!callback_f(static_cast<command_type::request&>(req), static_cast<command_type::response&>(resp))) \ + if(!callback_f(static_cast<command_type::request&>(req), static_cast<command_type::response&>(resp), &m_conn_context)) \ { \ LOG_ERROR("Failed to " << #callback_f << "()"); \ response_info.m_response_code = 500; \ @@ -97,7 +97,7 @@ uint64_t ticks1 = misc_utils::get_tick_count(); \ boost::value_initialized<command_type::response> resp;\ MINFO(m_conn_context << "calling " << s_pattern); \ - if(!callback_f(static_cast<command_type::request&>(req), static_cast<command_type::response&>(resp))) \ + if(!callback_f(static_cast<command_type::request&>(req), static_cast<command_type::response&>(resp), &m_conn_context)) \ { \ LOG_ERROR("Failed to " << #callback_f << "()"); \ response_info.m_response_code = 500; \ @@ -182,7 +182,7 @@ fail_resp.jsonrpc = "2.0"; \ fail_resp.id = req.id; \ MINFO(m_conn_context << "Calling RPC method " << method_name); \ - if(!callback_f(req.params, resp.result, fail_resp.error)) \ + if(!callback_f(req.params, resp.result, fail_resp.error, &m_conn_context)) \ { \ epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(fail_resp), response_info.m_body); \ return true; \ @@ -201,7 +201,7 @@ fail_resp.jsonrpc = "2.0"; \ fail_resp.id = req.id; \ MINFO(m_conn_context << "calling RPC method " << method_name); \ - if(!callback_f(req.params, resp.result, fail_resp.error, m_conn_context, response_info)) \ + if(!callback_f(req.params, resp.result, fail_resp.error, response_info, &m_conn_context)) \ { \ epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(fail_resp), response_info.m_body); \ return true; \ @@ -215,7 +215,7 @@ { \ PREPARE_OBJECTS_FROM_JSON(command_type) \ MINFO(m_conn_context << "calling RPC method " << method_name); \ - if(!callback_f(req.params, resp.result)) \ + if(!callback_f(req.params, resp.result, &m_conn_context)) \ { \ epee::json_rpc::error_response fail_resp = AUTO_VAL_INIT(fail_resp); \ fail_resp.jsonrpc = "2.0"; \ diff --git a/contrib/epee/include/net/http_server_impl_base.h b/contrib/epee/include/net/http_server_impl_base.h index 5669824c1..236067580 100644 --- a/contrib/epee/include/net/http_server_impl_base.h +++ b/contrib/epee/include/net/http_server_impl_base.h @@ -58,7 +58,10 @@ namespace epee bool init(std::function<void(size_t, uint8_t*)> rng, const std::string& bind_port = "0", const std::string& bind_ip = "0.0.0.0", std::vector<std::string> access_control_origins = std::vector<std::string>(), - boost::optional<net_utils::http::login> user = boost::none) + boost::optional<net_utils::http::login> user = boost::none, + epee::net_utils::ssl_support_t ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_autodetect, + const std::pair<std::string, std::string> &private_key_and_certificate_path = {}, + const std::list<std::string> &allowed_certificates = std::list<std::string>(), bool allow_any_cert = false) { //set self as callback handler @@ -75,7 +78,7 @@ namespace epee m_net_server.get_config_object().m_user = std::move(user); MGINFO("Binding on " << bind_ip << ":" << bind_port); - bool res = m_net_server.init_server(bind_port, bind_ip); + bool res = m_net_server.init_server(bind_port, bind_ip, ssl_support, private_key_and_certificate_path, allowed_certificates, allow_any_cert); if(!res) { LOG_ERROR("Failed to bind server"); diff --git a/contrib/epee/include/net/net_helper.h b/contrib/epee/include/net/net_helper.h index 94744ac21..5d9bb61cf 100644 --- a/contrib/epee/include/net/net_helper.h +++ b/contrib/epee/include/net/net_helper.h @@ -40,6 +40,7 @@ #include <boost/lambda/lambda.hpp> #include <boost/interprocess/detail/atomic.hpp> #include "net/net_utils_base.h" +#include "net/net_ssl.h" #include "misc_language.h" #undef MONERO_DEFAULT_LOG_CATEGORY @@ -57,6 +58,13 @@ namespace net_utils class blocked_mode_client { + enum try_connect_result_t + { + CONNECT_SUCCESS, + CONNECT_FAILURE, + CONNECT_NO_SSL, + }; + struct handler_obj @@ -84,9 +92,9 @@ namespace net_utils m_connected(false), m_deadline(m_io_service), m_shutdowned(0), - m_ssl(false), - m_ctx(boost::asio::ssl::context::sslv23), - m_ssl_socket(m_io_service,m_ctx) + m_ssl_support(epee::net_utils::ssl_support_t::e_ssl_support_autodetect), + m_ctx({boost::asio::ssl::context(boost::asio::ssl::context::sslv23), {}}), + m_ssl_socket(new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(m_io_service,m_ctx.context)) { @@ -110,28 +118,92 @@ namespace net_utils catch(...) { /* ignore */ } } + inline void set_ssl(epee::net_utils::ssl_support_t ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_autodetect, const std::pair<std::string, std::string> &private_key_and_certificate_path = {}, const std::list<std::string> &allowed_certificates = std::list<std::string>(), bool allow_any_cert = false) + { + if (ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_disabled) + m_ctx = {boost::asio::ssl::context(boost::asio::ssl::context::sslv23), {}}; + else + m_ctx = create_ssl_context(private_key_and_certificate_path, allowed_certificates, allow_any_cert); + m_ssl_support = ssl_support; + } + inline - bool connect(const std::string& addr, int port, std::chrono::milliseconds timeout, bool ssl = false, const std::string& bind_ip = "0.0.0.0") + bool connect(const std::string& addr, int port, std::chrono::milliseconds timeout, const std::string& bind_ip = "0.0.0.0") { - return connect(addr, std::to_string(port), timeout, ssl, bind_ip); + return connect(addr, std::to_string(port), timeout, bind_ip); } inline - bool connect(const std::string& addr, const std::string& port, std::chrono::milliseconds timeout, bool ssl = false, const std::string& bind_ip = "0.0.0.0") + try_connect_result_t try_connect(const std::string& addr, const std::string& port, const boost::asio::ip::tcp::endpoint &remote_endpoint, std::chrono::milliseconds timeout, const std::string& bind_ip, epee::net_utils::ssl_support_t ssl_support) { - m_connected = false; - m_ssl = ssl; + m_ssl_socket->next_layer().open(remote_endpoint.protocol()); + if(bind_ip != "0.0.0.0" && bind_ip != "0" && bind_ip != "" ) + { + boost::asio::ip::tcp::endpoint local_endpoint(boost::asio::ip::address::from_string(addr.c_str()), 0); + m_ssl_socket->next_layer().bind(local_endpoint); + } + + + m_deadline.expires_from_now(timeout); + + boost::system::error_code ec = boost::asio::error::would_block; + + m_ssl_socket->next_layer().async_connect(remote_endpoint, boost::lambda::var(ec) = boost::lambda::_1); + while (ec == boost::asio::error::would_block) + { + m_io_service.run_one(); + } + + if (!ec && m_ssl_socket->next_layer().is_open()) + { + m_connected = true; + m_deadline.expires_at(std::chrono::steady_clock::time_point::max()); + // SSL Options + if (ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled || ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect) + { + if (!ssl_handshake(*m_ssl_socket, boost::asio::ssl::stream_base::client, m_ctx)) + { + if (ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect) + { + boost::system::error_code ignored_ec; + m_ssl_socket->next_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec); + m_ssl_socket->next_layer().close(); + m_connected = false; + return CONNECT_NO_SSL; + } + else + { + MWARNING("Failed to establish SSL connection"); + m_connected = false; + return CONNECT_FAILURE; + } + } + m_ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_enabled; + } + return CONNECT_SUCCESS; + }else + { + MWARNING("Some problems at connect, message: " << ec.message()); + return CONNECT_FAILURE; + } + + } + + inline + bool connect(const std::string& addr, const std::string& port, std::chrono::milliseconds timeout, const std::string& bind_ip = "0.0.0.0") + { + m_connected = false; try { - m_ssl_socket.next_layer().close(); + m_ssl_socket->next_layer().close(); // Set SSL options // disable sslv2 - m_ctx.set_options(boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2); - m_ctx.set_default_verify_paths(); + m_ctx.context.set_options(boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2); + m_ctx.context.set_default_verify_paths(); + m_ssl_socket.reset(new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(m_io_service, m_ctx.context)); // Get a list of endpoints corresponding to the server name. - ////////////////////////////////////////////////////////////////////////// @@ -151,45 +223,20 @@ namespace net_utils //boost::asio::ip::tcp::endpoint remote_endpoint(boost::asio::ip::address::from_string(addr.c_str()), port); boost::asio::ip::tcp::endpoint remote_endpoint(*iterator); - - m_ssl_socket.next_layer().open(remote_endpoint.protocol()); - if(bind_ip != "0.0.0.0" && bind_ip != "0" && bind_ip != "" ) - { - boost::asio::ip::tcp::endpoint local_endpoint(boost::asio::ip::address::from_string(addr.c_str()), 0); - m_ssl_socket.next_layer().bind(local_endpoint); - } - - - m_deadline.expires_from_now(timeout); - - - boost::system::error_code ec = boost::asio::error::would_block; - - m_ssl_socket.next_layer().async_connect(remote_endpoint, boost::lambda::var(ec) = boost::lambda::_1); - while (ec == boost::asio::error::would_block) - { - m_io_service.run_one(); - } - - if (!ec && m_ssl_socket.next_layer().is_open()) + try_connect_result_t try_connect_result = try_connect(addr, port, remote_endpoint, timeout, bind_ip, m_ssl_support); + if (try_connect_result == CONNECT_FAILURE) + return false; + if (m_ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect) { - m_connected = true; - m_deadline.expires_at(std::chrono::steady_clock::time_point::max()); - // SSL Options - if(m_ssl) { - // Disable verification of host certificate - m_ssl_socket.set_verify_mode(boost::asio::ssl::verify_peer); - // Handshake - m_ssl_socket.next_layer().set_option(boost::asio::ip::tcp::no_delay(true)); - m_ssl_socket.handshake(boost::asio::ssl::stream_base::client); + m_ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_enabled; + if (try_connect_result == CONNECT_NO_SSL) + { + MERROR("SSL handshake failed on an autodetect connection, reconnecting without SSL"); + m_ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_disabled; + if (try_connect(addr, port, remote_endpoint, timeout, bind_ip, m_ssl_support) != CONNECT_SUCCESS) + return false; } - return true; - }else - { - MWARNING("Some problems at connect, message: " << ec.message()); - return false; } - } catch(const boost::system::system_error& er) { @@ -213,9 +260,9 @@ namespace net_utils if(m_connected) { m_connected = false; - if(m_ssl) + if(m_ssl_support != epee::net_utils::ssl_support_t::e_ssl_support_disabled) shutdown_ssl(); - m_ssl_socket.next_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both); + m_ssl_socket->next_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both); } } @@ -342,9 +389,13 @@ namespace net_utils return true; } - bool is_connected() + bool is_connected(bool *ssl = NULL) { - return m_connected && m_ssl_socket.next_layer().is_open(); + if (!m_connected || !m_ssl_socket->next_layer().is_open()) + return false; + if (ssl) + *ssl = m_ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled; + return true; } inline @@ -506,15 +557,15 @@ namespace net_utils { m_deadline.cancel(); boost::system::error_code ec; - if(m_ssl) + if(m_ssl_support != epee::net_utils::ssl_support_t::e_ssl_support_disabled) shutdown_ssl(); - m_ssl_socket.next_layer().cancel(ec); + m_ssl_socket->next_layer().cancel(ec); if(ec) MDEBUG("Problems at cancel: " << ec.message()); - m_ssl_socket.next_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); + m_ssl_socket->next_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); if(ec) MDEBUG("Problems at shutdown: " << ec.message()); - m_ssl_socket.next_layer().close(ec); + m_ssl_socket->next_layer().close(ec); if(ec) MDEBUG("Problems at close: " << ec.message()); boost::interprocess::ipcdetail::atomic_write32(&m_shutdowned, 1); @@ -533,7 +584,7 @@ namespace net_utils boost::asio::ip::tcp::socket& get_socket() { - return m_ssl_socket.next_layer(); + return m_ssl_socket->next_layer(); } private: @@ -550,7 +601,7 @@ namespace net_utils // connect(), read_line() or write_line() functions to return. LOG_PRINT_L3("Timed out socket"); m_connected = false; - m_ssl_socket.next_layer().close(); + m_ssl_socket->next_layer().close(); // There is no longer an active deadline. The expiry is set to positive // infinity so that the actor takes no action until a new deadline is set. @@ -565,7 +616,7 @@ namespace net_utils // ssl socket shutdown blocks if server doesn't respond. We close after 2 secs boost::system::error_code ec = boost::asio::error::would_block; m_deadline.expires_from_now(std::chrono::milliseconds(2000)); - m_ssl_socket.async_shutdown(boost::lambda::var(ec) = boost::lambda::_1); + m_ssl_socket->async_shutdown(boost::lambda::var(ec) = boost::lambda::_1); while (ec == boost::asio::error::would_block) { m_io_service.run_one(); @@ -586,35 +637,39 @@ namespace net_utils bool write(const void* data, size_t sz, boost::system::error_code& ec) { bool success; - if(m_ssl) - success = boost::asio::write(m_ssl_socket, boost::asio::buffer(data, sz), ec); + if(m_ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled) + success = boost::asio::write(*m_ssl_socket, boost::asio::buffer(data, sz), ec); else - success = boost::asio::write(m_ssl_socket.next_layer(), boost::asio::buffer(data, sz), ec); + success = boost::asio::write(m_ssl_socket->next_layer(), boost::asio::buffer(data, sz), ec); return success; } void async_write(const void* data, size_t sz, boost::system::error_code& ec) { - if(m_ssl) - boost::asio::async_write(m_ssl_socket, boost::asio::buffer(data, sz), boost::lambda::var(ec) = boost::lambda::_1); + if(m_ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled) + boost::asio::async_write(*m_ssl_socket, boost::asio::buffer(data, sz), boost::lambda::var(ec) = boost::lambda::_1); else - boost::asio::async_write(m_ssl_socket.next_layer(), boost::asio::buffer(data, sz), boost::lambda::var(ec) = boost::lambda::_1); + boost::asio::async_write(m_ssl_socket->next_layer(), boost::asio::buffer(data, sz), boost::lambda::var(ec) = boost::lambda::_1); } void async_read(char* buff, size_t sz, boost::asio::detail::transfer_at_least_t transfer_at_least, handler_obj& hndlr) { - if(!m_ssl) - boost::asio::async_read(m_ssl_socket.next_layer(), boost::asio::buffer(buff, sz), transfer_at_least, hndlr); + if(m_ssl_support != epee::net_utils::ssl_support_t::e_ssl_support_enabled) + boost::asio::async_read(m_ssl_socket->next_layer(), boost::asio::buffer(buff, sz), transfer_at_least, hndlr); else - boost::asio::async_read(m_ssl_socket, boost::asio::buffer(buff, sz), transfer_at_least, hndlr); + boost::asio::async_read(*m_ssl_socket, boost::asio::buffer(buff, sz), transfer_at_least, hndlr); } protected: boost::asio::io_service m_io_service; - boost::asio::ssl::context m_ctx; - boost::asio::ssl::stream<boost::asio::ip::tcp::socket> m_ssl_socket; - bool m_ssl; + epee::net_utils::ssl_context_t m_ctx; + std::shared_ptr<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>> m_ssl_socket; + epee::net_utils::ssl_support_t m_ssl_support; + std::string m_ssl_private_key; + std::string m_ssl_certificate; + std::list<std::string> m_ssl_allowed_certificates; + bool m_ssl_allow_any_cerl; bool m_initialized; bool m_connected; boost::asio::steady_timer m_deadline; @@ -722,7 +777,7 @@ namespace net_utils // asynchronous operations are cancelled. This allows the blocked // connect(), read_line() or write_line() functions to return. LOG_PRINT_L3("Timed out socket"); - m_ssl_socket.next_layer().close(); + m_ssl_socket->next_layer().close(); // There is no longer an active deadline. The expiry is set to positive // infinity so that the actor takes no action until a new deadline is set. diff --git a/contrib/epee/include/net/net_ssl.h b/contrib/epee/include/net/net_ssl.h new file mode 100644 index 000000000..9ae1883af --- /dev/null +++ b/contrib/epee/include/net/net_ssl.h @@ -0,0 +1,68 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the Andrey N. Sabelnikov nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + + + +#ifndef _NET_SSL_H +#define _NET_SSL_H + +#include <stdint.h> +#include <string> +#include <list> +#include <boost/utility/string_ref.hpp> +#include <boost/asio/ip/tcp.hpp> +#include <boost/asio/ssl.hpp> + +namespace epee +{ +namespace net_utils +{ + enum class ssl_support_t: uint8_t { + e_ssl_support_disabled, + e_ssl_support_enabled, + e_ssl_support_autodetect, + }; + + struct ssl_context_t + { + boost::asio::ssl::context context; + std::list<std::string> allowed_certificates; + bool allow_any_cert; + }; + + // https://security.stackexchange.com/questions/34780/checking-client-hello-for-https-classification + constexpr size_t get_ssl_magic_size() { return 9; } + bool is_ssl(const unsigned char *data, size_t len); + ssl_context_t create_ssl_context(const std::pair<std::string, std::string> &private_key_and_certificate_path, std::list<std::string> allowed_certificates, bool allow_any_cert); + void use_ssl_certificate(ssl_context_t &ssl_context, const std::pair<std::string, std::string> &private_key_and_certificate_path); + bool create_ssl_certificate(std::string &pkey_buffer, std::string &cert_buffer); + bool is_certificate_allowed(boost::asio::ssl::verify_context &ctx, const std::list<std::string> &allowed_certificates); + bool ssl_handshake(boost::asio::ssl::stream<boost::asio::ip::tcp::socket> &socket, boost::asio::ssl::stream_base::handshake_type type, const epee::net_utils::ssl_context_t &ssl_context); + bool ssl_support_from_string(ssl_support_t &ssl, boost::string_ref s); +} +} + +#endif //_NET_SSL_H diff --git a/contrib/epee/include/net/net_utils_base.h b/contrib/epee/include/net/net_utils_base.h index a133942fb..7ee0106b1 100644 --- a/contrib/epee/include/net/net_utils_base.h +++ b/contrib/epee/include/net/net_utils_base.h @@ -33,6 +33,7 @@ #include <boost/asio/io_service.hpp> #include <typeinfo> #include <type_traits> +#include "enums.h" #include "serialization/keyvalue_serialization.h" #include "misc_log_ex.h" @@ -43,6 +44,11 @@ #define MAKE_IP( a1, a2, a3, a4 ) (a1|(a2<<8)|(a3<<16)|(a4<<24)) #endif +namespace net +{ + class tor_address; +} + namespace epee { namespace net_utils @@ -53,6 +59,10 @@ namespace net_utils uint16_t m_port; public: + constexpr ipv4_network_address() noexcept + : ipv4_network_address(0, 0) + {} + constexpr ipv4_network_address(uint32_t ip, uint16_t port) noexcept : m_ip(ip), m_port(port) {} @@ -67,9 +77,10 @@ namespace net_utils std::string host_str() const; bool is_loopback() const; bool is_local() const; - static constexpr uint8_t get_type_id() noexcept { return ID; } + static constexpr address_type get_type_id() noexcept { return address_type::ipv4; } + static constexpr zone get_zone() noexcept { return zone::public_; } + static constexpr bool is_blockable() noexcept { return true; } - static const uint8_t ID = 1; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(m_ip) KV_SERIALIZE(m_port) @@ -103,7 +114,9 @@ namespace net_utils 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; + virtual address_type get_type_id() const = 0; + virtual zone get_zone() const = 0; + virtual bool is_blockable() const = 0; }; template<typename T> @@ -131,7 +144,9 @@ namespace net_utils 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(); } + virtual address_type get_type_id() const override { return value.get_type_id(); } + virtual zone get_zone() const override { return value.get_zone(); } + virtual bool is_blockable() const override { return value.is_blockable(); } }; std::shared_ptr<interface> self; @@ -146,6 +161,23 @@ namespace net_utils throw std::bad_cast{}; return static_cast<implementation<Type_>*>(self_)->value; } + + template<typename T, typename t_storage> + bool serialize_addr(std::false_type, t_storage& stg, typename t_storage::hsection hparent) + { + T addr{}; + if (!epee::serialization::selector<false>::serialize(addr, stg, hparent, "addr")) + return false; + *this = std::move(addr); + return true; + } + + template<typename T, typename t_storage> + bool serialize_addr(std::true_type, t_storage& stg, typename t_storage::hsection hparent) const + { + return epee::serialization::selector<true>::serialize(as<T>(), stg, hparent, "addr"); + } + public: network_address() : self(nullptr) {} template<typename T> @@ -158,43 +190,32 @@ namespace net_utils 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; } + address_type get_type_id() const { return self ? self->get_type_id() : address_type::invalid; } + zone get_zone() const { return self ? self->get_zone() : zone::invalid; } + bool is_blockable() const { return self ? self->is_blockable() : false; } 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; + // need to `#include "net/tor_address.h"` when serializing `network_address` + static constexpr std::integral_constant<bool, is_store> is_store_{}; + + std::uint8_t type = std::uint8_t(is_store ? this_ref.get_type_id() : address_type::invalid); if (!epee::serialization::selector<is_store>::serialize(type, stg, hparent_section, "type")) return false; - switch (type) + + switch (address_type(type)) { - case ipv4_network_address::ID: - { - if (!is_store) - { - const_cast<network_address&>(this_ref) = ipv4_network_address{0, 0}; - auto &addr = this_ref.template as_mutable<ipv4_network_address>(); - if (epee::serialization::selector<is_store>::serialize(addr, stg, hparent_section, "addr")) - MDEBUG("Found as addr: " << this_ref.str()); - else if (epee::serialization::selector<is_store>::serialize(addr, stg, hparent_section, "template as<ipv4_network_address>()")) - MDEBUG("Found as template as<ipv4_network_address>(): " << this_ref.str()); - else if (epee::serialization::selector<is_store>::serialize(addr, stg, hparent_section, "template as_mutable<ipv4_network_address>()")) - MDEBUG("Found as template as_mutable<ipv4_network_address>(): " << this_ref.str()); - else - { - MWARNING("Address not found"); - return false; - } - } - else - { - auto &addr = this_ref.template as_mutable<ipv4_network_address>(); - if (!epee::serialization::selector<is_store>::serialize(addr, stg, hparent_section, "addr")) - return false; - } + case address_type::ipv4: + return this_ref.template serialize_addr<ipv4_network_address>(is_store_, stg, hparent_section); + case address_type::tor: + return this_ref.template serialize_addr<net::tor_address>(is_store_, stg, hparent_section); + case address_type::invalid: + default: break; - } - default: MERROR("Unsupported network address type: " << (unsigned)type); return false; } + + MERROR("Unsupported network address type: " << (unsigned)type); + return false; END_KV_SERIALIZE_MAP() }; @@ -211,8 +232,6 @@ namespace net_utils inline bool operator>=(const network_address& lhs, const network_address& rhs) { return !lhs.less(rhs); } - bool create_network_address(network_address &address, const std::string &string, uint16_t default_port = 0); - /************************************************************************/ /* */ /************************************************************************/ @@ -222,54 +241,63 @@ namespace net_utils const network_address m_remote_address; const bool m_is_income; const time_t m_started; + const time_t m_ssl; time_t m_last_recv; time_t m_last_send; uint64_t m_recv_cnt; uint64_t m_send_cnt; double m_current_speed_down; double m_current_speed_up; + double m_max_speed_down; + double m_max_speed_up; connection_context_base(boost::uuids::uuid connection_id, - const network_address &remote_address, bool is_income, + const network_address &remote_address, bool is_income, bool ssl, time_t last_recv = 0, time_t last_send = 0, uint64_t recv_cnt = 0, uint64_t send_cnt = 0): m_connection_id(connection_id), m_remote_address(remote_address), m_is_income(is_income), m_started(time(NULL)), + m_ssl(ssl), m_last_recv(last_recv), m_last_send(last_send), m_recv_cnt(recv_cnt), m_send_cnt(send_cnt), m_current_speed_down(0), - m_current_speed_up(0) + m_current_speed_up(0), + m_max_speed_down(0), + m_max_speed_up(0) {} connection_context_base(): m_connection_id(), - m_remote_address(ipv4_network_address{0,0}), + m_remote_address(), m_is_income(false), m_started(time(NULL)), + m_ssl(false), m_last_recv(0), m_last_send(0), m_recv_cnt(0), m_send_cnt(0), m_current_speed_down(0), - m_current_speed_up(0) + m_current_speed_up(0), + m_max_speed_down(0), + m_max_speed_up(0) {} connection_context_base& operator=(const connection_context_base& a) { - set_details(a.m_connection_id, a.m_remote_address, a.m_is_income); + set_details(a.m_connection_id, a.m_remote_address, a.m_is_income, a.m_ssl); return *this; } private: template<class t_protocol_handler> friend class connection; - void set_details(boost::uuids::uuid connection_id, const network_address &remote_address, bool is_income) + void set_details(boost::uuids::uuid connection_id, const network_address &remote_address, bool is_income, bool ssl) { this->~connection_context_base(); - new(this) connection_context_base(connection_id, remote_address, is_income); + new(this) connection_context_base(connection_id, remote_address, is_income, ssl); } }; diff --git a/contrib/epee/include/string_tools.h b/contrib/epee/include/string_tools.h index f7539fb6c..2e65876e6 100644 --- a/contrib/epee/include/string_tools.h +++ b/contrib/epee/include/string_tools.h @@ -206,6 +206,15 @@ POP_WARNINGS return boost::lexical_cast<std::string>(val); } //---------------------------------------------------------------------------- + inline std::string to_string_hex(uint32_t val) + { + std::stringstream ss; + ss << std::hex << val; + std::string s; + ss >> s; + return s; + } + //---------------------------------------------------------------------------- inline bool compare_no_case(const std::string& str1, const std::string& str2) { diff --git a/contrib/epee/src/CMakeLists.txt b/contrib/epee/src/CMakeLists.txt index cea50c9dd..e913211ea 100644 --- a/contrib/epee/src/CMakeLists.txt +++ b/contrib/epee/src/CMakeLists.txt @@ -27,7 +27,7 @@ # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. add_library(epee STATIC hex.cpp http_auth.cpp mlog.cpp net_utils_base.cpp string_tools.cpp wipeable_string.cpp memwipe.c - connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp) + connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp net_ssl.cpp) if (USE_READLINE AND GNU_READLINE_FOUND) add_library(epee_readline STATIC readline_buffer.cpp) endif() diff --git a/contrib/epee/src/connection_basic.cpp b/contrib/epee/src/connection_basic.cpp index 7d145ee46..377fb3452 100644 --- a/contrib/epee/src/connection_basic.cpp +++ b/contrib/epee/src/connection_basic.cpp @@ -48,7 +48,7 @@ #include "net/network_throttle-detail.hpp" #undef MONERO_DEFAULT_LOG_CATEGORY -#define MONERO_DEFAULT_LOG_CATEGORY "net.p2p" +#define MONERO_DEFAULT_LOG_CATEGORY "net.conn" // ################################################################################################ // local (TU local) headers @@ -103,7 +103,7 @@ namespace net_utils // connection_basic_pimpl // ================================================================================================ -connection_basic_pimpl::connection_basic_pimpl(const std::string &name) : m_throttle(name) { } +connection_basic_pimpl::connection_basic_pimpl(const std::string &name) : m_throttle(name), m_peer_number(0) { } // ================================================================================================ // connection_basic @@ -113,29 +113,61 @@ connection_basic_pimpl::connection_basic_pimpl(const std::string &name) : m_thro int connection_basic_pimpl::m_default_tos; // methods: -connection_basic::connection_basic(boost::asio::io_service& io_service, std::atomic<long> &ref_sock_count, std::atomic<long> &sock_number) - : +connection_basic::connection_basic(boost::asio::ip::tcp::socket&& sock, boost::shared_ptr<socket_stats> stats, ssl_support_t ssl_support, ssl_context_t &ssl_context) + : + m_stats(std::move(stats)), + mI( new connection_basic_pimpl("peer") ), + strand_(sock.get_io_service()), + socket_(sock.get_io_service(), ssl_context.context), + m_want_close_connection(false), + m_was_shutdown(false), + m_ssl_support(ssl_support), + m_ssl_context(ssl_context) +{ + // add nullptr checks if removed + CHECK_AND_ASSERT_THROW_MES(bool(m_stats), "stats shared_ptr cannot be null"); + + socket_.next_layer() = std::move(sock); + + ++(m_stats->sock_count); // increase the global counter + mI->m_peer_number = m_stats->sock_number.fetch_add(1); // use, and increase the generated number + + std::string remote_addr_str = "?"; + try { boost::system::error_code e; remote_addr_str = socket().remote_endpoint(e).address().to_string(); } catch(...){} ; + + _note("Spawned connection #"<<mI->m_peer_number<<" to " << remote_addr_str << " currently we have sockets count:" << m_stats->sock_count); +} + +connection_basic::connection_basic(boost::asio::io_service &io_service, boost::shared_ptr<socket_stats> stats, ssl_support_t ssl_support, ssl_context_t &ssl_context) + : + m_stats(std::move(stats)), mI( new connection_basic_pimpl("peer") ), strand_(io_service), - socket_(io_service), + socket_(io_service, ssl_context.context), m_want_close_connection(false), m_was_shutdown(false), - m_ref_sock_count(ref_sock_count) -{ - ++ref_sock_count; // increase the global counter - mI->m_peer_number = sock_number.fetch_add(1); // use, and increase the generated number + m_ssl_support(ssl_support), + m_ssl_context(ssl_context) +{ + // add nullptr checks if removed + CHECK_AND_ASSERT_THROW_MES(bool(m_stats), "stats shared_ptr cannot be null"); + + ++(m_stats->sock_count); // increase the global counter + mI->m_peer_number = m_stats->sock_number.fetch_add(1); // use, and increase the generated number std::string remote_addr_str = "?"; - try { boost::system::error_code e; remote_addr_str = socket_.remote_endpoint(e).address().to_string(); } catch(...){} ; + try { boost::system::error_code e; remote_addr_str = socket().remote_endpoint(e).address().to_string(); } catch(...){} ; - _note("Spawned connection p2p#"<<mI->m_peer_number<<" to " << remote_addr_str << " currently we have sockets count:" << m_ref_sock_count); + _note("Spawned connection #"<<mI->m_peer_number<<" to " << remote_addr_str << " currently we have sockets count:" << m_stats->sock_count); } connection_basic::~connection_basic() noexcept(false) { + --(m_stats->sock_count); + std::string remote_addr_str = "?"; - m_ref_sock_count--; - try { boost::system::error_code e; remote_addr_str = socket_.remote_endpoint(e).address().to_string(); } catch(...){} ; - _note("Destructing connection p2p#"<<mI->m_peer_number << " to " << remote_addr_str); + try { boost::system::error_code e; remote_addr_str = socket().remote_endpoint(e).address().to_string(); } catch(...){} ; + _note("Destructing connection #"<<mI->m_peer_number << " to " << remote_addr_str); +try { throw 0; } catch(...){} } void connection_basic::set_rate_up_limit(uint64_t limit) { diff --git a/contrib/epee/src/net_ssl.cpp b/contrib/epee/src/net_ssl.cpp new file mode 100644 index 000000000..941799078 --- /dev/null +++ b/contrib/epee/src/net_ssl.cpp @@ -0,0 +1,319 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <string.h> +#include <boost/asio/ssl.hpp> +#include <openssl/ssl.h> +#include <openssl/pem.h> +#include "misc_log_ex.h" +#include "net/net_ssl.h" + +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "net.ssl" + +// openssl genrsa -out /tmp/KEY 4096 +// openssl req -new -key /tmp/KEY -out /tmp/REQ +// openssl x509 -req -days 999999 -sha256 -in /tmp/REQ -signkey /tmp/KEY -out /tmp/CERT + +namespace +{ + struct openssl_bio_free + { + void operator()(BIO* ptr) const noexcept + { + if (ptr) + BIO_free(ptr); + } + }; + using openssl_bio = std::unique_ptr<BIO, openssl_bio_free>; + + struct openssl_pkey_free + { + void operator()(EVP_PKEY* ptr) const noexcept + { + if (ptr) + EVP_PKEY_free(ptr); + } + }; + using openssl_pkey = std::unique_ptr<EVP_PKEY, openssl_pkey_free>; + +} + +namespace epee +{ +namespace net_utils +{ + +// https://stackoverflow.com/questions/256405/programmatically-create-x509-certificate-using-openssl +bool create_ssl_certificate(EVP_PKEY *&pkey, X509 *&cert) +{ + MGINFO("Generating SSL certificate"); + pkey = EVP_PKEY_new(); + openssl_pkey pkey_deleter{pkey}; + if (!pkey) + { + MERROR("Failed to create new private key"); + return false; + } + RSA *rsa = RSA_generate_key(4096, RSA_F4, NULL, NULL); + if (!rsa) + { + MERROR("Error generating RSA private key"); + return false; + } + if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) + { + RSA_free(rsa); + MERROR("Error assigning RSA private key"); + return false; + } + + cert = X509_new(); + if (!cert) + { + MERROR("Failed to create new X509 certificate"); + return false; + } + ASN1_INTEGER_set(X509_get_serialNumber(cert), 1); + X509_gmtime_adj(X509_get_notBefore(cert), 0); + X509_gmtime_adj(X509_get_notAfter(cert), 3600 * 24 * 182); // half a year + if (!X509_set_pubkey(cert, pkey)) + { + MERROR("Error setting pubkey on certificate"); + X509_free(cert); + return false; + } + X509_NAME *name = X509_get_subject_name(cert); + X509_set_issuer_name(cert, name); + + if (X509_sign(cert, pkey, EVP_sha256()) == 0) + { + MERROR("Error signing certificate"); + X509_free(cert); + return false; + } + return true; +} + +bool create_ssl_certificate(std::string &pkey_buffer, std::string &cert_buffer) +{ + EVP_PKEY *pkey; + X509 *cert; + if (!create_ssl_certificate(pkey, cert)) + return false; + BIO *bio_pkey = BIO_new(BIO_s_mem()), *bio_cert = BIO_new(BIO_s_mem()); + openssl_bio bio_pkey_deleter{bio_pkey}; + bool success = PEM_write_bio_PrivateKey(bio_pkey, pkey, NULL, NULL, 0, NULL, NULL) && PEM_write_bio_X509(bio_cert, cert); + X509_free(cert); + if (!success) + { + MERROR("Failed to write cert and/or pkey: " << ERR_get_error()); + return false; + } + BUF_MEM *buf = NULL; + BIO_get_mem_ptr(bio_pkey, &buf); + if (!buf || !buf->data || !buf->length) + { + MERROR("Failed to write pkey: " << ERR_get_error()); + return false; + } + pkey_buffer = std::string(buf->data, buf->length); + buf = NULL; + BIO_get_mem_ptr(bio_cert, &buf); + if (!buf || !buf->data || !buf->length) + { + MERROR("Failed to write cert: " << ERR_get_error()); + return false; + } + cert_buffer = std::string(buf->data, buf->length); + return success; +} + +ssl_context_t create_ssl_context(const std::pair<std::string, std::string> &private_key_and_certificate_path, std::list<std::string> allowed_certificates, bool allow_any_cert) +{ + ssl_context_t ssl_context({boost::asio::ssl::context(boost::asio::ssl::context::sslv23), std::move(allowed_certificates)}); + + // disable sslv2 + ssl_context.context.set_options(boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2); + ssl_context.context.set_default_verify_paths(); + + // set options on the SSL context for added security + SSL_CTX *ctx = ssl_context.context.native_handle(); + CHECK_AND_ASSERT_THROW_MES(ctx, "Failed to get SSL context"); + SSL_CTX_clear_options(ctx, SSL_OP_LEGACY_SERVER_CONNECT); // SSL_CTX_SET_OPTIONS(3) + SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); // https://stackoverflow.com/questions/22378442 +#ifdef SSL_OP_NO_TICKET + SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET); // https://stackoverflow.com/questions/22378442 +#endif +#ifdef SSL_OP_NO_RENEGOTIATION + SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION); +#endif +#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION + SSL_CTX_set_options(ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); +#endif +#ifdef SSL_OP_NO_COMPRESSION + SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION); +#endif + SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1); // https://github.com/ssllabs/research/wiki/SSL-and-TLS-Deployment-Best-Practices + + CHECK_AND_ASSERT_THROW_MES(private_key_and_certificate_path.first.empty() == private_key_and_certificate_path.second.empty(), "private key and certificate must be either both given or both empty"); + if (private_key_and_certificate_path.second.empty()) + { + std::string pkey, cert; + CHECK_AND_ASSERT_THROW_MES(create_ssl_certificate(pkey, cert), "Failed to create certificate"); + ssl_context.context.use_private_key(boost::asio::buffer(pkey), boost::asio::ssl::context::pem); + ssl_context.context.use_certificate(boost::asio::buffer(cert), boost::asio::ssl::context::pem); + } + else + { + ssl_context.context.use_private_key_file(private_key_and_certificate_path.first, boost::asio::ssl::context::pem); + ssl_context.context.use_certificate_file(private_key_and_certificate_path.second, boost::asio::ssl::context::pem); + } + ssl_context.allow_any_cert = allow_any_cert; + + return ssl_context; +} + +void use_ssl_certificate(ssl_context_t &ssl_context, const std::pair<std::string, std::string> &private_key_and_certificate_path) +{ + ssl_context.context.use_private_key_file(private_key_and_certificate_path.first, boost::asio::ssl::context::pem); + ssl_context.context.use_certificate_file(private_key_and_certificate_path.second, boost::asio::ssl::context::pem); +} + +bool is_ssl(const unsigned char *data, size_t len) +{ + if (len < get_ssl_magic_size()) + return false; + + // https://security.stackexchange.com/questions/34780/checking-client-hello-for-https-classification + MDEBUG("SSL detection buffer, " << len << " bytes: " + << (unsigned)(unsigned char)data[0] << " " << (unsigned)(unsigned char)data[1] << " " + << (unsigned)(unsigned char)data[2] << " " << (unsigned)(unsigned char)data[3] << " " + << (unsigned)(unsigned char)data[4] << " " << (unsigned)(unsigned char)data[5] << " " + << (unsigned)(unsigned char)data[6] << " " << (unsigned)(unsigned char)data[7] << " " + << (unsigned)(unsigned char)data[8]); + if (data[0] == 0x16) // record + if (data[1] == 3) // major version + if (data[5] == 1) // ClientHello + if (data[6] == 0 && data[3]*256 + data[4] == data[7]*256 + data[8] + 4) // length check + return true; + return false; +} + +bool is_certificate_allowed(boost::asio::ssl::verify_context &ctx, const std::list<std::string> &allowed_certificates) +{ + X509_STORE_CTX *sctx = ctx.native_handle(); + if (!sctx) + { + MERROR("Error getting verify_context handle"); + return false; + } + X509 *cert =X509_STORE_CTX_get_current_cert(sctx); + if (!cert) + { + MERROR("No certificate found in verify_context"); + return false; + } + + BIO *bio_cert = BIO_new(BIO_s_mem()); + openssl_bio bio_cert_deleter{bio_cert}; + bool success = PEM_write_bio_X509(bio_cert, cert); + if (!success) + { + MERROR("Failed to print certificate"); + return false; + } + BUF_MEM *buf = NULL; + BIO_get_mem_ptr(bio_cert, &buf); + if (!buf || !buf->data || !buf->length) + { + MERROR("Failed to write certificate: " << ERR_get_error()); + return false; + } + std::string certificate(std::string(buf->data, buf->length)); + return std::find(allowed_certificates.begin(), allowed_certificates.end(), certificate) != allowed_certificates.end(); +} + +bool ssl_handshake(boost::asio::ssl::stream<boost::asio::ip::tcp::socket> &socket, boost::asio::ssl::stream_base::handshake_type type, const epee::net_utils::ssl_context_t &ssl_context) +{ + bool verified = false; + socket.next_layer().set_option(boost::asio::ip::tcp::no_delay(true)); + socket.set_verify_mode(boost::asio::ssl::verify_peer); + socket.set_verify_callback([&](bool preverified, boost::asio::ssl::verify_context &ctx) + { + if (!preverified) + { + const int err = X509_STORE_CTX_get_error(ctx.native_handle()); + const int depth = X509_STORE_CTX_get_error_depth(ctx.native_handle()); + if (err != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT || depth != 0) + { + MERROR("Invalid SSL certificate, error " << err << " at depth " << depth << ", connection dropped"); + return false; + } + } + if (!ssl_context.allow_any_cert && !ssl_context.allowed_certificates.empty() && !is_certificate_allowed(ctx, ssl_context.allowed_certificates)) + { + MERROR("Certificate is not in the allowed list, connection droppped"); + return false; + } + verified = true; + return true; + }); + + boost::system::error_code ec; + socket.handshake(type, ec); + if (ec) + { + MERROR("handshake failed, connection dropped"); + return false; + } + if (!ssl_context.allow_any_cert && !verified) + { + MERROR("Peer did not provide a certificate in the allowed list, connection dropped"); + return false; + } + MDEBUG("SSL handshake success"); + return true; +} + +bool ssl_support_from_string(ssl_support_t &ssl, boost::string_ref s) +{ + if (s == "enabled") + ssl = epee::net_utils::ssl_support_t::e_ssl_support_enabled; + else if (s == "disabled") + ssl = epee::net_utils::ssl_support_t::e_ssl_support_disabled; + else if (s == "autodetect") + ssl = epee::net_utils::ssl_support_t::e_ssl_support_autodetect; + else + return false; + return true; +} + +} // namespace +} // namespace + diff --git a/contrib/epee/src/net_utils_base.cpp b/contrib/epee/src/net_utils_base.cpp index 263b344b4..9b781027e 100644 --- a/contrib/epee/src/net_utils_base.cpp +++ b/contrib/epee/src/net_utils_base.cpp @@ -8,8 +8,6 @@ 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(); } @@ -58,20 +56,6 @@ namespace epee { namespace net_utils return self_->is_same_host(*other_self); } - bool create_network_address(network_address &address, const std::string &string, uint16_t default_port) - { - uint32_t ip; - uint16_t port; - if (epee::string_tools::parse_peer_from_string(ip, port, string)) - { - if (default_port && !port) - port = default_port; - address = ipv4_network_address{ip, port}; - return true; - } - return false; - } - std::string print_connection_context(const connection_context_base& ctx) { std::stringstream ss; @@ -86,5 +70,31 @@ namespace epee { namespace net_utils return ss.str(); } + const char* zone_to_string(zone value) noexcept + { + switch (value) + { + case zone::public_: + return "public"; + case zone::i2p: + return "i2p"; + case zone::tor: + return "tor"; + default: + break; + } + return "invalid"; + } + + zone zone_from_string(const boost::string_ref value) noexcept + { + if (value == "public") + return zone::public_; + if (value == "i2p") + return zone::i2p; + if (value == "tor") + return zone::tor; + return zone::invalid; + } }} diff --git a/contrib/epee/src/readline_buffer.cpp b/contrib/epee/src/readline_buffer.cpp index c5949da0a..39369c43f 100644 --- a/contrib/epee/src/readline_buffer.cpp +++ b/contrib/epee/src/readline_buffer.cpp @@ -114,7 +114,7 @@ int rdln::readline_buffer::sync() int end = 0, point = 0; #endif - if (rl_end || *rl_prompt) + if (rl_end || (rl_prompt && *rl_prompt)) { #if RL_READLINE_VERSION >= 0x0700 rl_clear_visible_line(); @@ -137,7 +137,7 @@ int rdln::readline_buffer::sync() while ( this->snextc() != EOF ); #if RL_READLINE_VERSION < 0x0700 - if (end || *rl_prompt) + if (end || (rl_prompt && *rl_prompt)) { rl_restore_prompt(); rl_line_buffer = line; diff --git a/external/db_drivers/liblmdb/.gitignore b/external/db_drivers/liblmdb/.gitignore index d5102a87c..80b6d8114 100644 --- a/external/db_drivers/liblmdb/.gitignore +++ b/external/db_drivers/liblmdb/.gitignore @@ -5,6 +5,7 @@ mdb_copy mdb_stat mdb_dump mdb_load +mdb_drop *.lo *.[ao] *.so diff --git a/external/db_drivers/liblmdb/COPYRIGHT b/external/db_drivers/liblmdb/COPYRIGHT index 722d1a515..f076556eb 100644 --- a/external/db_drivers/liblmdb/COPYRIGHT +++ b/external/db_drivers/liblmdb/COPYRIGHT @@ -1,4 +1,4 @@ -Copyright 2011-2015 Howard Chu, Symas Corp. +Copyright 2011-2019 Howard Chu, Symas Corp. All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/external/db_drivers/liblmdb/Doxyfile b/external/db_drivers/liblmdb/Doxyfile index 5047c0bb1..5ca2cfe8f 100644 --- a/external/db_drivers/liblmdb/Doxyfile +++ b/external/db_drivers/liblmdb/Doxyfile @@ -253,7 +253,7 @@ IDL_PROPERTY_SUPPORT = YES # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. -DISTRIBUTE_GROUP_DOC = NO +DISTRIBUTE_GROUP_DOC = YES # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a diff --git a/external/db_drivers/liblmdb/Makefile b/external/db_drivers/liblmdb/Makefile index 186168038..942d0dbe4 100644 --- a/external/db_drivers/liblmdb/Makefile +++ b/external/db_drivers/liblmdb/Makefile @@ -26,6 +26,7 @@ OPT = -O2 -g CFLAGS = $(THREADS) $(OPT) $(W) $(XCFLAGS) LDLIBS = SOLIBS = +SOEXT = .so prefix = /usr/local exec_prefix = $(prefix) bindir = $(exec_prefix)/bin @@ -37,7 +38,7 @@ mandir = $(datarootdir)/man ######################################################################## IHDRS = lmdb.h -ILIBS = liblmdb.a liblmdb.so +ILIBS = liblmdb.a liblmdb$(SOEXT) IPROGS = mdb_stat mdb_copy mdb_dump mdb_load mdb_drop IDOCS = mdb_stat.1 mdb_copy.1 mdb_dump.1 mdb_load.1 mdb_drop.1 PROGS = $(IPROGS) mtest mtest2 mtest3 mtest4 mtest5 @@ -63,7 +64,7 @@ test: all liblmdb.a: mdb.o midl.o $(AR) rs $@ mdb.o midl.o -liblmdb.so: mdb.lo midl.lo +liblmdb$(SOEXT): mdb.lo midl.lo # $(CC) $(LDFLAGS) -pthread -shared -Wl,-Bsymbolic -o $@ mdb.o midl.o $(SOLIBS) $(CC) $(LDFLAGS) -pthread -shared -o $@ mdb.lo midl.lo $(SOLIBS) diff --git a/external/db_drivers/liblmdb/intro.doc b/external/db_drivers/liblmdb/intro.doc index 870c7bb8e..64dfcaad8 100644 --- a/external/db_drivers/liblmdb/intro.doc +++ b/external/db_drivers/liblmdb/intro.doc @@ -1,5 +1,5 @@ /* - * Copyright 2015 Howard Chu, Symas Corp. + * Copyright 2015-2018 Howard Chu, Symas Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/external/db_drivers/liblmdb/lmdb.h b/external/db_drivers/liblmdb/lmdb.h index 0bca3eb74..1f4736ce2 100644 --- a/external/db_drivers/liblmdb/lmdb.h +++ b/external/db_drivers/liblmdb/lmdb.h @@ -97,11 +97,12 @@ * transactions. Each transaction belongs to one thread. See below. * The #MDB_NOTLS flag changes this for read-only transactions. * - * - Use an MDB_env* in the process which opened it, without fork()ing. + * - Use an MDB_env* in the process which opened it, not after fork(). * * - Do not have open an LMDB database twice in the same process at * the same time. Not even from a plain open() call - close()ing it - * breaks flock() advisory locking. + * breaks fcntl() advisory locking. (It is OK to reopen it after + * fork() - exec*(), since the lockfile has FD_CLOEXEC set.) * * - Avoid long-lived transactions. Read transactions prevent * reuse of pages freed by newer write transactions, thus the @@ -135,7 +136,7 @@ * * @author Howard Chu, Symas Corporation. * - * @copyright Copyright 2011-2016 Howard Chu, Symas Corp. All rights reserved. + * @copyright Copyright 2011-2019 Howard Chu, Symas Corp. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP @@ -167,6 +168,7 @@ #include <sys/types.h> #include <inttypes.h> +#include <limits.h> #ifdef __cplusplus extern "C" { @@ -179,11 +181,30 @@ typedef int mdb_mode_t; typedef mode_t mdb_mode_t; #endif -#ifdef MDB_VL32 -typedef uint64_t mdb_size_t; -#define mdb_env_create mdb_env_create_vl32 /**< Prevent mixing with non-VL32 builds */ +#ifdef _WIN32 +# define MDB_FMT_Z "I" #else +# define MDB_FMT_Z "z" /**< printf/scanf format modifier for size_t */ +#endif + +#ifndef MDB_VL32 +/** Unsigned type used for mapsize, entry counts and page/transaction IDs. + * + * It is normally size_t, hence the name. Defining MDB_VL32 makes it + * uint64_t, but do not try this unless you know what you are doing. + */ typedef size_t mdb_size_t; +# define MDB_SIZE_MAX SIZE_MAX /**< max #mdb_size_t */ +/** #mdb_size_t printf formats, \b t = one of [diouxX] without quotes */ +# define MDB_PRIy(t) MDB_FMT_Z #t +/** #mdb_size_t scanf formats, \b t = one of [dioux] without quotes */ +# define MDB_SCNy(t) MDB_FMT_Z #t +#else +typedef uint64_t mdb_size_t; +# define MDB_SIZE_MAX UINT64_MAX +# define MDB_PRIy(t) PRI##t##64 +# define MDB_SCNy(t) SCN##t##64 +# define mdb_env_create mdb_env_create_vl32 /**< Prevent mixing with non-VL32 builds */ #endif /** An abstraction for a file handle. @@ -322,7 +343,8 @@ typedef void (MDB_rel_func)(MDB_val *item, void *oldptr, void *newptr, void *rel #define MDB_REVERSEKEY 0x02 /** use sorted duplicates */ #define MDB_DUPSORT 0x04 - /** numeric keys in native byte order: either unsigned int or size_t. + /** numeric keys in native byte order, either unsigned int or #mdb_size_t. + * (lmdb expects 32-bit int <= size_t <= 32/64-bit mdb_size_t.) * The keys must all be of the same size. */ #define MDB_INTEGERKEY 0x08 /** with #MDB_DUPSORT, sorted dup items have fixed size */ @@ -380,7 +402,7 @@ typedef enum MDB_cursor_op { MDB_GET_BOTH, /**< Position at key/data pair. Only for #MDB_DUPSORT */ MDB_GET_BOTH_RANGE, /**< position at key, nearest data. Only for #MDB_DUPSORT */ MDB_GET_CURRENT, /**< Return key/data at current cursor position */ - MDB_GET_MULTIPLE, /**< Return key and up to a page of duplicate data items + MDB_GET_MULTIPLE, /**< Return up to a page of duplicate data items from current cursor position. Move cursor to prepare for #MDB_NEXT_MULTIPLE. Only for #MDB_DUPFIXED */ MDB_LAST, /**< Position at last key/data item */ @@ -389,7 +411,7 @@ typedef enum MDB_cursor_op { MDB_NEXT, /**< Position at next data item */ MDB_NEXT_DUP, /**< Position at next data item of current key. Only for #MDB_DUPSORT */ - MDB_NEXT_MULTIPLE, /**< Return key and up to a page of duplicate data items + MDB_NEXT_MULTIPLE, /**< Return up to a page of duplicate data items from next cursor position. Move cursor to prepare for #MDB_NEXT_MULTIPLE. Only for #MDB_DUPFIXED */ MDB_NEXT_NODUP, /**< Position at first data item of next key */ @@ -400,7 +422,7 @@ typedef enum MDB_cursor_op { MDB_SET, /**< Position at specified key */ MDB_SET_KEY, /**< Position at specified key, return key + data */ MDB_SET_RANGE, /**< Position at first key greater than or equal to specified key. */ - MDB_PREV_MULTIPLE /**< Position at previous page and return key and up to + MDB_PREV_MULTIPLE /**< Position at previous page and return up to a page of duplicate data items. Only for #MDB_DUPFIXED */ } MDB_cursor_op; @@ -458,8 +480,10 @@ typedef enum MDB_cursor_op { #define MDB_BAD_VALSIZE (-30781) /** The specified DBI was changed unexpectedly */ #define MDB_BAD_DBI (-30780) + /** Unexpected problem - txn should abort */ +#define MDB_PROBLEM (-30779) /** The last defined error code */ -#define MDB_LAST_ERRCODE MDB_BAD_DBI +#define MDB_LAST_ERRCODE MDB_PROBLEM /** @} */ /** @brief Statistics for a database in the environment */ @@ -696,6 +720,7 @@ int mdb_env_copyfd(MDB_env *env, mdb_filehandle_t fd); * <li>#MDB_CP_COMPACT - Perform compaction while copying: omit free * pages and sequentially renumber all pages in output. This option * consumes more CPU and runs more slowly than the default. + * Currently it fails if the environment has suffered a page leak. * </ul> * @return A non-zero error value on failure and 0 on success. */ @@ -811,6 +836,10 @@ int mdb_env_get_path(MDB_env *env, const char **path); /** @brief Return the filedescriptor for the given environment. * + * This function may be called after fork(), so the descriptor can be + * closed before exec*(). Other LMDB file descriptors have FD_CLOEXEC. + * (Until LMDB 0.9.18, only the lockfile had that.) + * * @param[in] env An environment handle returned by #mdb_env_create() * @param[out] fd Address of a mdb_filehandle_t to contain the descriptor. * @return A non-zero error value on failure and 0 on success. Some possible @@ -1112,14 +1141,16 @@ int mdb_txn_renew(MDB_txn *txn); * keys must be unique and may have only a single data item. * <li>#MDB_INTEGERKEY * Keys are binary integers in native byte order, either unsigned int - * or size_t, and will be sorted as such. + * or #mdb_size_t, and will be sorted as such. + * (lmdb expects 32-bit int <= size_t <= 32/64-bit mdb_size_t.) * The keys must all be of the same size. * <li>#MDB_DUPFIXED * This flag may only be used in combination with #MDB_DUPSORT. This option * tells the library that the data items for this database are all the same * size, which allows further optimizations in storage and retrieval. When - * all data items are the same size, the #MDB_GET_MULTIPLE and #MDB_NEXT_MULTIPLE - * cursor operations may be used to retrieve multiple items at once. + * all data items are the same size, the #MDB_GET_MULTIPLE, #MDB_NEXT_MULTIPLE + * and #MDB_PREV_MULTIPLE cursor operations may be used to retrieve multiple + * items at once. * <li>#MDB_INTEGERDUP * This option specifies that duplicate data items are binary integers, * similar to #MDB_INTEGERKEY keys. @@ -1524,6 +1555,10 @@ int mdb_cursor_put(MDB_cursor *cursor, MDB_val *key, MDB_val *data, /** @brief Delete current key/data pair * * This function deletes the key/data pair to which the cursor refers. + * This does not invalidate the cursor, so operations such as MDB_NEXT + * can still be used on it. + * Both MDB_NEXT and MDB_GET_CURRENT will return the same record after + * this operation. * @param[in] cursor A cursor handle returned by #mdb_cursor_open() * @param[in] flags Options for this operation. This parameter * must be set to 0 or one of the values described here. diff --git a/external/db_drivers/liblmdb/mdb.c b/external/db_drivers/liblmdb/mdb.c index 8e2b1eca1..3b2745f95 100644 --- a/external/db_drivers/liblmdb/mdb.c +++ b/external/db_drivers/liblmdb/mdb.c @@ -5,7 +5,7 @@ * BerkeleyDB API, but much simplified. */ /* - * Copyright 2011-2016 Howard Chu, Symas Corp. + * Copyright 2011-2019 Howard Chu, Symas Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -41,6 +41,7 @@ #ifdef _WIN32 #include <malloc.h> #include <windows.h> +#include <wchar.h> /* get wcscpy() */ /* We use native NT APIs to setup the memory map, so that we can * let the DB file grow incrementally instead of always preallocating @@ -51,7 +52,7 @@ * NTDLL.DLL at runtime, to avoid buildtime dependencies on any * NTDLL import libraries. */ -typedef NTSTATUS WINAPI (NtCreateSectionFunc) +typedef NTSTATUS (WINAPI NtCreateSectionFunc) (OUT PHANDLE sh, IN ACCESS_MASK acc, IN void * oa OPTIONAL, IN PLARGE_INTEGER ms OPTIONAL, @@ -64,7 +65,7 @@ typedef enum _SECTION_INHERIT { ViewUnmap = 2 } SECTION_INHERIT; -typedef NTSTATUS WINAPI (NtMapViewOfSectionFunc) +typedef NTSTATUS (WINAPI NtMapViewOfSectionFunc) (IN PHANDLE sh, IN HANDLE ph, IN OUT PVOID *addr, IN ULONG_PTR zbits, IN SIZE_T cs, IN OUT PLARGE_INTEGER off OPTIONAL, @@ -73,7 +74,7 @@ typedef NTSTATUS WINAPI (NtMapViewOfSectionFunc) static NtMapViewOfSectionFunc *NtMapViewOfSection; -typedef NTSTATUS WINAPI (NtCloseFunc)(HANDLE h); +typedef NTSTATUS (WINAPI NtCloseFunc)(HANDLE h); static NtCloseFunc *NtClose; @@ -147,6 +148,10 @@ typedef SSIZE_T ssize_t; /* Most platforms have posix_memalign, older may only have memalign */ #define HAVE_MEMALIGN 1 #include <malloc.h> +/* On Solaris, we need the POSIX sigwait function */ +#if defined (__sun) +# define _POSIX_PTHREAD_SEMANTICS 1 +#endif #endif #if !(defined(BYTE_ORDER) || defined(__BYTE_ORDER)) @@ -154,7 +159,7 @@ typedef SSIZE_T ssize_t; #include <resolv.h> /* defines BYTE_ORDER on HPUX and Solaris */ #endif -#if defined(__APPLE__) || defined (BSD) +#if defined(__APPLE__) || defined (BSD) || defined(__FreeBSD_kernel__) # if !(defined(MDB_USE_POSIX_MUTEX) || defined(MDB_USE_POSIX_SEM)) # define MDB_USE_SYSV_SEM 1 # endif @@ -165,6 +170,7 @@ typedef SSIZE_T ssize_t; #ifndef _WIN32 #include <pthread.h> +#include <signal.h> #ifdef MDB_USE_POSIX_SEM # define MDB_USE_HASH 1 #include <semaphore.h> @@ -234,7 +240,7 @@ union semun { #if (BYTE_ORDER == LITTLE_ENDIAN) == (BYTE_ORDER == BIG_ENDIAN) # error "Unknown or unsupported endianness (BYTE_ORDER)" -#elif (-6 & 5) || CHAR_BIT != 8 || UINT_MAX < 0xffffffff || ULONG_MAX % 0xFFFF +#elif (-6 & 5) || CHAR_BIT!=8 || UINT_MAX!=0xffffffff || MDB_SIZE_MAX%UINT_MAX # error "Two's complement, reasonably sized integer types, please" #endif @@ -309,6 +315,10 @@ union semun { # define MDB_USE_ROBUST 0 # else # define MDB_USE_ROBUST 1 +# endif +#endif /* !MDB_USE_ROBUST */ + +#if defined(MDB_USE_POSIX_MUTEX) && (MDB_USE_ROBUST) /* glibc < 2.12 only provided _np API */ # if (defined(__GLIBC__) && GLIBC_VER < 0x02000c) || \ (defined(PTHREAD_MUTEX_ROBUST_NP) && !defined(PTHREAD_MUTEX_ROBUST)) @@ -316,10 +326,9 @@ union semun { # define pthread_mutexattr_setrobust(attr, flag) pthread_mutexattr_setrobust_np(attr, flag) # define pthread_mutex_consistent(mutex) pthread_mutex_consistent_np(mutex) # endif -# endif -#endif /* MDB_USE_ROBUST */ +#endif /* MDB_USE_POSIX_MUTEX && MDB_USE_ROBUST */ -#if defined(MDB_OWNERDEAD) && MDB_USE_ROBUST +#if defined(MDB_OWNERDEAD) && (MDB_USE_ROBUST) #define MDB_ROBUST_SUPPORTED 1 #endif @@ -342,8 +351,10 @@ typedef HANDLE mdb_mutex_t, mdb_mutexref_t; #define pthread_mutex_lock(x) WaitForSingleObject(*x, INFINITE) #define pthread_cond_signal(x) SetEvent(*x) #define pthread_cond_wait(cond,mutex) do{SignalObjectAndWait(*mutex, *cond, INFINITE, FALSE); WaitForSingleObject(*mutex, INFINITE);}while(0) -#define THREAD_CREATE(thr,start,arg) thr=CreateThread(NULL,0,start,arg,0,NULL) -#define THREAD_FINISH(thr) WaitForSingleObject(thr, INFINITE) +#define THREAD_CREATE(thr,start,arg) \ + (((thr) = CreateThread(NULL, 0, start, arg, 0, NULL)) ? 0 : ErrCode()) +#define THREAD_FINISH(thr) \ + (WaitForSingleObject(thr, INFINITE) ? ErrCode() : 0) #define LOCK_MUTEX0(mutex) WaitForSingleObject(mutex, INFINITE) #define UNLOCK_MUTEX(mutex) ReleaseMutex(mutex) #define mdb_mutex_consistent(mutex) 0 @@ -359,12 +370,10 @@ typedef HANDLE mdb_mutex_t, mdb_mutexref_t; #else #define MDB_PROCESS_QUERY_LIMITED_INFORMATION 0x1000 #endif -#define Z "I" #else #define THREAD_RET void * #define THREAD_CREATE(thr,start,arg) pthread_create(&thr,NULL,start,arg) #define THREAD_FINISH(thr) pthread_join(thr,NULL) -#define Z "z" /**< printf format modifier for size_t */ /** For MDB_LOCK_FORMAT: True if readers take a pid lock in the lockfile */ #define MDB_PIDLOCK 1 @@ -418,15 +427,15 @@ mdb_sem_wait(mdb_mutexref_t sem) #define mdb_mutex_consistent(mutex) 0 #else /* MDB_USE_POSIX_MUTEX: */ - /** Shared mutex/semaphore as it is stored (mdb_mutex_t), and as - * local variables keep it (mdb_mutexref_t). + /** Shared mutex/semaphore as the original is stored. * - * An mdb_mutex_t can be assigned to an mdb_mutexref_t. They can - * be the same, or an array[size 1] and a pointer. - * @{ + * Not for copies. Instead it can be assigned to an #mdb_mutexref_t. + * When mdb_mutexref_t is a pointer and mdb_mutex_t is not, then it + * is array[size 1] so it can be assigned to the pointer. */ -typedef pthread_mutex_t mdb_mutex_t[1], *mdb_mutexref_t; - /* @} */ +typedef pthread_mutex_t mdb_mutex_t[1]; + /** Reference to an #mdb_mutex_t */ +typedef pthread_mutex_t *mdb_mutexref_t; /** Lock the reader or writer mutex. * Returns 0 or a code to give #mdb_mutex_failed(), as in #LOCK_MUTEX(). */ @@ -462,28 +471,23 @@ typedef pthread_mutex_t mdb_mutex_t[1], *mdb_mutexref_t; #define GET_PAGESIZE(x) ((x) = sysconf(_SC_PAGE_SIZE)) #endif -#ifdef MDB_VL32 -#ifdef _WIN32 -#define Y "I64" -#else -#define Y "ll" -#endif -#else -#define Y Z -#endif +#define Z MDB_FMT_Z /**< printf/scanf format modifier for size_t */ +#define Yu MDB_PRIy(u) /**< printf format for #mdb_size_t */ +#define Yd MDB_PRIy(d) /**< printf format for 'signed #mdb_size_t' */ -#if defined(_WIN32) || defined(MDB_USE_POSIX_SEM) -#define MNAME_LEN 32 -#elif defined(MDB_USE_SYSV_SEM) +#ifdef MDB_USE_SYSV_SEM #define MNAME_LEN (sizeof(int)) #else #define MNAME_LEN (sizeof(pthread_mutex_t)) #endif -#ifdef MDB_USE_SYSV_SEM -#define SYSV_SEM_FLAG 1 /**< SysV sems in lockfile format */ -#else -#define SYSV_SEM_FLAG 0 +/** Initial part of #MDB_env.me_mutexname[]. + * Changes to this code must be reflected in #MDB_LOCK_FORMAT. + */ +#ifdef _WIN32 +#define MUTEXNAME_PREFIX "Global\\MDB" +#elif defined MDB_USE_POSIX_SEM +#define MUTEXNAME_PREFIX "/MDB" #endif /** @} */ @@ -627,7 +631,11 @@ static txnid_t mdb_debug_start; /** The version number for a database's datafile format. */ #define MDB_DATA_VERSION ((MDB_DEVEL) ? 999 : 1) /** The version number for a database's lockfile format. */ -#define MDB_LOCK_VERSION ((MDB_DEVEL) ? 999 : 1) +#define MDB_LOCK_VERSION ((MDB_DEVEL) ? 999 : 2) + /** Number of bits representing #MDB_LOCK_VERSION in #MDB_LOCK_FORMAT. + * The remaining bits must leave room for #MDB_lock_desc. + */ +#define MDB_LOCK_VERSION_BITS 12 /** @brief The max size of a key we can write, or 0 for computed max. * @@ -693,12 +701,27 @@ static txnid_t mdb_debug_start; /** Round \b n up to an even number. */ #define EVEN(n) (((n) + 1U) & -2) /* sign-extending -2 to match n+1U */ + /** Least significant 1-bit of \b n. n must be of an unsigned type. */ +#define LOW_BIT(n) ((n) & (-(n))) + + /** (log2(\b p2) % \b n), for p2 = power of 2 and 0 < n < 8. */ +#define LOG2_MOD(p2, n) (7 - 86 / ((p2) % ((1U<<(n))-1) + 11)) + /* Explanation: Let p2 = 2**(n*y + x), x<n and M = (1U<<n)-1. Now p2 = + * (M+1)**y * 2**x = 2**x (mod M). Finally "/" "happens" to return 7-x. + */ + + /** Should be alignment of \b type. Ensure it is a power of 2. */ +#define ALIGNOF2(type) \ + LOW_BIT(offsetof(struct { char ch_; type align_; }, align_)) + /** Used for offsets within a single page. * Since memory pages are typically 4 or 8KB in size, 12-13 bits, * this is plenty. */ typedef uint16_t indx_t; +typedef unsigned long long mdb_hash_t; + /** Default size of memory map. * This is certainly too small for any actual applications. Apps should always set * the size explicitly using #mdb_env_set_mapsize(). @@ -827,7 +850,8 @@ typedef struct MDB_txbody { */ volatile unsigned mtb_numreaders; #if defined(_WIN32) || defined(MDB_USE_POSIX_SEM) - char mtb_rmname[MNAME_LEN]; + /** Binary form of names of the reader/writer locks */ + mdb_hash_t mtb_mutexid; #elif defined(MDB_USE_SYSV_SEM) int mtb_semid; int mtb_rlocked; @@ -846,20 +870,18 @@ typedef struct MDB_txninfo { #define mti_magic mt1.mtb.mtb_magic #define mti_format mt1.mtb.mtb_format #define mti_rmutex mt1.mtb.mtb_rmutex -#define mti_rmname mt1.mtb.mtb_rmname #define mti_txnid mt1.mtb.mtb_txnid #define mti_numreaders mt1.mtb.mtb_numreaders +#define mti_mutexid mt1.mtb.mtb_mutexid #ifdef MDB_USE_SYSV_SEM #define mti_semid mt1.mtb.mtb_semid #define mti_rlocked mt1.mtb.mtb_rlocked #endif char pad[(sizeof(MDB_txbody)+CACHELINE-1) & ~(CACHELINE-1)]; } mt1; +#if !(defined(_WIN32) || defined(MDB_USE_POSIX_SEM)) union { -#if defined(_WIN32) || defined(MDB_USE_POSIX_SEM) - char mt2_wmname[MNAME_LEN]; -#define mti_wmname mt2.mt2_wmname -#elif defined MDB_USE_SYSV_SEM +#ifdef MDB_USE_SYSV_SEM int mt2_wlocked; #define mti_wlocked mt2.mt2_wlocked #else @@ -868,21 +890,79 @@ typedef struct MDB_txninfo { #endif char pad[(MNAME_LEN+CACHELINE-1) & ~(CACHELINE-1)]; } mt2; +#endif MDB_reader mti_readers[1]; } MDB_txninfo; /** Lockfile format signature: version, features and field layout */ #define MDB_LOCK_FORMAT \ - ((uint32_t) \ - ((MDB_LOCK_VERSION) \ - /* Flags which describe functionality */ \ - + (SYSV_SEM_FLAG << 18) \ - + (((MDB_PIDLOCK) != 0) << 16))) + ((uint32_t) \ + (((MDB_LOCK_VERSION) % (1U << MDB_LOCK_VERSION_BITS)) \ + + MDB_lock_desc * (1U << MDB_LOCK_VERSION_BITS))) + + /** Lock type and layout. Values 0-119. _WIN32 implies #MDB_PIDLOCK. + * Some low values are reserved for future tweaks. + */ +#ifdef _WIN32 +# define MDB_LOCK_TYPE (0 + ALIGNOF2(mdb_hash_t)/8 % 2) +#elif defined MDB_USE_POSIX_SEM +# define MDB_LOCK_TYPE (4 + ALIGNOF2(mdb_hash_t)/8 % 2) +#elif defined MDB_USE_SYSV_SEM +# define MDB_LOCK_TYPE (8) +#elif defined MDB_USE_POSIX_MUTEX +/* We do not know the inside of a POSIX mutex and how to check if mutexes + * used by two executables are compatible. Just check alignment and size. + */ +# define MDB_LOCK_TYPE (10 + \ + LOG2_MOD(ALIGNOF2(pthread_mutex_t), 5) + \ + sizeof(pthread_mutex_t) / 4U % 22 * 5) +#endif + +enum { + /** Magic number for lockfile layout and features. + * + * This *attempts* to stop liblmdb variants compiled with conflicting + * options from using the lockfile at the same time and thus breaking + * it. It describes locking types, and sizes and sometimes alignment + * of the various lockfile items. + * + * The detected ranges are mostly guesswork, or based simply on how + * big they could be without using more bits. So we can tweak them + * in good conscience when updating #MDB_LOCK_VERSION. + */ + MDB_lock_desc = + /* Default CACHELINE=64 vs. other values (have seen mention of 32-256) */ + (CACHELINE==64 ? 0 : 1 + LOG2_MOD(CACHELINE >> (CACHELINE>64), 5)) + + 6 * (sizeof(MDB_PID_T)/4 % 3) /* legacy(2) to word(4/8)? */ + + 18 * (sizeof(pthread_t)/4 % 5) /* can be struct{id, active data} */ + + 90 * (sizeof(MDB_txbody) / CACHELINE % 3) + + 270 * (MDB_LOCK_TYPE % 120) + /* The above is < 270*120 < 2**15 */ + + ((sizeof(txnid_t) == 8) << 15) /* 32bit/64bit */ + + ((sizeof(MDB_reader) > CACHELINE) << 16) + /* Not really needed - implied by MDB_LOCK_TYPE != (_WIN32 locking) */ + + (((MDB_PIDLOCK) != 0) << 17) + /* 18 bits total: Must be <= (32 - MDB_LOCK_VERSION_BITS). */ +}; /** @} */ -/** Common header for all page types. - * Overflow records occupy a number of contiguous pages with no - * headers on any page after the first. +/** Common header for all page types. The page type depends on #mp_flags. + * + * #P_BRANCH and #P_LEAF pages have unsorted '#MDB_node's at the end, with + * sorted #mp_ptrs[] entries referring to them. Exception: #P_LEAF2 pages + * omit mp_ptrs and pack sorted #MDB_DUPFIXED values after the page header. + * + * #P_OVERFLOW records occupy one or more contiguous pages where only the + * first has a page header. They hold the real data of #F_BIGDATA nodes. + * + * #P_SUBP sub-pages are small leaf "pages" with duplicate data. + * A node with flag #F_DUPDATA but not #F_SUBDATA contains a sub-page. + * (Duplicate data can also go in sub-databases, which use normal pages.) + * + * #P_META pages contain #MDB_meta, the start point of an LMDB snapshot. + * + * Each non-metapage up to #MDB_meta.%mm_last_pg is reachable exactly once + * in the snapshot: Either used by a database or listed in a freeDB record. */ typedef struct MDB_page { #define mp_pgno mp_p.p_pgno @@ -891,7 +971,7 @@ typedef struct MDB_page { pgno_t p_pgno; /**< page number */ struct MDB_page *p_next; /**< for in-memory list of freed pages */ } mp_p; - uint16_t mp_pad; + uint16_t mp_pad; /**< key size if this is a LEAF2 page */ /** @defgroup mdb_page Page Flags * @ingroup internal * Flags for the page headers. @@ -958,25 +1038,34 @@ typedef struct MDB_page { /** The number of overflow pages needed to store the given size. */ #define OVPAGES(size, psize) ((PAGEHDRSZ-1 + (size)) / (psize) + 1) - /** Link in #MDB_txn.%mt_loose_pgs list */ + /** Link in #MDB_txn.%mt_loose_pgs list. + * Kept outside the page header, which is needed when reusing the page. + */ #define NEXT_LOOSE_PAGE(p) (*(MDB_page **)((p) + 2)) /** Header for a single key/data pair within a page. * Used in pages of type #P_BRANCH and #P_LEAF without #P_LEAF2. * We guarantee 2-byte alignment for 'MDB_node's. + * + * #mn_lo and #mn_hi are used for data size on leaf nodes, and for child + * pgno on branch nodes. On 64 bit platforms, #mn_flags is also used + * for pgno. (Branch nodes have no flags). Lo and hi are in host byte + * order in case some accesses can be optimized to 32-bit word access. + * + * Leaf node flags describe node contents. #F_BIGDATA says the node's + * data part is the page number of an overflow page with actual data. + * #F_DUPDATA and #F_SUBDATA can be combined giving duplicate data in + * a sub-page/sub-database, and named databases (just #F_SUBDATA). */ typedef struct MDB_node { - /** lo and hi are used for data size on leaf nodes and for - * child pgno on branch nodes. On 64 bit platforms, flags - * is also used for pgno. (Branch nodes have no flags). - * They are in host byte order in case that lets some - * accesses be optimized into a 32-bit word access. - */ + /** part of data size or pgno + * @{ */ #if BYTE_ORDER == LITTLE_ENDIAN - unsigned short mn_lo, mn_hi; /**< part of data size or pgno */ + unsigned short mn_lo, mn_hi; #else unsigned short mn_hi, mn_lo; #endif + /** @} */ /** @defgroup mdb_node Node Flags * @ingroup internal * Flags for node headers. @@ -1041,7 +1130,7 @@ typedef struct MDB_node { #ifdef MISALIGNED_OK #define COPY_PGNO(dst,src) dst = src #else -#if SIZE_MAX > 4294967295UL +#if MDB_SIZE_MAX > 0xffffffffU #define COPY_PGNO(dst,src) do { \ unsigned short *s, *d; \ s = (unsigned short *)&(src); \ @@ -1086,9 +1175,9 @@ typedef struct MDB_db { pgno_t md_root; /**< the root page of this tree */ } MDB_db; - /** mdb_dbi_open flags */ #define MDB_VALID 0x8000 /**< DB handle is valid, for me_dbflags */ #define PERSISTENT_FLAGS (0xffff & ~(MDB_VALID)) + /** #mdb_dbi_open() flags */ #define VALID_FLAGS (MDB_REVERSEKEY|MDB_DUPSORT|MDB_INTEGERKEY|MDB_DUPFIXED|\ MDB_INTEGERDUP|MDB_REVERSEDUP|MDB_CREATE) @@ -1121,13 +1210,16 @@ typedef struct MDB_meta { #else void *mm_address; /**< address for fixed mapping */ #endif - pgno_t mm_mapsize; /**< size of mmap region */ + mdb_size_t mm_mapsize; /**< size of mmap region */ MDB_db mm_dbs[CORE_DBS]; /**< first is free space, 2nd is main db */ /** The size of pages used in this DB */ #define mm_psize mm_dbs[FREE_DBI].md_pad /** Any persistent environment flags. @ref mdb_env */ #define mm_flags mm_dbs[FREE_DBI].md_flags - pgno_t mm_last_pg; /**< last used page in file */ + /** Last used page in the datafile. + * Actually the file may be shorter if the freeDB lists the final pages. + */ + pgno_t mm_last_pg; volatile txnid_t mm_txnid; /**< txnid that committed this page */ } MDB_meta; @@ -1180,7 +1272,7 @@ struct MDB_txn { * in this transaction, linked through #NEXT_LOOSE_PAGE(page). */ MDB_page *mt_loose_pgs; - /* #Number of loose pages (#mt_loose_pgs) */ + /** Number of loose pages (#mt_loose_pgs) */ int mt_loose_count; /** The sorted list of dirty pages we temporarily wrote to disk * because the dirty list was full. page numbers in here are @@ -1203,11 +1295,12 @@ struct MDB_txn { * @ingroup internal * @{ */ -#define DB_DIRTY 0x01 /**< DB was modified or is DUPSORT data */ +#define DB_DIRTY 0x01 /**< DB was written in this txn */ #define DB_STALE 0x02 /**< Named-DB record is older than txnID */ #define DB_NEW 0x04 /**< Named-DB handle opened in this txn */ #define DB_VALID 0x08 /**< DB handle is valid, see also #MDB_VALID */ #define DB_USRVALID 0x10 /**< As #DB_VALID, but not set for #FREE_DBI */ +#define DB_DUPDATA 0x20 /**< DB is #MDB_DUPSORT data */ /** @} */ /** In write txns, array of cursors for each DB */ MDB_cursor **mt_cursors; @@ -1317,6 +1410,11 @@ struct MDB_cursor { indx_t mc_ki[CURSOR_STACK]; /**< stack of page indices */ #ifdef MDB_VL32 MDB_page *mc_ovpg; /**< a referenced overflow page */ +# define MC_OVPG(mc) ((mc)->mc_ovpg) +# define MC_SET_OVPG(mc, pg) ((mc)->mc_ovpg = (pg)) +#else +# define MC_OVPG(mc) ((MDB_page *)0) +# define MC_SET_OVPG(mc, pg) ((void)0) #endif }; @@ -1336,6 +1434,23 @@ typedef struct MDB_xcursor { unsigned char mx_dbflag; } MDB_xcursor; + /** Check if there is an inited xcursor */ +#define XCURSOR_INITED(mc) \ + ((mc)->mc_xcursor && ((mc)->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) + + /** Update the xcursor's sub-page pointer, if any, in \b mc. Needed + * when the node which contains the sub-page may have moved. Called + * with leaf page \b mp = mc->mc_pg[\b top]. + */ +#define XCURSOR_REFRESH(mc, top, mp) do { \ + MDB_page *xr_pg = (mp); \ + MDB_node *xr_node; \ + if (!XCURSOR_INITED(mc) || (mc)->mc_ki[top] >= NUMKEYS(xr_pg)) break; \ + xr_node = NODEPTR(xr_pg, (mc)->mc_ki[top]); \ + if ((xr_node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) \ + (mc)->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(xr_node); \ +} while (0) + /** State of FreeDB old pages, stored in the MDB_env */ typedef struct MDB_pgstate { pgno_t *mf_pghead; /**< Reclaimed freeDB pages, or NULL before use */ @@ -1346,7 +1461,7 @@ typedef struct MDB_pgstate { struct MDB_env { HANDLE me_fd; /**< The main data file */ HANDLE me_lfd; /**< The lock file */ - HANDLE me_mfd; /**< just for writing the meta pages */ + HANDLE me_mfd; /**< For writing and syncing the meta pages */ #if defined(MDB_VL32) && defined(_WIN32) HANDLE me_fmh; /**< File Mapping handle */ #endif @@ -1407,6 +1522,10 @@ struct MDB_env { #else mdb_mutex_t me_rmutex; mdb_mutex_t me_wmutex; +# if defined(_WIN32) || defined(MDB_USE_POSIX_SEM) + /** Half-initialized name of mutexes, to be completed by #MUTEXNAME() */ + char me_mutexname[sizeof(MUTEXNAME_PREFIX) + 11]; +# endif #endif #ifdef MDB_VL32 MDB_ID3L me_rpages; /**< like #mt_rpages, but global to env */ @@ -1522,19 +1641,25 @@ static int mdb_reader_check0(MDB_env *env, int rlocked, int *dead); static MDB_cmp_func mdb_cmp_memn, mdb_cmp_memnr, mdb_cmp_int, mdb_cmp_cint, mdb_cmp_long; /** @endcond */ -/** Compare two items pointing at size_t's of unknown alignment. */ +/** Compare two items pointing at '#mdb_size_t's of unknown alignment. */ #ifdef MISALIGNED_OK # define mdb_cmp_clong mdb_cmp_long #else # define mdb_cmp_clong mdb_cmp_cint #endif +/** True if we need #mdb_cmp_clong() instead of \b cmp for #MDB_INTEGERDUP */ +#define NEED_CMP_CLONG(cmp, ksize) \ + (UINT_MAX < MDB_SIZE_MAX && \ + (cmp) == mdb_cmp_int && (ksize) == sizeof(mdb_size_t)) + #ifdef _WIN32 static SECURITY_DESCRIPTOR mdb_null_sd; static SECURITY_ATTRIBUTES mdb_all_sa; static int mdb_sec_inited; -static int utf8_to_utf16(const char *src, int srcsize, wchar_t **dst, int *dstsize); +struct MDB_name; +static int utf8_to_utf16(const char *src, struct MDB_name *dst, int xtra); #endif /** Return the library version info. */ @@ -1569,6 +1694,7 @@ static char *const mdb_errstr[] = { "MDB_BAD_TXN: Transaction must abort, has a child, or is invalid", "MDB_BAD_VALSIZE: Unsupported size of key/DB name/data, or wrong DUPFIXED size", "MDB_BAD_DBI: The specified DBI handle was closed/changed unexpectedly", + "MDB_PROBLEM: Unexpected problem - txn should abort", }; char * @@ -1641,11 +1767,7 @@ mdb_assert_fail(MDB_env *env, const char *expr_txt, if (env->me_assert_func) env->me_assert_func(env, buf); fprintf(stderr, "%s\n", buf); -#ifdef NDEBUG - _exit(); -#else abort(); -#endif } #else # define mdb_assert0(env, expr, expr_txt) ((void) 0) @@ -1717,20 +1839,20 @@ mdb_page_list(MDB_page *mp) case P_LEAF|P_LEAF2: type = "LEAF2 page"; break; case P_LEAF|P_LEAF2|P_SUBP: type = "LEAF2 sub-page"; break; case P_OVERFLOW: - fprintf(stderr, "Overflow page %"Y"u pages %u%s\n", + fprintf(stderr, "Overflow page %"Yu" pages %u%s\n", pgno, mp->mp_pages, state); return; case P_META: - fprintf(stderr, "Meta-page %"Y"u txnid %"Y"u\n", + fprintf(stderr, "Meta-page %"Yu" txnid %"Yu"\n", pgno, ((MDB_meta *)METADATA(mp))->mm_txnid); return; default: - fprintf(stderr, "Bad page %"Y"u flags 0x%u\n", pgno, mp->mp_flags); + fprintf(stderr, "Bad page %"Yu" flags 0x%X\n", pgno, mp->mp_flags); return; } nkeys = NUMKEYS(mp); - fprintf(stderr, "%s %"Y"u numkeys %d%s\n", type, pgno, nkeys, state); + fprintf(stderr, "%s %"Yu" numkeys %d%s\n", type, pgno, nkeys, state); for (i=0; i<nkeys; i++) { if (IS_LEAF2(mp)) { /* LEAF2 pages have no mp_ptrs[] or node headers */ @@ -1745,7 +1867,7 @@ mdb_page_list(MDB_page *mp) key.mv_data = node->mn_data; nsize = NODESIZE + key.mv_size; if (IS_BRANCH(mp)) { - fprintf(stderr, "key %d: page %"Y"u, %s\n", i, NODEPGNO(node), + fprintf(stderr, "key %d: page %"Yu", %s\n", i, NODEPGNO(node), DKEY(&key)); total += nsize; } else { @@ -1780,7 +1902,7 @@ mdb_cursor_chk(MDB_cursor *mc) } if (mc->mc_ki[i] >= NUMKEYS(mc->mc_pg[i])) printf("ack!\n"); - if (mc->mc_xcursor && (mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) { + if (XCURSOR_INITED(mc)) { node = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); if (((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) && mc->mc_xcursor->mx_cursor.mc_pg[0] != NODEDATA(node)) { @@ -1841,7 +1963,7 @@ static void mdb_audit(MDB_txn *txn) } } if (freecount + count + NUM_METAS != txn->mt_next_pgno) { - fprintf(stderr, "audit: %"Y"u freecount: %"Y"u count: %"Y"u total: %"Y"u next_pgno: %"Y"u\n", + fprintf(stderr, "audit: %"Yu" freecount: %"Yu" count: %"Yu" total: %"Yu" next_pgno: %"Yu"\n", txn->mt_txnid, freecount, count+NUM_METAS, freecount+count+NUM_METAS, txn->mt_next_pgno); } @@ -1858,15 +1980,14 @@ int mdb_dcmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a, const MDB_val *b) { MDB_cmp_func *dcmp = txn->mt_dbxs[dbi].md_dcmp; -#if UINT_MAX < SIZE_MAX || defined(MDB_VL32) - if (dcmp == mdb_cmp_int && a->mv_size == sizeof(mdb_size_t)) + if (NEED_CMP_CLONG(dcmp, a->mv_size)) dcmp = mdb_cmp_clong; -#endif return dcmp(a, b); } /** Allocate memory for a page. * Re-use old malloc'd pages first for singletons, otherwise just malloc. + * Set #MDB_TXN_ERROR on failure. */ static MDB_page * mdb_page_malloc(MDB_txn *txn, unsigned num) @@ -1978,8 +2099,14 @@ mdb_cursor_unref(MDB_cursor *mc) mc->mc_pg[0] = NULL; mc->mc_flags &= ~C_INITIALIZED; } +#define MDB_CURSOR_UNREF(mc, force) \ + (((force) || ((mc)->mc_flags & C_INITIALIZED)) \ + ? mdb_cursor_unref(mc) \ + : (void)0) + #else #define MDB_PAGE_UNREF(txn, mp) +#define MDB_CURSOR_UNREF(mc, force) ((void)0) #endif /* MDB_VL32 */ /** Loosen or free a single page. @@ -2011,7 +2138,7 @@ mdb_page_loose(MDB_cursor *mc, MDB_page *mp) if (mp != dl[x].mptr) { /* bad cursor? */ mc->mc_flags &= ~(C_INITIALIZED|C_EOF); txn->mt_flags |= MDB_TXN_ERROR; - return MDB_CORRUPTED; + return MDB_PROBLEM; } /* ok, it's ours */ loose = 1; @@ -2023,8 +2150,7 @@ mdb_page_loose(MDB_cursor *mc, MDB_page *mp) } } if (loose) { - DPRINTF(("loosen db %d page %"Y"u", DDBI(mc), - mp->mp_pgno)); + DPRINTF(("loosen db %d page %"Yu, DDBI(mc), mp->mp_pgno)); NEXT_LOOSE_PAGE(mp) = txn->mt_loose_pgs; txn->mt_loose_pgs = mp; txn->mt_loose_count++; @@ -2057,13 +2183,9 @@ mdb_pages_xkeep(MDB_cursor *mc, unsigned pflags, int all) unsigned i, j; int rc = MDB_SUCCESS, level; - /* Mark pages seen by cursors */ - if (mc->mc_flags & C_UNTRACK) - mc = NULL; /* will find mc in mt_cursors */ - for (i = txn->mt_numdbs;; mc = txn->mt_cursors[--i]) { - for (; mc; mc=mc->mc_next) { - if (!(mc->mc_flags & C_INITIALIZED)) - continue; + /* Mark pages seen by cursors: First m0, then tracked cursors */ + for (i = txn->mt_numdbs;; ) { + if (mc->mc_flags & C_INITIALIZED) { for (m3 = mc;; m3 = &mx->mx_cursor) { mp = NULL; for (j=0; j<m3->mc_snum; j++) { @@ -2082,10 +2204,13 @@ mdb_pages_xkeep(MDB_cursor *mc, unsigned pflags, int all) break; } } - if (i == 0) - break; + mc = mc->mc_next; + for (; !mc || mc == m0; mc = txn->mt_cursors[--i]) + if (i == 0) + goto mark_done; } +mark_done: if (all) { /* Mark dirty root pages */ for (i=0; i<txn->mt_numdbs; i++) { @@ -2275,7 +2400,7 @@ mdb_page_dirty(MDB_txn *txn, MDB_page *mp) } /** Allocate page numbers and memory for writing. Maintain me_pglast, - * me_pghead and mt_next_pgno. + * me_pghead and mt_next_pgno. Set #MDB_TXN_ERROR on failure. * * If there are free pages available from older transactions, they * are re-used first. Otherwise allocate a new page at mt_next_pgno. @@ -2321,8 +2446,7 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp) np = txn->mt_loose_pgs; txn->mt_loose_pgs = NEXT_LOOSE_PAGE(np); txn->mt_loose_count--; - DPRINTF(("db %d use loose page %"Y"u", DDBI(mc), - np->mp_pgno)); + DPRINTF(("db %d use loose page %"Yu, DDBI(mc), np->mp_pgno)); *mp = np; return MDB_SUCCESS; } @@ -2408,7 +2532,7 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp) np = m2.mc_pg[m2.mc_top]; leaf = NODEPTR(np, m2.mc_ki[m2.mc_top]); if ((rc = mdb_node_read(&m2, leaf, &data)) != MDB_SUCCESS) - return rc; + goto fail; idl = (MDB_ID *) data.mv_data; i = idl[0]; @@ -2424,10 +2548,10 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp) } env->me_pglast = last; #if (MDB_DEBUG) > 1 - DPRINTF(("IDL read txn %"Y"u root %"Y"u num %u", + DPRINTF(("IDL read txn %"Yu" root %"Yu" num %u", last, txn->mt_dbs[FREE_DBI].md_root, i)); for (j = i; j; j--) - DPRINTF(("IDL %"Y"u", idl[j])); + DPRINTF(("IDL %"Yu, idl[j])); #endif /* Merge in descending sorted order */ mdb_midl_xmerge(mop, idl); @@ -2572,6 +2696,7 @@ mdb_page_unspill(MDB_txn *txn, MDB_page *mp, MDB_page **ret) } /** Touch a page: make it dirty and re-insert into tree with updated pgno. + * Set #MDB_TXN_ERROR on failure. * @param[in] mc cursor pointing to the page to be touched * @return 0 on success, non-zero on failure. */ @@ -2597,7 +2722,7 @@ mdb_page_touch(MDB_cursor *mc) (rc = mdb_page_alloc(mc, 1, &np))) goto fail; pgno = np->mp_pgno; - DPRINTF(("touched db %d page %"Y"u -> %"Y"u", DDBI(mc), + DPRINTF(("touched db %d page %"Yu" -> %"Yu, DDBI(mc), mp->mp_pgno, pgno)); mdb_cassert(mc, mp->mp_pgno != pgno); mdb_midl_xappend(txn->mt_free_pgs, mp->mp_pgno); @@ -2621,7 +2746,7 @@ mdb_page_touch(MDB_cursor *mc) if (mp != dl[x].mptr) { /* bad cursor? */ mc->mc_flags &= ~(C_INITIALIZED|C_EOF); txn->mt_flags |= MDB_TXN_ERROR; - return MDB_CORRUPTED; + return MDB_PROBLEM; } return 0; } @@ -2660,14 +2785,8 @@ done: if (m2 == mc) continue; if (m2->mc_pg[mc->mc_top] == mp) { m2->mc_pg[mc->mc_top] = np; - if ((mc->mc_db->md_flags & MDB_DUPSORT) && - IS_LEAF(np) && - (m2->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) - { - MDB_node *leaf = NODEPTR(np, m2->mc_ki[mc->mc_top]); - if ((leaf->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) - m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(leaf); - } + if (IS_LEAF(np)) + XCURSOR_REFRESH(m2, mc->mc_top, np); } } } @@ -2998,7 +3117,7 @@ mdb_txn_renew(MDB_txn *txn) rc = mdb_txn_renew0(txn); if (rc == MDB_SUCCESS) { - DPRINTF(("renew txn %"Y"u%c %p on mdbenv %p, root page %"Y"u", + DPRINTF(("renew txn %"Yu"%c %p on mdbenv %p, root page %"Yu, txn->mt_txnid, (txn->mt_flags & MDB_TXN_RDONLY) ? 'r' : 'w', (void *)txn, (void *)txn->mt_env, txn->mt_dbs[MAIN_DBI].md_root)); } @@ -3116,7 +3235,7 @@ renew: } else { txn->mt_flags |= flags; /* could not change txn=me_txn0 earlier */ *ret = txn; - DPRINTF(("begin txn %"Y"u%c %p on mdbenv %p, root page %"Y"u", + DPRINTF(("begin txn %"Yu"%c %p on mdbenv %p, root page %"Yu, txn->mt_txnid, (flags & MDB_RDONLY) ? 'r' : 'w', (void *) txn, (void *) env, txn->mt_dbs[MAIN_DBI].md_root)); } @@ -3183,7 +3302,7 @@ mdb_txn_end(MDB_txn *txn, unsigned mode) /* Export or close DBI handles opened in this txn */ mdb_dbis_update(txn, mode & MDB_END_UPDATE); - DPRINTF(("%s txn %"Y"u%c %p on mdbenv %p, root page %"Y"u", + DPRINTF(("%s txn %"Yu"%c %p on mdbenv %p, root page %"Yu, names[mode & MDB_END_OPMASK], txn->mt_txnid, (txn->mt_flags & MDB_TXN_RDONLY) ? 'r' : 'w', (void *) txn, (void *)env, txn->mt_dbs[MAIN_DBI].md_root)); @@ -3325,10 +3444,41 @@ mdb_freelist_save(MDB_txn *txn) * we may be unable to return them to me_pghead. */ MDB_page *mp = txn->mt_loose_pgs; + MDB_ID2 *dl = txn->mt_u.dirty_list; + unsigned x; if ((rc = mdb_midl_need(&txn->mt_free_pgs, txn->mt_loose_count)) != 0) return rc; - for (; mp; mp = NEXT_LOOSE_PAGE(mp)) + for (; mp; mp = NEXT_LOOSE_PAGE(mp)) { mdb_midl_xappend(txn->mt_free_pgs, mp->mp_pgno); + /* must also remove from dirty list */ + if (txn->mt_flags & MDB_TXN_WRITEMAP) { + for (x=1; x<=dl[0].mid; x++) + if (dl[x].mid == mp->mp_pgno) + break; + mdb_tassert(txn, x <= dl[0].mid); + } else { + x = mdb_mid2l_search(dl, mp->mp_pgno); + mdb_tassert(txn, dl[x].mid == mp->mp_pgno); + } + dl[x].mptr = NULL; + mdb_dpage_free(env, mp); + } + { + /* squash freed slots out of the dirty list */ + unsigned y; + for (y=1; dl[y].mptr && y <= dl[0].mid; y++); + if (y <= dl[0].mid) { + for(x=y, y++;;) { + while (!dl[y].mptr && y <= dl[0].mid) y++; + if (y > dl[0].mid) break; + dl[x++] = dl[y++]; + } + dl[0].mid = x-1; + } else { + /* all slots freed */ + dl[0].mid = 0; + } + } txn->mt_loose_pgs = NULL; txn->mt_loose_count = 0; } @@ -3384,10 +3534,10 @@ mdb_freelist_save(MDB_txn *txn) #if (MDB_DEBUG) > 1 { unsigned int i = free_pgs[0]; - DPRINTF(("IDL write txn %"Y"u root %"Y"u num %u", + DPRINTF(("IDL write txn %"Yu" root %"Yu" num %u", txn->mt_txnid, txn->mt_dbs[FREE_DBI].md_root, i)); for (; i; i--) - DPRINTF(("IDL %"Y"u", free_pgs[i])); + DPRINTF(("IDL %"Yu, free_pgs[i])); } #endif continue; @@ -3555,7 +3705,7 @@ mdb_page_flush(MDB_txn *txn, int keep) * the write offset, to at least save the overhead of a Seek * system call. */ - DPRINTF(("committing page %"Z"u", pgno)); + DPRINTF(("committing page %"Yu, pgno)); memset(&ov, 0, sizeof(ov)); ov.Offset = pos & 0xffffffff; ov.OffsetHigh = pos >> 16 >> 16; @@ -3606,7 +3756,7 @@ retry_seek: wpos = pos; wsize = 0; } - DPRINTF(("committing page %"Y"u", pgno)); + DPRINTF(("committing page %"Yu, pgno)); next_pos = pos + size; iov[n].iov_len = size; iov[n].iov_base = (char *)dp; @@ -3821,7 +3971,7 @@ mdb_txn_commit(MDB_txn *txn) !(txn->mt_flags & (MDB_TXN_DIRTY|MDB_TXN_SPILLS))) goto done; - DPRINTF(("committing txn %"Y"u %p on mdbenv %p, root page %"Y"u", + DPRINTF(("committing txn %"Yu" %p on mdbenv %p, root page %"Yu, txn->mt_txnid, (void*)txn, (void*)env, txn->mt_dbs[MAIN_DBI].md_root)); /* Update DB root pointers */ @@ -3929,7 +4079,7 @@ mdb_env_read_header(MDB_env *env, int prev, MDB_meta *meta) p = (MDB_page *)&pbuf; if (!F_ISSET(p->mp_flags, P_META)) { - DPRINTF(("page %"Y"u not a meta page", p->mp_pgno)); + DPRINTF(("page %"Yu" not a meta page", p->mp_pgno)); return MDB_INVALID; } @@ -4041,7 +4191,7 @@ mdb_env_write_meta(MDB_txn *txn) #endif toggle = txn->mt_txnid & 1; - DPRINTF(("writing meta page %d for root page %"Y"u", + DPRINTF(("writing meta page %d for root page %"Yu, toggle, txn->mt_dbs[MAIN_DBI].md_root)); env = txn->mt_env; @@ -4093,7 +4243,10 @@ mdb_env_write_meta(MDB_txn *txn) len = sizeof(MDB_meta) - off; off += (char *)mp - env->me_map; - /* Write to the SYNC fd */ + /* Write to the SYNC fd unless MDB_NOSYNC/MDB_NOMETASYNC. + * (me_mfd goes to the same file as me_fd, but writing to it + * also syncs to disk. Avoids a separate fdatasync() call.) + */ mfd = (flags & (MDB_NOSYNC|MDB_NOMETASYNC)) ? env->me_fd : env->me_mfd; #ifdef _WIN32 { @@ -4382,6 +4535,189 @@ mdb_fsize(HANDLE fd, mdb_size_t *size) return MDB_SUCCESS; } + +#ifdef _WIN32 +typedef wchar_t mdb_nchar_t; +# define MDB_NAME(str) L##str +# define mdb_name_cpy wcscpy +#else +/** Character type for file names: char on Unix, wchar_t on Windows */ +typedef char mdb_nchar_t; +# define MDB_NAME(str) str /**< #mdb_nchar_t[] string literal */ +# define mdb_name_cpy strcpy /**< Copy name (#mdb_nchar_t string) */ +#endif + +/** Filename - string of #mdb_nchar_t[] */ +typedef struct MDB_name { + int mn_len; /**< Length */ + int mn_alloced; /**< True if #mn_val was malloced */ + mdb_nchar_t *mn_val; /**< Contents */ +} MDB_name; + +/** Filename suffixes [datafile,lockfile][without,with MDB_NOSUBDIR] */ +static const mdb_nchar_t *const mdb_suffixes[2][2] = { + { MDB_NAME("/data.mdb"), MDB_NAME("") }, + { MDB_NAME("/lock.mdb"), MDB_NAME("-lock") } +}; + +#define MDB_SUFFLEN 9 /**< Max string length in #mdb_suffixes[] */ + +/** Set up filename + scratch area for filename suffix, for opening files. + * It should be freed with #mdb_fname_destroy(). + * On Windows, paths are converted from char *UTF-8 to wchar_t *UTF-16. + * + * @param[in] path Pathname for #mdb_env_open(). + * @param[in] envflags Whether a subdir and/or lockfile will be used. + * @param[out] fname Resulting filename, with room for a suffix if necessary. + */ +static int ESECT +mdb_fname_init(const char *path, unsigned envflags, MDB_name *fname) +{ + int no_suffix = F_ISSET(envflags, MDB_NOSUBDIR|MDB_NOLOCK); + fname->mn_alloced = 0; +#ifdef _WIN32 + return utf8_to_utf16(path, fname, no_suffix ? 0 : MDB_SUFFLEN); +#else + fname->mn_len = strlen(path); + if (no_suffix) + fname->mn_val = (char *) path; + else if ((fname->mn_val = malloc(fname->mn_len + MDB_SUFFLEN+1)) != NULL) { + fname->mn_alloced = 1; + strcpy(fname->mn_val, path); + } + else + return ENOMEM; + return MDB_SUCCESS; +#endif +} + +/** Destroy \b fname from #mdb_fname_init() */ +#define mdb_fname_destroy(fname) \ + do { if ((fname).mn_alloced) free((fname).mn_val); } while (0) + +#ifdef O_CLOEXEC /* POSIX.1-2008: Set FD_CLOEXEC atomically at open() */ +# define MDB_CLOEXEC O_CLOEXEC +#else +# define MDB_CLOEXEC 0 +#endif + +/** File type, access mode etc. for #mdb_fopen() */ +enum mdb_fopen_type { +#ifdef _WIN32 + MDB_O_RDONLY, MDB_O_RDWR, MDB_O_META, MDB_O_COPY, MDB_O_LOCKS +#else + /* A comment in mdb_fopen() explains some O_* flag choices. */ + MDB_O_RDONLY= O_RDONLY, /**< for RDONLY me_fd */ + MDB_O_RDWR = O_RDWR |O_CREAT, /**< for me_fd */ + MDB_O_META = O_WRONLY|MDB_DSYNC |MDB_CLOEXEC, /**< for me_mfd */ + MDB_O_COPY = O_WRONLY|O_CREAT|O_EXCL|MDB_CLOEXEC, /**< for #mdb_env_copy() */ + /** Bitmask for open() flags in enum #mdb_fopen_type. The other bits + * distinguish otherwise-equal MDB_O_* constants from each other. + */ + MDB_O_MASK = MDB_O_RDWR|MDB_CLOEXEC | MDB_O_RDONLY|MDB_O_META|MDB_O_COPY, + MDB_O_LOCKS = MDB_O_RDWR|MDB_CLOEXEC | ((MDB_O_MASK+1) & ~MDB_O_MASK) /**< for me_lfd */ +#endif +}; + +/** Open an LMDB file. + * @param[in] env The LMDB environment. + * @param[in,out] fname Path from from #mdb_fname_init(). A suffix is + * appended if necessary to create the filename, without changing mn_len. + * @param[in] which Determines file type, access mode, etc. + * @param[in] mode The Unix permissions for the file, if we create it. + * @param[out] res Resulting file handle. + * @return 0 on success, non-zero on failure. + */ +static int ESECT +mdb_fopen(const MDB_env *env, MDB_name *fname, + enum mdb_fopen_type which, mdb_mode_t mode, + HANDLE *res) +{ + int rc = MDB_SUCCESS; + HANDLE fd; +#ifdef _WIN32 + DWORD acc, share, disp, attrs; +#else + int flags; +#endif + + if (fname->mn_alloced) /* modifiable copy */ + mdb_name_cpy(fname->mn_val + fname->mn_len, + mdb_suffixes[which==MDB_O_LOCKS][F_ISSET(env->me_flags, MDB_NOSUBDIR)]); + + /* The directory must already exist. Usually the file need not. + * MDB_O_META requires the file because we already created it using + * MDB_O_RDWR. MDB_O_COPY must not overwrite an existing file. + * + * With MDB_O_COPY we do not want the OS to cache the writes, since + * the source data is already in the OS cache. + * + * The lockfile needs FD_CLOEXEC (close file descriptor on exec*()) + * to avoid the flock() issues noted under Caveats in lmdb.h. + * Also set it for other filehandles which the user cannot get at + * and close himself, which he may need after fork(). I.e. all but + * me_fd, which programs do use via mdb_env_get_fd(). + */ + +#ifdef _WIN32 + acc = GENERIC_READ|GENERIC_WRITE; + share = FILE_SHARE_READ|FILE_SHARE_WRITE; + disp = OPEN_ALWAYS; + attrs = FILE_ATTRIBUTE_NORMAL; + switch (which) { + case MDB_O_RDONLY: /* read-only datafile */ + acc = GENERIC_READ; + disp = OPEN_EXISTING; + break; + case MDB_O_META: /* for writing metapages */ + acc = GENERIC_WRITE; + disp = OPEN_EXISTING; + attrs = FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH; + break; + case MDB_O_COPY: /* mdb_env_copy() & co */ + acc = GENERIC_WRITE; + share = 0; + disp = CREATE_NEW; + attrs = FILE_FLAG_NO_BUFFERING|FILE_FLAG_WRITE_THROUGH; + break; + default: break; /* silence gcc -Wswitch (not all enum values handled) */ + } + fd = CreateFileW(fname->mn_val, acc, share, NULL, disp, attrs, NULL); +#else + fd = open(fname->mn_val, which & MDB_O_MASK, mode); +#endif + + if (fd == INVALID_HANDLE_VALUE) + rc = ErrCode(); +#ifndef _WIN32 + else { + if (which != MDB_O_RDONLY && which != MDB_O_RDWR) { + /* Set CLOEXEC if we could not pass it to open() */ + if (!MDB_CLOEXEC && (flags = fcntl(fd, F_GETFD)) != -1) + (void) fcntl(fd, F_SETFD, flags | FD_CLOEXEC); + } + if (which == MDB_O_COPY && env->me_psize >= env->me_os_psize) { + /* This may require buffer alignment. There is no portable + * way to ask how much, so we require OS pagesize alignment. + */ +# ifdef F_NOCACHE /* __APPLE__ */ + (void) fcntl(fd, F_NOCACHE, 1); +# elif defined O_DIRECT + /* open(...O_DIRECT...) would break on filesystems without + * O_DIRECT support (ITS#7682). Try to set it here instead. + */ + if ((flags = fcntl(fd, F_GETFL)) != -1) + (void) fcntl(fd, F_SETFL, flags | O_DIRECT); +# endif + } + } +#endif /* !_WIN32 */ + + *res = fd; + return rc; +} + + #ifdef BROKEN_FDATASYNC #include <sys/utsname.h> #include <sys/vfs.h> @@ -4407,16 +4743,16 @@ mdb_env_open2(MDB_env *env, int prev) if (!NtCreateSection) { HMODULE h = GetModuleHandle("NTDLL.DLL"); if (!h) - return MDB_PANIC; + return MDB_PROBLEM; NtClose = (NtCloseFunc *)GetProcAddress(h, "NtClose"); if (!NtClose) - return MDB_PANIC; + return MDB_PROBLEM; NtMapViewOfSection = (NtMapViewOfSectionFunc *)GetProcAddress(h, "NtMapViewOfSection"); if (!NtMapViewOfSection) - return MDB_PANIC; + return MDB_PROBLEM; NtCreateSection = (NtCreateSectionFunc *)GetProcAddress(h, "NtCreateSection"); if (!NtCreateSection) - return MDB_PANIC; + return MDB_PROBLEM; } #endif /* _WIN32 */ @@ -4554,13 +4890,13 @@ mdb_env_open2(MDB_env *env, int prev) DPRINTF(("opened database version %u, pagesize %u", meta->mm_version, env->me_psize)); - DPRINTF(("using meta page %d", (int) (meta->mm_txnid & 1))); - DPRINTF(("depth: %u", db->md_depth)); - DPRINTF(("entries: %"Y"u", db->md_entries)); - DPRINTF(("branch pages: %"Y"u", db->md_branch_pages)); - DPRINTF(("leaf pages: %"Y"u", db->md_leaf_pages)); - DPRINTF(("overflow pages: %"Y"u", db->md_overflow_pages)); - DPRINTF(("root: %"Y"u", db->md_root)); + DPRINTF(("using meta page %d", (int) (meta->mm_txnid & 1))); + DPRINTF(("depth: %u", db->md_depth)); + DPRINTF(("entries: %"Yu, db->md_entries)); + DPRINTF(("branch pages: %"Yu, db->md_branch_pages)); + DPRINTF(("leaf pages: %"Yu, db->md_leaf_pages)); + DPRINTF(("overflow pages: %"Yu, db->md_overflow_pages)); + DPRINTF(("root: %"Yu, db->md_root)); } #endif @@ -4577,7 +4913,11 @@ mdb_env_reader_dest(void *ptr) { MDB_reader *reader = ptr; - reader->mr_pid = 0; +#ifndef _WIN32 + if (reader->mr_pid == getpid()) /* catch pthread_exit() in child process */ +#endif + /* We omit the mutex, so do this atomically (i.e. skip mr_txnid) */ + reader->mr_pid = 0; } #ifdef _WIN32 @@ -4749,32 +5089,21 @@ mdb_env_excl_lock(MDB_env *env, int *excl) * Share and Enjoy! :-) */ -typedef unsigned long long mdb_hash_t; -#define MDB_HASH_INIT ((mdb_hash_t)0xcbf29ce484222325ULL) - /** perform a 64 bit Fowler/Noll/Vo FNV-1a hash on a buffer * @param[in] val value to hash - * @param[in] hval initial value for hash + * @param[in] len length of value * @return 64 bit hash - * - * NOTE: To use the recommended 64 bit FNV-1a hash, use MDB_HASH_INIT as the - * hval arg on the first call. */ static mdb_hash_t -mdb_hash_val(MDB_val *val, mdb_hash_t hval) +mdb_hash(const void *val, size_t len) { - unsigned char *s = (unsigned char *)val->mv_data; /* unsigned string */ - unsigned char *end = s + val->mv_size; + const unsigned char *s = (const unsigned char *) val, *end = s + len; + mdb_hash_t hval = 0xcbf29ce484222325ULL; /* - * FNV-1a hash each octet of the string + * FNV-1a hash each octet of the buffer */ while (s < end) { - /* xor the bottom with the current octet */ - hval ^= (mdb_hash_t)*s++; - - /* multiply by the 64 bit FNV magic prime mod 2^64 */ - hval += (hval << 1) + (hval << 4) + (hval << 5) + - (hval << 7) + (hval << 8) + (hval << 40); + hval = (hval ^ *s++) * 0x100000001b3ULL; } /* return our new hash value */ return hval; @@ -4791,47 +5120,49 @@ mdb_hash_val(MDB_val *val, mdb_hash_t hval) static const char mdb_a85[]= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~"; static void ESECT -mdb_pack85(unsigned long l, char *out) +mdb_pack85(unsigned long long l, char *out) { int i; - for (i=0; i<5; i++) { + for (i=0; i<10 && l; i++) { *out++ = mdb_a85[l % 85]; l /= 85; } + *out = '\0'; } +/** Init #MDB_env.me_mutexname[] except the char which #MUTEXNAME() will set. + * Changes to this code must be reflected in #MDB_LOCK_FORMAT. + */ static void ESECT -mdb_hash_enc(MDB_val *val, char *encbuf) +mdb_env_mname_init(MDB_env *env) { - mdb_hash_t h = mdb_hash_val(val, MDB_HASH_INIT); - - mdb_pack85(h, encbuf); - mdb_pack85(h>>32, encbuf+5); - encbuf[10] = '\0'; + char *nm = env->me_mutexname; + strcpy(nm, MUTEXNAME_PREFIX); + mdb_pack85(env->me_txns->mti_mutexid, nm + sizeof(MUTEXNAME_PREFIX)); } + +/** Return env->me_mutexname after filling in ch ('r'/'w') for convenience */ +#define MUTEXNAME(env, ch) ( \ + (void) ((env)->me_mutexname[sizeof(MUTEXNAME_PREFIX)-1] = (ch)), \ + (env)->me_mutexname) + #endif /** Open and/or initialize the lock region for the environment. * @param[in] env The LMDB environment. - * @param[in] lpath The pathname of the file used for the lock region. + * @param[in] fname Filename + scratch area, from #mdb_fname_init(). * @param[in] mode The Unix permissions for the file, if we create it. * @param[in,out] excl In -1, out lock type: -1 none, 0 shared, 1 exclusive * @return 0 on success, non-zero on failure. */ static int ESECT -mdb_env_setup_locks(MDB_env *env, char *lpath, int mode, int *excl) +mdb_env_setup_locks(MDB_env *env, MDB_name *fname, int mode, int *excl) { #ifdef _WIN32 # define MDB_ERRCODE_ROFS ERROR_WRITE_PROTECT #else # define MDB_ERRCODE_ROFS EROFS -#ifdef O_CLOEXEC /* Linux: Open file and set FD_CLOEXEC atomically */ -# define MDB_CLOEXEC O_CLOEXEC -#else - int fdflags; -# define MDB_CLOEXEC 0 -#endif #endif #ifdef MDB_USE_SYSV_SEM int semid; @@ -4840,30 +5171,14 @@ mdb_env_setup_locks(MDB_env *env, char *lpath, int mode, int *excl) int rc; off_t size, rsize; -#ifdef _WIN32 - wchar_t *wlpath; - rc = utf8_to_utf16(lpath, -1, &wlpath, NULL); - if (rc) - return rc; - env->me_lfd = CreateFileW(wlpath, GENERIC_READ|GENERIC_WRITE, - FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL, NULL); - free(wlpath); -#else - env->me_lfd = open(lpath, O_RDWR|O_CREAT|MDB_CLOEXEC, mode); -#endif - if (env->me_lfd == INVALID_HANDLE_VALUE) { - rc = ErrCode(); + rc = mdb_fopen(env, fname, MDB_O_LOCKS, mode, &env->me_lfd); + if (rc) { + /* Omit lockfile if read-only env on read-only filesystem */ if (rc == MDB_ERRCODE_ROFS && (env->me_flags & MDB_RDONLY)) { return MDB_SUCCESS; } - goto fail_errno; + goto fail; } -#if ! ((MDB_CLOEXEC) || defined(_WIN32)) - /* Lose record locks when exec*() */ - if ((fdflags = fcntl(env->me_lfd, F_GETFD) | FD_CLOEXEC) >= 0) - fcntl(env->me_lfd, F_SETFD, fdflags); -#endif if (!(env->me_flags & MDB_NOTLS)) { rc = pthread_key_create(&env->me_txkey, mdb_env_reader_dest); @@ -4929,8 +5244,6 @@ mdb_env_setup_locks(MDB_env *env, char *lpath, int mode, int *excl) DWORD nhigh; DWORD nlow; } idbuf; - MDB_val val; - char encbuf[11]; if (!mdb_sec_inited) { InitializeSecurityDescriptor(&mdb_null_sd, @@ -4945,14 +5258,11 @@ mdb_env_setup_locks(MDB_env *env, char *lpath, int mode, int *excl) idbuf.volume = stbuf.dwVolumeSerialNumber; idbuf.nhigh = stbuf.nFileIndexHigh; idbuf.nlow = stbuf.nFileIndexLow; - val.mv_data = &idbuf; - val.mv_size = sizeof(idbuf); - mdb_hash_enc(&val, encbuf); - sprintf(env->me_txns->mti_rmname, "Global\\MDBr%s", encbuf); - sprintf(env->me_txns->mti_wmname, "Global\\MDBw%s", encbuf); - env->me_rmutex = CreateMutexA(&mdb_all_sa, FALSE, env->me_txns->mti_rmname); + env->me_txns->mti_mutexid = mdb_hash(&idbuf, sizeof(idbuf)); + mdb_env_mname_init(env); + env->me_rmutex = CreateMutexA(&mdb_all_sa, FALSE, MUTEXNAME(env, 'r')); if (!env->me_rmutex) goto fail_errno; - env->me_wmutex = CreateMutexA(&mdb_all_sa, FALSE, env->me_txns->mti_wmname); + env->me_wmutex = CreateMutexA(&mdb_all_sa, FALSE, MUTEXNAME(env, 'w')); if (!env->me_wmutex) goto fail_errno; #elif defined(MDB_USE_POSIX_SEM) struct stat stbuf; @@ -4960,37 +5270,35 @@ mdb_env_setup_locks(MDB_env *env, char *lpath, int mode, int *excl) dev_t dev; ino_t ino; } idbuf; - MDB_val val; - char encbuf[11]; #if defined(__NetBSD__) #define MDB_SHORT_SEMNAMES 1 /* limited to 14 chars */ #endif if (fstat(env->me_lfd, &stbuf)) goto fail_errno; + memset(&idbuf, 0, sizeof(idbuf)); idbuf.dev = stbuf.st_dev; idbuf.ino = stbuf.st_ino; - val.mv_data = &idbuf; - val.mv_size = sizeof(idbuf); - mdb_hash_enc(&val, encbuf); + env->me_txns->mti_mutexid = mdb_hash(&idbuf, sizeof(idbuf)) #ifdef MDB_SHORT_SEMNAMES - encbuf[9] = '\0'; /* drop name from 15 chars to 14 chars */ + /* Max 9 base85-digits. We truncate here instead of in + * mdb_env_mname_init() to keep the latter portable. + */ + % ((mdb_hash_t)85*85*85*85*85*85*85*85*85) #endif - sprintf(env->me_txns->mti_rmname, "/MDBr%s", encbuf); - sprintf(env->me_txns->mti_wmname, "/MDBw%s", encbuf); + ; + mdb_env_mname_init(env); /* Clean up after a previous run, if needed: Try to * remove both semaphores before doing anything else. */ - sem_unlink(env->me_txns->mti_rmname); - sem_unlink(env->me_txns->mti_wmname); - env->me_rmutex = sem_open(env->me_txns->mti_rmname, - O_CREAT|O_EXCL, mode, 1); + sem_unlink(MUTEXNAME(env, 'r')); + sem_unlink(MUTEXNAME(env, 'w')); + env->me_rmutex = sem_open(MUTEXNAME(env, 'r'), O_CREAT|O_EXCL, mode, 1); if (env->me_rmutex == SEM_FAILED) goto fail_errno; - env->me_wmutex = sem_open(env->me_txns->mti_wmname, - O_CREAT|O_EXCL, mode, 1); + env->me_wmutex = sem_open(MUTEXNAME(env, 'w'), O_CREAT|O_EXCL, mode, 1); if (env->me_wmutex == SEM_FAILED) goto fail_errno; #elif defined(MDB_USE_SYSV_SEM) unsigned short vals[2] = {1, 1}; - key_t key = ftok(lpath, 'M'); + key_t key = ftok(fname->mn_val, 'M'); /* fname is lockfile path now */ if (key == -1) goto fail_errno; semid = semget(key, 2, (mode & 0777) | IPC_CREAT); @@ -5000,6 +5308,8 @@ mdb_env_setup_locks(MDB_env *env, char *lpath, int mode, int *excl) if (semctl(semid, 0, SETALL, semu) < 0) goto fail_errno; env->me_txns->mti_semid = semid; + env->me_txns->mti_rlocked = 0; + env->me_txns->mti_wlocked = 0; #else /* MDB_USE_POSIX_MUTEX: */ pthread_mutexattr_t mattr; @@ -5010,15 +5320,17 @@ mdb_env_setup_locks(MDB_env *env, char *lpath, int mode, int *excl) memset(env->me_txns->mti_rmutex, 0, sizeof(*env->me_txns->mti_rmutex)); memset(env->me_txns->mti_wmutex, 0, sizeof(*env->me_txns->mti_wmutex)); - if ((rc = pthread_mutexattr_init(&mattr)) - || (rc = pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED)) + if ((rc = pthread_mutexattr_init(&mattr)) != 0) + goto fail; + rc = pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED); #ifdef MDB_ROBUST_SUPPORTED - || (rc = pthread_mutexattr_setrobust(&mattr, PTHREAD_MUTEX_ROBUST)) + if (!rc) rc = pthread_mutexattr_setrobust(&mattr, PTHREAD_MUTEX_ROBUST); #endif - || (rc = pthread_mutex_init(env->me_txns->mti_rmutex, &mattr)) - || (rc = pthread_mutex_init(env->me_txns->mti_wmutex, &mattr))) - goto fail; + if (!rc) rc = pthread_mutex_init(env->me_txns->mti_rmutex, &mattr); + if (!rc) rc = pthread_mutex_init(env->me_txns->mti_wmutex, &mattr); pthread_mutexattr_destroy(&mattr); + if (rc) + goto fail; #endif /* _WIN32 || ... */ env->me_txns->mti_magic = MDB_MAGIC; @@ -5046,14 +5358,16 @@ mdb_env_setup_locks(MDB_env *env, char *lpath, int mode, int *excl) goto fail; } #ifdef _WIN32 - env->me_rmutex = OpenMutexA(SYNCHRONIZE, FALSE, env->me_txns->mti_rmname); + mdb_env_mname_init(env); + env->me_rmutex = OpenMutexA(SYNCHRONIZE, FALSE, MUTEXNAME(env, 'r')); if (!env->me_rmutex) goto fail_errno; - env->me_wmutex = OpenMutexA(SYNCHRONIZE, FALSE, env->me_txns->mti_wmname); + env->me_wmutex = OpenMutexA(SYNCHRONIZE, FALSE, MUTEXNAME(env, 'w')); if (!env->me_wmutex) goto fail_errno; #elif defined(MDB_USE_POSIX_SEM) - env->me_rmutex = sem_open(env->me_txns->mti_rmname, 0); + mdb_env_mname_init(env); + env->me_rmutex = sem_open(MUTEXNAME(env, 'r'), 0); if (env->me_rmutex == SEM_FAILED) goto fail_errno; - env->me_wmutex = sem_open(env->me_txns->mti_wmname, 0); + env->me_wmutex = sem_open(MUTEXNAME(env, 'w'), 0); if (env->me_wmutex == SEM_FAILED) goto fail_errno; #elif defined(MDB_USE_SYSV_SEM) semid = env->me_txns->mti_semid; @@ -5074,13 +5388,6 @@ mdb_env_setup_locks(MDB_env *env, char *lpath, int mode, int *excl) env->me_rmutex->locked = &env->me_txns->mti_rlocked; env->me_wmutex->locked = &env->me_txns->mti_wlocked; #endif -#ifdef MDB_VL32 -#ifdef _WIN32 - env->me_rpmutex = CreateMutex(NULL, FALSE, NULL); -#else - pthread_mutex_init(&env->me_rpmutex, NULL); -#endif -#endif return MDB_SUCCESS; @@ -5090,12 +5397,6 @@ fail: return rc; } - /** The name of the lock file in the DB environment */ -#define LOCKNAME "/lock.mdb" - /** The name of the data file in the DB environment */ -#define DATANAME "/data.mdb" - /** The suffix of the lock file when no subdir is used */ -#define LOCKSUFF "-lock" /** Only a subset of the @ref mdb_env flags can be changed * at runtime. Changing other flags requires closing the * environment and re-opening it with the new flags. @@ -5111,11 +5412,8 @@ fail: int ESECT mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode) { - int oflags, rc, len, excl = -1; - char *lpath, *dpath; -#ifdef _WIN32 - wchar_t *wpath; -#endif + int rc, excl = -1; + MDB_name fname; if (env->me_fd!=INVALID_HANDLE_VALUE || (flags & ~(CHANGEABLE|CHANGELESS))) return EINVAL; @@ -5130,28 +5428,27 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode return EINVAL; } #endif + flags |= env->me_flags; - len = strlen(path); - if (flags & MDB_NOSUBDIR) { - rc = len + sizeof(LOCKSUFF) + len + 1; - } else { - rc = len + sizeof(LOCKNAME) + len + sizeof(DATANAME); - } - lpath = malloc(rc); - if (!lpath) - return ENOMEM; - if (flags & MDB_NOSUBDIR) { - dpath = lpath + len + sizeof(LOCKSUFF); - sprintf(lpath, "%s" LOCKSUFF, path); - strcpy(dpath, path); - } else { - dpath = lpath + len + sizeof(LOCKNAME); - sprintf(lpath, "%s" LOCKNAME, path); - sprintf(dpath, "%s" DATANAME, path); + rc = mdb_fname_init(path, flags, &fname); + if (rc) + return rc; + +#ifdef MDB_VL32 +#ifdef _WIN32 + env->me_rpmutex = CreateMutex(NULL, FALSE, NULL); + if (!env->me_rpmutex) { + rc = ErrCode(); + goto leave; } +#else + rc = pthread_mutex_init(&env->me_rpmutex, NULL); + if (rc) + goto leave; +#endif +#endif + flags |= MDB_ENV_ACTIVE; /* tell mdb_env_close0() to clean up */ - rc = MDB_SUCCESS; - flags |= env->me_flags; if (flags & MDB_RDONLY) { /* silently ignore WRITEMAP when we're only getting read access */ flags &= ~MDB_WRITEMAP; @@ -5160,8 +5457,13 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode (env->me_dirty_list = calloc(MDB_IDL_UM_SIZE, sizeof(MDB_ID2))))) rc = ENOMEM; } + + env->me_flags = flags; + if (rc) + goto leave; + #ifdef MDB_VL32 - if (!rc) { + { env->me_rpages = malloc(MDB_ERPAGE_SIZE * sizeof(MDB_ID3)); if (!env->me_rpages) { rc = ENOMEM; @@ -5171,9 +5473,6 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode env->me_rpcheck = MDB_ERPAGE_SIZE/2; } #endif - env->me_flags = flags |= MDB_ENV_ACTIVE; - if (rc) - goto leave; env->me_path = strdup(path); env->me_dbxs = calloc(env->me_maxdbs, sizeof(MDB_dbx)); @@ -5187,73 +5486,35 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode /* For RDONLY, get lockfile after we know datafile exists */ if (!(flags & (MDB_RDONLY|MDB_NOLOCK))) { - rc = mdb_env_setup_locks(env, lpath, mode, &excl); + rc = mdb_env_setup_locks(env, &fname, mode, &excl); if (rc) goto leave; + if ((flags & MDB_PREVSNAPSHOT) && !excl) { + rc = EAGAIN; + goto leave; + } } -#ifdef _WIN32 - if (F_ISSET(flags, MDB_RDONLY)) { - oflags = GENERIC_READ; - len = OPEN_EXISTING; - } else { - oflags = GENERIC_READ|GENERIC_WRITE; - len = OPEN_ALWAYS; - } - mode = FILE_ATTRIBUTE_NORMAL; - rc = utf8_to_utf16(dpath, -1, &wpath, NULL); + rc = mdb_fopen(env, &fname, + (flags & MDB_RDONLY) ? MDB_O_RDONLY : MDB_O_RDWR, + mode, &env->me_fd); if (rc) goto leave; - env->me_fd = CreateFileW(wpath, oflags, FILE_SHARE_READ|FILE_SHARE_WRITE, - NULL, len, mode, NULL); - free(wpath); -#else - if (F_ISSET(flags, MDB_RDONLY)) - oflags = O_RDONLY; - else - oflags = O_RDWR | O_CREAT; - - env->me_fd = open(dpath, oflags, mode); -#endif - if (env->me_fd == INVALID_HANDLE_VALUE) { - rc = ErrCode(); - goto leave; - } if ((flags & (MDB_RDONLY|MDB_NOLOCK)) == MDB_RDONLY) { - rc = mdb_env_setup_locks(env, lpath, mode, &excl); + rc = mdb_env_setup_locks(env, &fname, mode, &excl); if (rc) goto leave; - if ((flags & MDB_PREVSNAPSHOT) && !excl) { - rc = EAGAIN; - goto leave; - } } if ((rc = mdb_env_open2(env, flags & MDB_PREVSNAPSHOT)) == MDB_SUCCESS) { - if (flags & (MDB_RDONLY|MDB_WRITEMAP)) { - env->me_mfd = env->me_fd; - } else { + if (!(flags & (MDB_RDONLY|MDB_WRITEMAP))) { /* Synchronous fd for meta writes. Needed even with * MDB_NOSYNC/MDB_NOMETASYNC, in case these get reset. */ -#ifdef _WIN32 - len = OPEN_EXISTING; - rc = utf8_to_utf16(dpath, -1, &wpath, NULL); + rc = mdb_fopen(env, &fname, MDB_O_META, mode, &env->me_mfd); if (rc) goto leave; - env->me_mfd = CreateFileW(wpath, oflags, - FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, len, - mode | FILE_FLAG_WRITE_THROUGH, NULL); - free(wpath); -#else - oflags &= ~O_CREAT; - env->me_mfd = open(dpath, oflags | MDB_DSYNC, mode); -#endif - if (env->me_mfd == INVALID_HANDLE_VALUE) { - rc = ErrCode(); - goto leave; - } } DPRINTF(("opened dbenv %p", (void *) env)); if (excl > 0 && !(flags & MDB_PREVSNAPSHOT)) { @@ -5296,7 +5557,7 @@ leave: if (rc) { mdb_env_close0(env, excl); } - free(lpath); + mdb_fname_destroy(fname); return rc; } @@ -5324,11 +5585,13 @@ mdb_env_close0(MDB_env *env, int excl) #ifdef MDB_VL32 if (env->me_txn0 && env->me_txn0->mt_rpages) free(env->me_txn0->mt_rpages); - { unsigned int x; - for (x=1; x<=env->me_rpages[0].mid; x++) - munmap(env->me_rpages[x].mptr, env->me_rpages[x].mcnt * env->me_psize); + if (env->me_rpages) { + MDB_ID3L el = env->me_rpages; + unsigned int x; + for (x=1; x<=el[0].mid; x++) + munmap(el[x].mptr, el[x].mcnt * env->me_psize); + free(el); } - free(env->me_rpages); #endif free(env->me_txn0); mdb_midl_free(env->me_free_pgs); @@ -5353,12 +5616,12 @@ mdb_env_close0(MDB_env *env, int excl) munmap(env->me_map, env->me_mapsize); #endif } - if (env->me_mfd != env->me_fd && env->me_mfd != INVALID_HANDLE_VALUE) + if (env->me_mfd != INVALID_HANDLE_VALUE) (void) close(env->me_mfd); if (env->me_fd != INVALID_HANDLE_VALUE) (void) close(env->me_fd); if (env->me_txns) { - MDB_PID_T pid = env->me_pid; + MDB_PID_T pid = getpid(); /* Clearing readers is done in this function because * me_txkey with its destructor must be disabled first. * @@ -5388,8 +5651,8 @@ mdb_env_close0(MDB_env *env, int excl) if (excl == 0) mdb_env_excl_lock(env, &excl); if (excl > 0) { - sem_unlink(env->me_txns->mti_rmname); - sem_unlink(env->me_txns->mti_wmname); + sem_unlink(MUTEXNAME(env, 'r')); + sem_unlink(MUTEXNAME(env, 'w')); } } #elif defined(MDB_USE_SYSV_SEM) @@ -5447,7 +5710,7 @@ mdb_env_close(MDB_env *env) free(env); } -/** Compare two items pointing at aligned mdb_size_t's */ +/** Compare two items pointing at aligned #mdb_size_t's */ static int mdb_cmp_long(const MDB_val *a, const MDB_val *b) { @@ -5458,7 +5721,7 @@ mdb_cmp_long(const MDB_val *a, const MDB_val *b) /** Compare two items pointing at aligned unsigned int's. * * This is also set as #MDB_INTEGERDUP|#MDB_DUPFIXED's #MDB_dbx.%md_dcmp, - * but #mdb_cmp_clong() is called instead if the data type is mdb_size_t. + * but #mdb_cmp_clong() is called instead if the data type is #mdb_size_t. */ static int mdb_cmp_int(const MDB_val *a, const MDB_val *b) @@ -5563,7 +5826,7 @@ mdb_node_search(MDB_cursor *mc, MDB_val *key, int *exactp) nkeys = NUMKEYS(mp); - DPRINTF(("searching %u keys in %s %spage %"Y"u", + DPRINTF(("searching %u keys in %s %spage %"Yu, nkeys, IS_LEAF(mp) ? "leaf" : "branch", IS_SUBP(mp) ? "sub-" : "", mdb_dbg_pgno(mp))); @@ -5611,7 +5874,7 @@ mdb_node_search(MDB_cursor *mc, MDB_val *key, int *exactp) DPRINTF(("found leaf index %u [%s], rc = %i", i, DKEY(&nodekey), rc)); else - DPRINTF(("found branch index %u [%s -> %"Y"u], rc = %i", + DPRINTF(("found branch index %u [%s -> %"Yu"], rc = %i", i, DKEY(&nodekey), NODEPGNO(node), rc)); #endif if (rc == 0) @@ -5659,7 +5922,7 @@ static void mdb_cursor_pop(MDB_cursor *mc) { if (mc->mc_snum) { - DPRINTF(("popping page %"Y"u off db %d cursor %p", + DPRINTF(("popping page %"Yu" off db %d cursor %p", mc->mc_pg[mc->mc_top]->mp_pgno, DDBI(mc), (void *) mc)); mc->mc_snum--; @@ -5671,11 +5934,13 @@ mdb_cursor_pop(MDB_cursor *mc) } } -/** Push a page onto the top of the cursor's stack. */ +/** Push a page onto the top of the cursor's stack. + * Set #MDB_TXN_ERROR on failure. + */ static int mdb_cursor_push(MDB_cursor *mc, MDB_page *mp) { - DPRINTF(("pushing page %"Y"u on db %d cursor %p", mp->mp_pgno, + DPRINTF(("pushing page %"Yu" on db %d cursor %p", mp->mp_pgno, DDBI(mc), (void *) mc)); if (mc->mc_snum >= CURSOR_STACK) { @@ -5979,6 +6244,7 @@ ok: #endif /** Find the address of the page corresponding to a given page number. + * Set #MDB_TXN_ERROR on failure. * @param[in] mc the cursor accessing the page. * @param[in] pgno the page number for the page to retrieve. * @param[out] ret address of a pointer where the page's address will be stored. @@ -5989,9 +6255,6 @@ static int mdb_page_get(MDB_cursor *mc, pgno_t pgno, MDB_page **ret, int *lvl) { MDB_txn *txn = mc->mc_txn; -#ifndef MDB_VL32 - MDB_env *env = txn->mt_env; -#endif MDB_page *p = NULL; int level; @@ -6010,14 +6273,7 @@ mdb_page_get(MDB_cursor *mc, pgno_t pgno, MDB_page **ret, int *lvl) MDB_ID pn = pgno << 1; x = mdb_midl_search(tx2->mt_spill_pgs, pn); if (x <= tx2->mt_spill_pgs[0] && tx2->mt_spill_pgs[x] == pn) { -#ifdef MDB_VL32 - int rc = mdb_rpage_get(txn, pgno, &p); - if (rc) - return rc; -#else - p = (MDB_page *)(env->me_map + env->me_psize * pgno); -#endif - goto done; + goto mapped; } } if (dl[0].mid) { @@ -6031,21 +6287,26 @@ mdb_page_get(MDB_cursor *mc, pgno_t pgno, MDB_page **ret, int *lvl) } while ((tx2 = tx2->mt_parent) != NULL); } - if (pgno < txn->mt_next_pgno) { - level = 0; + if (pgno >= txn->mt_next_pgno) { + DPRINTF(("page %"Yu" not found", pgno)); + txn->mt_flags |= MDB_TXN_ERROR; + return MDB_PAGE_NOTFOUND; + } + + level = 0; + +mapped: + { #ifdef MDB_VL32 - { - int rc = mdb_rpage_get(txn, pgno, &p); - if (rc) - return rc; + int rc = mdb_rpage_get(txn, pgno, &p); + if (rc) { + txn->mt_flags |= MDB_TXN_ERROR; + return rc; } #else + MDB_env *env = txn->mt_env; p = (MDB_page *)(env->me_map + env->me_psize * pgno); #endif - } else { - DPRINTF(("page %"Y"u not found", pgno)); - txn->mt_flags |= MDB_TXN_ERROR; - return MDB_PAGE_NOTFOUND; } done: @@ -6069,18 +6330,27 @@ mdb_page_search_root(MDB_cursor *mc, MDB_val *key, int flags) MDB_node *node; indx_t i; - DPRINTF(("branch page %"Y"u has %u keys", mp->mp_pgno, NUMKEYS(mp))); + DPRINTF(("branch page %"Yu" has %u keys", mp->mp_pgno, NUMKEYS(mp))); /* Don't assert on branch pages in the FreeDB. We can get here * while in the process of rebalancing a FreeDB branch page; we must * let that proceed. ITS#8336 */ mdb_cassert(mc, !mc->mc_dbi || NUMKEYS(mp) > 1); - DPRINTF(("found index 0 to page %"Y"u", NODEPGNO(NODEPTR(mp, 0)))); + DPRINTF(("found index 0 to page %"Yu, NODEPGNO(NODEPTR(mp, 0)))); if (flags & (MDB_PS_FIRST|MDB_PS_LAST)) { i = 0; - if (flags & MDB_PS_LAST) + if (flags & MDB_PS_LAST) { i = NUMKEYS(mp) - 1; + /* if already init'd, see if we're already in right place */ + if (mc->mc_flags & C_INITIALIZED) { + if (mc->mc_ki[mc->mc_top] == i) { + mc->mc_top = mc->mc_snum++; + mp = mc->mc_pg[mc->mc_top]; + goto ready; + } + } + } } else { int exact; node = mdb_node_search(mc, key, &exact); @@ -6106,6 +6376,7 @@ mdb_page_search_root(MDB_cursor *mc, MDB_val *key, int flags) if ((rc = mdb_cursor_push(mc, mp))) return rc; +ready: if (flags & MDB_PS_MODIFY) { if ((rc = mdb_page_touch(mc)) != 0) return rc; @@ -6120,7 +6391,7 @@ mdb_page_search_root(MDB_cursor *mc, MDB_val *key, int flags) return MDB_CORRUPTED; } - DPRINTF(("found leaf page %"Y"u for key [%s]", mp->mp_pgno, + DPRINTF(("found leaf page %"Yu" for key [%s]", mp->mp_pgno, key ? DKEY(key) : "null")); mc->mc_flags |= C_INITIALIZED; mc->mc_flags &= ~C_EOF; @@ -6235,7 +6506,7 @@ mdb_page_search(MDB_cursor *mc, MDB_val *key, int flags) mc->mc_snum = 1; mc->mc_top = 0; - DPRINTF(("db %d root page %"Y"u has flags 0x%X", + DPRINTF(("db %d root page %"Yu" has flags 0x%X", DDBI(mc), root, mc->mc_pg[0]->mp_flags)); if (flags & MDB_PS_MODIFY) { @@ -6260,7 +6531,7 @@ mdb_ovpage_free(MDB_cursor *mc, MDB_page *mp) MDB_ID pn = pg << 1; int rc; - DPRINTF(("free ov page %"Y"u (%d)", pg, ovpages)); + DPRINTF(("free ov page %"Yu" (%d)", pg, ovpages)); /* If the page is dirty or on the spill list we just acquired it, * so we should give it back to our current free list, if any. * Otherwise put it onto the list of pages we freed in this txn. @@ -6301,7 +6572,7 @@ mdb_ovpage_free(MDB_cursor *mc, MDB_page *mp) j = ++(dl[0].mid); dl[j] = ix; /* Unsorted. OK when MDB_TXN_ERROR. */ txn->mt_flags |= MDB_TXN_ERROR; - return MDB_CORRUPTED; + return MDB_PROBLEM; } } txn->mt_dirty_room++; @@ -6342,12 +6613,10 @@ mdb_node_read(MDB_cursor *mc, MDB_node *leaf, MDB_val *data) pgno_t pgno; int rc; -#ifdef MDB_VL32 - if (mc->mc_ovpg) { - MDB_PAGE_UNREF(mc->mc_txn, mc->mc_ovpg); - mc->mc_ovpg = 0; + if (MC_OVPG(mc)) { + MDB_PAGE_UNREF(mc->mc_txn, MC_OVPG(mc)); + MC_SET_OVPG(mc, NULL); } -#endif if (!F_ISSET(leaf->mn_flags, F_BIGDATA)) { data->mv_size = NODEDSZ(leaf); data->mv_data = NODEDATA(leaf); @@ -6359,13 +6628,11 @@ mdb_node_read(MDB_cursor *mc, MDB_node *leaf, MDB_val *data) data->mv_size = NODEDSZ(leaf); memcpy(&pgno, NODEDATA(leaf), sizeof(pgno)); if ((rc = mdb_page_get(mc, pgno, &omp, NULL)) != 0) { - DPRINTF(("read overflow page %"Y"u failed", pgno)); + DPRINTF(("read overflow page %"Yu" failed", pgno)); return rc; } data->mv_data = METADATA(omp); -#ifdef MDB_VL32 - mc->mc_ovpg = omp; -#endif + MC_SET_OVPG(mc, omp); return MDB_SUCCESS; } @@ -6389,14 +6656,10 @@ mdb_get(MDB_txn *txn, MDB_dbi dbi, mdb_cursor_init(&mc, txn, dbi, &mx); rc = mdb_cursor_set(&mc, key, data, MDB_SET, &exact); -#ifdef MDB_VL32 - { - /* unref all the pages - caller must copy the data - * before doing anything else - */ - mdb_cursor_unref(&mc); - } -#endif + /* unref all the pages when MDB_VL32 - caller must copy the data + * before doing anything else + */ + MDB_CURSOR_UNREF(&mc, 1); return rc; } @@ -6426,7 +6689,7 @@ mdb_cursor_sibling(MDB_cursor *mc, int move_right) op = mc->mc_pg[mc->mc_top]; #endif mdb_cursor_pop(mc); - DPRINTF(("parent page is page %"Y"u, index %u", + DPRINTF(("parent page is page %"Yu", index %u", mc->mc_pg[mc->mc_top]->mp_pgno, mc->mc_ki[mc->mc_top])); if (move_right ? (mc->mc_ki[mc->mc_top] + 1u >= NUMKEYS(mc->mc_pg[mc->mc_top])) @@ -6473,14 +6736,20 @@ mdb_cursor_next(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op) MDB_node *leaf; int rc; - if (mc->mc_flags & C_EOF) { + if ((mc->mc_flags & C_DEL && op == MDB_NEXT_DUP)) return MDB_NOTFOUND; - } - mdb_cassert(mc, mc->mc_flags & C_INITIALIZED); + if (!(mc->mc_flags & C_INITIALIZED)) + return mdb_cursor_first(mc, key, data); mp = mc->mc_pg[mc->mc_top]; + if (mc->mc_flags & C_EOF) { + if (mc->mc_ki[mc->mc_top] >= NUMKEYS(mp)-1) + return MDB_NOTFOUND; + mc->mc_flags ^= C_EOF; + } + if (mc->mc_db->md_flags & MDB_DUPSORT) { leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]); if (F_ISSET(leaf->mn_flags, F_DUPDATA)) { @@ -6492,13 +6761,9 @@ mdb_cursor_next(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op) return rc; } } -#ifdef MDB_VL32 else { - if (mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) { - mdb_cursor_unref(&mc->mc_xcursor->mx_cursor); - } + MDB_CURSOR_UNREF(&mc->mc_xcursor->mx_cursor, 0); } -#endif } else { mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF); if (op == MDB_NEXT_DUP) @@ -6506,7 +6771,7 @@ mdb_cursor_next(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op) } } - DPRINTF(("cursor_next: top page is %"Y"u in cursor %p", + DPRINTF(("cursor_next: top page is %"Yu" in cursor %p", mdb_dbg_pgno(mp), (void *) mc)); if (mc->mc_flags & C_DEL) { mc->mc_flags ^= C_DEL; @@ -6520,12 +6785,12 @@ mdb_cursor_next(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op) return rc; } mp = mc->mc_pg[mc->mc_top]; - DPRINTF(("next page is %"Y"u, key index %u", mp->mp_pgno, mc->mc_ki[mc->mc_top])); + DPRINTF(("next page is %"Yu", key index %u", mp->mp_pgno, mc->mc_ki[mc->mc_top])); } else mc->mc_ki[mc->mc_top]++; skip: - DPRINTF(("==> cursor points to page %"Y"u with %u keys, key index %u", + DPRINTF(("==> cursor points to page %"Yu" with %u keys, key index %u", mdb_dbg_pgno(mp), NUMKEYS(mp), mc->mc_ki[mc->mc_top])); if (IS_LEAF2(mp)) { @@ -6563,7 +6828,12 @@ mdb_cursor_prev(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op) MDB_node *leaf; int rc; - mdb_cassert(mc, mc->mc_flags & C_INITIALIZED); + if (!(mc->mc_flags & C_INITIALIZED)) { + rc = mdb_cursor_last(mc, key, data); + if (rc) + return rc; + mc->mc_ki[mc->mc_top]++; + } mp = mc->mc_pg[mc->mc_top]; @@ -6580,13 +6850,9 @@ mdb_cursor_prev(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op) return rc; } } -#ifdef MDB_VL32 else { - if (mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) { - mdb_cursor_unref(&mc->mc_xcursor->mx_cursor); - } + MDB_CURSOR_UNREF(&mc->mc_xcursor->mx_cursor, 0); } -#endif } else { mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF); if (op == MDB_PREV_DUP) @@ -6594,7 +6860,7 @@ mdb_cursor_prev(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op) } } - DPRINTF(("cursor_prev: top page is %"Y"u in cursor %p", + DPRINTF(("cursor_prev: top page is %"Yu" in cursor %p", mdb_dbg_pgno(mp), (void *) mc)); mc->mc_flags &= ~(C_EOF|C_DEL); @@ -6606,13 +6872,11 @@ mdb_cursor_prev(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op) } mp = mc->mc_pg[mc->mc_top]; mc->mc_ki[mc->mc_top] = NUMKEYS(mp) - 1; - DPRINTF(("prev page is %"Y"u, key index %u", mp->mp_pgno, mc->mc_ki[mc->mc_top])); + DPRINTF(("prev page is %"Yu", key index %u", mp->mp_pgno, mc->mc_ki[mc->mc_top])); } else mc->mc_ki[mc->mc_top]--; - mc->mc_flags &= ~C_EOF; - - DPRINTF(("==> cursor points to page %"Y"u with %u keys, key index %u", + DPRINTF(("==> cursor points to page %"Yu" with %u keys, key index %u", mdb_dbg_pgno(mp), NUMKEYS(mp), mc->mc_ki[mc->mc_top])); if (IS_LEAF2(mp)) { @@ -6656,11 +6920,7 @@ mdb_cursor_set(MDB_cursor *mc, MDB_val *key, MDB_val *data, return MDB_BAD_VALSIZE; if (mc->mc_xcursor) { -#ifdef MDB_VL32 - if (mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) { - mdb_cursor_unref(&mc->mc_xcursor->mx_cursor); - } -#endif + MDB_CURSOR_UNREF(&mc->mc_xcursor->mx_cursor, 0); mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF); } @@ -6728,6 +6988,7 @@ mdb_cursor_set(MDB_cursor *mc, MDB_val *key, MDB_val *data, } } rc = 0; + mc->mc_flags &= ~C_EOF; goto set2; } } @@ -6819,10 +7080,8 @@ set1: if ((rc = mdb_node_read(mc, leaf, &olddata)) != MDB_SUCCESS) return rc; dcmp = mc->mc_dbx->md_dcmp; -#if UINT_MAX < SIZE_MAX || defined(MDB_VL32) - if (dcmp == mdb_cmp_int && olddata.mv_size == sizeof(mdb_size_t)) + if (NEED_CMP_CLONG(dcmp, olddata.mv_size)) dcmp = mdb_cmp_clong; -#endif rc = dcmp(data, &olddata); if (rc) { if (op == MDB_GET_BOTH || rc > 0) @@ -6855,11 +7114,7 @@ mdb_cursor_first(MDB_cursor *mc, MDB_val *key, MDB_val *data) MDB_node *leaf; if (mc->mc_xcursor) { -#ifdef MDB_VL32 - if (mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) { - mdb_cursor_unref(&mc->mc_xcursor->mx_cursor); - } -#endif + MDB_CURSOR_UNREF(&mc->mc_xcursor->mx_cursor, 0); mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF); } @@ -6905,24 +7160,17 @@ mdb_cursor_last(MDB_cursor *mc, MDB_val *key, MDB_val *data) MDB_node *leaf; if (mc->mc_xcursor) { -#ifdef MDB_VL32 - if (mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) { - mdb_cursor_unref(&mc->mc_xcursor->mx_cursor); - } -#endif + MDB_CURSOR_UNREF(&mc->mc_xcursor->mx_cursor, 0); mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF); } - if (!(mc->mc_flags & C_EOF)) { - - if (!(mc->mc_flags & C_INITIALIZED) || mc->mc_top) { - rc = mdb_page_search(mc, NULL, MDB_PS_LAST); - if (rc != MDB_SUCCESS) - return rc; - } - mdb_cassert(mc, IS_LEAF(mc->mc_pg[mc->mc_top])); - + if (!(mc->mc_flags & C_INITIALIZED) || mc->mc_top) { + rc = mdb_page_search(mc, NULL, MDB_PS_LAST); + if (rc != MDB_SUCCESS) + return rc; } + mdb_cassert(mc, IS_LEAF(mc->mc_pg[mc->mc_top])); + mc->mc_ki[mc->mc_top] = NUMKEYS(mc->mc_pg[mc->mc_top]) - 1; mc->mc_flags |= C_INITIALIZED|C_EOF; leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); @@ -7036,10 +7284,7 @@ mdb_cursor_get(MDB_cursor *mc, MDB_val *key, MDB_val *data, rc = MDB_INCOMPATIBLE; break; } - if (!(mc->mc_flags & C_INITIALIZED)) - rc = mdb_cursor_first(mc, key, data); - else - rc = mdb_cursor_next(mc, key, data, MDB_NEXT_DUP); + rc = mdb_cursor_next(mc, key, data, MDB_NEXT_DUP); if (rc == MDB_SUCCESS) { if (mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) { MDB_cursor *mx; @@ -7081,21 +7326,11 @@ fetchm: case MDB_NEXT: case MDB_NEXT_DUP: case MDB_NEXT_NODUP: - if (!(mc->mc_flags & C_INITIALIZED)) - rc = mdb_cursor_first(mc, key, data); - else - rc = mdb_cursor_next(mc, key, data, op); + rc = mdb_cursor_next(mc, key, data, op); break; case MDB_PREV: case MDB_PREV_DUP: case MDB_PREV_NODUP: - if (!(mc->mc_flags & C_INITIALIZED)) { - rc = mdb_cursor_last(mc, key, data); - if (rc) - break; - mc->mc_flags |= C_INITIALIZED; - mc->mc_ki[mc->mc_top]++; - } rc = mdb_cursor_prev(mc, key, data, op); break; case MDB_FIRST: @@ -7112,6 +7347,11 @@ fetchm: rc = MDB_INCOMPATIBLE; break; } + if (mc->mc_ki[mc->mc_top] >= NUMKEYS(mc->mc_pg[mc->mc_top])) { + mc->mc_ki[mc->mc_top] = NUMKEYS(mc->mc_pg[mc->mc_top]); + rc = MDB_NOTFOUND; + break; + } { MDB_node *leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); if (!F_ISSET(leaf->mn_flags, F_DUPDATA)) { @@ -7153,7 +7393,8 @@ mdb_cursor_touch(MDB_cursor *mc) { int rc = MDB_SUCCESS; - if (mc->mc_dbi >= CORE_DBS && !(*mc->mc_dbflag & DB_DIRTY)) { + if (mc->mc_dbi >= CORE_DBS && !(*mc->mc_dbflag & (DB_DIRTY|DB_DUPDATA))) { + /* Touch DB record of named DB */ MDB_cursor mc2; MDB_xcursor mcx; if (TXN_DBI_CHANGED(mc->mc_txn, mc->mc_dbi)) @@ -7378,10 +7619,8 @@ more: if (flags == MDB_CURRENT) goto current; dcmp = mc->mc_dbx->md_dcmp; -#if UINT_MAX < SIZE_MAX || defined(MDB_VL32) - if (dcmp == mdb_cmp_int && olddata.mv_size == sizeof(mdb_size_t)) + if (NEED_CMP_CLONG(dcmp, olddata.mv_size)) dcmp = mdb_cmp_clong; -#endif /* does data match? */ if (!dcmp(data, &olddata)) { if (flags & (MDB_NODUPDATA|MDB_APPENDDUP)) @@ -7477,8 +7716,9 @@ prep_subDB: } else { memcpy((char *)mp + mp->mp_upper + PAGEBASE, (char *)fp + fp->mp_upper + PAGEBASE, olddata.mv_size - fp->mp_upper - PAGEBASE); + memcpy((char *)(&mp->mp_ptrs), (char *)(&fp->mp_ptrs), NUMKEYS(fp) * sizeof(mp->mp_ptrs[0])); for (i=0; i<NUMKEYS(fp); i++) - mp->mp_ptrs[i] = fp->mp_ptrs[i] + offset; + mp->mp_ptrs[i] += offset; } } @@ -7532,8 +7772,13 @@ current: /* Note - this page is already counted in parent's dirty_room */ rc2 = mdb_mid2l_insert(mc->mc_txn->mt_u.dirty_list, &id2); mdb_cassert(mc, rc2 == 0); + /* Currently we make the page look as with put() in the + * parent txn, in case the user peeks at MDB_RESERVEd + * or unused parts. Some users treat ovpages specially. + */ if (!(flags & MDB_RESERVE)) { - /* Copy end of page, adjusting alignment so + /* Skip the part where LMDB will put *data. + * Copy end of page, adjusting alignment so * compiler may copy words instead of bytes. */ off = (PAGEHDRSZ + data->mv_size) & -sizeof(size_t); @@ -7602,11 +7847,7 @@ new_sub: if (m3->mc_ki[i] >= mc->mc_ki[i] && insert_key) { m3->mc_ki[i]++; } - if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) { - MDB_node *n2 = NODEPTR(mp, m3->mc_ki[i]); - if ((n2->mn_flags & (F_SUBDATA|F_DUPDATA)) == F_DUPDATA) - m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(n2); - } + XCURSOR_REFRESH(m3, i, mp); } } } @@ -7648,7 +7889,6 @@ put_sub: MDB_xcursor *mx = mc->mc_xcursor; unsigned i = mc->mc_top; MDB_page *mp = mc->mc_pg[i]; - int nkeys = NUMKEYS(mp); for (m2 = mc->mc_txn->mt_cursors[mc->mc_dbi]; m2; m2=m2->mc_next) { if (m2 == mc || m2->mc_snum < mc->mc_snum) continue; @@ -7656,10 +7896,8 @@ put_sub: if (m2->mc_pg[i] == mp) { if (m2->mc_ki[i] == mc->mc_ki[i]) { mdb_xcursor_init2(m2, mx, new_dupdata); - } else if (!insert_key && m2->mc_ki[i] < nkeys) { - MDB_node *n2 = NODEPTR(mp, m2->mc_ki[i]); - if ((n2->mn_flags & (F_SUBDATA|F_DUPDATA)) == F_DUPDATA) - m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(n2); + } else if (!insert_key) { + XCURSOR_REFRESH(m2, i, mp); } } } @@ -7701,7 +7939,7 @@ put_sub: return rc; bad_sub: if (rc == MDB_KEYEXIST) /* should not happen, we deleted that item */ - rc = MDB_CORRUPTED; + rc = MDB_PROBLEM; } mc->mc_txn->mt_flags |= MDB_TXN_ERROR; return rc; @@ -7764,13 +8002,7 @@ mdb_cursor_del(MDB_cursor *mc, unsigned int flags) if (m2 == mc || m2->mc_snum < mc->mc_snum) continue; if (!(m2->mc_flags & C_INITIALIZED)) continue; if (m2->mc_pg[mc->mc_top] == mp) { - if (m2->mc_ki[mc->mc_top] == mc->mc_ki[mc->mc_top]) { - m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(leaf); - } else { - MDB_node *n2 = NODEPTR(mp, m2->mc_ki[mc->mc_top]); - if (!(n2->mn_flags & F_SUBDATA)) - m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(n2); - } + XCURSOR_REFRESH(m2, mc->mc_top, mp); } } } @@ -7815,6 +8047,7 @@ fail: } /** Allocate and initialize new pages for a database. + * Set #MDB_TXN_ERROR on failure. * @param[in] mc a cursor on the database being added to. * @param[in] flags flags defining what type of page is being allocated. * @param[in] num the number of pages to allocate. This is usually 1, @@ -7830,7 +8063,7 @@ mdb_page_new(MDB_cursor *mc, uint32_t flags, int num, MDB_page **mp) if ((rc = mdb_page_alloc(mc, num, &np))) return rc; - DPRINTF(("allocated new mpage %"Y"u, page size %u", + DPRINTF(("allocated new mpage %"Yu", page size %u", np->mp_pgno, mc->mc_txn->mt_env->me_psize)); np->mp_flags = flags | P_DIRTY; np->mp_lower = (PAGEHDRSZ-PAGEBASE); @@ -7900,6 +8133,7 @@ mdb_branch_size(MDB_env *env, MDB_val *key) } /** Add a node to the page pointed to by the cursor. + * Set #MDB_TXN_ERROR on failure. * @param[in] mc The cursor for this operation. * @param[in] indx The index on the page where the new node should be added. * @param[in] key The key for the new node. @@ -7930,7 +8164,7 @@ mdb_node_add(MDB_cursor *mc, indx_t indx, mdb_cassert(mc, mp->mp_upper >= mp->mp_lower); - DPRINTF(("add to %s %spage %"Y"u index %i, data size %"Z"u key size %"Z"u [%s]", + DPRINTF(("add to %s %spage %"Yu" index %i, data size %"Z"u key size %"Z"u [%s]", IS_LEAF(mp) ? "leaf" : "branch", IS_SUBP(mp) ? "sub-" : "", mdb_dbg_pgno(mp), indx, data ? data->mv_size : 0, @@ -7971,7 +8205,7 @@ mdb_node_add(MDB_cursor *mc, indx_t indx, goto full; if ((rc = mdb_page_new(mc, P_OVERFLOW, ovpages, &ofp))) return rc; - DPRINTF(("allocated overflow page %"Y"u", ofp->mp_pgno)); + DPRINTF(("allocated overflow page %"Yu, ofp->mp_pgno)); flags |= F_BIGDATA; goto update; } else { @@ -8028,7 +8262,7 @@ update: return MDB_SUCCESS; full: - DPRINTF(("not enough room in page %"Y"u, got %u ptrs", + DPRINTF(("not enough room in page %"Yu", got %u ptrs", mdb_dbg_pgno(mp), NUMKEYS(mp))); DPRINTF(("upper-lower = %u - %u = %"Z"d", mp->mp_upper,mp->mp_lower,room)); DPRINTF(("node size = %"Z"u", node_size)); @@ -8051,7 +8285,7 @@ mdb_node_del(MDB_cursor *mc, int ksize) MDB_node *node; char *base; - DPRINTF(("delete node %u on %s page %"Y"u", indx, + DPRINTF(("delete node %u on %s page %"Yu, indx, IS_LEAF(mp) ? "leaf" : "branch", mdb_dbg_pgno(mp))); numkeys = NUMKEYS(mp); mdb_cassert(mc, indx < numkeys); @@ -8160,9 +8394,7 @@ mdb_xcursor_init0(MDB_cursor *mc) mx->mx_cursor.mc_dbflag = &mx->mx_dbflag; mx->mx_cursor.mc_snum = 0; mx->mx_cursor.mc_top = 0; -#ifdef MDB_VL32 - mx->mx_cursor.mc_ovpg = 0; -#endif + MC_SET_OVPG(&mx->mx_cursor, NULL); mx->mx_cursor.mc_flags = C_SUB | (mc->mc_flags & (C_ORIG_RDONLY|C_WRITEMAP)); mx->mx_dbx.md_name.mv_size = 0; mx->mx_dbx.md_name.mv_data = NULL; @@ -8210,13 +8442,11 @@ mdb_xcursor_init1(MDB_cursor *mc, MDB_node *node) mx->mx_db.md_flags |= MDB_INTEGERKEY; } } - DPRINTF(("Sub-db -%u root page %"Y"u", mx->mx_cursor.mc_dbi, + DPRINTF(("Sub-db -%u root page %"Yu, mx->mx_cursor.mc_dbi, mx->mx_db.md_root)); - mx->mx_dbflag = DB_VALID|DB_USRVALID|DB_DIRTY; /* DB_DIRTY guides mdb_cursor_touch */ -#if UINT_MAX < SIZE_MAX || defined(MDB_VL32) - if (mx->mx_dbx.md_cmp == mdb_cmp_int && mx->mx_db.md_pad == sizeof(mdb_size_t)) + mx->mx_dbflag = DB_VALID|DB_USRVALID|DB_DUPDATA; + if (NEED_CMP_CLONG(mx->mx_dbx.md_cmp, mx->mx_db.md_pad)) mx->mx_dbx.md_cmp = mdb_cmp_clong; -#endif } @@ -8238,8 +8468,8 @@ mdb_xcursor_init2(MDB_cursor *mc, MDB_xcursor *src_mx, int new_dupdata) mx->mx_cursor.mc_top = 0; mx->mx_cursor.mc_flags |= C_INITIALIZED; mx->mx_cursor.mc_ki[0] = 0; - mx->mx_dbflag = DB_VALID|DB_USRVALID|DB_DIRTY; /* DB_DIRTY guides mdb_cursor_touch */ -#if UINT_MAX < SIZE_MAX + mx->mx_dbflag = DB_VALID|DB_USRVALID|DB_DUPDATA; +#if UINT_MAX < MDB_SIZE_MAX /* matches mdb_xcursor_init1:NEED_CMP_CLONG() */ mx->mx_dbx.md_cmp = src_mx->mx_dbx.md_cmp; #endif } else if (!(mx->mx_cursor.mc_flags & C_INITIALIZED)) { @@ -8247,7 +8477,7 @@ mdb_xcursor_init2(MDB_cursor *mc, MDB_xcursor *src_mx, int new_dupdata) } mx->mx_db = src_mx->mx_db; mx->mx_cursor.mc_pg[0] = src_mx->mx_cursor.mc_pg[0]; - DPRINTF(("Sub-db -%u root page %"Y"u", mx->mx_cursor.mc_dbi, + DPRINTF(("Sub-db -%u root page %"Yu, mx->mx_cursor.mc_dbi, mx->mx_db.md_root)); } @@ -8266,9 +8496,7 @@ mdb_cursor_init(MDB_cursor *mc, MDB_txn *txn, MDB_dbi dbi, MDB_xcursor *mx) mc->mc_top = 0; mc->mc_pg[0] = 0; mc->mc_ki[0] = 0; -#ifdef MDB_VL32 - mc->mc_ovpg = 0; -#endif + MC_SET_OVPG(mc, NULL); mc->mc_flags = txn->mt_flags & (C_ORIG_RDONLY|C_WRITEMAP); if (txn->mt_dbs[dbi].md_flags & MDB_DUPSORT) { mdb_tassert(txn, mx != NULL); @@ -8350,9 +8578,15 @@ mdb_cursor_count(MDB_cursor *mc, mdb_size_t *countp) if (!(mc->mc_flags & C_INITIALIZED)) return EINVAL; - if (!mc->mc_snum || (mc->mc_flags & C_EOF)) + if (!mc->mc_snum) return MDB_NOTFOUND; + if (mc->mc_flags & C_EOF) { + if (mc->mc_ki[mc->mc_top] >= NUMKEYS(mc->mc_pg[mc->mc_top])) + return MDB_NOTFOUND; + mc->mc_flags ^= C_EOF; + } + leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); if (!F_ISSET(leaf->mn_flags, F_DUPDATA)) { *countp = 1; @@ -8368,13 +8602,14 @@ mdb_cursor_count(MDB_cursor *mc, mdb_size_t *countp) void mdb_cursor_close(MDB_cursor *mc) { -#ifdef MDB_VL32 if (mc) { - mdb_cursor_unref(mc); + MDB_CURSOR_UNREF(mc, 0); } -#endif if (mc && !mc->mc_backup) { - /* remove from txn, if tracked */ + /* Remove from txn, if tracked. + * A read-only txn (!C_UNTRACK) may have been freed already, + * so do not peek inside it. Only write txns track cursors. + */ if ((mc->mc_flags & C_UNTRACK) && mc->mc_txn->mt_cursors) { MDB_cursor **prev = &mc->mc_txn->mt_cursors[mc->mc_dbi]; while (*prev && *prev != mc) prev = &(*prev)->mc_next; @@ -8399,6 +8634,7 @@ mdb_cursor_dbi(MDB_cursor *mc) } /** Replace the key for a branch node with a new key. + * Set #MDB_TXN_ERROR on failure. * @param[in] mc Cursor pointing to the node to operate on. * @param[in] key The new key to use. * @return 0 on success, non-zero on failure. @@ -8424,7 +8660,7 @@ mdb_update_key(MDB_cursor *mc, MDB_val *key) char kbuf2[DKBUF_MAXKEYSIZE*2+1]; k2.mv_data = NODEKEY(node); k2.mv_size = node->mn_ksize; - DPRINTF(("update key %u (ofs %u) [%s] to [%s] on page %"Y"u", + DPRINTF(("update key %u (ofs %u) [%s] to [%s] on page %"Yu, indx, ptr, mdb_dkey(&k2, kbuf2), DKEY(key), @@ -8572,7 +8808,7 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft) return rc; } - DPRINTF(("moving %s node %u [%s] on page %"Y"u to node %u on page %"Y"u", + DPRINTF(("moving %s node %u [%s] on page %"Yu" to node %u on page %"Yu, IS_LEAF(csrc->mc_pg[csrc->mc_top]) ? "leaf" : "branch", csrc->mc_ki[csrc->mc_top], DKEY(&key), @@ -8618,12 +8854,8 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft) m3->mc_ki[csrc->mc_top] = cdst->mc_ki[cdst->mc_top]; m3->mc_ki[csrc->mc_top-1]++; } - if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) && - IS_LEAF(mps)) { - MDB_node *node = NODEPTR(m3->mc_pg[csrc->mc_top], m3->mc_ki[csrc->mc_top]); - if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) - m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node); - } + if (IS_LEAF(mps)) + XCURSOR_REFRESH(m3, csrc->mc_top, m3->mc_pg[csrc->mc_top]); } } else /* Adding on the right, bump others down */ @@ -8644,12 +8876,8 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft) } else { m3->mc_ki[csrc->mc_top]--; } - if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) && - IS_LEAF(mps)) { - MDB_node *node = NODEPTR(m3->mc_pg[csrc->mc_top], m3->mc_ki[csrc->mc_top]); - if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) - m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node); - } + if (IS_LEAF(mps)) + XCURSOR_REFRESH(m3, csrc->mc_top, m3->mc_pg[csrc->mc_top]); } } } @@ -8666,7 +8894,7 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft) key.mv_size = NODEKSZ(srcnode); key.mv_data = NODEKEY(srcnode); } - DPRINTF(("update separator for source page %"Y"u to [%s]", + DPRINTF(("update separator for source page %"Yu" to [%s]", csrc->mc_pg[csrc->mc_top]->mp_pgno, DKEY(&key))); mdb_cursor_copy(csrc, &mn); mn.mc_snum--; @@ -8697,7 +8925,7 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft) key.mv_size = NODEKSZ(srcnode); key.mv_data = NODEKEY(srcnode); } - DPRINTF(("update separator for destination page %"Y"u to [%s]", + DPRINTF(("update separator for destination page %"Yu" to [%s]", cdst->mc_pg[cdst->mc_top]->mp_pgno, DKEY(&key))); mdb_cursor_copy(cdst, &mn); mn.mc_snum--; @@ -8743,7 +8971,7 @@ mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst) psrc = csrc->mc_pg[csrc->mc_top]; pdst = cdst->mc_pg[cdst->mc_top]; - DPRINTF(("merging page %"Y"u into %"Y"u", psrc->mp_pgno, pdst->mp_pgno)); + DPRINTF(("merging page %"Yu" into %"Yu, psrc->mp_pgno, pdst->mp_pgno)); mdb_cassert(csrc, csrc->mc_snum > 1); /* can't merge root page */ mdb_cassert(csrc, cdst->mc_snum > 1); @@ -8800,7 +9028,7 @@ mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst) } } - DPRINTF(("dst page %"Y"u now has %u keys (%.1f%% filled)", + DPRINTF(("dst page %"Yu" now has %u keys (%.1f%% filled)", pdst->mp_pgno, NUMKEYS(pdst), (float)PAGEFILL(cdst->mc_txn->mt_env, pdst) / 10)); @@ -8850,12 +9078,8 @@ mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst) m3->mc_ki[top-1] > csrc->mc_ki[top-1]) { m3->mc_ki[top-1]--; } - if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) && - IS_LEAF(psrc)) { - MDB_node *node = NODEPTR(m3->mc_pg[top], m3->mc_ki[top]); - if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) - m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node); - } + if (IS_LEAF(psrc)) + XCURSOR_REFRESH(m3, top, m3->mc_pg[top]); } } { @@ -8888,9 +9112,7 @@ mdb_cursor_copy(const MDB_cursor *csrc, MDB_cursor *cdst) cdst->mc_snum = csrc->mc_snum; cdst->mc_top = csrc->mc_top; cdst->mc_flags = csrc->mc_flags; -#ifdef MDB_VL32 - cdst->mc_ovpg = csrc->mc_ovpg; -#endif + MC_SET_OVPG(cdst, MC_OVPG(csrc)); for (i=0; i<csrc->mc_snum; i++) { cdst->mc_pg[i] = csrc->mc_pg[i]; @@ -8919,14 +9141,14 @@ mdb_rebalance(MDB_cursor *mc) minkeys = 1; thresh = FILL_THRESHOLD; } - DPRINTF(("rebalancing %s page %"Y"u (has %u keys, %.1f%% full)", + DPRINTF(("rebalancing %s page %"Yu" (has %u keys, %.1f%% full)", IS_LEAF(mc->mc_pg[mc->mc_top]) ? "leaf" : "branch", mdb_dbg_pgno(mc->mc_pg[mc->mc_top]), NUMKEYS(mc->mc_pg[mc->mc_top]), (float)PAGEFILL(mc->mc_txn->mt_env, mc->mc_pg[mc->mc_top]) / 10)); if (PAGEFILL(mc->mc_txn->mt_env, mc->mc_pg[mc->mc_top]) >= thresh && NUMKEYS(mc->mc_pg[mc->mc_top]) >= minkeys) { - DPRINTF(("no need to rebalance page %"Y"u, above fill threshold", + DPRINTF(("no need to rebalance page %"Yu", above fill threshold", mdb_dbg_pgno(mc->mc_pg[mc->mc_top]))); return MDB_SUCCESS; } @@ -9055,7 +9277,7 @@ mdb_rebalance(MDB_cursor *mc) fromleft = 1; } - DPRINTF(("found neighbor page %"Y"u (%u keys, %.1f%% full)", + DPRINTF(("found neighbor page %"Yu" (%u keys, %.1f%% full)", mn.mc_pg[mn.mc_top]->mp_pgno, NUMKEYS(mn.mc_pg[mn.mc_top]), (float)PAGEFILL(mc->mc_txn->mt_env, mn.mc_pg[mn.mc_top]) / 10)); @@ -9112,16 +9334,15 @@ mdb_cursor_del0(MDB_cursor *mc) if (m3->mc_pg[mc->mc_top] == mp) { if (m3->mc_ki[mc->mc_top] == ki) { m3->mc_flags |= C_DEL; - if (mc->mc_db->md_flags & MDB_DUPSORT) - m3->mc_xcursor->mx_cursor.mc_flags &= ~C_INITIALIZED; + if (mc->mc_db->md_flags & MDB_DUPSORT) { + /* Sub-cursor referred into dataset which is gone */ + m3->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF); + } + continue; } else if (m3->mc_ki[mc->mc_top] > ki) { m3->mc_ki[mc->mc_top]--; } - if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) { - MDB_node *node = NODEPTR(m3->mc_pg[mc->mc_top], m3->mc_ki[mc->mc_top]); - if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) - m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node); - } + XCURSOR_REFRESH(m3, mc->mc_top, mp); } } } @@ -9147,11 +9368,32 @@ mdb_cursor_del0(MDB_cursor *mc) continue; if (m3->mc_pg[mc->mc_top] == mp) { /* if m3 points past last node in page, find next sibling */ - if (m3->mc_ki[mc->mc_top] >= nkeys) { - rc = mdb_cursor_sibling(m3, 1); - if (rc == MDB_NOTFOUND) { - m3->mc_flags |= C_EOF; - rc = MDB_SUCCESS; + if (m3->mc_ki[mc->mc_top] >= mc->mc_ki[mc->mc_top]) { + if (m3->mc_ki[mc->mc_top] >= nkeys) { + rc = mdb_cursor_sibling(m3, 1); + if (rc == MDB_NOTFOUND) { + m3->mc_flags |= C_EOF; + rc = MDB_SUCCESS; + continue; + } + } + if (mc->mc_db->md_flags & MDB_DUPSORT) { + MDB_node *node = NODEPTR(m3->mc_pg[m3->mc_top], m3->mc_ki[m3->mc_top]); + /* If this node has dupdata, it may need to be reinited + * because its data has moved. + * If the xcursor was not initd it must be reinited. + * Else if node points to a subDB, nothing is needed. + * Else (xcursor was initd, not a subDB) needs mc_pg[0] reset. + */ + if (node->mn_flags & F_DUPDATA) { + if (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) { + if (!(node->mn_flags & F_SUBDATA)) + m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node); + } else { + mdb_xcursor_init1(m3, node); + m3->mc_xcursor->mx_cursor.mc_flags |= C_DEL; + } + } } } } @@ -9216,7 +9458,6 @@ mdb_del0(MDB_txn *txn, MDB_dbi dbi, * run out of space, triggering a split. We need this * cursor to be consistent until the end of the rebalance. */ - mc.mc_flags |= C_UNTRACK; mc.mc_next = txn->mt_cursors[dbi]; txn->mt_cursors[dbi] = &mc; rc = mdb_cursor_del(&mc, flags); @@ -9226,6 +9467,7 @@ mdb_del0(MDB_txn *txn, MDB_dbi dbi, } /** Split a page and insert a new node. + * Set #MDB_TXN_ERROR on failure. * @param[in,out] mc Cursor pointing to the page and desired insertion index. * The cursor will be updated to point to the actual page and index where * the node got inserted after the split. @@ -9257,7 +9499,7 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno newindx = mc->mc_ki[mc->mc_top]; nkeys = NUMKEYS(mp); - DPRINTF(("-----> splitting %s page %"Y"u and adding [%s] at index %i/%i", + DPRINTF(("-----> splitting %s page %"Yu" and adding [%s] at index %i/%i", IS_LEAF(mp) ? "leaf" : "branch", mp->mp_pgno, DKEY(newkey), mc->mc_ki[mc->mc_top], nkeys)); @@ -9265,7 +9507,7 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno if ((rc = mdb_page_new(mc, mp->mp_flags, 1, &rp))) return rc; rp->mp_pad = mp->mp_pad; - DPRINTF(("new right sibling: page %"Y"u", rp->mp_pgno)); + DPRINTF(("new right sibling: page %"Yu, rp->mp_pgno)); /* Usually when splitting the root page, the cursor * height is 1. But when called from mdb_update_key, @@ -9283,7 +9525,7 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno mc->mc_pg[0] = pp; mc->mc_ki[0] = 0; mc->mc_db->md_root = pp->mp_pgno; - DPRINTF(("root split! new root = %"Y"u", pp->mp_pgno)); + DPRINTF(("root split! new root = %"Yu, pp->mp_pgno)); new_root = mc->mc_db->md_depth++; /* Add left (implicit) pointer. */ @@ -9300,7 +9542,7 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno ptop = 0; } else { ptop = mc->mc_top-1; - DPRINTF(("parent branch page is %"Y"u", mc->mc_pg[ptop]->mp_pgno)); + DPRINTF(("parent branch page is %"Yu, mc->mc_pg[ptop]->mp_pgno)); } mdb_cursor_copy(mc, &mn); @@ -9475,7 +9717,7 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno } else { /* find right page's left sibling */ mc->mc_ki[ptop] = mn.mc_ki[ptop]; - mdb_cursor_sibling(mc, 0); + rc = mdb_cursor_sibling(mc, 0); } } } else { @@ -9484,6 +9726,8 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno mn.mc_top++; } if (rc != MDB_SUCCESS) { + if (rc == MDB_NOTFOUND) /* improper mdb_cursor_sibling() result */ + rc = MDB_PROBLEM; goto done; } if (nflags & MDB_APPEND) { @@ -9635,12 +9879,8 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno m3->mc_ki[ptop] >= mc->mc_ki[ptop]) { m3->mc_ki[ptop]++; } - if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) && - IS_LEAF(mp)) { - MDB_node *node = NODEPTR(m3->mc_pg[mc->mc_top], m3->mc_ki[mc->mc_top]); - if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) - m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node); - } + if (IS_LEAF(mp)) + XCURSOR_REFRESH(m3, mc->mc_top, m3->mc_pg[mc->mc_top]); } } DPRINTF(("mp left: %d, rp left: %d", SIZELEFT(mp), SIZELEFT(rp))); @@ -9681,23 +9921,26 @@ mdb_put(MDB_txn *txn, MDB_dbi dbi, #ifndef MDB_WBUF #define MDB_WBUF (1024*1024) #endif +#define MDB_EOF 0x10 /**< #mdb_env_copyfd1() is done reading */ - /** State needed for a compacting copy. */ + /** State needed for a double-buffering compacting copy. */ typedef struct mdb_copy { + MDB_env *mc_env; + MDB_txn *mc_txn; pthread_mutex_t mc_mutex; - pthread_cond_t mc_cond; + pthread_cond_t mc_cond; /**< Condition variable for #mc_new */ char *mc_wbuf[2]; char *mc_over[2]; - MDB_env *mc_env; - MDB_txn *mc_txn; int mc_wlen[2]; int mc_olen[2]; pgno_t mc_next_pgno; HANDLE mc_fd; - int mc_status; - volatile int mc_new; - int mc_toggle; - + int mc_toggle; /**< Buffer number in provider */ + int mc_new; /**< (0-2 buffers to write) | (#MDB_EOF at end) */ + /** Error code. Never cleared if set. Both threads can set nonzero + * to fail the copy. Not mutex-protected, LMDB expects atomic int. + */ + volatile int mc_error; } mdb_copy; /** Dedicated writer thread for compacting copy. */ @@ -9713,26 +9956,38 @@ mdb_env_copythr(void *arg) #else int len; #define DO_WRITE(rc, fd, ptr, w2, len) len = write(fd, ptr, w2); rc = (len >= 0) +#ifdef SIGPIPE + sigset_t set; + sigemptyset(&set); + sigaddset(&set, SIGPIPE); + if ((rc = pthread_sigmask(SIG_BLOCK, &set, NULL)) != 0) + my->mc_error = rc; +#endif #endif pthread_mutex_lock(&my->mc_mutex); - my->mc_new = 0; - pthread_cond_signal(&my->mc_cond); for(;;) { while (!my->mc_new) pthread_cond_wait(&my->mc_cond, &my->mc_mutex); - if (my->mc_new < 0) { - my->mc_new = 0; + if (my->mc_new == 0 + MDB_EOF) /* 0 buffers, just EOF */ break; - } - my->mc_new = 0; wsize = my->mc_wlen[toggle]; ptr = my->mc_wbuf[toggle]; again: - while (wsize > 0) { + rc = MDB_SUCCESS; + while (wsize > 0 && !my->mc_error) { DO_WRITE(rc, my->mc_fd, ptr, wsize, len); if (!rc) { rc = ErrCode(); +#if defined(SIGPIPE) && !defined(_WIN32) + if (rc == EPIPE) { + /* Collect the pending SIGPIPE, otherwise at least OS X + * gives it to the process on thread-exit (ITS#8504). + */ + int tmp; + sigwait(&set, &tmp); + } +#endif break; } else if (len > 0) { rc = MDB_SUCCESS; @@ -9745,8 +10000,7 @@ again: } } if (rc) { - my->mc_status = rc; - break; + my->mc_error = rc; } /* If there's an overflow page tail, write it too */ if (my->mc_olen[toggle]) { @@ -9757,38 +10011,45 @@ again: } my->mc_wlen[toggle] = 0; toggle ^= 1; + /* Return the empty buffer to provider */ + my->mc_new--; pthread_cond_signal(&my->mc_cond); } - pthread_cond_signal(&my->mc_cond); pthread_mutex_unlock(&my->mc_mutex); return (THREAD_RET)0; #undef DO_WRITE } - /** Tell the writer thread there's a buffer ready to write */ + /** Give buffer and/or #MDB_EOF to writer thread, await unused buffer. + * + * @param[in] my control structure. + * @param[in] adjust (1 to hand off 1 buffer) | (MDB_EOF when ending). + */ static int ESECT -mdb_env_cthr_toggle(mdb_copy *my, int st) +mdb_env_cthr_toggle(mdb_copy *my, int adjust) { - int toggle = my->mc_toggle ^ 1; pthread_mutex_lock(&my->mc_mutex); - if (my->mc_status) { - pthread_mutex_unlock(&my->mc_mutex); - return my->mc_status; - } - while (my->mc_new == 1) - pthread_cond_wait(&my->mc_cond, &my->mc_mutex); - my->mc_new = st; - my->mc_toggle = toggle; + my->mc_new += adjust; pthread_cond_signal(&my->mc_cond); + while (my->mc_new & 2) /* both buffers in use */ + pthread_cond_wait(&my->mc_cond, &my->mc_mutex); pthread_mutex_unlock(&my->mc_mutex); - return 0; + + my->mc_toggle ^= (adjust & 1); + /* Both threads reset mc_wlen, to be safe from threading errors */ + my->mc_wlen[my->mc_toggle] = 0; + return my->mc_error; } - /** Depth-first tree traversal for compacting copy. */ + /** Depth-first tree traversal for compacting copy. + * @param[in] my control structure. + * @param[in,out] pg database root. + * @param[in] flags includes #F_DUPDATA if it is a sorted-duplicate sub-DB. + */ static int ESECT mdb_env_cwalk(mdb_copy *my, pgno_t *pg, int flags) { - MDB_cursor mc; + MDB_cursor mc = {0}; MDB_node *ni; MDB_page *mo, *mp, *leaf; char *buf, *ptr; @@ -9800,8 +10061,8 @@ mdb_env_cwalk(mdb_copy *my, pgno_t *pg, int flags) return MDB_SUCCESS; mc.mc_snum = 1; - mc.mc_top = 0; mc.mc_txn = my->mc_txn; + mc.mc_flags = my->mc_txn->mt_flags & (C_ORIG_RDONLY|C_WRITEMAP); rc = mdb_page_get(&mc, *pg, &mc.mc_pg[0], NULL); if (rc) @@ -9847,6 +10108,7 @@ mdb_env_cwalk(mdb_copy *my, pgno_t *pg, int flags) } memcpy(&pg, NODEDATA(ni), sizeof(pg)); + memcpy(NODEDATA(ni), &my->mc_next_pgno, sizeof(pgno_t)); rc = mdb_page_get(&mc, pg, &omp, NULL); if (rc) goto done; @@ -9869,7 +10131,6 @@ mdb_env_cwalk(mdb_copy *my, pgno_t *pg, int flags) goto done; toggle = my->mc_toggle; } - memcpy(NODEDATA(ni), &mo->mp_pgno, sizeof(pgno_t)); } else if (ni->mn_flags & F_SUBDATA) { MDB_db db; @@ -9947,47 +10208,56 @@ mdb_env_copyfd1(MDB_env *env, HANDLE fd) { MDB_meta *mm; MDB_page *mp; - mdb_copy my; + mdb_copy my = {0}; MDB_txn *txn = NULL; pthread_t thr; - int rc; + pgno_t root, new_root; + int rc = MDB_SUCCESS; #ifdef _WIN32 - my.mc_mutex = CreateMutex(NULL, FALSE, NULL); - my.mc_cond = CreateEvent(NULL, FALSE, FALSE, NULL); + if (!(my.mc_mutex = CreateMutex(NULL, FALSE, NULL)) || + !(my.mc_cond = CreateEvent(NULL, FALSE, FALSE, NULL))) { + rc = ErrCode(); + goto done; + } my.mc_wbuf[0] = _aligned_malloc(MDB_WBUF*2, env->me_os_psize); - if (my.mc_wbuf[0] == NULL) - return errno; + if (my.mc_wbuf[0] == NULL) { + /* _aligned_malloc() sets errno, but we use Windows error codes */ + rc = ERROR_NOT_ENOUGH_MEMORY; + goto done; + } #else - pthread_mutex_init(&my.mc_mutex, NULL); - pthread_cond_init(&my.mc_cond, NULL); + if ((rc = pthread_mutex_init(&my.mc_mutex, NULL)) != 0) + return rc; + if ((rc = pthread_cond_init(&my.mc_cond, NULL)) != 0) + goto done2; #ifdef HAVE_MEMALIGN my.mc_wbuf[0] = memalign(env->me_os_psize, MDB_WBUF*2); - if (my.mc_wbuf[0] == NULL) - return errno; + if (my.mc_wbuf[0] == NULL) { + rc = errno; + goto done; + } #else - rc = posix_memalign((void **)&my.mc_wbuf[0], env->me_os_psize, MDB_WBUF*2); - if (rc) - return rc; + { + void *p; + if ((rc = posix_memalign(&p, env->me_os_psize, MDB_WBUF*2)) != 0) + goto done; + my.mc_wbuf[0] = p; + } #endif #endif memset(my.mc_wbuf[0], 0, MDB_WBUF*2); my.mc_wbuf[1] = my.mc_wbuf[0] + MDB_WBUF; - my.mc_wlen[0] = 0; - my.mc_wlen[1] = 0; - my.mc_olen[0] = 0; - my.mc_olen[1] = 0; my.mc_next_pgno = NUM_METAS; - my.mc_status = 0; - my.mc_new = 1; - my.mc_toggle = 0; my.mc_env = env; my.mc_fd = fd; - THREAD_CREATE(thr, mdb_env_copythr, &my); + rc = THREAD_CREATE(thr, mdb_env_copythr, &my); + if (rc) + goto done; rc = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn); if (rc) - return rc; + goto finish; mp = (MDB_page *)my.mc_wbuf[0]; memset(mp, 0, NUM_METAS * env->me_psize); @@ -10003,57 +10273,64 @@ mdb_env_copyfd1(MDB_env *env, HANDLE fd) *(MDB_meta *)METADATA(mp) = *mm; mm = (MDB_meta *)METADATA(mp); - /* Count the number of free pages, subtract from lastpg to find - * number of active pages - */ - { + /* Set metapage 1 with current main DB */ + root = new_root = txn->mt_dbs[MAIN_DBI].md_root; + if (root != P_INVALID) { + /* Count free pages + freeDB pages. Subtract from last_pg + * to find the new last_pg, which also becomes the new root. + */ MDB_ID freecount = 0; MDB_cursor mc; MDB_val key, data; mdb_cursor_init(&mc, txn, FREE_DBI, NULL); while ((rc = mdb_cursor_get(&mc, &key, &data, MDB_NEXT)) == 0) freecount += *(MDB_ID *)data.mv_data; + if (rc != MDB_NOTFOUND) + goto finish; freecount += txn->mt_dbs[FREE_DBI].md_branch_pages + txn->mt_dbs[FREE_DBI].md_leaf_pages + txn->mt_dbs[FREE_DBI].md_overflow_pages; - /* Set metapage 1 */ - mm->mm_last_pg = txn->mt_next_pgno - freecount - 1; + new_root = txn->mt_next_pgno - 1 - freecount; + mm->mm_last_pg = new_root; mm->mm_dbs[MAIN_DBI] = txn->mt_dbs[MAIN_DBI]; - if (mm->mm_last_pg > NUM_METAS-1) { - mm->mm_dbs[MAIN_DBI].md_root = mm->mm_last_pg; - mm->mm_txnid = 1; - } else { - mm->mm_dbs[MAIN_DBI].md_root = P_INVALID; - } + mm->mm_dbs[MAIN_DBI].md_root = new_root; + } else { + /* When the DB is empty, handle it specially to + * fix any breakage like page leaks from ITS#8174. + */ + mm->mm_dbs[MAIN_DBI].md_flags = txn->mt_dbs[MAIN_DBI].md_flags; + } + if (root != P_INVALID || mm->mm_dbs[MAIN_DBI].md_flags) { + mm->mm_txnid = 1; /* use metapage 1 */ } + my.mc_wlen[0] = env->me_psize * NUM_METAS; my.mc_txn = txn; - pthread_mutex_lock(&my.mc_mutex); - while(my.mc_new) - pthread_cond_wait(&my.mc_cond, &my.mc_mutex); - pthread_mutex_unlock(&my.mc_mutex); - rc = mdb_env_cwalk(&my, &txn->mt_dbs[MAIN_DBI].md_root, 0); - if (rc == MDB_SUCCESS && my.mc_wlen[my.mc_toggle]) - rc = mdb_env_cthr_toggle(&my, 1); - mdb_env_cthr_toggle(&my, -1); - pthread_mutex_lock(&my.mc_mutex); - while(my.mc_new) - pthread_cond_wait(&my.mc_cond, &my.mc_mutex); - pthread_mutex_unlock(&my.mc_mutex); - THREAD_FINISH(thr); + rc = mdb_env_cwalk(&my, &root, 0); + if (rc == MDB_SUCCESS && root != new_root) { + rc = MDB_INCOMPATIBLE; /* page leak or corrupt DB */ + } +finish: + if (rc) + my.mc_error = rc; + mdb_env_cthr_toggle(&my, 1 | MDB_EOF); + rc = THREAD_FINISH(thr); mdb_txn_abort(txn); + +done: #ifdef _WIN32 - CloseHandle(my.mc_cond); - CloseHandle(my.mc_mutex); - _aligned_free(my.mc_wbuf[0]); + if (my.mc_wbuf[0]) _aligned_free(my.mc_wbuf[0]); + if (my.mc_cond) CloseHandle(my.mc_cond); + if (my.mc_mutex) CloseHandle(my.mc_mutex); #else + free(my.mc_wbuf[0]); pthread_cond_destroy(&my.mc_cond); +done2: pthread_mutex_destroy(&my.mc_mutex); - free(my.mc_wbuf[0]); #endif - return rc; + return rc ? rc : my.mc_error; } /** Copy environment as-is. */ @@ -10174,67 +10451,20 @@ mdb_env_copyfd(MDB_env *env, HANDLE fd) int ESECT mdb_env_copy2(MDB_env *env, const char *path, unsigned int flags) { - int rc, len; - char *lpath; + int rc; + MDB_name fname; HANDLE newfd = INVALID_HANDLE_VALUE; -#ifdef _WIN32 - wchar_t *wpath; -#endif - - if (env->me_flags & MDB_NOSUBDIR) { - lpath = (char *)path; - } else { - len = strlen(path); - len += sizeof(DATANAME); - lpath = malloc(len); - if (!lpath) - return ENOMEM; - sprintf(lpath, "%s" DATANAME, path); - } - /* The destination path must exist, but the destination file must not. - * We don't want the OS to cache the writes, since the source data is - * already in the OS cache. - */ -#ifdef _WIN32 - rc = utf8_to_utf16(lpath, -1, &wpath, NULL); - if (rc) - goto leave; - newfd = CreateFileW(wpath, GENERIC_WRITE, 0, NULL, CREATE_NEW, - FILE_FLAG_NO_BUFFERING|FILE_FLAG_WRITE_THROUGH, NULL); - free(wpath); -#else - newfd = open(lpath, O_WRONLY|O_CREAT|O_EXCL, 0666); -#endif - if (newfd == INVALID_HANDLE_VALUE) { - rc = ErrCode(); - goto leave; - } - - if (env->me_psize >= env->me_os_psize) { -#ifdef O_DIRECT - /* Set O_DIRECT if the file system supports it */ - if ((rc = fcntl(newfd, F_GETFL)) != -1) - (void) fcntl(newfd, F_SETFL, rc | O_DIRECT); -#endif -#ifdef F_NOCACHE /* __APPLE__ */ - rc = fcntl(newfd, F_NOCACHE, 1); - if (rc) { - rc = ErrCode(); - goto leave; - } -#endif + rc = mdb_fname_init(path, env->me_flags | MDB_NOLOCK, &fname); + if (rc == MDB_SUCCESS) { + rc = mdb_fopen(env, &fname, MDB_O_COPY, 0666, &newfd); + mdb_fname_destroy(fname); } - - rc = mdb_env_copyfd2(env, newfd, flags); - -leave: - if (!(env->me_flags & MDB_NOSUBDIR)) - free(lpath); - if (newfd != INVALID_HANDLE_VALUE) + if (rc == MDB_SUCCESS) { + rc = mdb_env_copyfd2(env, newfd, flags); if (close(newfd) < 0 && rc == MDB_SUCCESS) rc = ErrCode(); - + } return rc; } @@ -10456,8 +10686,11 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *db MDB_node *node = NODEPTR(mc.mc_pg[mc.mc_top], mc.mc_ki[mc.mc_top]); if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) != F_SUBDATA) return MDB_INCOMPATIBLE; - } else if (! (rc == MDB_NOTFOUND && (flags & MDB_CREATE))) { - return rc; + } else { + if (rc != MDB_NOTFOUND || !(flags & MDB_CREATE)) + return rc; + if (F_ISSET(txn->mt_flags, MDB_TXN_RDONLY)) + return EACCES; } /* Done here so we cannot fail after creating a new DB */ @@ -10471,7 +10704,8 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *db memset(&dummy, 0, sizeof(dummy)); dummy.md_root = P_INVALID; dummy.md_flags = flags & PERSISTENT_FLAGS; - rc = mdb_cursor_put(&mc, &key, &data, F_SUBDATA); + WITH_CURSOR_TRACKING(mc, + rc = mdb_cursor_put(&mc, &key, &data, F_SUBDATA)); dbflag |= DB_DIRTY; } @@ -10641,10 +10875,8 @@ pop: done: if (rc) txn->mt_flags |= MDB_TXN_ERROR; -#ifdef MDB_VL32 /* drop refcount for mx's pages */ - mdb_cursor_unref(&mx); -#endif + MDB_CURSOR_UNREF(&mx, 0); } else if (rc == MDB_NOTFOUND) { rc = MDB_SUCCESS; } @@ -10764,7 +10996,7 @@ mdb_reader_list(MDB_env *env, MDB_msg_func *func, void *ctx) if (mr[i].mr_pid) { txnid_t txnid = mr[i].mr_txnid; sprintf(buf, txnid == (txnid_t)-1 ? - "%10d %"Z"x -\n" : "%10d %"Z"x %"Y"u\n", + "%10d %"Z"x -\n" : "%10d %"Z"x %"Yu"\n", (int)mr[i].mr_pid, (size_t)mr[i].mr_tid, txnid); if (first) { first = 0; @@ -10833,7 +11065,7 @@ mdb_reader_check(MDB_env *env, int *dead) return env->me_txns ? mdb_reader_check0(env, 0, dead) : MDB_SUCCESS; } -/** As #mdb_reader_check(). rlocked = <caller locked the reader mutex>. */ +/** As #mdb_reader_check(). \b rlocked is set if caller locked #me_rmutex. */ static int ESECT mdb_reader_check0(MDB_env *env, int rlocked, int *dead) { @@ -10869,7 +11101,7 @@ mdb_reader_check0(MDB_env *env, int rlocked, int *dead) } for (; j<rdrs; j++) if (mr[j].mr_pid == pid) { - DPRINTF(("clear stale reader pid %u txn %"Y"d", + DPRINTF(("clear stale reader pid %u txn %"Yd, (unsigned) pid, mr[j].mr_txnid)); mr[j].mr_pid = 0; count++; @@ -10936,25 +11168,32 @@ mdb_mutex_failed(MDB_env *env, mdb_mutexref_t mutex, int rc) return rc; } #endif /* MDB_ROBUST_SUPPORTED */ -/** @} */ #if defined(_WIN32) -static int utf8_to_utf16(const char *src, int srcsize, wchar_t **dst, int *dstsize) -{ - int need; - wchar_t *result; - need = MultiByteToWideChar(CP_UTF8, 0, src, srcsize, NULL, 0); - if (need == 0xFFFD) - return EILSEQ; - if (need == 0) - return EINVAL; - result = malloc(sizeof(wchar_t) * need); - if (!result) - return ENOMEM; - MultiByteToWideChar(CP_UTF8, 0, src, srcsize, result, need); - if (dstsize) - *dstsize = need; - *dst = result; - return 0; +/** Convert \b src to new wchar_t[] string with room for \b xtra extra chars */ +static int ESECT +utf8_to_utf16(const char *src, MDB_name *dst, int xtra) +{ + int rc, need = 0; + wchar_t *result = NULL; + for (;;) { /* malloc result, then fill it in */ + need = MultiByteToWideChar(CP_UTF8, 0, src, -1, result, need); + if (!need) { + rc = ErrCode(); + free(result); + return rc; + } + if (!result) { + result = malloc(sizeof(wchar_t) * (need + xtra)); + if (!result) + return ENOMEM; + continue; + } + dst->mn_alloced = 1; + dst->mn_len = need - 1; + dst->mn_val = result; + return MDB_SUCCESS; + } } #endif /* defined(_WIN32) */ +/** @} */ diff --git a/external/db_drivers/liblmdb/mdb_copy.1 b/external/db_drivers/liblmdb/mdb_copy.1 index 401e47abd..30e4754f1 100644 --- a/external/db_drivers/liblmdb/mdb_copy.1 +++ b/external/db_drivers/liblmdb/mdb_copy.1 @@ -1,5 +1,5 @@ -.TH MDB_COPY 1 "2014/06/20" "LMDB 0.9.14" -.\" Copyright 2012-2015 Howard Chu, Symas Corp. All Rights Reserved. +.TH MDB_COPY 1 "2017/07/31" "LMDB 0.9.70" +.\" Copyright 2012-2019 Howard Chu, Symas Corp. All Rights Reserved. .\" Copying restrictions apply. See COPYRIGHT/LICENSE. .SH NAME mdb_copy \- LMDB environment copy tool @@ -38,6 +38,7 @@ Write the library version number to the standard output, and exit. Compact while copying. Only current data pages will be copied; freed or unused pages will be omitted from the copy. This option will slow down the backup process as it is more CPU-intensive. +Currently it fails if the environment has suffered a page leak. .TP .BR \-n Open LDMB environment(s) which do not use subdirectories. diff --git a/external/db_drivers/liblmdb/mdb_copy.c b/external/db_drivers/liblmdb/mdb_copy.c index 95a6e7130..23be81506 100644 --- a/external/db_drivers/liblmdb/mdb_copy.c +++ b/external/db_drivers/liblmdb/mdb_copy.c @@ -1,6 +1,6 @@ /* mdb_copy.c - memory-mapped database backup tool */ /* - * Copyright 2012-2015 Howard Chu, Symas Corp. + * Copyright 2012-2018 Howard Chu, Symas Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/external/db_drivers/liblmdb/mdb_drop.1 b/external/db_drivers/liblmdb/mdb_drop.1 index 997e29118..10666e520 100644 --- a/external/db_drivers/liblmdb/mdb_drop.1 +++ b/external/db_drivers/liblmdb/mdb_drop.1 @@ -1,5 +1,5 @@ .TH MDB_DROP 1 "2017/11/19" "LMDB 0.9.70" -.\" Copyright 2014-2017 Howard Chu, Symas Corp. All Rights Reserved. +.\" Copyright 2014-2018 Howard Chu, Symas Corp. All Rights Reserved. .\" Copying restrictions apply. See COPYRIGHT/LICENSE. .SH NAME mdb_drop \- LMDB database delete tool diff --git a/external/db_drivers/liblmdb/mdb_drop.c b/external/db_drivers/liblmdb/mdb_drop.c index 725891685..7d2af4b62 100644 --- a/external/db_drivers/liblmdb/mdb_drop.c +++ b/external/db_drivers/liblmdb/mdb_drop.c @@ -1,6 +1,6 @@ /* mdb_drop.c - memory-mapped database delete tool */ /* - * Copyright 2016-2017 Howard Chu, Symas Corp. + * Copyright 2016-2018 Howard Chu, Symas Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/external/db_drivers/liblmdb/mdb_dump.1 b/external/db_drivers/liblmdb/mdb_dump.1 index a25fb92e9..424ad9321 100644 --- a/external/db_drivers/liblmdb/mdb_dump.1 +++ b/external/db_drivers/liblmdb/mdb_dump.1 @@ -1,5 +1,5 @@ -.TH MDB_DUMP 1 "2014/06/20" "LMDB 0.9.14" -.\" Copyright 2014-2015 Howard Chu, Symas Corp. All Rights Reserved. +.TH MDB_DUMP 1 "2017/07/31" "LMDB 0.9.70" +.\" Copyright 2014-2017 Howard Chu, Symas Corp. All Rights Reserved. .\" Copying restrictions apply. See COPYRIGHT/LICENSE. .SH NAME mdb_dump \- LMDB environment export tool diff --git a/external/db_drivers/liblmdb/mdb_dump.c b/external/db_drivers/liblmdb/mdb_dump.c index 7a42bc0b6..b7737f12d 100644 --- a/external/db_drivers/liblmdb/mdb_dump.c +++ b/external/db_drivers/liblmdb/mdb_dump.c @@ -1,6 +1,6 @@ /* mdb_dump.c - memory-mapped database dump tool */ /* - * Copyright 2011-2015 Howard Chu, Symas Corp. + * Copyright 2011-2018 Howard Chu, Symas Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -20,20 +20,7 @@ #include <signal.h> #include "lmdb.h" -#ifdef _WIN32 -#define Z "I" -#else -#define Z "z" -#endif -#ifdef MDB_VL32 -#ifdef _WIN32 -#define Y "I64" -#else -#define Y "ll" -#endif -#else -#define Y Z -#endif +#define Yu MDB_PRIy(u) #define PRINT 1 static int mode; @@ -124,7 +111,7 @@ static int dumpit(MDB_txn *txn, MDB_dbi dbi, char *name) if (name) printf("database=%s\n", name); printf("type=btree\n"); - printf("mapsize=%" Y "u\n", info.me_mapsize); + printf("mapsize=%"Yu"\n", info.me_mapsize); if (info.me_mapaddr) printf("mapaddr=%p\n", info.me_mapaddr); printf("maxreaders=%u\n", info.me_maxreaders); diff --git a/external/db_drivers/liblmdb/mdb_load.1 b/external/db_drivers/liblmdb/mdb_load.1 index ede3702d9..a2f8373c5 100644 --- a/external/db_drivers/liblmdb/mdb_load.1 +++ b/external/db_drivers/liblmdb/mdb_load.1 @@ -1,5 +1,5 @@ -.TH MDB_LOAD 1 "2014/06/20" "LMDB 0.9.14" -.\" Copyright 2014-2015 Howard Chu, Symas Corp. All Rights Reserved. +.TH MDB_LOAD 1 "2015/09/30" "LMDB 0.9.17" +.\" Copyright 2014-2018 Howard Chu, Symas Corp. All Rights Reserved. .\" Copying restrictions apply. See COPYRIGHT/LICENSE. .SH NAME mdb_load \- LMDB environment import tool diff --git a/external/db_drivers/liblmdb/mdb_load.c b/external/db_drivers/liblmdb/mdb_load.c index c74ce81c9..ad911c088 100644 --- a/external/db_drivers/liblmdb/mdb_load.c +++ b/external/db_drivers/liblmdb/mdb_load.c @@ -1,6 +1,6 @@ /* mdb_load.c - memory-mapped database load tool */ /* - * Copyright 2011-2015 Howard Chu, Symas Corp. + * Copyright 2011-2018 Howard Chu, Symas Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ static int mode; static char *subname = NULL; -static size_t lineno; +static mdb_size_t lineno; static int version; static int flags; @@ -39,20 +39,7 @@ static MDB_envinfo info; static MDB_val kbuf, dbuf; static MDB_val k0buf; -#ifdef _WIN32 -#define Z "I" -#else -#define Z "z" -#endif -#ifdef MDB_VL32 -#ifdef _WIN32 -#define Y "I64" -#else -#define Y "ll" -#endif -#else -#define Y Z -#endif +#define Yu MDB_PRIy(u) #define STRLENOF(s) (sizeof(s)-1) @@ -84,7 +71,7 @@ static void readhdr(void) if (!strncmp(dbuf.mv_data, "VERSION=", STRLENOF("VERSION="))) { version=atoi((char *)dbuf.mv_data+STRLENOF("VERSION=")); if (version > 3) { - fprintf(stderr, "%s: line %" Z "d: unsupported VERSION %d\n", + fprintf(stderr, "%s: line %"Yu": unsupported VERSION %d\n", prog, lineno, version); exit(EXIT_FAILURE); } @@ -94,7 +81,7 @@ static void readhdr(void) if (!strncmp((char *)dbuf.mv_data+STRLENOF("FORMAT="), "print", STRLENOF("print"))) mode |= PRINT; else if (strncmp((char *)dbuf.mv_data+STRLENOF("FORMAT="), "bytevalue", STRLENOF("bytevalue"))) { - fprintf(stderr, "%s: line %" Z "d: unsupported FORMAT %s\n", + fprintf(stderr, "%s: line %"Yu": unsupported FORMAT %s\n", prog, lineno, (char *)dbuf.mv_data+STRLENOF("FORMAT=")); exit(EXIT_FAILURE); } @@ -105,7 +92,7 @@ static void readhdr(void) subname = strdup((char *)dbuf.mv_data+STRLENOF("database=")); } else if (!strncmp(dbuf.mv_data, "type=", STRLENOF("type="))) { if (strncmp((char *)dbuf.mv_data+STRLENOF("type="), "btree", STRLENOF("btree"))) { - fprintf(stderr, "%s: line %" Z "d: unsupported type %s\n", + fprintf(stderr, "%s: line %"Yu": unsupported type %s\n", prog, lineno, (char *)dbuf.mv_data+STRLENOF("type=")); exit(EXIT_FAILURE); } @@ -115,7 +102,7 @@ static void readhdr(void) if (ptr) *ptr = '\0'; i = sscanf((char *)dbuf.mv_data+STRLENOF("mapaddr="), "%p", &info.me_mapaddr); if (i != 1) { - fprintf(stderr, "%s: line %" Z "d: invalid mapaddr %s\n", + fprintf(stderr, "%s: line %"Yu": invalid mapaddr %s\n", prog, lineno, (char *)dbuf.mv_data+STRLENOF("mapaddr=")); exit(EXIT_FAILURE); } @@ -123,9 +110,10 @@ static void readhdr(void) int i; ptr = memchr(dbuf.mv_data, '\n', dbuf.mv_size); if (ptr) *ptr = '\0'; - i = sscanf((char *)dbuf.mv_data+STRLENOF("mapsize="), "%" Y "u", &info.me_mapsize); + i = sscanf((char *)dbuf.mv_data+STRLENOF("mapsize="), + "%" MDB_SCNy(u), &info.me_mapsize); if (i != 1) { - fprintf(stderr, "%s: line %" Z "d: invalid mapsize %s\n", + fprintf(stderr, "%s: line %"Yu": invalid mapsize %s\n", prog, lineno, (char *)dbuf.mv_data+STRLENOF("mapsize=")); exit(EXIT_FAILURE); } @@ -135,7 +123,7 @@ static void readhdr(void) if (ptr) *ptr = '\0'; i = sscanf((char *)dbuf.mv_data+STRLENOF("maxreaders="), "%u", &info.me_maxreaders); if (i != 1) { - fprintf(stderr, "%s: line %" Z "d: invalid maxreaders %s\n", + fprintf(stderr, "%s: line %"Yu": invalid maxreaders %s\n", prog, lineno, (char *)dbuf.mv_data+STRLENOF("maxreaders=")); exit(EXIT_FAILURE); } @@ -151,12 +139,12 @@ static void readhdr(void) if (!dbflags[i].bit) { ptr = memchr(dbuf.mv_data, '=', dbuf.mv_size); if (!ptr) { - fprintf(stderr, "%s: line %" Z "d: unexpected format\n", + fprintf(stderr, "%s: line %"Yu": unexpected format\n", prog, lineno); exit(EXIT_FAILURE); } else { *ptr = '\0'; - fprintf(stderr, "%s: line %" Z "d: unrecognized keyword ignored: %s\n", + fprintf(stderr, "%s: line %"Yu": unrecognized keyword ignored: %s\n", prog, lineno, (char *)dbuf.mv_data); } } @@ -166,7 +154,7 @@ static void readhdr(void) static void badend(void) { - fprintf(stderr, "%s: line %" Z "d: unexpected end of input\n", + fprintf(stderr, "%s: line %"Yu": unexpected end of input\n", prog, lineno); } @@ -224,7 +212,7 @@ badend: buf->mv_data = realloc(buf->mv_data, buf->mv_size*2); if (!buf->mv_data) { Eof = 1; - fprintf(stderr, "%s: line %" Z "d: out of memory, line too long\n", + fprintf(stderr, "%s: line %"Yu": out of memory, line too long\n", prog, lineno); return EOF; } @@ -259,7 +247,8 @@ badend: c2 += 2; } } else { - c1++; c2++; + /* copies are redundant when no escapes were used */ + *c1++ = *c2++; } } } else { @@ -435,7 +424,7 @@ int main(int argc, char *argv[]) rc = readline(&data, &dbuf); if (rc) { - fprintf(stderr, "%s: line %" Z "d: failed to read key value\n", prog, lineno); + fprintf(stderr, "%s: line %"Yu": failed to read key value\n", prog, lineno); goto txn_abort; } @@ -463,7 +452,7 @@ int main(int argc, char *argv[]) if (batch == 100) { rc = mdb_txn_commit(txn); if (rc) { - fprintf(stderr, "%s: line %" Z "d: txn_commit: %s\n", + fprintf(stderr, "%s: line %"Yu": txn_commit: %s\n", prog, lineno, mdb_strerror(rc)); goto env_close; } @@ -487,7 +476,7 @@ int main(int argc, char *argv[]) rc = mdb_txn_commit(txn); txn = NULL; if (rc) { - fprintf(stderr, "%s: line %" Z "d: txn_commit: %s\n", + fprintf(stderr, "%s: line %"Yu": txn_commit: %s\n", prog, lineno, mdb_strerror(rc)); goto env_close; } diff --git a/external/db_drivers/liblmdb/mdb_stat.1 b/external/db_drivers/liblmdb/mdb_stat.1 index bf49bd3bd..83988a0fa 100644 --- a/external/db_drivers/liblmdb/mdb_stat.1 +++ b/external/db_drivers/liblmdb/mdb_stat.1 @@ -1,5 +1,5 @@ -.TH MDB_STAT 1 "2014/06/20" "LMDB 0.9.14" -.\" Copyright 2012-2015 Howard Chu, Symas Corp. All Rights Reserved. +.TH MDB_STAT 1 "2017/07/31" "LMDB 0.9.70" +.\" Copyright 2012-2019 Howard Chu, Symas Corp. All Rights Reserved. .\" Copying restrictions apply. See COPYRIGHT/LICENSE. .SH NAME mdb_stat \- LMDB environment status tool diff --git a/external/db_drivers/liblmdb/mdb_stat.c b/external/db_drivers/liblmdb/mdb_stat.c index 30ec81fea..08f30befd 100644 --- a/external/db_drivers/liblmdb/mdb_stat.c +++ b/external/db_drivers/liblmdb/mdb_stat.c @@ -1,6 +1,6 @@ /* mdb_stat.c - memory-mapped database status tool */ /* - * Copyright 2011-2015 Howard Chu, Symas Corp. + * Copyright 2011-2018 Howard Chu, Symas Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -17,20 +17,8 @@ #include <unistd.h> #include "lmdb.h" -#ifdef _WIN32 -#define Z "I" -#else -#define Z "z" -#endif -#ifdef MDB_VL32 -#ifdef _WIN32 -#define Y "I64" -#else -#define Y "ll" -#endif -#else -#define Y Z -#endif +#define Z MDB_FMT_Z +#define Yu MDB_PRIy(u) static void prstat(MDB_stat *ms) { @@ -38,10 +26,10 @@ static void prstat(MDB_stat *ms) printf(" Page size: %u\n", ms->ms_psize); #endif printf(" Tree depth: %u\n", ms->ms_depth); - printf(" Branch pages: %"Y"u\n", ms->ms_branch_pages); - printf(" Leaf pages: %"Y"u\n", ms->ms_leaf_pages); - printf(" Overflow pages: %"Y"u\n", ms->ms_overflow_pages); - printf(" Entries: %"Y"u\n", ms->ms_entries); + printf(" Branch pages: %"Yu"\n", ms->ms_branch_pages); + printf(" Leaf pages: %"Yu"\n", ms->ms_leaf_pages); + printf(" Overflow pages: %"Yu"\n", ms->ms_overflow_pages); + printf(" Entries: %"Yu"\n", ms->ms_entries); } static void usage(char *prog) @@ -138,11 +126,11 @@ int main(int argc, char *argv[]) (void)mdb_env_info(env, &mei); printf("Environment Info\n"); printf(" Map address: %p\n", mei.me_mapaddr); - printf(" Map size: %"Y"u\n", mei.me_mapsize); + printf(" Map size: %"Yu"\n", mei.me_mapsize); printf(" Page size: %u\n", mst.ms_psize); - printf(" Max pages: %"Y"u\n", mei.me_mapsize / mst.ms_psize); - printf(" Number of pages used: %"Y"u\n", mei.me_last_pgno+1); - printf(" Last transaction ID: %"Y"u\n", mei.me_last_txnid); + printf(" Max pages: %"Yu"\n", mei.me_mapsize / mst.ms_psize); + printf(" Number of pages used: %"Yu"\n", mei.me_last_pgno+1); + printf(" Last transaction ID: %"Yu"\n", mei.me_last_txnid); printf(" Max readers: %u\n", mei.me_maxreaders); printf(" Number of readers used: %u\n", mei.me_numreaders); } @@ -169,7 +157,7 @@ int main(int argc, char *argv[]) if (freinfo) { MDB_cursor *cursor; MDB_val key, data; - size_t pages = 0, *iptr; + mdb_size_t pages = 0, *iptr; printf("Freelist Status\n"); dbi = 0; @@ -189,7 +177,7 @@ int main(int argc, char *argv[]) pages += *iptr; if (freinfo > 1) { char *bad = ""; - size_t pg, prev; + mdb_size_t pg, prev; ssize_t i, j, span = 0; j = *iptr++; for (i = j, prev = 1; --i >= 0; ) { @@ -200,20 +188,20 @@ int main(int argc, char *argv[]) pg += span; for (; i >= span && iptr[i-span] == pg; span++, pg++) ; } - printf(" Transaction %"Z"u, %"Z"d pages, maxspan %"Z"d%s\n", - *(size_t *)key.mv_data, j, span, bad); + printf(" Transaction %"Yu", %"Z"d pages, maxspan %"Z"d%s\n", + *(mdb_size_t *)key.mv_data, j, span, bad); if (freinfo > 2) { for (--j; j >= 0; ) { pg = iptr[j]; for (span=1; --j >= 0 && iptr[j] == pg+span; span++) ; - printf(span>1 ? " %9"Z"u[%"Z"d]\n" : " %9"Z"u\n", + printf(span>1 ? " %9"Yu"[%"Z"d]\n" : " %9"Yu"\n", pg, span); } } } } mdb_cursor_close(cursor); - printf(" Free pages: %"Z"u\n", pages); + printf(" Free pages: %"Yu"\n", pages); } rc = mdb_open(txn, subname, 0, &dbi); diff --git a/external/db_drivers/liblmdb/midl.c b/external/db_drivers/liblmdb/midl.c index 152a1ec0d..ee89822e3 100644 --- a/external/db_drivers/liblmdb/midl.c +++ b/external/db_drivers/liblmdb/midl.c @@ -3,7 +3,8 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software <http://www.openldap.org/>. * - * Copyright 2000-2015 The OpenLDAP Foundation. + * Copyright 2000-2019 The OpenLDAP Foundation. + * Portions Copyright 2001-2018 Howard Chu, Symas Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/external/db_drivers/liblmdb/midl.h b/external/db_drivers/liblmdb/midl.h index 1555ecb19..0f826771a 100644 --- a/external/db_drivers/liblmdb/midl.h +++ b/external/db_drivers/liblmdb/midl.h @@ -11,7 +11,8 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software <http://www.openldap.org/>. * - * Copyright 2000-2015 The OpenLDAP Foundation. + * Copyright 2000-2019 The OpenLDAP Foundation. + * Portions Copyright 2001-2019 Howard Chu, Symas Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,8 +27,7 @@ #ifndef _MDB_MIDL_H_ #define _MDB_MIDL_H_ -#include <stddef.h> -#include <inttypes.h> +#include "lmdb.h" #ifdef __cplusplus extern "C" { @@ -43,11 +43,7 @@ extern "C" { /** A generic unsigned ID number. These were entryIDs in back-bdb. * Preferably it should have the same size as a pointer. */ -#ifdef MDB_VL32 -typedef uint64_t MDB_ID; -#else -typedef size_t MDB_ID; -#endif +typedef mdb_size_t MDB_ID; /** An IDL is an ID List, a sorted array of IDs. The first * element of the array is a counter for how many actual diff --git a/external/db_drivers/liblmdb/mtest.c b/external/db_drivers/liblmdb/mtest.c index 9d15088b0..6fc5840c3 100644 --- a/external/db_drivers/liblmdb/mtest.c +++ b/external/db_drivers/liblmdb/mtest.c @@ -1,6 +1,6 @@ /* mtest.c - memory-mapped database tester/toy */ /* - * Copyright 2011-2015 Howard Chu, Symas Corp. + * Copyright 2011-2018 Howard Chu, Symas Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/external/db_drivers/liblmdb/mtest2.c b/external/db_drivers/liblmdb/mtest2.c index eacbe59d5..64b742aa4 100644 --- a/external/db_drivers/liblmdb/mtest2.c +++ b/external/db_drivers/liblmdb/mtest2.c @@ -1,6 +1,6 @@ /* mtest2.c - memory-mapped database tester/toy */ /* - * Copyright 2011-2015 Howard Chu, Symas Corp. + * Copyright 2011-2018 Howard Chu, Symas Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/external/db_drivers/liblmdb/mtest3.c b/external/db_drivers/liblmdb/mtest3.c index 9db79e625..81e4bbf9b 100644 --- a/external/db_drivers/liblmdb/mtest3.c +++ b/external/db_drivers/liblmdb/mtest3.c @@ -1,6 +1,6 @@ /* mtest3.c - memory-mapped database tester/toy */ /* - * Copyright 2011-2015 Howard Chu, Symas Corp. + * Copyright 2011-2018 Howard Chu, Symas Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/external/db_drivers/liblmdb/mtest4.c b/external/db_drivers/liblmdb/mtest4.c index 6df890e2d..c355cf105 100644 --- a/external/db_drivers/liblmdb/mtest4.c +++ b/external/db_drivers/liblmdb/mtest4.c @@ -1,6 +1,6 @@ /* mtest4.c - memory-mapped database tester/toy */ /* - * Copyright 2011-2015 Howard Chu, Symas Corp. + * Copyright 2011-2018 Howard Chu, Symas Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/external/db_drivers/liblmdb/mtest5.c b/external/db_drivers/liblmdb/mtest5.c index 14e3c0da4..95793ec1f 100644 --- a/external/db_drivers/liblmdb/mtest5.c +++ b/external/db_drivers/liblmdb/mtest5.c @@ -1,6 +1,6 @@ /* mtest5.c - memory-mapped database tester/toy */ /* - * Copyright 2011-2015 Howard Chu, Symas Corp. + * Copyright 2011-2018 Howard Chu, Symas Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/external/db_drivers/liblmdb/mtest6.c b/external/db_drivers/liblmdb/mtest6.c index ae3c7f264..cb0d4d73c 100644 --- a/external/db_drivers/liblmdb/mtest6.c +++ b/external/db_drivers/liblmdb/mtest6.c @@ -1,6 +1,6 @@ /* mtest6.c - memory-mapped database tester/toy */ /* - * Copyright 2011-2015 Howard Chu, Symas Corp. + * Copyright 2011-2018 Howard Chu, Symas Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/external/db_drivers/liblmdb/sample-bdb.txt b/external/db_drivers/liblmdb/sample-bdb.txt index 563807a2b..97220f0ed 100644 --- a/external/db_drivers/liblmdb/sample-bdb.txt +++ b/external/db_drivers/liblmdb/sample-bdb.txt @@ -3,7 +3,7 @@ * Do a line-by-line comparison of this and sample-mdb.txt */ /* - * Copyright 2012-2015 Howard Chu, Symas Corp. + * Copyright 2012-2018 Howard Chu, Symas Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/external/db_drivers/liblmdb/sample-mdb.txt b/external/db_drivers/liblmdb/sample-mdb.txt index 10a256870..1d20ed3d0 100644 --- a/external/db_drivers/liblmdb/sample-mdb.txt +++ b/external/db_drivers/liblmdb/sample-mdb.txt @@ -3,7 +3,7 @@ * Do a line-by-line comparison of this and sample-bdb.txt */ /* - * Copyright 2012-2015 Howard Chu, Symas Corp. + * Copyright 2012-2018 Howard Chu, Symas Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a0b62da77..f1454b48e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -110,6 +110,7 @@ add_subdirectory(checkpoints) add_subdirectory(cryptonote_basic) add_subdirectory(cryptonote_core) add_subdirectory(multisig) +add_subdirectory(net) if(NOT IOS) add_subdirectory(blockchain_db) endif() diff --git a/src/blockchain_db/blockchain_db.cpp b/src/blockchain_db/blockchain_db.cpp index c25798c1e..041759593 100644 --- a/src/blockchain_db/blockchain_db.cpp +++ b/src/blockchain_db/blockchain_db.cpp @@ -197,6 +197,7 @@ void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const transacti uint64_t BlockchainDB::add_block( const block& blk , size_t block_weight + , uint64_t long_term_block_weight , const difficulty_type& cumulative_difficulty , const uint64_t& coins_generated , const std::vector<transaction>& txs @@ -241,7 +242,7 @@ uint64_t BlockchainDB::add_block( const block& blk // call out to subclass implementation to add the block & metadata time1 = epee::misc_utils::get_tick_count(); - add_block(blk, block_weight, cumulative_difficulty, coins_generated, num_rct_outs, blk_hash); + add_block(blk, block_weight, long_term_block_weight, cumulative_difficulty, coins_generated, num_rct_outs, blk_hash); TIME_MEASURE_FINISH(time1); time_add_block1 += time1; @@ -267,7 +268,10 @@ void BlockchainDB::pop_block(block& blk, std::vector<transaction>& txs) for (const auto& h : boost::adaptors::reverse(blk.tx_hashes)) { - txs.push_back(get_tx(h)); + cryptonote::transaction tx; + if (!get_tx(h, tx) && !get_pruned_tx(h, tx)) + throw DB_ERROR("Failed to get pruned or unpruned transaction from the db"); + txs.push_back(std::move(tx)); remove_transaction(h); } remove_transaction(get_transaction_hash(blk.miner_tx)); @@ -280,7 +284,7 @@ bool BlockchainDB::is_open() const void BlockchainDB::remove_transaction(const crypto::hash& tx_hash) { - transaction tx = get_tx(tx_hash); + transaction tx = get_pruned_tx(tx_hash); for (const txin_v& tx_input : tx.vin) { @@ -325,6 +329,17 @@ bool BlockchainDB::get_tx(const crypto::hash& h, cryptonote::transaction &tx) co return true; } +bool BlockchainDB::get_pruned_tx(const crypto::hash& h, cryptonote::transaction &tx) const +{ + blobdata bd; + if (!get_pruned_tx_blob(h, bd)) + return false; + if (!parse_and_validate_tx_base_from_blob(bd, tx)) + throw DB_ERROR("Failed to parse transaction base from blob retrieved from the db"); + + return true; +} + transaction BlockchainDB::get_tx(const crypto::hash& h) const { transaction tx; @@ -333,6 +348,14 @@ transaction BlockchainDB::get_tx(const crypto::hash& h) const return tx; } +transaction BlockchainDB::get_pruned_tx(const crypto::hash& h) const +{ + transaction tx; + if (!get_pruned_tx(h, tx)) + throw TX_DNE(std::string("pruned tx with hash ").append(epee::string_tools::pod_to_hex(h)).append(" not found in db").c_str()); + return tx; +} + void BlockchainDB::reset_stats() { num_calls = 0; diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h index fe61aabd8..c3f11ba28 100644 --- a/src/blockchain_db/blockchain_db.h +++ b/src/blockchain_db/blockchain_db.h @@ -358,12 +358,14 @@ private: * * @param blk the block to be added * @param block_weight the weight of the block (transactions and all) + * @param long_term_block_weight the long term block weight of the block (transactions and all) * @param cumulative_difficulty the accumulated difficulty after this block * @param coins_generated the number of coins generated total after this block * @param blk_hash the hash of the block */ virtual void add_block( const block& blk , size_t block_weight + , uint64_t long_term_block_weight , const difficulty_type& cumulative_difficulty , const uint64_t& coins_generated , uint64_t num_rct_outs @@ -375,7 +377,7 @@ private: * * The subclass implementing this will remove the block data from the top * block in the chain. The data to be removed is that which was added in - * BlockchainDB::add_block(const block& blk, size_t block_weight, const difficulty_type& cumulative_difficulty, const uint64_t& coins_generated, const crypto::hash& blk_hash) + * BlockchainDB::add_block(const block& blk, size_t block_weight, uint64_t long_term_block_weight, const difficulty_type& cumulative_difficulty, const uint64_t& coins_generated, const crypto::hash& blk_hash) * * If any of this cannot be done, the subclass should throw the corresponding * subclass of DB_EXCEPTION @@ -789,6 +791,7 @@ public: * * @param blk the block to be added * @param block_weight the size of the block (transactions and all) + * @param long_term_block_weight the long term weight of the block (transactions and all) * @param cumulative_difficulty the accumulated difficulty after this block * @param coins_generated the number of coins generated total after this block * @param txs the transactions in the block @@ -797,6 +800,7 @@ public: */ virtual uint64_t add_block( const block& blk , size_t block_weight + , uint64_t long_term_block_weight , const difficulty_type& cumulative_difficulty , const uint64_t& coins_generated , const std::vector<transaction>& txs @@ -985,6 +989,17 @@ public: virtual uint64_t get_block_already_generated_coins(const uint64_t& height) const = 0; /** + * @brief fetch a block's long term weight + * + * If the block does not exist, the subclass should throw BLOCK_DNE + * + * @param height the height requested + * + * @return the long term weight + */ + virtual uint64_t get_block_long_term_weight(const uint64_t& height) const = 0; + + /** * @brief fetch a block's hash * * The subclass should return hash of the block with the @@ -1126,6 +1141,17 @@ public: virtual transaction get_tx(const crypto::hash& h) const; /** + * @brief fetches the transaction base with the given hash + * + * If the transaction does not exist, the subclass should throw TX_DNE. + * + * @param h the hash to look for + * + * @return the transaction with the given hash + */ + virtual transaction get_pruned_tx(const crypto::hash& h) const; + + /** * @brief fetches the transaction with the given hash * * If the transaction does not exist, the subclass should return false. @@ -1137,6 +1163,17 @@ public: virtual bool get_tx(const crypto::hash& h, transaction &tx) const; /** + * @brief fetches the transaction base with the given hash + * + * If the transaction does not exist, the subclass should return false. + * + * @param h the hash to look for + * + * @return true iff the transaction was found + */ + virtual bool get_pruned_tx(const crypto::hash& h, transaction &tx) const; + + /** * @brief fetches the transaction blob with the given hash * * The subclass should return the transaction stored which has the given @@ -1165,6 +1202,21 @@ public: virtual bool get_pruned_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const = 0; /** + * @brief fetches the prunable transaction blob with the given hash + * + * The subclass should return the prunable transaction stored which has the given + * hash. + * + * If the transaction does not exist, or if we do not have that prunable data, + * the subclass should return false. + * + * @param h the hash to look for + * + * @return true iff the transaction was found and we have its prunable data + */ + virtual bool get_prunable_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const = 0; + + /** * @brief fetches the prunable transaction hash * * The subclass should return the hash of the prunable transaction data. @@ -1413,6 +1465,31 @@ public: virtual void prune_outputs(uint64_t amount) = 0; /** + * @brief get the blockchain pruning seed + * @return the blockchain pruning seed + */ + virtual uint32_t get_blockchain_pruning_seed() const = 0; + + /** + * @brief prunes the blockchain + * @param pruning_seed the seed to use, 0 for default (highly recommended) + * @return success iff true + */ + virtual bool prune_blockchain(uint32_t pruning_seed = 0) = 0; + + /** + * @brief prunes recent blockchain changes as needed, iff pruning is enabled + * @return success iff true + */ + virtual bool update_pruning() = 0; + + /** + * @brief checks pruning was done correctly, iff enabled + * @return success iff true + */ + virtual bool check_pruning() = 0; + + /** * @brief runs a function over all txpool transactions * * The subclass should run the passed function for each txpool tx it has diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 2b5fa7fd9..9d2f7821e 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -29,12 +29,14 @@ #include <boost/filesystem.hpp> #include <boost/format.hpp> +#include <boost/circular_buffer.hpp> #include <memory> // std::unique_ptr #include <cstring> // memcpy #include "string_tools.h" #include "file_io_utils.h" #include "common/util.h" +#include "common/pruning.h" #include "cryptonote_basic/cryptonote_format_utils.h" #include "crypto/crypto.h" #include "profile_tools.h" @@ -52,7 +54,7 @@ using epee::string_tools::pod_to_hex; using namespace crypto; // Increase when the DB structure changes -#define VERSION 3 +#define VERSION 4 namespace { @@ -130,14 +132,20 @@ private: std::unique_ptr<char[]> data; }; -int compare_uint64(const MDB_val *a, const MDB_val *b) +} + +namespace cryptonote { - const uint64_t va = *(const uint64_t *)a->mv_data; - const uint64_t vb = *(const uint64_t *)b->mv_data; + +int BlockchainLMDB::compare_uint64(const MDB_val *a, const MDB_val *b) +{ + uint64_t va, vb; + memcpy(&va, a->mv_data, sizeof(va)); + memcpy(&vb, b->mv_data, sizeof(vb)); return (va < vb) ? -1 : va > vb; } -int compare_hash32(const MDB_val *a, const MDB_val *b) +int BlockchainLMDB::compare_hash32(const MDB_val *a, const MDB_val *b) { uint32_t *va = (uint32_t*) a->mv_data; uint32_t *vb = (uint32_t*) b->mv_data; @@ -151,13 +159,18 @@ int compare_hash32(const MDB_val *a, const MDB_val *b) return 0; } -int compare_string(const MDB_val *a, const MDB_val *b) +int BlockchainLMDB::compare_string(const MDB_val *a, const MDB_val *b) { const char *va = (const char*) a->mv_data; const char *vb = (const char*) b->mv_data; return strcmp(va, vb); } +} + +namespace +{ + /* DB schema: * * Table Key Data @@ -169,6 +182,7 @@ int compare_string(const MDB_val *a, const MDB_val *b) * txs_pruned txn ID pruned txn blob * txs_prunable txn ID prunable txn blob * txs_prunable_hash txn ID prunable txn hash + * txs_prunable_tip txn ID height * tx_indices txn hash {txn ID, metadata} * tx_outputs txn ID [txn amount output indices] * @@ -196,6 +210,7 @@ const char* const LMDB_TXS = "txs"; const char* const LMDB_TXS_PRUNED = "txs_pruned"; const char* const LMDB_TXS_PRUNABLE = "txs_prunable"; const char* const LMDB_TXS_PRUNABLE_HASH = "txs_prunable_hash"; +const char* const LMDB_TXS_PRUNABLE_TIP = "txs_prunable_tip"; const char* const LMDB_TX_INDICES = "tx_indices"; const char* const LMDB_TX_OUTPUTS = "tx_outputs"; @@ -263,7 +278,7 @@ typedef struct mdb_block_info_old crypto::hash bi_hash; } mdb_block_info_old; -typedef struct mdb_block_info +typedef struct mdb_block_info_2 { uint64_t bi_height; uint64_t bi_timestamp; @@ -272,18 +287,27 @@ typedef struct mdb_block_info difficulty_type bi_diff; crypto::hash bi_hash; uint64_t bi_cum_rct; -} mdb_block_info; +} mdb_block_info_2; + +typedef struct mdb_block_info_3 +{ + uint64_t bi_height; + uint64_t bi_timestamp; + uint64_t bi_coins; + uint64_t bi_weight; // a size_t really but we need 32-bit compat + difficulty_type bi_diff; + crypto::hash bi_hash; + uint64_t bi_cum_rct; + uint64_t bi_long_term_block_weight; +} mdb_block_info_3; + +typedef mdb_block_info_3 mdb_block_info; typedef struct blk_height { crypto::hash bh_hash; uint64_t bh_height; } blk_height; -typedef struct txindex { - crypto::hash key; - tx_data_t data; -} txindex; - typedef struct pre_rct_outkey { uint64_t amount_index; uint64_t output_id; @@ -495,7 +519,7 @@ void BlockchainLMDB::do_resize(uint64_t increase_size) mdb_env_stat(m_env, &mst); // add 1Gb per resize, instead of doing a percentage increase - uint64_t new_mapsize = (double) mei.me_mapsize + add_size; + uint64_t new_mapsize = (uint64_t) mei.me_mapsize + add_size; // If given, use increase_size instead of above way of resizing. // This is currently used for increasing by an estimated size at start of new @@ -549,18 +573,18 @@ bool BlockchainLMDB::need_resize(uint64_t threshold_size) const // additional size needed. uint64_t size_used = mst.ms_psize * mei.me_last_pgno; - LOG_PRINT_L1("DB map size: " << mei.me_mapsize); - LOG_PRINT_L1("Space used: " << size_used); - LOG_PRINT_L1("Space remaining: " << mei.me_mapsize - size_used); - LOG_PRINT_L1("Size threshold: " << threshold_size); + MDEBUG("DB map size: " << mei.me_mapsize); + MDEBUG("Space used: " << size_used); + MDEBUG("Space remaining: " << mei.me_mapsize - size_used); + MDEBUG("Size threshold: " << threshold_size); float resize_percent = RESIZE_PERCENT; - LOG_PRINT_L1(boost::format("Percent used: %.04f Percent threshold: %.04f") % ((double)size_used/mei.me_mapsize) % resize_percent); + MDEBUG(boost::format("Percent used: %.04f Percent threshold: %.04f") % ((double)size_used/mei.me_mapsize) % resize_percent); if (threshold_size > 0) { if (mei.me_mapsize - size_used < threshold_size) { - LOG_PRINT_L1("Threshold met (size-based)"); + MINFO("Threshold met (size-based)"); return true; } else @@ -569,7 +593,7 @@ bool BlockchainLMDB::need_resize(uint64_t threshold_size) const if ((double)size_used / mei.me_mapsize > resize_percent) { - LOG_PRINT_L1("Threshold met (percent-based)"); + MINFO("Threshold met (percent-based)"); return true; } return false; @@ -581,7 +605,7 @@ bool BlockchainLMDB::need_resize(uint64_t threshold_size) const void BlockchainLMDB::check_and_resize_for_batch(uint64_t batch_num_blocks, uint64_t batch_bytes) { LOG_PRINT_L3("BlockchainLMDB::" << __func__); - LOG_PRINT_L1("[" << __func__ << "] " << "checking DB size"); + MTRACE("[" << __func__ << "] " << "checking DB size"); const uint64_t min_increase_size = 512 * (1 << 20); uint64_t threshold_size = 0; uint64_t increase_size = 0; @@ -685,7 +709,7 @@ estim: return threshold_size; } -void BlockchainLMDB::add_block(const block& blk, size_t block_weight, const difficulty_type& cumulative_difficulty, const uint64_t& coins_generated, +void BlockchainLMDB::add_block(const block& blk, size_t block_weight, uint64_t long_term_block_weight, const difficulty_type& cumulative_difficulty, const uint64_t& coins_generated, uint64_t num_rct_outs, const crypto::hash& blk_hash) { LOG_PRINT_L3("BlockchainLMDB::" << __func__); @@ -745,6 +769,7 @@ void BlockchainLMDB::add_block(const block& blk, size_t block_weight, const diff const mdb_block_info *bi_prev = (const mdb_block_info*)h.mv_data; bi.bi_cum_rct += bi_prev->bi_cum_rct; } + bi.bi_long_term_block_weight = long_term_block_weight; MDB_val_set(val, bi); result = mdb_cursor_put(m_cur_block_info, (MDB_val *)&zerokval, &val, MDB_APPENDDUP); @@ -811,6 +836,7 @@ uint64_t BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, cons CURSOR(txs_pruned) CURSOR(txs_prunable) CURSOR(txs_prunable_hash) + CURSOR(txs_prunable_tip) CURSOR(tx_indices) MDB_val_set(val_tx_id, tx_id); @@ -858,6 +884,14 @@ uint64_t BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, cons if (result) throw0(DB_ERROR(lmdb_error("Failed to add prunable tx blob to db transaction: ", result).c_str())); + if (get_blockchain_pruning_seed()) + { + MDB_val_set(val_height, m_height); + result = mdb_cursor_put(m_cur_txs_prunable_tip, &val_tx_id, &val_height, 0); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to add prunable tx id to db transaction: ", result).c_str())); + } + if (tx.version > 1) { MDB_val_set(val_prunable_hash, tx_prunable_hash); @@ -883,6 +917,7 @@ void BlockchainLMDB::remove_transaction_data(const crypto::hash& tx_hash, const CURSOR(txs_pruned) CURSOR(txs_prunable) CURSOR(txs_prunable_hash) + CURSOR(txs_prunable_tip) CURSOR(tx_outputs) MDB_val_set(val_h, tx_hash); @@ -898,11 +933,25 @@ void BlockchainLMDB::remove_transaction_data(const crypto::hash& tx_hash, const if (result) throw1(DB_ERROR(lmdb_error("Failed to add removal of pruned tx to db transaction: ", result).c_str())); - if ((result = mdb_cursor_get(m_cur_txs_prunable, &val_tx_id, NULL, MDB_SET))) + result = mdb_cursor_get(m_cur_txs_prunable, &val_tx_id, NULL, MDB_SET); + if (result == 0) + { + result = mdb_cursor_del(m_cur_txs_prunable, 0); + if (result) + throw1(DB_ERROR(lmdb_error("Failed to add removal of prunable tx to db transaction: ", result).c_str())); + } + else if (result != MDB_NOTFOUND) throw1(DB_ERROR(lmdb_error("Failed to locate prunable tx for removal: ", result).c_str())); - result = mdb_cursor_del(m_cur_txs_prunable, 0); - if (result) - throw1(DB_ERROR(lmdb_error("Failed to add removal of prunable tx to db transaction: ", result).c_str())); + + result = mdb_cursor_get(m_cur_txs_prunable_tip, &val_tx_id, NULL, MDB_SET); + if (result && result != MDB_NOTFOUND) + throw1(DB_ERROR(lmdb_error("Failed to locate tx id for removal: ", result).c_str())); + if (result == 0) + { + result = mdb_cursor_del(m_cur_txs_prunable_tip, 0); + if (result) + throw1(DB_ERROR(lmdb_error("Error adding removal of tx id to db transaction", result).c_str())); + } if (tx.version > 1) { @@ -1280,14 +1329,14 @@ void BlockchainLMDB::open(const std::string& filename, const int db_flags) MDB_envinfo mei; mdb_env_info(m_env, &mei); - uint64_t cur_mapsize = (double)mei.me_mapsize; + uint64_t cur_mapsize = (uint64_t)mei.me_mapsize; if (cur_mapsize < mapsize) { if (auto result = mdb_env_set_mapsize(m_env, mapsize)) throw0(DB_ERROR(lmdb_error("Failed to set max memory map size: ", result).c_str())); mdb_env_info(m_env, &mei); - cur_mapsize = (double)mei.me_mapsize; + cur_mapsize = (uint64_t)mei.me_mapsize; LOG_PRINT_L1("LMDB memory map size: " << cur_mapsize); } @@ -1308,6 +1357,7 @@ void BlockchainLMDB::open(const std::string& filename, const int db_flags) // open necessary databases, and set properties as needed // uses macros to avoid having to change things too many places + // also change blockchain_prune.cpp to match lmdb_db_open(txn, LMDB_BLOCKS, MDB_INTEGERKEY | MDB_CREATE, m_blocks, "Failed to open db handle for m_blocks"); lmdb_db_open(txn, LMDB_BLOCK_INFO, MDB_INTEGERKEY | MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED, m_block_info, "Failed to open db handle for m_block_info"); @@ -1316,7 +1366,9 @@ void BlockchainLMDB::open(const std::string& filename, const int db_flags) lmdb_db_open(txn, LMDB_TXS, MDB_INTEGERKEY | MDB_CREATE, m_txs, "Failed to open db handle for m_txs"); lmdb_db_open(txn, LMDB_TXS_PRUNED, MDB_INTEGERKEY | MDB_CREATE, m_txs_pruned, "Failed to open db handle for m_txs_pruned"); lmdb_db_open(txn, LMDB_TXS_PRUNABLE, MDB_INTEGERKEY | MDB_CREATE, m_txs_prunable, "Failed to open db handle for m_txs_prunable"); - lmdb_db_open(txn, LMDB_TXS_PRUNABLE_HASH, MDB_INTEGERKEY | MDB_CREATE, m_txs_prunable_hash, "Failed to open db handle for m_txs_prunable_hash"); + lmdb_db_open(txn, LMDB_TXS_PRUNABLE_HASH, MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED | MDB_CREATE, m_txs_prunable_hash, "Failed to open db handle for m_txs_prunable_hash"); + if (!(mdb_flags & MDB_RDONLY)) + lmdb_db_open(txn, LMDB_TXS_PRUNABLE_TIP, MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED | MDB_CREATE, m_txs_prunable_tip, "Failed to open db handle for m_txs_prunable_tip"); lmdb_db_open(txn, LMDB_TX_INDICES, MDB_INTEGERKEY | MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED, m_tx_indices, "Failed to open db handle for m_tx_indices"); lmdb_db_open(txn, LMDB_TX_OUTPUTS, MDB_INTEGERKEY | MDB_CREATE, m_tx_outputs, "Failed to open db handle for m_tx_outputs"); @@ -1344,6 +1396,10 @@ void BlockchainLMDB::open(const std::string& filename, const int db_flags) mdb_set_dupsort(txn, m_output_amounts, compare_uint64); mdb_set_dupsort(txn, m_output_txs, compare_uint64); mdb_set_dupsort(txn, m_block_info, compare_uint64); + if (!(mdb_flags & MDB_RDONLY)) + mdb_set_dupsort(txn, m_txs_prunable_tip, compare_uint64); + mdb_set_compare(txn, m_txs_prunable, compare_uint64); + mdb_set_dupsort(txn, m_txs_prunable_hash, compare_uint64); mdb_set_compare(txn, m_txpool_meta, compare_hash32); mdb_set_compare(txn, m_txpool_blob, compare_hash32); @@ -1502,6 +1558,8 @@ void BlockchainLMDB::reset() throw0(DB_ERROR(lmdb_error("Failed to drop m_txs_prunable: ", result).c_str())); if (auto result = mdb_drop(txn, m_txs_prunable_hash, 0)) throw0(DB_ERROR(lmdb_error("Failed to drop m_txs_prunable_hash: ", result).c_str())); + if (auto result = mdb_drop(txn, m_txs_prunable_tip, 0)) + throw0(DB_ERROR(lmdb_error("Failed to drop m_txs_prunable_tip: ", result).c_str())); if (auto result = mdb_drop(txn, m_tx_indices, 0)) throw0(DB_ERROR(lmdb_error("Failed to drop m_tx_indices: ", result).c_str())); if (auto result = mdb_drop(txn, m_tx_outputs, 0)) @@ -1827,6 +1885,290 @@ cryptonote::blobdata BlockchainLMDB::get_txpool_tx_blob(const crypto::hash& txid return bd; } +uint32_t BlockchainLMDB::get_blockchain_pruning_seed() const +{ + LOG_PRINT_L3("BlockchainLMDB::" << __func__); + check_open(); + + TXN_PREFIX_RDONLY(); + RCURSOR(properties) + MDB_val_str(k, "pruning_seed"); + MDB_val v; + int result = mdb_cursor_get(m_cur_properties, &k, &v, MDB_SET); + if (result == MDB_NOTFOUND) + return 0; + if (result) + throw0(DB_ERROR(lmdb_error("Failed to retrieve pruning seed: ", result).c_str())); + if (v.mv_size != sizeof(uint32_t)) + throw0(DB_ERROR("Failed to retrieve or create pruning seed: unexpected value size")); + uint32_t pruning_seed; + memcpy(&pruning_seed, v.mv_data, sizeof(pruning_seed)); + TXN_POSTFIX_RDONLY(); + return pruning_seed; +} + +static bool is_v1_tx(MDB_cursor *c_txs_pruned, MDB_val *tx_id) +{ + MDB_val v; + int ret = mdb_cursor_get(c_txs_pruned, tx_id, &v, MDB_SET); + if (ret) + throw0(DB_ERROR(lmdb_error("Failed to find transaction pruned data: ", ret).c_str())); + if (v.mv_size == 0) + throw0(DB_ERROR("Invalid transaction pruned data")); + return cryptonote::is_v1_tx(cryptonote::blobdata_ref{(const char*)v.mv_data, v.mv_size}); +} + +enum { prune_mode_prune, prune_mode_update, prune_mode_check }; + +bool BlockchainLMDB::prune_worker(int mode, uint32_t pruning_seed) +{ + LOG_PRINT_L3("BlockchainLMDB::" << __func__); + const uint32_t log_stripes = tools::get_pruning_log_stripes(pruning_seed); + if (log_stripes && log_stripes != CRYPTONOTE_PRUNING_LOG_STRIPES) + throw0(DB_ERROR("Pruning seed not in range")); + pruning_seed = tools::get_pruning_stripe(pruning_seed);; + if (pruning_seed > (1ul << CRYPTONOTE_PRUNING_LOG_STRIPES)) + throw0(DB_ERROR("Pruning seed not in range")); + check_open(); + + TIME_MEASURE_START(t); + + size_t n_total_records = 0, n_prunable_records = 0, n_pruned_records = 0; + uint64_t n_bytes = 0; + + mdb_txn_safe txn; + auto result = mdb_txn_begin(m_env, NULL, 0, txn); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", result).c_str())); + + MDB_stat db_stats; + if ((result = mdb_stat(txn, m_txs_prunable, &db_stats))) + throw0(DB_ERROR(lmdb_error("Failed to query m_txs_prunable: ", result).c_str())); + const size_t pages0 = db_stats.ms_branch_pages + db_stats.ms_leaf_pages + db_stats.ms_overflow_pages; + + MDB_val_str(k, "pruning_seed"); + MDB_val v; + result = mdb_get(txn, m_properties, &k, &v); + bool prune_tip_table = false; + if (result == MDB_NOTFOUND) + { + // not pruned yet + if (mode != prune_mode_prune) + { + txn.abort(); + TIME_MEASURE_FINISH(t); + MDEBUG("Pruning not enabled, nothing to do"); + return true; + } + if (pruning_seed == 0) + pruning_seed = tools::get_random_stripe(); + pruning_seed = tools::make_pruning_seed(pruning_seed, CRYPTONOTE_PRUNING_LOG_STRIPES); + v.mv_data = &pruning_seed; + v.mv_size = sizeof(pruning_seed); + result = mdb_put(txn, m_properties, &k, &v, 0); + if (result) + throw0(DB_ERROR("Failed to save pruning seed")); + prune_tip_table = false; + } + else if (result == 0) + { + // pruned already + if (v.mv_size != sizeof(uint32_t)) + throw0(DB_ERROR("Failed to retrieve or create pruning seed: unexpected value size")); + const uint32_t data = *(const uint32_t*)v.mv_data; + if (pruning_seed == 0) + pruning_seed = tools::get_pruning_stripe(data); + if (tools::get_pruning_stripe(data) != pruning_seed) + throw0(DB_ERROR("Blockchain already pruned with different seed")); + if (tools::get_pruning_log_stripes(data) != CRYPTONOTE_PRUNING_LOG_STRIPES) + throw0(DB_ERROR("Blockchain already pruned with different base")); + pruning_seed = tools::make_pruning_seed(pruning_seed, CRYPTONOTE_PRUNING_LOG_STRIPES); + prune_tip_table = (mode == prune_mode_update); + } + else + { + throw0(DB_ERROR(lmdb_error("Failed to retrieve or create pruning seed: ", result).c_str())); + } + + if (mode == prune_mode_check) + MINFO("Checking blockchain pruning..."); + else + MINFO("Pruning blockchain..."); + + MDB_cursor *c_txs_pruned, *c_txs_prunable, *c_txs_prunable_tip; + result = mdb_cursor_open(txn, m_txs_pruned, &c_txs_pruned); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for txs_pruned: ", result).c_str())); + result = mdb_cursor_open(txn, m_txs_prunable, &c_txs_prunable); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for txs_prunable: ", result).c_str())); + result = mdb_cursor_open(txn, m_txs_prunable_tip, &c_txs_prunable_tip); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for txs_prunable_tip: ", result).c_str())); + const uint64_t blockchain_height = height(); + + if (prune_tip_table) + { + MDB_cursor_op op = MDB_FIRST; + while (1) + { + int ret = mdb_cursor_get(c_txs_prunable_tip, &k, &v, op); + op = MDB_NEXT; + if (ret == MDB_NOTFOUND) + break; + if (ret) + throw0(DB_ERROR(lmdb_error("Failed to enumerate transactions: ", ret).c_str())); + + uint64_t block_height; + memcpy(&block_height, v.mv_data, sizeof(block_height)); + if (block_height + CRYPTONOTE_PRUNING_TIP_BLOCKS < blockchain_height) + { + ++n_total_records; + if (!tools::has_unpruned_block(block_height, blockchain_height, pruning_seed) && !is_v1_tx(c_txs_pruned, &k)) + { + ++n_prunable_records; + result = mdb_cursor_get(c_txs_prunable, &k, &v, MDB_SET); + if (result == MDB_NOTFOUND) + MWARNING("Already pruned at height " << block_height << "/" << blockchain_height); + else if (result) + throw0(DB_ERROR(lmdb_error("Failed to find transaction prunable data: ", result).c_str())); + else + { + MDEBUG("Pruning at height " << block_height << "/" << blockchain_height); + ++n_pruned_records; + n_bytes += k.mv_size + v.mv_size; + result = mdb_cursor_del(c_txs_prunable, 0); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to delete transaction prunable data: ", result).c_str())); + } + } + result = mdb_cursor_del(c_txs_prunable_tip, 0); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to delete transaction tip data: ", result).c_str())); + } + } + } + else + { + MDB_cursor *c_tx_indices; + result = mdb_cursor_open(txn, m_tx_indices, &c_tx_indices); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for tx_indices: ", result).c_str())); + MDB_cursor_op op = MDB_FIRST; + while (1) + { + int ret = mdb_cursor_get(c_tx_indices, &k, &v, op); + op = MDB_NEXT; + if (ret == MDB_NOTFOUND) + break; + if (ret) + throw0(DB_ERROR(lmdb_error("Failed to enumerate transactions: ", ret).c_str())); + + ++n_total_records; + //const txindex *ti = (const txindex *)v.mv_data; + txindex ti; + memcpy(&ti, v.mv_data, sizeof(ti)); + const uint64_t block_height = ti.data.block_id; + if (block_height + CRYPTONOTE_PRUNING_TIP_BLOCKS >= blockchain_height) + { + MDB_val_set(kp, ti.data.tx_id); + MDB_val_set(vp, block_height); + if (mode == prune_mode_check) + { + result = mdb_cursor_get(c_txs_prunable_tip, &kp, &vp, MDB_SET); + if (result && result != MDB_NOTFOUND) + throw0(DB_ERROR(lmdb_error("Error looking for transaction prunable data: ", result).c_str())); + if (result == MDB_NOTFOUND) + MERROR("Transaction not found in prunable tip table for height " << block_height << "/" << blockchain_height << + ", seed " << epee::string_tools::to_string_hex(pruning_seed)); + } + else + { + result = mdb_cursor_put(c_txs_prunable_tip, &kp, &vp, 0); + if (result && result != MDB_NOTFOUND) + throw0(DB_ERROR(lmdb_error("Error looking for transaction prunable data: ", result).c_str())); + } + } + MDB_val_set(kp, ti.data.tx_id); + if (!tools::has_unpruned_block(block_height, blockchain_height, pruning_seed) && !is_v1_tx(c_txs_pruned, &kp)) + { + result = mdb_cursor_get(c_txs_prunable, &kp, &v, MDB_SET); + if (result && result != MDB_NOTFOUND) + throw0(DB_ERROR(lmdb_error("Error looking for transaction prunable data: ", result).c_str())); + if (mode == prune_mode_check) + { + if (result != MDB_NOTFOUND) + MERROR("Prunable data found for pruned height " << block_height << "/" << blockchain_height << + ", seed " << epee::string_tools::to_string_hex(pruning_seed)); + } + else + { + ++n_prunable_records; + if (result == MDB_NOTFOUND) + MWARNING("Already pruned at height " << block_height << "/" << blockchain_height); + else + { + MDEBUG("Pruning at height " << block_height << "/" << blockchain_height); + ++n_pruned_records; + n_bytes += kp.mv_size + v.mv_size; + result = mdb_cursor_del(c_txs_prunable, 0); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to delete transaction prunable data: ", result).c_str())); + } + } + } + else + { + if (mode == prune_mode_check) + { + MDB_val_set(kp, ti.data.tx_id); + result = mdb_cursor_get(c_txs_prunable, &kp, &v, MDB_SET); + if (result && result != MDB_NOTFOUND) + throw0(DB_ERROR(lmdb_error("Error looking for transaction prunable data: ", result).c_str())); + if (result == MDB_NOTFOUND) + MERROR("Prunable data not found for unpruned height " << block_height << "/" << blockchain_height << + ", seed " << epee::string_tools::to_string_hex(pruning_seed)); + } + } + } + mdb_cursor_close(c_tx_indices); + } + + if ((result = mdb_stat(txn, m_txs_prunable, &db_stats))) + throw0(DB_ERROR(lmdb_error("Failed to query m_txs_prunable: ", result).c_str())); + const size_t pages1 = db_stats.ms_branch_pages + db_stats.ms_leaf_pages + db_stats.ms_overflow_pages; + const size_t db_bytes = (pages0 - pages1) * db_stats.ms_psize; + + mdb_cursor_close(c_txs_prunable_tip); + mdb_cursor_close(c_txs_prunable); + mdb_cursor_close(c_txs_pruned); + + txn.commit(); + + TIME_MEASURE_FINISH(t); + + MINFO((mode == prune_mode_check ? "Checked" : "Pruned") << " blockchain in " << + t << " ms: " << (n_bytes/1024.0f/1024.0f) << " MB (" << db_bytes/1024.0f/1024.0f << " MB) pruned in " << + n_pruned_records << " records (" << pages0 - pages1 << "/" << pages0 << " " << db_stats.ms_psize << " byte pages), " << + n_prunable_records << "/" << n_total_records << " pruned records"); + return true; +} + +bool BlockchainLMDB::prune_blockchain(uint32_t pruning_seed) +{ + return prune_worker(prune_mode_prune, pruning_seed); +} + +bool BlockchainLMDB::update_pruning() +{ + return prune_worker(prune_mode_update, 0); +} + +bool BlockchainLMDB::check_pruning() +{ + return prune_worker(prune_mode_check, 0); +} + bool BlockchainLMDB::for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)> f, bool include_blob, bool include_unrelayed_txes) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); @@ -2160,6 +2502,29 @@ uint64_t BlockchainLMDB::get_block_already_generated_coins(const uint64_t& heigh return ret; } +uint64_t BlockchainLMDB::get_block_long_term_weight(const uint64_t& height) const +{ + LOG_PRINT_L3("BlockchainLMDB::" << __func__); + check_open(); + + TXN_PREFIX_RDONLY(); + RCURSOR(block_info); + + MDB_val_set(result, height); + auto get_result = mdb_cursor_get(m_cur_block_info, (MDB_val *)&zerokval, &result, MDB_GET_BOTH); + if (get_result == MDB_NOTFOUND) + { + throw0(BLOCK_DNE(std::string("Attempt to get block long term weight from height ").append(boost::lexical_cast<std::string>(height)).append(" failed -- block info not in db").c_str())); + } + else if (get_result) + throw0(DB_ERROR("Error attempting to retrieve a long term block weight from the db")); + + mdb_block_info *bi = (mdb_block_info *)result.mv_data; + uint64_t ret = bi->bi_long_term_block_weight; + TXN_POSTFIX_RDONLY(); + return ret; +} + crypto::hash BlockchainLMDB::get_block_hash_from_height(const uint64_t& height) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); @@ -2428,6 +2793,36 @@ bool BlockchainLMDB::get_pruned_tx_blob(const crypto::hash& h, cryptonote::blobd return true; } +bool BlockchainLMDB::get_prunable_tx_blob(const crypto::hash& h, cryptonote::blobdata &bd) const +{ + LOG_PRINT_L3("BlockchainLMDB::" << __func__); + check_open(); + + TXN_PREFIX_RDONLY(); + RCURSOR(tx_indices); + RCURSOR(txs_prunable); + + MDB_val_set(v, h); + MDB_val result; + auto get_result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &v, MDB_GET_BOTH); + if (get_result == 0) + { + const txindex *tip = (const txindex *)v.mv_data; + MDB_val_set(val_tx_id, tip->data.tx_id); + get_result = mdb_cursor_get(m_cur_txs_prunable, &val_tx_id, &result, MDB_SET); + } + if (get_result == MDB_NOTFOUND) + return false; + else if (get_result) + throw0(DB_ERROR(lmdb_error("DB error attempting to fetch tx from hash", get_result).c_str())); + + bd.assign(reinterpret_cast<char*>(result.mv_data), result.mv_size); + + TXN_POSTFIX_RDONLY(); + + return true; +} + bool BlockchainLMDB::get_prunable_tx_hash(const crypto::hash& tx_hash, crypto::hash &prunable_hash) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); @@ -3168,7 +3563,7 @@ void BlockchainLMDB::block_txn_abort() } } -uint64_t BlockchainLMDB::add_block(const block& blk, size_t block_weight, const difficulty_type& cumulative_difficulty, const uint64_t& coins_generated, +uint64_t BlockchainLMDB::add_block(const block& blk, size_t block_weight, uint64_t long_term_block_weight, const difficulty_type& cumulative_difficulty, const uint64_t& coins_generated, const std::vector<transaction>& txs) { LOG_PRINT_L3("BlockchainLMDB::" << __func__); @@ -3187,7 +3582,7 @@ uint64_t BlockchainLMDB::add_block(const block& blk, size_t block_weight, const try { - BlockchainDB::add_block(blk, block_weight, cumulative_difficulty, coins_generated, txs); + BlockchainDB::add_block(blk, block_weight, long_term_block_weight, cumulative_difficulty, coins_generated, txs); } catch (const DB_ERROR_TXN_START& e) { @@ -4392,6 +4787,7 @@ void BlockchainLMDB::migrate_2_3() throw0(DB_ERROR(lmdb_error("Failed to delete old block_info table: ", result).c_str())); RENAME_DB("block_infn"); + mdb_dbi_close(m_env, m_block_info); lmdb_db_open(txn, "block_info", MDB_INTEGERKEY | MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED, m_block_info, "Failed to open db handle for block_infn"); mdb_set_dupsort(txn, m_block_info, compare_uint64); @@ -4412,6 +4808,166 @@ void BlockchainLMDB::migrate_2_3() txn.commit(); } +void BlockchainLMDB::migrate_3_4() +{ + LOG_PRINT_L3("BlockchainLMDB::" << __func__); + uint64_t i; + int result; + mdb_txn_safe txn(false); + MDB_val k, v; + char *ptr; + bool past_long_term_weight = false; + + MGINFO_YELLOW("Migrating blockchain from DB version 3 to 4 - this may take a while:"); + + do { + LOG_PRINT_L1("migrating block info:"); + + result = mdb_txn_begin(m_env, NULL, 0, txn); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", result).c_str())); + + MDB_stat db_stats; + if ((result = mdb_stat(txn, m_blocks, &db_stats))) + throw0(DB_ERROR(lmdb_error("Failed to query m_blocks: ", result).c_str())); + const uint64_t blockchain_height = db_stats.ms_entries; + + boost::circular_buffer<uint64_t> long_term_block_weights(CRYPTONOTE_LONG_TERM_BLOCK_WEIGHT_WINDOW_SIZE); + + /* the block_info table name is the same but the old version and new version + * have incompatible data. Create a new table. We want the name to be similar + * to the old name so that it will occupy the same location in the DB. + */ + MDB_dbi o_block_info = m_block_info; + lmdb_db_open(txn, "block_infn", MDB_INTEGERKEY | MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED, m_block_info, "Failed to open db handle for block_infn"); + mdb_set_dupsort(txn, m_block_info, compare_uint64); + + + MDB_cursor *c_blocks; + result = mdb_cursor_open(txn, m_blocks, &c_blocks); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for blocks: ", result).c_str())); + + MDB_cursor *c_old, *c_cur; + i = 0; + while(1) { + if (!(i % 1000)) { + if (i) { + LOGIF(el::Level::Info) { + std::cout << i << " / " << blockchain_height << " \r" << std::flush; + } + txn.commit(); + result = mdb_txn_begin(m_env, NULL, 0, txn); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", result).c_str())); + } + result = mdb_cursor_open(txn, m_block_info, &c_cur); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for block_infn: ", result).c_str())); + result = mdb_cursor_open(txn, o_block_info, &c_old); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for block_info: ", result).c_str())); + result = mdb_cursor_open(txn, m_blocks, &c_blocks); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to open a cursor for blocks: ", result).c_str())); + if (!i) { + MDB_stat db_stat; + result = mdb_stat(txn, m_block_info, &db_stats); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to query m_block_info: ", result).c_str())); + i = db_stats.ms_entries; + } + } + result = mdb_cursor_get(c_old, &k, &v, MDB_NEXT); + if (result == MDB_NOTFOUND) { + txn.commit(); + break; + } + else if (result) + throw0(DB_ERROR(lmdb_error("Failed to get a record from block_info: ", result).c_str())); + const mdb_block_info_2 *bi_old = (const mdb_block_info_2*)v.mv_data; + mdb_block_info_3 bi; + bi.bi_height = bi_old->bi_height; + bi.bi_timestamp = bi_old->bi_timestamp; + bi.bi_coins = bi_old->bi_coins; + bi.bi_weight = bi_old->bi_weight; + bi.bi_diff = bi_old->bi_diff; + bi.bi_hash = bi_old->bi_hash; + bi.bi_cum_rct = bi_old->bi_cum_rct; + + // get block major version to determine which rule is in place + if (!past_long_term_weight) + { + MDB_val_copy<uint64_t> kb(bi.bi_height); + MDB_val vb; + result = mdb_cursor_get(c_blocks, &kb, &vb, MDB_SET); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to query m_blocks: ", result).c_str())); + if (vb.mv_size == 0) + throw0(DB_ERROR("Invalid data from m_blocks")); + const uint8_t block_major_version = *((const uint8_t*)vb.mv_data); + if (block_major_version >= HF_VERSION_LONG_TERM_BLOCK_WEIGHT) + past_long_term_weight = true; + } + + uint64_t long_term_block_weight; + if (past_long_term_weight) + { + std::vector<uint64_t> weights(long_term_block_weights.begin(), long_term_block_weights.end()); + uint64_t long_term_effective_block_median_weight = std::max<uint64_t>(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5, epee::misc_utils::median(weights)); + long_term_block_weight = std::min<uint64_t>(bi.bi_weight, long_term_effective_block_median_weight + long_term_effective_block_median_weight * 2 / 5); + } + else + { + long_term_block_weight = bi.bi_weight; + } + long_term_block_weights.push_back(long_term_block_weight); + bi.bi_long_term_block_weight = long_term_block_weight; + + MDB_val_set(nv, bi); + result = mdb_cursor_put(c_cur, (MDB_val *)&zerokval, &nv, MDB_APPENDDUP); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to put a record into block_infn: ", result).c_str())); + /* we delete the old records immediately, so the overall DB and mapsize should not grow. + * This is a little slower than just letting mdb_drop() delete it all at the end, but + * it saves a significant amount of disk space. + */ + result = mdb_cursor_del(c_old, 0); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to delete a record from block_info: ", result).c_str())); + i++; + } + + result = mdb_txn_begin(m_env, NULL, 0, txn); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", result).c_str())); + /* Delete the old table */ + result = mdb_drop(txn, o_block_info, 1); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to delete old block_info table: ", result).c_str())); + + RENAME_DB("block_infn"); + mdb_dbi_close(m_env, m_block_info); + + lmdb_db_open(txn, "block_info", MDB_INTEGERKEY | MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED, m_block_info, "Failed to open db handle for block_infn"); + mdb_set_dupsort(txn, m_block_info, compare_uint64); + + txn.commit(); + } while(0); + + uint32_t version = 4; + v.mv_data = (void *)&version; + v.mv_size = sizeof(version); + MDB_val_str(vk, "version"); + result = mdb_txn_begin(m_env, NULL, 0, txn); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", result).c_str())); + result = mdb_put(txn, m_properties, &vk, &v, 0); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to update version for the db: ", result).c_str())); + txn.commit(); +} + void BlockchainLMDB::migrate(const uint32_t oldversion) { if (oldversion < 1) @@ -4420,6 +4976,8 @@ void BlockchainLMDB::migrate(const uint32_t oldversion) migrate_1_2(); if (oldversion < 3) migrate_2_3(); + if (oldversion < 4) + migrate_3_4(); } } // namespace cryptonote diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h index a60956ab1..5764f9ae4 100644 --- a/src/blockchain_db/lmdb/db_lmdb.h +++ b/src/blockchain_db/lmdb/db_lmdb.h @@ -40,6 +40,11 @@ namespace cryptonote { +typedef struct txindex { + crypto::hash key; + tx_data_t data; +} txindex; + typedef struct mdb_txn_cursors { MDB_cursor *m_txc_blocks; @@ -53,6 +58,7 @@ typedef struct mdb_txn_cursors MDB_cursor *m_txc_txs_pruned; MDB_cursor *m_txc_txs_prunable; MDB_cursor *m_txc_txs_prunable_hash; + MDB_cursor *m_txc_txs_prunable_tip; MDB_cursor *m_txc_tx_indices; MDB_cursor *m_txc_tx_outputs; @@ -62,6 +68,8 @@ typedef struct mdb_txn_cursors MDB_cursor *m_txc_txpool_blob; MDB_cursor *m_txc_hf_versions; + + MDB_cursor *m_txc_properties; } mdb_txn_cursors; #define m_cur_blocks m_cursors->m_txc_blocks @@ -73,12 +81,14 @@ typedef struct mdb_txn_cursors #define m_cur_txs_pruned m_cursors->m_txc_txs_pruned #define m_cur_txs_prunable m_cursors->m_txc_txs_prunable #define m_cur_txs_prunable_hash m_cursors->m_txc_txs_prunable_hash +#define m_cur_txs_prunable_tip m_cursors->m_txc_txs_prunable_tip #define m_cur_tx_indices m_cursors->m_txc_tx_indices #define m_cur_tx_outputs m_cursors->m_txc_tx_outputs #define m_cur_spent_keys m_cursors->m_txc_spent_keys #define m_cur_txpool_meta m_cursors->m_txc_txpool_meta #define m_cur_txpool_blob m_cursors->m_txc_txpool_blob #define m_cur_hf_versions m_cursors->m_txc_hf_versions +#define m_cur_properties m_cursors->m_txc_properties typedef struct mdb_rflags { @@ -92,12 +102,14 @@ typedef struct mdb_rflags bool m_rf_txs_pruned; bool m_rf_txs_prunable; bool m_rf_txs_prunable_hash; + bool m_rf_txs_prunable_tip; bool m_rf_tx_indices; bool m_rf_tx_outputs; bool m_rf_spent_keys; bool m_rf_txpool_meta; bool m_rf_txpool_blob; bool m_rf_hf_versions; + bool m_rf_properties; } mdb_rflags; typedef struct mdb_threadinfo @@ -213,6 +225,8 @@ public: virtual uint64_t get_block_already_generated_coins(const uint64_t& height) const; + virtual uint64_t get_block_long_term_weight(const uint64_t& height) const; + virtual crypto::hash get_block_hash_from_height(const uint64_t& height) const; virtual std::vector<block> get_blocks_range(const uint64_t& h1, const uint64_t& h2) const; @@ -232,6 +246,7 @@ public: virtual bool get_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const; virtual bool get_pruned_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const; + virtual bool get_prunable_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const; virtual bool get_prunable_tx_hash(const crypto::hash& tx_hash, crypto::hash &prunable_hash) const; virtual uint64_t get_tx_count() const; @@ -264,6 +279,11 @@ public: virtual bool get_txpool_tx_meta(const crypto::hash& txid, txpool_tx_meta_t &meta) const; virtual bool get_txpool_tx_blob(const crypto::hash& txid, cryptonote::blobdata &bd) const; virtual cryptonote::blobdata get_txpool_tx_blob(const crypto::hash& txid) const; + virtual uint32_t get_blockchain_pruning_seed() const; + virtual bool prune_blockchain(uint32_t pruning_seed = 0); + virtual bool update_pruning(); + virtual bool check_pruning(); + virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)> f, bool include_blob = false, bool include_unrelayed_txes = true) const; virtual bool for_all_key_images(std::function<bool(const crypto::key_image&)>) const; @@ -274,6 +294,7 @@ public: virtual uint64_t add_block( const block& blk , size_t block_weight + , uint64_t long_term_block_weight , const difficulty_type& cumulative_difficulty , const uint64_t& coins_generated , const std::vector<transaction>& txs @@ -309,6 +330,11 @@ public: bool get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t to_height, std::vector<uint64_t> &distribution, uint64_t &base) const; + // helper functions + static int compare_uint64(const MDB_val *a, const MDB_val *b); + static int compare_hash32(const MDB_val *a, const MDB_val *b); + static int compare_string(const MDB_val *a, const MDB_val *b); + private: void do_resize(uint64_t size_increase=0); @@ -318,6 +344,7 @@ private: virtual void add_block( const block& blk , size_t block_weight + , uint64_t long_term_block_weight , const difficulty_type& cumulative_difficulty , const uint64_t& coins_generated , uint64_t num_rct_outs @@ -361,6 +388,8 @@ private: inline void check_open() const; + bool prune_worker(int mode, uint32_t pruning_seed); + virtual bool is_read_only() const; virtual uint64_t get_database_size() const; @@ -380,6 +409,9 @@ private: // migrate from DB version 2 to 3 void migrate_2_3(); + // migrate from DB version 3 to 4 + void migrate_3_4(); + void cleanup_batch(); private: @@ -393,6 +425,7 @@ private: MDB_dbi m_txs_pruned; MDB_dbi m_txs_prunable; MDB_dbi m_txs_prunable_hash; + MDB_dbi m_txs_prunable_tip; MDB_dbi m_tx_indices; MDB_dbi m_tx_outputs; diff --git a/tests/unit_tests/testdb.h b/src/blockchain_db/testdb.h index 8f5cf70e8..35dfbe673 100644 --- a/tests/unit_tests/testdb.h +++ b/src/blockchain_db/testdb.h @@ -33,9 +33,11 @@ #include <string> #include <vector> #include <map> -#include "gtest/gtest.h" -#include "blockchain_db/blockchain_db.h" +#include "blockchain_db.h" + +namespace cryptonote +{ class BaseTestDB: public cryptonote::BlockchainDB { public: @@ -73,6 +75,7 @@ public: virtual cryptonote::difficulty_type get_block_cumulative_difficulty(const uint64_t& height) const { return 10; } virtual cryptonote::difficulty_type get_block_difficulty(const uint64_t& height) const { return 0; } virtual uint64_t get_block_already_generated_coins(const uint64_t& height) const { return 10000000000; } + virtual uint64_t get_block_long_term_weight(const uint64_t& height) const { return 128; } virtual crypto::hash get_block_hash_from_height(const uint64_t& height) const { return crypto::hash(); } virtual std::vector<cryptonote::block> get_blocks_range(const uint64_t& h1, const uint64_t& h2) const { return std::vector<cryptonote::block>(); } virtual std::vector<crypto::hash> get_hashes_range(const uint64_t& h1, const uint64_t& h2) const { return std::vector<crypto::hash>(); } @@ -128,6 +131,7 @@ public: virtual void add_block( const cryptonote::block& blk , size_t block_weight + , uint64_t long_term_block_weight , const cryptonote::difficulty_type& cumulative_difficulty , const uint64_t& coins_generated , uint64_t num_rct_outs @@ -145,3 +149,4 @@ public: virtual void prune_outputs(uint64_t amount) {} }; +} diff --git a/src/blockchain_utilities/CMakeLists.txt b/src/blockchain_utilities/CMakeLists.txt index ddf575c29..df74eb695 100644 --- a/src/blockchain_utilities/CMakeLists.txt +++ b/src/blockchain_utilities/CMakeLists.txt @@ -92,6 +92,17 @@ monero_private_headers(blockchain_prune_known_spent_data +set(blockchain_prune_sources + blockchain_prune.cpp + ) + +set(blockchain_prune_private_headers) + +monero_private_headers(blockchain_prune + ${blockchain_prune_private_headers}) + + + set(blockchain_ancestry_sources blockchain_ancestry.cpp ) @@ -298,3 +309,25 @@ set_property(TARGET blockchain_prune_known_spent_data PROPERTY OUTPUT_NAME "monero-blockchain-prune-known-spent-data") install(TARGETS blockchain_prune_known_spent_data DESTINATION bin) + +monero_add_executable(blockchain_prune + ${blockchain_prune_sources} + ${blockchain_prune_private_headers}) + +set_property(TARGET blockchain_prune + PROPERTY + OUTPUT_NAME "monero-blockchain-prune") +install(TARGETS blockchain_prune DESTINATION bin) + +target_link_libraries(blockchain_prune + PRIVATE + cryptonote_core + blockchain_db + p2p + version + epee + ${Boost_FILESYSTEM_LIBRARY} + ${Boost_SYSTEM_LIBRARY} + ${Boost_THREAD_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${EXTRA_LIBRARIES}) diff --git a/src/blockchain_utilities/blockchain_export.cpp b/src/blockchain_utilities/blockchain_export.cpp index 5a49f3478..5c5bc7f69 100644 --- a/src/blockchain_utilities/blockchain_export.cpp +++ b/src/blockchain_utilities/blockchain_export.cpp @@ -177,6 +177,12 @@ int main(int argc, char* argv[]) } r = core_storage->init(db, opt_testnet ? cryptonote::TESTNET : opt_stagenet ? cryptonote::STAGENET : cryptonote::MAINNET); + if (core_storage->get_blockchain_pruning_seed()) + { + LOG_PRINT_L0("Blockchain is pruned, cannot export"); + return 1; + } + CHECK_AND_ASSERT_MES(r, 1, "Failed to initialize source blockchain storage"); LOG_PRINT_L0("Source blockchain storage initialized OK"); LOG_PRINT_L0("Exporting blockchain raw data..."); diff --git a/src/blockchain_utilities/blockchain_import.cpp b/src/blockchain_utilities/blockchain_import.cpp index 2a8a6f494..e6ec20c3b 100644 --- a/src/blockchain_utilities/blockchain_import.cpp +++ b/src/blockchain_utilities/blockchain_import.cpp @@ -485,7 +485,8 @@ int import_from_file(cryptonote::core& core, const std::string& import_file_path try { - core.get_blockchain_storage().get_db().add_block(b, block_weight, cumulative_difficulty, coins_generated, txs); + uint64_t long_term_block_weight = core.get_blockchain_storage().get_next_long_term_block_weight(block_weight); + core.get_blockchain_storage().get_db().add_block(b, block_weight, long_term_block_weight, cumulative_difficulty, coins_generated, txs); } catch (const std::exception& e) { diff --git a/src/blockchain_utilities/blockchain_prune.cpp b/src/blockchain_utilities/blockchain_prune.cpp new file mode 100644 index 000000000..8e13f2c04 --- /dev/null +++ b/src/blockchain_utilities/blockchain_prune.cpp @@ -0,0 +1,663 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <array> +#include <lmdb.h> +#include <boost/algorithm/string.hpp> +#include "common/command_line.h" +#include "common/pruning.h" +#include "cryptonote_core/cryptonote_core.h" +#include "cryptonote_core/blockchain.h" +#include "blockchain_db/blockchain_db.h" +#include "blockchain_db/lmdb/db_lmdb.h" +#include "blockchain_db/db_types.h" +#include "version.h" + +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "bcutil" + +#define MDB_val_set(var, val) MDB_val var = {sizeof(val), (void *)&val} + +namespace po = boost::program_options; +using namespace epee; +using namespace cryptonote; + +static std::string db_path; + +// default to fast:1 +static uint64_t records_per_sync = 128; +static const size_t slack = 512 * 1024 * 1024; + +static std::error_code replace_file(const boost::filesystem::path& replacement_name, const boost::filesystem::path& replaced_name) +{ + std::error_code ec = tools::replace_file(replacement_name.string(), replaced_name.string()); + if (ec) + MERROR("Error renaming " << replacement_name << " to " << replaced_name << ": " << ec.message()); + return ec; +} + +static void open(MDB_env *&env, const boost::filesystem::path &path, uint64_t db_flags, bool readonly) +{ + int dbr; + int flags = 0; + + if (db_flags & DBF_FAST) + flags |= MDB_NOSYNC; + if (db_flags & DBF_FASTEST) + flags |= MDB_NOSYNC | MDB_WRITEMAP | MDB_MAPASYNC; + if (readonly) + flags |= MDB_RDONLY; + + dbr = mdb_env_create(&env); + if (dbr) throw std::runtime_error("Failed to create LDMB environment: " + std::string(mdb_strerror(dbr))); + dbr = mdb_env_set_maxdbs(env, 32); + if (dbr) throw std::runtime_error("Failed to set max env dbs: " + std::string(mdb_strerror(dbr))); + dbr = mdb_env_open(env, path.string().c_str(), flags, 0664); + if (dbr) throw std::runtime_error("Failed to open database file '" + + path.string() + "': " + std::string(mdb_strerror(dbr))); +} + +static void close(MDB_env *env) +{ + mdb_env_close(env); +} + +static void add_size(MDB_env *env, uint64_t bytes) +{ + try + { + boost::filesystem::path path(db_path); + boost::filesystem::space_info si = boost::filesystem::space(path); + if(si.available < bytes) + { + MERROR("!! WARNING: Insufficient free space to extend database !!: " << + (si.available >> 20L) << " MB available, " << (bytes >> 20L) << " MB needed"); + return; + } + } + catch(...) + { + // print something but proceed. + MWARNING("Unable to query free disk space."); + } + + MDB_envinfo mei; + mdb_env_info(env, &mei); + MDB_stat mst; + mdb_env_stat(env, &mst); + + uint64_t new_mapsize = (uint64_t)mei.me_mapsize + bytes; + new_mapsize += (new_mapsize % mst.ms_psize); + + int result = mdb_env_set_mapsize(env, new_mapsize); + if (result) + throw std::runtime_error("Failed to set new mapsize to " + std::to_string(new_mapsize) + ": " + std::string(mdb_strerror(result))); + + MGINFO("LMDB Mapsize increased." << " Old: " << mei.me_mapsize / (1024 * 1024) << "MiB" << ", New: " << new_mapsize / (1024 * 1024) << "MiB"); +} + +static void check_resize(MDB_env *env, size_t bytes) +{ + MDB_envinfo mei; + MDB_stat mst; + + mdb_env_info(env, &mei); + mdb_env_stat(env, &mst); + + uint64_t size_used = mst.ms_psize * mei.me_last_pgno; + if (size_used + bytes + slack >= mei.me_mapsize) + add_size(env, size_used + bytes + 2 * slack - mei.me_mapsize); +} + +static bool resize_point(size_t nrecords, MDB_env *env, MDB_txn **txn, size_t &bytes) +{ + if (nrecords % records_per_sync && bytes <= slack / 2) + return false; + int dbr = mdb_txn_commit(*txn); + if (dbr) throw std::runtime_error("Failed to commit txn: " + std::string(mdb_strerror(dbr))); + check_resize(env, bytes); + dbr = mdb_txn_begin(env, NULL, 0, txn); + if (dbr) throw std::runtime_error("Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr))); + bytes = 0; + return true; +} + +static void copy_table(MDB_env *env0, MDB_env *env1, const char *table, unsigned int flags, unsigned int putflags, int (*cmp)(const MDB_val*, const MDB_val*)=0) +{ + MDB_dbi dbi0, dbi1; + MDB_txn *txn0, *txn1; + MDB_cursor *cur0, *cur1; + bool tx_active0 = false, tx_active1 = false; + int dbr; + + MINFO("Copying " << table); + + epee::misc_utils::auto_scope_leave_caller txn_dtor = epee::misc_utils::create_scope_leave_handler([&](){ + if (tx_active1) mdb_txn_abort(txn1); + if (tx_active0) mdb_txn_abort(txn0); + }); + + dbr = mdb_txn_begin(env0, NULL, MDB_RDONLY, &txn0); + if (dbr) throw std::runtime_error("Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr))); + tx_active0 = true; + dbr = mdb_txn_begin(env1, NULL, 0, &txn1); + if (dbr) throw std::runtime_error("Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr))); + tx_active1 = true; + + dbr = mdb_dbi_open(txn0, table, flags, &dbi0); + if (dbr) throw std::runtime_error("Failed to open LMDB dbi: " + std::string(mdb_strerror(dbr))); + if (cmp) + ((flags & MDB_DUPSORT) ? mdb_set_dupsort : mdb_set_compare)(txn0, dbi0, cmp); + + dbr = mdb_dbi_open(txn1, table, flags, &dbi1); + if (dbr) throw std::runtime_error("Failed to open LMDB dbi: " + std::string(mdb_strerror(dbr))); + if (cmp) + ((flags & MDB_DUPSORT) ? mdb_set_dupsort : mdb_set_compare)(txn1, dbi1, cmp); + + dbr = mdb_txn_commit(txn1); + if (dbr) throw std::runtime_error("Failed to commit txn: " + std::string(mdb_strerror(dbr))); + tx_active1 = false; + MDB_stat stats; + dbr = mdb_env_stat(env0, &stats); + if (dbr) throw std::runtime_error("Failed to stat " + std::string(table) + " LMDB table: " + std::string(mdb_strerror(dbr))); + check_resize(env1, (stats.ms_branch_pages + stats.ms_overflow_pages + stats.ms_leaf_pages) * stats.ms_psize); + dbr = mdb_txn_begin(env1, NULL, 0, &txn1); + if (dbr) throw std::runtime_error("Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr))); + tx_active1 = true; + + dbr = mdb_drop(txn1, dbi1, 0); + if (dbr) throw std::runtime_error("Failed to empty " + std::string(table) + " LMDB table: " + std::string(mdb_strerror(dbr))); + + dbr = mdb_cursor_open(txn0, dbi0, &cur0); + if (dbr) throw std::runtime_error("Failed to create LMDB cursor: " + std::string(mdb_strerror(dbr))); + dbr = mdb_cursor_open(txn1, dbi1, &cur1); + if (dbr) throw std::runtime_error("Failed to create LMDB cursor: " + std::string(mdb_strerror(dbr))); + + MDB_val k; + MDB_val v; + MDB_cursor_op op = MDB_FIRST; + size_t nrecords = 0, bytes = 0; + while (1) + { + int ret = mdb_cursor_get(cur0, &k, &v, op); + op = MDB_NEXT; + if (ret == MDB_NOTFOUND) + break; + if (ret) + throw std::runtime_error("Failed to enumerate " + std::string(table) + " records: " + std::string(mdb_strerror(ret))); + + bytes += k.mv_size + v.mv_size; + if (resize_point(++nrecords, env1, &txn1, bytes)) + { + dbr = mdb_cursor_open(txn1, dbi1, &cur1); + if (dbr) throw std::runtime_error("Failed to create LMDB cursor: " + std::string(mdb_strerror(dbr))); + } + + ret = mdb_cursor_put(cur1, &k, &v, putflags); + if (ret) + throw std::runtime_error("Failed to write " + std::string(table) + " record: " + std::string(mdb_strerror(ret))); + } + + mdb_cursor_close(cur1); + mdb_cursor_close(cur0); + mdb_txn_commit(txn1); + tx_active1 = false; + mdb_txn_commit(txn0); + tx_active0 = false; + mdb_dbi_close(env1, dbi1); + mdb_dbi_close(env0, dbi0); +} + +static bool is_v1_tx(MDB_cursor *c_txs_pruned, MDB_val *tx_id) +{ + MDB_val v; + int ret = mdb_cursor_get(c_txs_pruned, tx_id, &v, MDB_SET); + if (ret) + throw std::runtime_error("Failed to find transaction pruned data: " + std::string(mdb_strerror(ret))); + if (v.mv_size == 0) + throw std::runtime_error("Invalid transaction pruned data"); + return cryptonote::is_v1_tx(cryptonote::blobdata_ref{(const char*)v.mv_data, v.mv_size}); +} + +static void prune(MDB_env *env0, MDB_env *env1) +{ + MDB_dbi dbi0_blocks, dbi0_txs_pruned, dbi0_txs_prunable, dbi0_tx_indices, dbi1_txs_prunable, dbi1_txs_prunable_tip, dbi1_properties; + MDB_txn *txn0, *txn1; + MDB_cursor *cur0_txs_pruned, *cur0_txs_prunable, *cur0_tx_indices, *cur1_txs_prunable, *cur1_txs_prunable_tip; + bool tx_active0 = false, tx_active1 = false; + int dbr; + + MGINFO("Creating pruned txs_prunable"); + + epee::misc_utils::auto_scope_leave_caller txn_dtor = epee::misc_utils::create_scope_leave_handler([&](){ + if (tx_active1) mdb_txn_abort(txn1); + if (tx_active0) mdb_txn_abort(txn0); + }); + + dbr = mdb_txn_begin(env0, NULL, MDB_RDONLY, &txn0); + if (dbr) throw std::runtime_error("Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr))); + tx_active0 = true; + dbr = mdb_txn_begin(env1, NULL, 0, &txn1); + if (dbr) throw std::runtime_error("Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr))); + tx_active1 = true; + + dbr = mdb_dbi_open(txn0, "txs_pruned", MDB_INTEGERKEY, &dbi0_txs_pruned); + if (dbr) throw std::runtime_error("Failed to open LMDB dbi: " + std::string(mdb_strerror(dbr))); + mdb_set_compare(txn0, dbi0_txs_pruned, BlockchainLMDB::compare_uint64); + dbr = mdb_cursor_open(txn0, dbi0_txs_pruned, &cur0_txs_pruned); + if (dbr) throw std::runtime_error("Failed to create LMDB cursor: " + std::string(mdb_strerror(dbr))); + + dbr = mdb_dbi_open(txn0, "txs_prunable", MDB_INTEGERKEY, &dbi0_txs_prunable); + if (dbr) throw std::runtime_error("Failed to open LMDB dbi: " + std::string(mdb_strerror(dbr))); + mdb_set_compare(txn0, dbi0_txs_prunable, BlockchainLMDB::compare_uint64); + dbr = mdb_cursor_open(txn0, dbi0_txs_prunable, &cur0_txs_prunable); + if (dbr) throw std::runtime_error("Failed to create LMDB cursor: " + std::string(mdb_strerror(dbr))); + + dbr = mdb_dbi_open(txn0, "tx_indices", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, &dbi0_tx_indices); + if (dbr) throw std::runtime_error("Failed to open LMDB dbi: " + std::string(mdb_strerror(dbr))); + mdb_set_dupsort(txn0, dbi0_tx_indices, BlockchainLMDB::compare_hash32); + dbr = mdb_cursor_open(txn0, dbi0_tx_indices, &cur0_tx_indices); + if (dbr) throw std::runtime_error("Failed to create LMDB cursor: " + std::string(mdb_strerror(dbr))); + + dbr = mdb_dbi_open(txn1, "txs_prunable", MDB_INTEGERKEY, &dbi1_txs_prunable); + if (dbr) throw std::runtime_error("Failed to open LMDB dbi: " + std::string(mdb_strerror(dbr))); + mdb_set_compare(txn1, dbi1_txs_prunable, BlockchainLMDB::compare_uint64); + dbr = mdb_cursor_open(txn1, dbi1_txs_prunable, &cur1_txs_prunable); + if (dbr) throw std::runtime_error("Failed to create LMDB cursor: " + std::string(mdb_strerror(dbr))); + + dbr = mdb_dbi_open(txn1, "txs_prunable_tip", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, &dbi1_txs_prunable_tip); + if (dbr) throw std::runtime_error("Failed to open LMDB dbi: " + std::string(mdb_strerror(dbr))); + mdb_set_dupsort(txn1, dbi1_txs_prunable_tip, BlockchainLMDB::compare_uint64); + dbr = mdb_cursor_open(txn1, dbi1_txs_prunable_tip, &cur1_txs_prunable_tip); + if (dbr) throw std::runtime_error("Failed to create LMDB cursor: " + std::string(mdb_strerror(dbr))); + + dbr = mdb_drop(txn1, dbi1_txs_prunable, 0); + if (dbr) throw std::runtime_error("Failed to empty LMDB table: " + std::string(mdb_strerror(dbr))); + dbr = mdb_drop(txn1, dbi1_txs_prunable_tip, 0); + if (dbr) throw std::runtime_error("Failed to empty LMDB table: " + std::string(mdb_strerror(dbr))); + + dbr = mdb_dbi_open(txn1, "properties", 0, &dbi1_properties); + if (dbr) throw std::runtime_error("Failed to open LMDB dbi: " + std::string(mdb_strerror(dbr))); + + MDB_val k, v; + uint32_t pruning_seed = tools::make_pruning_seed(tools::get_random_stripe(), CRYPTONOTE_PRUNING_LOG_STRIPES); + static char pruning_seed_key[] = "pruning_seed"; + k.mv_data = pruning_seed_key; + k.mv_size = strlen("pruning_seed") + 1; + v.mv_data = (void*)&pruning_seed; + v.mv_size = sizeof(pruning_seed); + dbr = mdb_put(txn1, dbi1_properties, &k, &v, 0); + if (dbr) throw std::runtime_error("Failed to save pruning seed: " + std::string(mdb_strerror(dbr))); + + MDB_stat stats; + dbr = mdb_dbi_open(txn0, "blocks", 0, &dbi0_blocks); + if (dbr) throw std::runtime_error("Failed to open LMDB dbi: " + std::string(mdb_strerror(dbr))); + dbr = mdb_stat(txn0, dbi0_blocks, &stats); + if (dbr) throw std::runtime_error("Failed to query size of blocks: " + std::string(mdb_strerror(dbr))); + mdb_dbi_close(env0, dbi0_blocks); + const uint64_t blockchain_height = stats.ms_entries; + size_t nrecords = 0, bytes = 0; + + MDB_cursor_op op = MDB_FIRST; + while (1) + { + int ret = mdb_cursor_get(cur0_tx_indices, &k, &v, op); + op = MDB_NEXT; + if (ret == MDB_NOTFOUND) + break; + if (ret) throw std::runtime_error("Failed to enumerate records: " + std::string(mdb_strerror(ret))); + + const txindex *ti = (const txindex*)v.mv_data; + const uint64_t block_height = ti->data.block_id; + MDB_val_set(kk, ti->data.tx_id); + if (block_height + CRYPTONOTE_PRUNING_TIP_BLOCKS >= blockchain_height) + { + MDEBUG(block_height << "/" << blockchain_height << " is in tip"); + MDB_val_set(vv, block_height); + dbr = mdb_cursor_put(cur1_txs_prunable_tip, &kk, &vv, 0); + if (dbr) throw std::runtime_error("Failed to write prunable tx tip data: " + std::string(mdb_strerror(dbr))); + bytes += kk.mv_size + vv.mv_size; + } + if (tools::has_unpruned_block(block_height, blockchain_height, pruning_seed) || is_v1_tx(cur0_txs_pruned, &kk)) + { + MDB_val vv; + dbr = mdb_cursor_get(cur0_txs_prunable, &kk, &vv, MDB_SET); + if (dbr) throw std::runtime_error("Failed to read prunable tx data: " + std::string(mdb_strerror(dbr))); + bytes += kk.mv_size + vv.mv_size; + if (resize_point(++nrecords, env1, &txn1, bytes)) + { + dbr = mdb_cursor_open(txn1, dbi1_txs_prunable, &cur1_txs_prunable); + if (dbr) throw std::runtime_error("Failed to create LMDB cursor: " + std::string(mdb_strerror(dbr))); + dbr = mdb_cursor_open(txn1, dbi1_txs_prunable_tip, &cur1_txs_prunable_tip); + if (dbr) throw std::runtime_error("Failed to create LMDB cursor: " + std::string(mdb_strerror(dbr))); + } + dbr = mdb_cursor_put(cur1_txs_prunable, &kk, &vv, 0); + if (dbr) throw std::runtime_error("Failed to write prunable tx data: " + std::string(mdb_strerror(dbr))); + } + else + { + MDEBUG("" << block_height << "/" << blockchain_height << " should be pruned, dropping"); + } + } + + mdb_cursor_close(cur1_txs_prunable_tip); + mdb_cursor_close(cur1_txs_prunable); + mdb_cursor_close(cur0_txs_prunable); + mdb_cursor_close(cur0_txs_pruned); + mdb_cursor_close(cur0_tx_indices); + mdb_txn_commit(txn1); + tx_active1 = false; + mdb_txn_commit(txn0); + tx_active0 = false; + mdb_dbi_close(env1, dbi1_properties); + mdb_dbi_close(env1, dbi1_txs_prunable_tip); + mdb_dbi_close(env1, dbi1_txs_prunable); + mdb_dbi_close(env0, dbi0_txs_prunable); + mdb_dbi_close(env0, dbi0_txs_pruned); + mdb_dbi_close(env0, dbi0_tx_indices); +} + +static bool parse_db_sync_mode(std::string db_sync_mode, uint64_t &db_flags) +{ + std::vector<std::string> options; + boost::trim(db_sync_mode); + boost::split(options, db_sync_mode, boost::is_any_of(" :")); + + for(const auto &option : options) + MDEBUG("option: " << option); + + // default to fast:async:1 + uint64_t DEFAULT_FLAGS = DBF_FAST; + + db_flags = 0; + + if(options.size() == 0) + { + // default to fast:async:1 + db_flags = DEFAULT_FLAGS; + } + + bool safemode = false; + if(options.size() >= 1) + { + if(options[0] == "safe") + { + safemode = true; + db_flags = DBF_SAFE; + } + else if(options[0] == "fast") + { + db_flags = DBF_FAST; + } + else if(options[0] == "fastest") + { + db_flags = DBF_FASTEST; + records_per_sync = 1000; // default to fastest:async:1000 + } + else + return false; + } + + if(options.size() >= 2 && !safemode) + { + char *endptr; + uint64_t bps = strtoull(options[1].c_str(), &endptr, 0); + if (*endptr != '\0') + return false; + records_per_sync = bps; + } + + return true; +} + +int main(int argc, char* argv[]) +{ + TRY_ENTRY(); + + epee::string_tools::set_module_name_and_folder(argv[0]); + + std::string default_db_type = "lmdb"; + + std::string available_dbs = cryptonote::blockchain_db_types(", "); + available_dbs = "available: " + available_dbs; + + uint32_t log_level = 0; + + tools::on_startup(); + + boost::filesystem::path output_file_path; + + po::options_description desc_cmd_only("Command line options"); + po::options_description desc_cmd_sett("Command line options and settings options"); + const command_line::arg_descriptor<std::string> arg_log_level = {"log-level", "0-4 or categories", ""}; + const command_line::arg_descriptor<std::string> arg_database = { + "database", available_dbs.c_str(), default_db_type + }; + const command_line::arg_descriptor<std::string> arg_db_sync_mode = { + "db-sync-mode" + , "Specify sync option, using format [safe|fast|fastest]:[nrecords_per_sync]." + , "fast:1000" + }; + const command_line::arg_descriptor<bool> arg_copy_pruned_database = {"copy-pruned-database", "Copy database anyway if already pruned"}; + + command_line::add_arg(desc_cmd_sett, cryptonote::arg_data_dir); + command_line::add_arg(desc_cmd_sett, cryptonote::arg_testnet_on); + command_line::add_arg(desc_cmd_sett, cryptonote::arg_stagenet_on); + command_line::add_arg(desc_cmd_sett, arg_log_level); + command_line::add_arg(desc_cmd_sett, arg_database); + command_line::add_arg(desc_cmd_sett, arg_db_sync_mode); + command_line::add_arg(desc_cmd_sett, arg_copy_pruned_database); + command_line::add_arg(desc_cmd_only, command_line::arg_help); + + po::options_description desc_options("Allowed options"); + desc_options.add(desc_cmd_only).add(desc_cmd_sett); + + po::variables_map vm; + bool r = command_line::handle_error_helper(desc_options, [&]() + { + auto parser = po::command_line_parser(argc, argv).options(desc_options); + po::store(parser.run(), vm); + po::notify(vm); + return true; + }); + if (! r) + return 1; + + if (command_line::get_arg(vm, command_line::arg_help)) + { + std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL; + std::cout << desc_options << std::endl; + return 1; + } + + mlog_configure(mlog_get_default_log_path("monero-blockchain-prune.log"), true); + if (!command_line::is_arg_defaulted(vm, arg_log_level)) + mlog_set_log(command_line::get_arg(vm, arg_log_level).c_str()); + else + mlog_set_log(std::string(std::to_string(log_level) + ",bcutil:INFO").c_str()); + + MINFO("Starting..."); + + bool opt_testnet = command_line::get_arg(vm, cryptonote::arg_testnet_on); + bool opt_stagenet = command_line::get_arg(vm, cryptonote::arg_stagenet_on); + network_type net_type = opt_testnet ? TESTNET : opt_stagenet ? STAGENET : MAINNET; + bool opt_copy_pruned_database = command_line::get_arg(vm, arg_copy_pruned_database); + std::string data_dir = command_line::get_arg(vm, cryptonote::arg_data_dir); + while (boost::ends_with(data_dir, "/") || boost::ends_with(data_dir, "\\")) + data_dir.pop_back(); + + std::string db_type = command_line::get_arg(vm, arg_database); + if (!cryptonote::blockchain_valid_db_type(db_type)) + { + MERROR("Invalid database type: " << db_type); + return 1; + } + if (db_type != "lmdb") + { + MERROR("Unsupported database type: " << db_type << ". Only lmdb is supported"); + return 1; + } + + std::string db_sync_mode = command_line::get_arg(vm, arg_db_sync_mode); + uint64_t db_flags = 0; + if (!parse_db_sync_mode(db_sync_mode, db_flags)) + { + MERROR("Invalid db sync mode: " << db_sync_mode); + return 1; + } + + // If we wanted to use the memory pool, we would set up a fake_core. + + // Use Blockchain instead of lower-level BlockchainDB for two reasons: + // 1. Blockchain has the init() method for easy setup + // 2. exporter needs to use get_current_blockchain_height(), get_block_id_by_height(), get_block_by_hash() + // + // cannot match blockchain_storage setup above with just one line, + // e.g. + // Blockchain* core_storage = new Blockchain(NULL); + // because unlike blockchain_storage constructor, which takes a pointer to + // tx_memory_pool, Blockchain's constructor takes tx_memory_pool object. + MINFO("Initializing source blockchain (BlockchainDB)"); + std::array<std::unique_ptr<Blockchain>, 2> core_storage; + Blockchain *blockchain = NULL; + tx_memory_pool m_mempool(*blockchain); + boost::filesystem::path paths[2]; + bool already_pruned = false; + for (size_t n = 0; n < core_storage.size(); ++n) + { + core_storage[n].reset(new Blockchain(m_mempool)); + + BlockchainDB* db = new_db(db_type); + if (db == NULL) + { + MERROR("Attempted to use non-existent database type: " << db_type); + throw std::runtime_error("Attempting to use non-existent database type"); + } + MDEBUG("database: " << db_type); + + if (n == 1) + { + paths[1] = boost::filesystem::path(data_dir) / (db->get_db_name() + "-pruned"); + if (boost::filesystem::exists(paths[1])) + { + if (!boost::filesystem::is_directory(paths[1])) + { + MERROR("LMDB needs a directory path, but a file was passed: " << paths[1].string()); + return 1; + } + } + else + { + if (!boost::filesystem::create_directories(paths[1])) + { + MERROR("Failed to create directory: " << paths[1].string()); + return 1; + } + } + db_path = paths[1].string(); + } + else + { + paths[0] = boost::filesystem::path(data_dir) / db->get_db_name(); + } + + MINFO("Loading blockchain from folder " << paths[n] << " ..."); + + try + { + db->open(paths[n].string(), n == 0 ? DBF_RDONLY : 0); + } + catch (const std::exception& e) + { + MERROR("Error opening database: " << e.what()); + return 1; + } + r = core_storage[n]->init(db, net_type); + + std::string source_dest = n == 0 ? "source" : "pruned"; + CHECK_AND_ASSERT_MES(r, 1, "Failed to initialize " << source_dest << " blockchain storage"); + MINFO(source_dest << " blockchain storage initialized OK"); + if (n == 0 && core_storage[0]->get_blockchain_pruning_seed()) + { + if (!opt_copy_pruned_database) + { + MERROR("Blockchain is already pruned, use --" << arg_copy_pruned_database.name << " to copy it anyway"); + return 1; + } + already_pruned = true; + } + } + core_storage[0]->deinit(); + core_storage[0].reset(NULL); + core_storage[1]->deinit(); + core_storage[1].reset(NULL); + + MINFO("Pruning..."); + MDB_env *env0 = NULL, *env1 = NULL; + open(env0, paths[0], db_flags, true); + open(env1, paths[1], db_flags, false); + copy_table(env0, env1, "blocks", MDB_INTEGERKEY, MDB_APPEND); + copy_table(env0, env1, "block_info", MDB_INTEGERKEY | MDB_DUPSORT| MDB_DUPFIXED, MDB_APPENDDUP, BlockchainLMDB::compare_uint64); + copy_table(env0, env1, "block_heights", MDB_INTEGERKEY | MDB_DUPSORT| MDB_DUPFIXED, 0, BlockchainLMDB::compare_hash32); + //copy_table(env0, env1, "txs", MDB_INTEGERKEY); + copy_table(env0, env1, "txs_pruned", MDB_INTEGERKEY, MDB_APPEND); + copy_table(env0, env1, "txs_prunable_hash", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, MDB_APPEND); + // not copied: prunable, prunable_tip + copy_table(env0, env1, "tx_indices", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, 0, BlockchainLMDB::compare_hash32); + copy_table(env0, env1, "tx_outputs", MDB_INTEGERKEY, MDB_APPEND); + copy_table(env0, env1, "output_txs", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, MDB_APPENDDUP, BlockchainLMDB::compare_uint64); + copy_table(env0, env1, "output_amounts", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, MDB_APPENDDUP, BlockchainLMDB::compare_uint64); + copy_table(env0, env1, "spent_keys", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, MDB_NODUPDATA, BlockchainLMDB::compare_hash32); + copy_table(env0, env1, "txpool_meta", 0, MDB_NODUPDATA, BlockchainLMDB::compare_hash32); + copy_table(env0, env1, "txpool_blob", 0, MDB_NODUPDATA, BlockchainLMDB::compare_hash32); + copy_table(env0, env1, "hf_versions", MDB_INTEGERKEY, MDB_APPEND); + copy_table(env0, env1, "properties", 0, 0, BlockchainLMDB::compare_string); + if (already_pruned) + { + copy_table(env0, env1, "txs_prunable", MDB_INTEGERKEY, MDB_APPEND, BlockchainLMDB::compare_uint64); + copy_table(env0, env1, "txs_prunable_tip", MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, MDB_NODUPDATA, BlockchainLMDB::compare_uint64); + } + else + { + prune(env0, env1); + } + close(env1); + close(env0); + + MINFO("Swapping databases, pre-pruning blockchain will be left in " << paths[0].string() + "-old and can be removed if desired"); + if (replace_file(paths[0].string(), paths[0].string() + "-old") || replace_file(paths[1].string(), paths[0].string())) + { + MERROR("Blockchain pruned OK, but renaming failed"); + return 1; + } + + MINFO("Blockchain pruned OK"); + return 0; + + CATCH_ENTRY("Pruning error", 1); +} diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 3b1eb6d23..212a1891e 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -40,6 +40,7 @@ set(common_sources notify.cpp password.cpp perf_timer.cpp + pruning.cpp spawn.cpp threadpool.cpp updates.cpp @@ -69,6 +70,7 @@ set(common_private_headers http_connection.h notify.h pod-class.h + pruning.h rpc_client.h scoped_message_writer.h unordered_containers_boost_serialization.h diff --git a/src/common/download.cpp b/src/common/download.cpp index 58ce0595f..7c38cfa5b 100644 --- a/src/common/download.cpp +++ b/src/common/download.cpp @@ -179,8 +179,8 @@ namespace tools lock.unlock(); - bool ssl = u_c.schema == "https"; - uint16_t port = u_c.port ? u_c.port : ssl ? 443 : 80; + epee::net_utils::ssl_support_t ssl = u_c.schema == "https" ? epee::net_utils::ssl_support_t::e_ssl_support_enabled : epee::net_utils::ssl_support_t::e_ssl_support_disabled; + uint16_t port = u_c.port ? u_c.port : ssl == epee::net_utils::ssl_support_t::e_ssl_support_enabled ? 443 : 80; MDEBUG("Connecting to " << u_c.host << ":" << port); client.set_server(u_c.host, std::to_string(port), boost::none, ssl); if (!client.connect(std::chrono::seconds(30))) diff --git a/src/common/notify.cpp b/src/common/notify.cpp index cadc68ea7..e2df5096d 100644 --- a/src/common/notify.cpp +++ b/src/common/notify.cpp @@ -27,11 +27,15 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <boost/algorithm/string.hpp> +#include <stdarg.h> #include "misc_log_ex.h" #include "file_io_utils.h" #include "spawn.h" #include "notify.h" +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "notify" + namespace tools { @@ -44,17 +48,34 @@ Notify::Notify(const char *spec) { CHECK_AND_ASSERT_THROW_MES(spec, "Null spec"); - boost::split(args, spec, boost::is_any_of(" ")); + boost::split(args, spec, boost::is_any_of(" \t"), boost::token_compress_on); CHECK_AND_ASSERT_THROW_MES(args.size() > 0, "Failed to parse spec"); + if (strchr(spec, '\'') || strchr(spec, '\"') || strchr(spec, '\\')) + MWARNING("A notification spec contains a quote or backslash: note that these are handled verbatim, which may not be the intent"); filename = args[0]; CHECK_AND_ASSERT_THROW_MES(epee::file_io_utils::is_file_exist(filename), "File not found: " << filename); } -int Notify::notify(const char *parameter) +static void replace(std::vector<std::string> &v, const char *tag, const char *s) +{ + for (std::string &str: v) + boost::replace_all(str, tag, s); +} + +int Notify::notify(const char *tag, const char *s, ...) { std::vector<std::string> margs = args; - for (std::string &s: margs) - boost::replace_all(s, "%s", parameter); + + replace(margs, tag, s); + + va_list ap; + va_start(ap, s); + while ((tag = va_arg(ap, const char*))) + { + s = va_arg(ap, const char*); + replace(margs, tag, s); + } + va_end(ap); return tools::spawn(filename.c_str(), margs, false); } diff --git a/src/common/notify.h b/src/common/notify.h index 81aacebb0..f813e8def 100644 --- a/src/common/notify.h +++ b/src/common/notify.h @@ -39,7 +39,7 @@ class Notify public: Notify(const char *spec); - int notify(const char *parameter); + int notify(const char *tag, const char *s, ...); private: std::string filename; diff --git a/src/common/pruning.cpp b/src/common/pruning.cpp new file mode 100644 index 000000000..442b24e4e --- /dev/null +++ b/src/common/pruning.cpp @@ -0,0 +1,116 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "cryptonote_config.h" +#include "misc_log_ex.h" +#include "crypto/crypto.h" +#include "pruning.h" + +namespace tools +{ + +uint32_t make_pruning_seed(uint32_t stripe, uint32_t log_stripes) +{ + CHECK_AND_ASSERT_THROW_MES(log_stripes <= PRUNING_SEED_LOG_STRIPES_MASK, "log_stripes out of range"); + CHECK_AND_ASSERT_THROW_MES(stripe > 0 && stripe <= (1ul << log_stripes), "stripe out of range"); + return (log_stripes << PRUNING_SEED_LOG_STRIPES_SHIFT) | ((stripe - 1) << PRUNING_SEED_STRIPE_SHIFT); +} + +bool has_unpruned_block(uint64_t block_height, uint64_t blockchain_height, uint32_t pruning_seed) +{ + const uint32_t stripe = get_pruning_stripe(pruning_seed); + if (stripe == 0) + return true; + const uint32_t log_stripes = get_pruning_log_stripes(pruning_seed); + uint32_t block_stripe = get_pruning_stripe(block_height, blockchain_height, log_stripes); + return block_stripe == 0 || block_stripe == stripe; +} + +uint32_t get_pruning_stripe(uint64_t block_height, uint64_t blockchain_height, uint32_t log_stripes) +{ + if (block_height + CRYPTONOTE_PRUNING_TIP_BLOCKS >= blockchain_height) + return 0; + return ((block_height / CRYPTONOTE_PRUNING_STRIPE_SIZE) & (uint64_t)((1ul << log_stripes) - 1)) + 1; +} + +uint32_t get_pruning_seed(uint64_t block_height, uint64_t blockchain_height, uint32_t log_stripes) +{ + const uint32_t stripe = get_pruning_stripe(block_height, blockchain_height, log_stripes); + if (stripe == 0) + return 0; + return make_pruning_seed(stripe, log_stripes); +} + +uint64_t get_next_unpruned_block_height(uint64_t block_height, uint64_t blockchain_height, uint32_t pruning_seed) +{ + CHECK_AND_ASSERT_MES(block_height <= CRYPTONOTE_MAX_BLOCK_NUMBER+1, block_height, "block_height too large"); + CHECK_AND_ASSERT_MES(blockchain_height <= CRYPTONOTE_MAX_BLOCK_NUMBER+1, block_height, "blockchain_height too large"); + const uint32_t stripe = get_pruning_stripe(pruning_seed); + if (stripe == 0) + return block_height; + if (block_height + CRYPTONOTE_PRUNING_TIP_BLOCKS >= blockchain_height) + return block_height; + const uint32_t seed_log_stripes = get_pruning_log_stripes(pruning_seed); + const uint64_t log_stripes = seed_log_stripes ? seed_log_stripes : CRYPTONOTE_PRUNING_LOG_STRIPES; + const uint64_t mask = (1ul << log_stripes) - 1; + const uint32_t block_pruning_stripe = ((block_height / CRYPTONOTE_PRUNING_STRIPE_SIZE) & mask) + 1; + if (block_pruning_stripe == stripe) + return block_height; + const uint64_t cycles = ((block_height / CRYPTONOTE_PRUNING_STRIPE_SIZE) >> log_stripes); + const uint64_t cycle_start = cycles + ((stripe > block_pruning_stripe) ? 0 : 1); + const uint64_t h = cycle_start * (CRYPTONOTE_PRUNING_STRIPE_SIZE << log_stripes) + (stripe - 1) * CRYPTONOTE_PRUNING_STRIPE_SIZE; + if (h + CRYPTONOTE_PRUNING_TIP_BLOCKS > blockchain_height) + return blockchain_height < CRYPTONOTE_PRUNING_TIP_BLOCKS ? 0 : blockchain_height - CRYPTONOTE_PRUNING_TIP_BLOCKS; + CHECK_AND_ASSERT_MES(h >= block_height, block_height, "h < block_height, unexpected"); + return h; +} + +uint64_t get_next_pruned_block_height(uint64_t block_height, uint64_t blockchain_height, uint32_t pruning_seed) +{ + const uint32_t stripe = get_pruning_stripe(pruning_seed); + if (stripe == 0) + return blockchain_height; + if (block_height + CRYPTONOTE_PRUNING_TIP_BLOCKS >= blockchain_height) + return blockchain_height; + const uint32_t seed_log_stripes = get_pruning_log_stripes(pruning_seed); + const uint64_t log_stripes = seed_log_stripes ? seed_log_stripes : CRYPTONOTE_PRUNING_LOG_STRIPES; + const uint64_t mask = (1ul << log_stripes) - 1; + const uint32_t block_pruning_seed = ((block_height / CRYPTONOTE_PRUNING_STRIPE_SIZE) & mask) + 1; + if (block_pruning_seed != stripe) + return block_height; + const uint32_t next_stripe = 1 + (block_pruning_seed & mask); + return get_next_unpruned_block_height(block_height, blockchain_height, tools::make_pruning_seed(next_stripe, log_stripes)); +} + +uint32_t get_random_stripe() +{ + return 1 + crypto::rand<uint8_t>() % (1ul << CRYPTONOTE_PRUNING_LOG_STRIPES); +} + +} + diff --git a/src/common/pruning.h b/src/common/pruning.h new file mode 100644 index 000000000..3fac3c0fa --- /dev/null +++ b/src/common/pruning.h @@ -0,0 +1,52 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include <stdint.h> + +namespace tools +{ + static constexpr uint32_t PRUNING_SEED_LOG_STRIPES_SHIFT = 7; + static constexpr uint32_t PRUNING_SEED_LOG_STRIPES_MASK = 0x7; + static constexpr uint32_t PRUNING_SEED_STRIPE_SHIFT = 0; + static constexpr uint32_t PRUNING_SEED_STRIPE_MASK = 0x7f; + + constexpr inline uint32_t get_pruning_log_stripes(uint32_t pruning_seed) { return (pruning_seed >> PRUNING_SEED_LOG_STRIPES_SHIFT) & PRUNING_SEED_LOG_STRIPES_MASK; } + inline uint32_t get_pruning_stripe(uint32_t pruning_seed) { if (pruning_seed == 0) return 0; return 1 + ((pruning_seed >> PRUNING_SEED_STRIPE_SHIFT) & PRUNING_SEED_STRIPE_MASK); } + + uint32_t make_pruning_seed(uint32_t stripe, uint32_t log_stripes); + + bool has_unpruned_block(uint64_t block_height, uint64_t blockchain_height, uint32_t pruning_seed); + uint32_t get_pruning_stripe(uint64_t block_height, uint64_t blockchain_height, uint32_t log_stripes); + uint32_t get_pruning_seed(uint64_t block_height, uint64_t blockchain_height, uint32_t log_stripes); + uint64_t get_next_unpruned_block_height(uint64_t block_height, uint64_t blockchain_height, uint32_t pruning_seed); + uint64_t get_next_pruned_block_height(uint64_t block_height, uint64_t blockchain_height, uint32_t pruning_seed); + uint32_t get_random_stripe(); +} + diff --git a/src/common/spawn.cpp b/src/common/spawn.cpp index b2d03f62f..e03552f8c 100644 --- a/src/common/spawn.cpp +++ b/src/common/spawn.cpp @@ -42,6 +42,9 @@ #include "util.h" #include "spawn.h" +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "spawn" + namespace tools { diff --git a/src/common/varint.h b/src/common/varint.h index 151d13dbf..904255afc 100644 --- a/src/common/varint.h +++ b/src/common/varint.h @@ -123,6 +123,6 @@ namespace tools { */ template<typename InputIt, typename T> int read_varint(InputIt &&first, InputIt &&last, T &i) { - return read_varint<std::numeric_limits<T>::digits, InputIt, T>(std::move(first), std::move(last), i); + return read_varint<std::numeric_limits<T>::digits>(std::forward<InputIt>(first), std::forward<InputIt>(last), i); } } diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt index 0c635e7cb..5ce43be22 100644 --- a/src/crypto/CMakeLists.txt +++ b/src/crypto/CMakeLists.txt @@ -45,6 +45,8 @@ set(crypto_sources random.c skein.c slow-hash.c + CryptonightR_JIT.c + CryptonightR_template.S tree-hash.c) set(crypto_headers) @@ -66,7 +68,9 @@ set(crypto_private_headers oaes_lib.h random.h skein.h - skein_port.h) + skein_port.h + CryptonightR_JIT.h + CryptonightR_template.h) monero_private_headers(cncrypto ${crypto_private_headers}) @@ -101,4 +105,5 @@ if (ANDROID OR IOS) endif() endif() - +# cheat because cmake and ccache hate each other +set_property(SOURCE CryptonightR_template.S PROPERTY LANGUAGE C) diff --git a/src/crypto/CryptonightR_JIT.c b/src/crypto/CryptonightR_JIT.c new file mode 100644 index 000000000..9add65296 --- /dev/null +++ b/src/crypto/CryptonightR_JIT.c @@ -0,0 +1,102 @@ +#include <assert.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> +#include <stdio.h> +#include <unistd.h> + +#include "int-util.h" +#include "hash-ops.h" +#include "variant4_random_math.h" +#include "CryptonightR_JIT.h" +#include "CryptonightR_template.h" + +static const uint8_t prologue[] = { + 0x4C, 0x8B, 0xD7, // mov r10, rdi + 0x53, // push rbx + 0x55, // push rbp + 0x41, 0x57, // push r15 + 0x4C, 0x8B, 0xDC, // mov r11, rsp + 0x41, 0x8B, 0x1A, // mov ebx, DWORD PTR [r10] + 0x41, 0x8B, 0x72, 0x04, // mov esi, DWORD PTR [r10+4] + 0x41, 0x8B, 0x7A, 0x08, // mov edi, DWORD PTR [r10+8] + 0x41, 0x8B, 0x6A, 0x0C, // mov ebp, DWORD PTR [r10+12] + 0x41, 0x8B, 0x62, 0x10, // mov esp, DWORD PTR [r10+16] + 0x45, 0x8B, 0x7A, 0x14, // mov r15d, DWORD PTR [r10+20] + 0x41, 0x8B, 0x42, 0x18, // mov eax, DWORD PTR [r10+24] + 0x41, 0x8B, 0x52, 0x1C, // mov edx, DWORD PTR [r10+28] + 0x45, 0x8B, 0x4A, 0x20, // mov r9d, DWORD PTR [r10+32] +}; + +static const uint8_t epilogue[] = { + 0x49, 0x8B, 0xE3, // mov rsp, r11 + 0x41, 0x89, 0x1A, // mov DWORD PTR [r10], ebx + 0x41, 0x89, 0x72, 0x04, // mov DWORD PTR [r10+4], esi + 0x41, 0x89, 0x7A, 0x08, // mov DWORD PTR [r10+8], edi + 0x41, 0x89, 0x6A, 0x0C, // mov DWORD PTR [r10+12], ebp + 0x41, 0x5F, // pop r15 + 0x5D, // pop rbp + 0x5B, // pop rbx + 0xC3, // ret +}; + +#define APPEND_CODE(src, size) \ + do { \ + if (JIT_code + (size) > JIT_code_end) \ + return -1; \ + memcpy(JIT_code, (src), (size)); \ + JIT_code += (size); \ + } while (0) + +int v4_generate_JIT_code(const struct V4_Instruction* code, v4_random_math_JIT_func buf, const size_t buf_size) +{ + uint8_t* JIT_code = (uint8_t*) buf; + const uint8_t* JIT_code_end = JIT_code + buf_size; + + APPEND_CODE(prologue, sizeof(prologue)); + + uint32_t prev_rot_src = 0xFFFFFFFFU; + + for (int i = 0;; ++i) + { + const struct V4_Instruction inst = code[i]; + if (inst.opcode == RET) + break; + + const uint8_t opcode = (inst.opcode == MUL) ? inst.opcode : (inst.opcode + 2); + + const uint32_t a = inst.dst_index; + const uint32_t b = inst.src_index; + const uint8_t c = opcode | (inst.dst_index << V4_OPCODE_BITS) | (((inst.src_index == 8) ? inst.dst_index : inst.src_index) << (V4_OPCODE_BITS + V4_DST_INDEX_BITS)); + + switch (inst.opcode) + { + case ROR: + case ROL: + if (b != prev_rot_src) + { + prev_rot_src = b; + const uint8_t* p1 = (const uint8_t*) instructions_mov[c]; + const uint8_t* p2 = (const uint8_t*) instructions_mov[c + 1]; + APPEND_CODE(p1, p2 - p1); + } + break; + } + + if (a == prev_rot_src) + prev_rot_src = 0xFFFFFFFFU; + + const uint8_t* p1 = (const uint8_t*) instructions[c]; + const uint8_t* p2 = (const uint8_t*) instructions[c + 1]; + APPEND_CODE(p1, p2 - p1); + + if (inst.opcode == ADD) + *(uint32_t*)(JIT_code - 4) = inst.C; + } + + APPEND_CODE(epilogue, sizeof(epilogue)); + + __builtin___clear_cache((char*)buf, (char*)JIT_code); + + return 0; +} diff --git a/src/crypto/CryptonightR_JIT.h b/src/crypto/CryptonightR_JIT.h new file mode 100644 index 000000000..5f689b37b --- /dev/null +++ b/src/crypto/CryptonightR_JIT.h @@ -0,0 +1,18 @@ +#ifndef CRYPTONIGHTR_JIT_H +#define CRYPTONIGHTR_JIT_H + +// Minimalistic JIT code generator for random math sequence in CryptonightR +// +// Usage: +// - Allocate writable and executable memory +// - Call v4_generate_JIT_code with "buf" pointed to memory allocated on previous step +// - Call the generated code instead of "v4_random_math(code, r)", omit the "code" parameter + +typedef void (*v4_random_math_JIT_func)(uint32_t* r) __attribute__((sysv_abi)); + +// Given the random math sequence, generates machine code (x86-64) for it +// Returns 0 if code was generated successfully +// Returns -1 if provided buffer was too small +int v4_generate_JIT_code(const struct V4_Instruction* code, v4_random_math_JIT_func buf, const size_t buf_size); + +#endif // CRYPTONIGHTR_JIT_H diff --git a/src/crypto/CryptonightR_template.S b/src/crypto/CryptonightR_template.S new file mode 100644 index 000000000..068de22ec --- /dev/null +++ b/src/crypto/CryptonightR_template.S @@ -0,0 +1,1590 @@ +#ifdef __APPLE__ +# define ALIGN(x) .align 6 +#else +# define ALIGN(x) .align 64 +#endif +.intel_syntax noprefix +#ifdef __APPLE__ +# define FN_PREFIX(fn) _ ## fn +.text +#else +# define FN_PREFIX(fn) fn +.section .text +#endif + +#define PUBLIC .global + +PUBLIC FN_PREFIX(CryptonightR_instruction0) +PUBLIC FN_PREFIX(CryptonightR_instruction1) +PUBLIC FN_PREFIX(CryptonightR_instruction2) +PUBLIC FN_PREFIX(CryptonightR_instruction3) +PUBLIC FN_PREFIX(CryptonightR_instruction4) +PUBLIC FN_PREFIX(CryptonightR_instruction5) +PUBLIC FN_PREFIX(CryptonightR_instruction6) +PUBLIC FN_PREFIX(CryptonightR_instruction7) +PUBLIC FN_PREFIX(CryptonightR_instruction8) +PUBLIC FN_PREFIX(CryptonightR_instruction9) +PUBLIC FN_PREFIX(CryptonightR_instruction10) +PUBLIC FN_PREFIX(CryptonightR_instruction11) +PUBLIC FN_PREFIX(CryptonightR_instruction12) +PUBLIC FN_PREFIX(CryptonightR_instruction13) +PUBLIC FN_PREFIX(CryptonightR_instruction14) +PUBLIC FN_PREFIX(CryptonightR_instruction15) +PUBLIC FN_PREFIX(CryptonightR_instruction16) +PUBLIC FN_PREFIX(CryptonightR_instruction17) +PUBLIC FN_PREFIX(CryptonightR_instruction18) +PUBLIC FN_PREFIX(CryptonightR_instruction19) +PUBLIC FN_PREFIX(CryptonightR_instruction20) +PUBLIC FN_PREFIX(CryptonightR_instruction21) +PUBLIC FN_PREFIX(CryptonightR_instruction22) +PUBLIC FN_PREFIX(CryptonightR_instruction23) +PUBLIC FN_PREFIX(CryptonightR_instruction24) +PUBLIC FN_PREFIX(CryptonightR_instruction25) +PUBLIC FN_PREFIX(CryptonightR_instruction26) +PUBLIC FN_PREFIX(CryptonightR_instruction27) +PUBLIC FN_PREFIX(CryptonightR_instruction28) +PUBLIC FN_PREFIX(CryptonightR_instruction29) +PUBLIC FN_PREFIX(CryptonightR_instruction30) +PUBLIC FN_PREFIX(CryptonightR_instruction31) +PUBLIC FN_PREFIX(CryptonightR_instruction32) +PUBLIC FN_PREFIX(CryptonightR_instruction33) +PUBLIC FN_PREFIX(CryptonightR_instruction34) +PUBLIC FN_PREFIX(CryptonightR_instruction35) +PUBLIC FN_PREFIX(CryptonightR_instruction36) +PUBLIC FN_PREFIX(CryptonightR_instruction37) +PUBLIC FN_PREFIX(CryptonightR_instruction38) +PUBLIC FN_PREFIX(CryptonightR_instruction39) +PUBLIC FN_PREFIX(CryptonightR_instruction40) +PUBLIC FN_PREFIX(CryptonightR_instruction41) +PUBLIC FN_PREFIX(CryptonightR_instruction42) +PUBLIC FN_PREFIX(CryptonightR_instruction43) +PUBLIC FN_PREFIX(CryptonightR_instruction44) +PUBLIC FN_PREFIX(CryptonightR_instruction45) +PUBLIC FN_PREFIX(CryptonightR_instruction46) +PUBLIC FN_PREFIX(CryptonightR_instruction47) +PUBLIC FN_PREFIX(CryptonightR_instruction48) +PUBLIC FN_PREFIX(CryptonightR_instruction49) +PUBLIC FN_PREFIX(CryptonightR_instruction50) +PUBLIC FN_PREFIX(CryptonightR_instruction51) +PUBLIC FN_PREFIX(CryptonightR_instruction52) +PUBLIC FN_PREFIX(CryptonightR_instruction53) +PUBLIC FN_PREFIX(CryptonightR_instruction54) +PUBLIC FN_PREFIX(CryptonightR_instruction55) +PUBLIC FN_PREFIX(CryptonightR_instruction56) +PUBLIC FN_PREFIX(CryptonightR_instruction57) +PUBLIC FN_PREFIX(CryptonightR_instruction58) +PUBLIC FN_PREFIX(CryptonightR_instruction59) +PUBLIC FN_PREFIX(CryptonightR_instruction60) +PUBLIC FN_PREFIX(CryptonightR_instruction61) +PUBLIC FN_PREFIX(CryptonightR_instruction62) +PUBLIC FN_PREFIX(CryptonightR_instruction63) +PUBLIC FN_PREFIX(CryptonightR_instruction64) +PUBLIC FN_PREFIX(CryptonightR_instruction65) +PUBLIC FN_PREFIX(CryptonightR_instruction66) +PUBLIC FN_PREFIX(CryptonightR_instruction67) +PUBLIC FN_PREFIX(CryptonightR_instruction68) +PUBLIC FN_PREFIX(CryptonightR_instruction69) +PUBLIC FN_PREFIX(CryptonightR_instruction70) +PUBLIC FN_PREFIX(CryptonightR_instruction71) +PUBLIC FN_PREFIX(CryptonightR_instruction72) +PUBLIC FN_PREFIX(CryptonightR_instruction73) +PUBLIC FN_PREFIX(CryptonightR_instruction74) +PUBLIC FN_PREFIX(CryptonightR_instruction75) +PUBLIC FN_PREFIX(CryptonightR_instruction76) +PUBLIC FN_PREFIX(CryptonightR_instruction77) +PUBLIC FN_PREFIX(CryptonightR_instruction78) +PUBLIC FN_PREFIX(CryptonightR_instruction79) +PUBLIC FN_PREFIX(CryptonightR_instruction80) +PUBLIC FN_PREFIX(CryptonightR_instruction81) +PUBLIC FN_PREFIX(CryptonightR_instruction82) +PUBLIC FN_PREFIX(CryptonightR_instruction83) +PUBLIC FN_PREFIX(CryptonightR_instruction84) +PUBLIC FN_PREFIX(CryptonightR_instruction85) +PUBLIC FN_PREFIX(CryptonightR_instruction86) +PUBLIC FN_PREFIX(CryptonightR_instruction87) +PUBLIC FN_PREFIX(CryptonightR_instruction88) +PUBLIC FN_PREFIX(CryptonightR_instruction89) +PUBLIC FN_PREFIX(CryptonightR_instruction90) +PUBLIC FN_PREFIX(CryptonightR_instruction91) +PUBLIC FN_PREFIX(CryptonightR_instruction92) +PUBLIC FN_PREFIX(CryptonightR_instruction93) +PUBLIC FN_PREFIX(CryptonightR_instruction94) +PUBLIC FN_PREFIX(CryptonightR_instruction95) +PUBLIC FN_PREFIX(CryptonightR_instruction96) +PUBLIC FN_PREFIX(CryptonightR_instruction97) +PUBLIC FN_PREFIX(CryptonightR_instruction98) +PUBLIC FN_PREFIX(CryptonightR_instruction99) +PUBLIC FN_PREFIX(CryptonightR_instruction100) +PUBLIC FN_PREFIX(CryptonightR_instruction101) +PUBLIC FN_PREFIX(CryptonightR_instruction102) +PUBLIC FN_PREFIX(CryptonightR_instruction103) +PUBLIC FN_PREFIX(CryptonightR_instruction104) +PUBLIC FN_PREFIX(CryptonightR_instruction105) +PUBLIC FN_PREFIX(CryptonightR_instruction106) +PUBLIC FN_PREFIX(CryptonightR_instruction107) +PUBLIC FN_PREFIX(CryptonightR_instruction108) +PUBLIC FN_PREFIX(CryptonightR_instruction109) +PUBLIC FN_PREFIX(CryptonightR_instruction110) +PUBLIC FN_PREFIX(CryptonightR_instruction111) +PUBLIC FN_PREFIX(CryptonightR_instruction112) +PUBLIC FN_PREFIX(CryptonightR_instruction113) +PUBLIC FN_PREFIX(CryptonightR_instruction114) +PUBLIC FN_PREFIX(CryptonightR_instruction115) +PUBLIC FN_PREFIX(CryptonightR_instruction116) +PUBLIC FN_PREFIX(CryptonightR_instruction117) +PUBLIC FN_PREFIX(CryptonightR_instruction118) +PUBLIC FN_PREFIX(CryptonightR_instruction119) +PUBLIC FN_PREFIX(CryptonightR_instruction120) +PUBLIC FN_PREFIX(CryptonightR_instruction121) +PUBLIC FN_PREFIX(CryptonightR_instruction122) +PUBLIC FN_PREFIX(CryptonightR_instruction123) +PUBLIC FN_PREFIX(CryptonightR_instruction124) +PUBLIC FN_PREFIX(CryptonightR_instruction125) +PUBLIC FN_PREFIX(CryptonightR_instruction126) +PUBLIC FN_PREFIX(CryptonightR_instruction127) +PUBLIC FN_PREFIX(CryptonightR_instruction128) +PUBLIC FN_PREFIX(CryptonightR_instruction129) +PUBLIC FN_PREFIX(CryptonightR_instruction130) +PUBLIC FN_PREFIX(CryptonightR_instruction131) +PUBLIC FN_PREFIX(CryptonightR_instruction132) +PUBLIC FN_PREFIX(CryptonightR_instruction133) +PUBLIC FN_PREFIX(CryptonightR_instruction134) +PUBLIC FN_PREFIX(CryptonightR_instruction135) +PUBLIC FN_PREFIX(CryptonightR_instruction136) +PUBLIC FN_PREFIX(CryptonightR_instruction137) +PUBLIC FN_PREFIX(CryptonightR_instruction138) +PUBLIC FN_PREFIX(CryptonightR_instruction139) +PUBLIC FN_PREFIX(CryptonightR_instruction140) +PUBLIC FN_PREFIX(CryptonightR_instruction141) +PUBLIC FN_PREFIX(CryptonightR_instruction142) +PUBLIC FN_PREFIX(CryptonightR_instruction143) +PUBLIC FN_PREFIX(CryptonightR_instruction144) +PUBLIC FN_PREFIX(CryptonightR_instruction145) +PUBLIC FN_PREFIX(CryptonightR_instruction146) +PUBLIC FN_PREFIX(CryptonightR_instruction147) +PUBLIC FN_PREFIX(CryptonightR_instruction148) +PUBLIC FN_PREFIX(CryptonightR_instruction149) +PUBLIC FN_PREFIX(CryptonightR_instruction150) +PUBLIC FN_PREFIX(CryptonightR_instruction151) +PUBLIC FN_PREFIX(CryptonightR_instruction152) +PUBLIC FN_PREFIX(CryptonightR_instruction153) +PUBLIC FN_PREFIX(CryptonightR_instruction154) +PUBLIC FN_PREFIX(CryptonightR_instruction155) +PUBLIC FN_PREFIX(CryptonightR_instruction156) +PUBLIC FN_PREFIX(CryptonightR_instruction157) +PUBLIC FN_PREFIX(CryptonightR_instruction158) +PUBLIC FN_PREFIX(CryptonightR_instruction159) +PUBLIC FN_PREFIX(CryptonightR_instruction160) +PUBLIC FN_PREFIX(CryptonightR_instruction161) +PUBLIC FN_PREFIX(CryptonightR_instruction162) +PUBLIC FN_PREFIX(CryptonightR_instruction163) +PUBLIC FN_PREFIX(CryptonightR_instruction164) +PUBLIC FN_PREFIX(CryptonightR_instruction165) +PUBLIC FN_PREFIX(CryptonightR_instruction166) +PUBLIC FN_PREFIX(CryptonightR_instruction167) +PUBLIC FN_PREFIX(CryptonightR_instruction168) +PUBLIC FN_PREFIX(CryptonightR_instruction169) +PUBLIC FN_PREFIX(CryptonightR_instruction170) +PUBLIC FN_PREFIX(CryptonightR_instruction171) +PUBLIC FN_PREFIX(CryptonightR_instruction172) +PUBLIC FN_PREFIX(CryptonightR_instruction173) +PUBLIC FN_PREFIX(CryptonightR_instruction174) +PUBLIC FN_PREFIX(CryptonightR_instruction175) +PUBLIC FN_PREFIX(CryptonightR_instruction176) +PUBLIC FN_PREFIX(CryptonightR_instruction177) +PUBLIC FN_PREFIX(CryptonightR_instruction178) +PUBLIC FN_PREFIX(CryptonightR_instruction179) +PUBLIC FN_PREFIX(CryptonightR_instruction180) +PUBLIC FN_PREFIX(CryptonightR_instruction181) +PUBLIC FN_PREFIX(CryptonightR_instruction182) +PUBLIC FN_PREFIX(CryptonightR_instruction183) +PUBLIC FN_PREFIX(CryptonightR_instruction184) +PUBLIC FN_PREFIX(CryptonightR_instruction185) +PUBLIC FN_PREFIX(CryptonightR_instruction186) +PUBLIC FN_PREFIX(CryptonightR_instruction187) +PUBLIC FN_PREFIX(CryptonightR_instruction188) +PUBLIC FN_PREFIX(CryptonightR_instruction189) +PUBLIC FN_PREFIX(CryptonightR_instruction190) +PUBLIC FN_PREFIX(CryptonightR_instruction191) +PUBLIC FN_PREFIX(CryptonightR_instruction192) +PUBLIC FN_PREFIX(CryptonightR_instruction193) +PUBLIC FN_PREFIX(CryptonightR_instruction194) +PUBLIC FN_PREFIX(CryptonightR_instruction195) +PUBLIC FN_PREFIX(CryptonightR_instruction196) +PUBLIC FN_PREFIX(CryptonightR_instruction197) +PUBLIC FN_PREFIX(CryptonightR_instruction198) +PUBLIC FN_PREFIX(CryptonightR_instruction199) +PUBLIC FN_PREFIX(CryptonightR_instruction200) +PUBLIC FN_PREFIX(CryptonightR_instruction201) +PUBLIC FN_PREFIX(CryptonightR_instruction202) +PUBLIC FN_PREFIX(CryptonightR_instruction203) +PUBLIC FN_PREFIX(CryptonightR_instruction204) +PUBLIC FN_PREFIX(CryptonightR_instruction205) +PUBLIC FN_PREFIX(CryptonightR_instruction206) +PUBLIC FN_PREFIX(CryptonightR_instruction207) +PUBLIC FN_PREFIX(CryptonightR_instruction208) +PUBLIC FN_PREFIX(CryptonightR_instruction209) +PUBLIC FN_PREFIX(CryptonightR_instruction210) +PUBLIC FN_PREFIX(CryptonightR_instruction211) +PUBLIC FN_PREFIX(CryptonightR_instruction212) +PUBLIC FN_PREFIX(CryptonightR_instruction213) +PUBLIC FN_PREFIX(CryptonightR_instruction214) +PUBLIC FN_PREFIX(CryptonightR_instruction215) +PUBLIC FN_PREFIX(CryptonightR_instruction216) +PUBLIC FN_PREFIX(CryptonightR_instruction217) +PUBLIC FN_PREFIX(CryptonightR_instruction218) +PUBLIC FN_PREFIX(CryptonightR_instruction219) +PUBLIC FN_PREFIX(CryptonightR_instruction220) +PUBLIC FN_PREFIX(CryptonightR_instruction221) +PUBLIC FN_PREFIX(CryptonightR_instruction222) +PUBLIC FN_PREFIX(CryptonightR_instruction223) +PUBLIC FN_PREFIX(CryptonightR_instruction224) +PUBLIC FN_PREFIX(CryptonightR_instruction225) +PUBLIC FN_PREFIX(CryptonightR_instruction226) +PUBLIC FN_PREFIX(CryptonightR_instruction227) +PUBLIC FN_PREFIX(CryptonightR_instruction228) +PUBLIC FN_PREFIX(CryptonightR_instruction229) +PUBLIC FN_PREFIX(CryptonightR_instruction230) +PUBLIC FN_PREFIX(CryptonightR_instruction231) +PUBLIC FN_PREFIX(CryptonightR_instruction232) +PUBLIC FN_PREFIX(CryptonightR_instruction233) +PUBLIC FN_PREFIX(CryptonightR_instruction234) +PUBLIC FN_PREFIX(CryptonightR_instruction235) +PUBLIC FN_PREFIX(CryptonightR_instruction236) +PUBLIC FN_PREFIX(CryptonightR_instruction237) +PUBLIC FN_PREFIX(CryptonightR_instruction238) +PUBLIC FN_PREFIX(CryptonightR_instruction239) +PUBLIC FN_PREFIX(CryptonightR_instruction240) +PUBLIC FN_PREFIX(CryptonightR_instruction241) +PUBLIC FN_PREFIX(CryptonightR_instruction242) +PUBLIC FN_PREFIX(CryptonightR_instruction243) +PUBLIC FN_PREFIX(CryptonightR_instruction244) +PUBLIC FN_PREFIX(CryptonightR_instruction245) +PUBLIC FN_PREFIX(CryptonightR_instruction246) +PUBLIC FN_PREFIX(CryptonightR_instruction247) +PUBLIC FN_PREFIX(CryptonightR_instruction248) +PUBLIC FN_PREFIX(CryptonightR_instruction249) +PUBLIC FN_PREFIX(CryptonightR_instruction250) +PUBLIC FN_PREFIX(CryptonightR_instruction251) +PUBLIC FN_PREFIX(CryptonightR_instruction252) +PUBLIC FN_PREFIX(CryptonightR_instruction253) +PUBLIC FN_PREFIX(CryptonightR_instruction254) +PUBLIC FN_PREFIX(CryptonightR_instruction255) +PUBLIC FN_PREFIX(CryptonightR_instruction256) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov0) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov1) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov2) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov3) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov4) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov5) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov6) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov7) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov8) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov9) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov10) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov11) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov12) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov13) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov14) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov15) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov16) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov17) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov18) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov19) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov20) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov21) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov22) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov23) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov24) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov25) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov26) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov27) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov28) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov29) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov30) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov31) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov32) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov33) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov34) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov35) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov36) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov37) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov38) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov39) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov40) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov41) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov42) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov43) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov44) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov45) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov46) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov47) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov48) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov49) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov50) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov51) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov52) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov53) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov54) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov55) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov56) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov57) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov58) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov59) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov60) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov61) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov62) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov63) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov64) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov65) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov66) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov67) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov68) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov69) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov70) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov71) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov72) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov73) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov74) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov75) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov76) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov77) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov78) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov79) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov80) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov81) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov82) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov83) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov84) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov85) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov86) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov87) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov88) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov89) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov90) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov91) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov92) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov93) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov94) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov95) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov96) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov97) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov98) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov99) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov100) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov101) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov102) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov103) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov104) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov105) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov106) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov107) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov108) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov109) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov110) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov111) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov112) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov113) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov114) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov115) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov116) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov117) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov118) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov119) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov120) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov121) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov122) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov123) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov124) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov125) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov126) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov127) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov128) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov129) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov130) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov131) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov132) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov133) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov134) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov135) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov136) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov137) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov138) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov139) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov140) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov141) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov142) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov143) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov144) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov145) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov146) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov147) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov148) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov149) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov150) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov151) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov152) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov153) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov154) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov155) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov156) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov157) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov158) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov159) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov160) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov161) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov162) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov163) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov164) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov165) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov166) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov167) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov168) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov169) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov170) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov171) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov172) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov173) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov174) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov175) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov176) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov177) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov178) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov179) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov180) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov181) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov182) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov183) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov184) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov185) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov186) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov187) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov188) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov189) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov190) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov191) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov192) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov193) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov194) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov195) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov196) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov197) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov198) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov199) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov200) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov201) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov202) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov203) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov204) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov205) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov206) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov207) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov208) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov209) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov210) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov211) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov212) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov213) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov214) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov215) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov216) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov217) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov218) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov219) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov220) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov221) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov222) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov223) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov224) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov225) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov226) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov227) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov228) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov229) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov230) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov231) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov232) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov233) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov234) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov235) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov236) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov237) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov238) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov239) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov240) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov241) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov242) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov243) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov244) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov245) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov246) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov247) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov248) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov249) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov250) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov251) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov252) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov253) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov254) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov255) +PUBLIC FN_PREFIX(CryptonightR_instruction_mov256) + +FN_PREFIX(CryptonightR_instruction0): + imul ebx, ebx +FN_PREFIX(CryptonightR_instruction1): + imul ebx, ebx +FN_PREFIX(CryptonightR_instruction2): + imul ebx, ebx +FN_PREFIX(CryptonightR_instruction3): + add ebx, r9d + add ebx, 2147483647 +FN_PREFIX(CryptonightR_instruction4): + sub ebx, r9d +FN_PREFIX(CryptonightR_instruction5): + ror ebx, cl +FN_PREFIX(CryptonightR_instruction6): + rol ebx, cl +FN_PREFIX(CryptonightR_instruction7): + xor ebx, r9d +FN_PREFIX(CryptonightR_instruction8): + imul esi, ebx +FN_PREFIX(CryptonightR_instruction9): + imul esi, ebx +FN_PREFIX(CryptonightR_instruction10): + imul esi, ebx +FN_PREFIX(CryptonightR_instruction11): + add esi, ebx + add esi, 2147483647 +FN_PREFIX(CryptonightR_instruction12): + sub esi, ebx +FN_PREFIX(CryptonightR_instruction13): + ror esi, cl +FN_PREFIX(CryptonightR_instruction14): + rol esi, cl +FN_PREFIX(CryptonightR_instruction15): + xor esi, ebx +FN_PREFIX(CryptonightR_instruction16): + imul edi, ebx +FN_PREFIX(CryptonightR_instruction17): + imul edi, ebx +FN_PREFIX(CryptonightR_instruction18): + imul edi, ebx +FN_PREFIX(CryptonightR_instruction19): + add edi, ebx + add edi, 2147483647 +FN_PREFIX(CryptonightR_instruction20): + sub edi, ebx +FN_PREFIX(CryptonightR_instruction21): + ror edi, cl +FN_PREFIX(CryptonightR_instruction22): + rol edi, cl +FN_PREFIX(CryptonightR_instruction23): + xor edi, ebx +FN_PREFIX(CryptonightR_instruction24): + imul ebp, ebx +FN_PREFIX(CryptonightR_instruction25): + imul ebp, ebx +FN_PREFIX(CryptonightR_instruction26): + imul ebp, ebx +FN_PREFIX(CryptonightR_instruction27): + add ebp, ebx + add ebp, 2147483647 +FN_PREFIX(CryptonightR_instruction28): + sub ebp, ebx +FN_PREFIX(CryptonightR_instruction29): + ror ebp, cl +FN_PREFIX(CryptonightR_instruction30): + rol ebp, cl +FN_PREFIX(CryptonightR_instruction31): + xor ebp, ebx +FN_PREFIX(CryptonightR_instruction32): + imul ebx, esi +FN_PREFIX(CryptonightR_instruction33): + imul ebx, esi +FN_PREFIX(CryptonightR_instruction34): + imul ebx, esi +FN_PREFIX(CryptonightR_instruction35): + add ebx, esi + add ebx, 2147483647 +FN_PREFIX(CryptonightR_instruction36): + sub ebx, esi +FN_PREFIX(CryptonightR_instruction37): + ror ebx, cl +FN_PREFIX(CryptonightR_instruction38): + rol ebx, cl +FN_PREFIX(CryptonightR_instruction39): + xor ebx, esi +FN_PREFIX(CryptonightR_instruction40): + imul esi, esi +FN_PREFIX(CryptonightR_instruction41): + imul esi, esi +FN_PREFIX(CryptonightR_instruction42): + imul esi, esi +FN_PREFIX(CryptonightR_instruction43): + add esi, r9d + add esi, 2147483647 +FN_PREFIX(CryptonightR_instruction44): + sub esi, r9d +FN_PREFIX(CryptonightR_instruction45): + ror esi, cl +FN_PREFIX(CryptonightR_instruction46): + rol esi, cl +FN_PREFIX(CryptonightR_instruction47): + xor esi, r9d +FN_PREFIX(CryptonightR_instruction48): + imul edi, esi +FN_PREFIX(CryptonightR_instruction49): + imul edi, esi +FN_PREFIX(CryptonightR_instruction50): + imul edi, esi +FN_PREFIX(CryptonightR_instruction51): + add edi, esi + add edi, 2147483647 +FN_PREFIX(CryptonightR_instruction52): + sub edi, esi +FN_PREFIX(CryptonightR_instruction53): + ror edi, cl +FN_PREFIX(CryptonightR_instruction54): + rol edi, cl +FN_PREFIX(CryptonightR_instruction55): + xor edi, esi +FN_PREFIX(CryptonightR_instruction56): + imul ebp, esi +FN_PREFIX(CryptonightR_instruction57): + imul ebp, esi +FN_PREFIX(CryptonightR_instruction58): + imul ebp, esi +FN_PREFIX(CryptonightR_instruction59): + add ebp, esi + add ebp, 2147483647 +FN_PREFIX(CryptonightR_instruction60): + sub ebp, esi +FN_PREFIX(CryptonightR_instruction61): + ror ebp, cl +FN_PREFIX(CryptonightR_instruction62): + rol ebp, cl +FN_PREFIX(CryptonightR_instruction63): + xor ebp, esi +FN_PREFIX(CryptonightR_instruction64): + imul ebx, edi +FN_PREFIX(CryptonightR_instruction65): + imul ebx, edi +FN_PREFIX(CryptonightR_instruction66): + imul ebx, edi +FN_PREFIX(CryptonightR_instruction67): + add ebx, edi + add ebx, 2147483647 +FN_PREFIX(CryptonightR_instruction68): + sub ebx, edi +FN_PREFIX(CryptonightR_instruction69): + ror ebx, cl +FN_PREFIX(CryptonightR_instruction70): + rol ebx, cl +FN_PREFIX(CryptonightR_instruction71): + xor ebx, edi +FN_PREFIX(CryptonightR_instruction72): + imul esi, edi +FN_PREFIX(CryptonightR_instruction73): + imul esi, edi +FN_PREFIX(CryptonightR_instruction74): + imul esi, edi +FN_PREFIX(CryptonightR_instruction75): + add esi, edi + add esi, 2147483647 +FN_PREFIX(CryptonightR_instruction76): + sub esi, edi +FN_PREFIX(CryptonightR_instruction77): + ror esi, cl +FN_PREFIX(CryptonightR_instruction78): + rol esi, cl +FN_PREFIX(CryptonightR_instruction79): + xor esi, edi +FN_PREFIX(CryptonightR_instruction80): + imul edi, edi +FN_PREFIX(CryptonightR_instruction81): + imul edi, edi +FN_PREFIX(CryptonightR_instruction82): + imul edi, edi +FN_PREFIX(CryptonightR_instruction83): + add edi, r9d + add edi, 2147483647 +FN_PREFIX(CryptonightR_instruction84): + sub edi, r9d +FN_PREFIX(CryptonightR_instruction85): + ror edi, cl +FN_PREFIX(CryptonightR_instruction86): + rol edi, cl +FN_PREFIX(CryptonightR_instruction87): + xor edi, r9d +FN_PREFIX(CryptonightR_instruction88): + imul ebp, edi +FN_PREFIX(CryptonightR_instruction89): + imul ebp, edi +FN_PREFIX(CryptonightR_instruction90): + imul ebp, edi +FN_PREFIX(CryptonightR_instruction91): + add ebp, edi + add ebp, 2147483647 +FN_PREFIX(CryptonightR_instruction92): + sub ebp, edi +FN_PREFIX(CryptonightR_instruction93): + ror ebp, cl +FN_PREFIX(CryptonightR_instruction94): + rol ebp, cl +FN_PREFIX(CryptonightR_instruction95): + xor ebp, edi +FN_PREFIX(CryptonightR_instruction96): + imul ebx, ebp +FN_PREFIX(CryptonightR_instruction97): + imul ebx, ebp +FN_PREFIX(CryptonightR_instruction98): + imul ebx, ebp +FN_PREFIX(CryptonightR_instruction99): + add ebx, ebp + add ebx, 2147483647 +FN_PREFIX(CryptonightR_instruction100): + sub ebx, ebp +FN_PREFIX(CryptonightR_instruction101): + ror ebx, cl +FN_PREFIX(CryptonightR_instruction102): + rol ebx, cl +FN_PREFIX(CryptonightR_instruction103): + xor ebx, ebp +FN_PREFIX(CryptonightR_instruction104): + imul esi, ebp +FN_PREFIX(CryptonightR_instruction105): + imul esi, ebp +FN_PREFIX(CryptonightR_instruction106): + imul esi, ebp +FN_PREFIX(CryptonightR_instruction107): + add esi, ebp + add esi, 2147483647 +FN_PREFIX(CryptonightR_instruction108): + sub esi, ebp +FN_PREFIX(CryptonightR_instruction109): + ror esi, cl +FN_PREFIX(CryptonightR_instruction110): + rol esi, cl +FN_PREFIX(CryptonightR_instruction111): + xor esi, ebp +FN_PREFIX(CryptonightR_instruction112): + imul edi, ebp +FN_PREFIX(CryptonightR_instruction113): + imul edi, ebp +FN_PREFIX(CryptonightR_instruction114): + imul edi, ebp +FN_PREFIX(CryptonightR_instruction115): + add edi, ebp + add edi, 2147483647 +FN_PREFIX(CryptonightR_instruction116): + sub edi, ebp +FN_PREFIX(CryptonightR_instruction117): + ror edi, cl +FN_PREFIX(CryptonightR_instruction118): + rol edi, cl +FN_PREFIX(CryptonightR_instruction119): + xor edi, ebp +FN_PREFIX(CryptonightR_instruction120): + imul ebp, ebp +FN_PREFIX(CryptonightR_instruction121): + imul ebp, ebp +FN_PREFIX(CryptonightR_instruction122): + imul ebp, ebp +FN_PREFIX(CryptonightR_instruction123): + add ebp, r9d + add ebp, 2147483647 +FN_PREFIX(CryptonightR_instruction124): + sub ebp, r9d +FN_PREFIX(CryptonightR_instruction125): + ror ebp, cl +FN_PREFIX(CryptonightR_instruction126): + rol ebp, cl +FN_PREFIX(CryptonightR_instruction127): + xor ebp, r9d +FN_PREFIX(CryptonightR_instruction128): + imul ebx, esp +FN_PREFIX(CryptonightR_instruction129): + imul ebx, esp +FN_PREFIX(CryptonightR_instruction130): + imul ebx, esp +FN_PREFIX(CryptonightR_instruction131): + add ebx, esp + add ebx, 2147483647 +FN_PREFIX(CryptonightR_instruction132): + sub ebx, esp +FN_PREFIX(CryptonightR_instruction133): + ror ebx, cl +FN_PREFIX(CryptonightR_instruction134): + rol ebx, cl +FN_PREFIX(CryptonightR_instruction135): + xor ebx, esp +FN_PREFIX(CryptonightR_instruction136): + imul esi, esp +FN_PREFIX(CryptonightR_instruction137): + imul esi, esp +FN_PREFIX(CryptonightR_instruction138): + imul esi, esp +FN_PREFIX(CryptonightR_instruction139): + add esi, esp + add esi, 2147483647 +FN_PREFIX(CryptonightR_instruction140): + sub esi, esp +FN_PREFIX(CryptonightR_instruction141): + ror esi, cl +FN_PREFIX(CryptonightR_instruction142): + rol esi, cl +FN_PREFIX(CryptonightR_instruction143): + xor esi, esp +FN_PREFIX(CryptonightR_instruction144): + imul edi, esp +FN_PREFIX(CryptonightR_instruction145): + imul edi, esp +FN_PREFIX(CryptonightR_instruction146): + imul edi, esp +FN_PREFIX(CryptonightR_instruction147): + add edi, esp + add edi, 2147483647 +FN_PREFIX(CryptonightR_instruction148): + sub edi, esp +FN_PREFIX(CryptonightR_instruction149): + ror edi, cl +FN_PREFIX(CryptonightR_instruction150): + rol edi, cl +FN_PREFIX(CryptonightR_instruction151): + xor edi, esp +FN_PREFIX(CryptonightR_instruction152): + imul ebp, esp +FN_PREFIX(CryptonightR_instruction153): + imul ebp, esp +FN_PREFIX(CryptonightR_instruction154): + imul ebp, esp +FN_PREFIX(CryptonightR_instruction155): + add ebp, esp + add ebp, 2147483647 +FN_PREFIX(CryptonightR_instruction156): + sub ebp, esp +FN_PREFIX(CryptonightR_instruction157): + ror ebp, cl +FN_PREFIX(CryptonightR_instruction158): + rol ebp, cl +FN_PREFIX(CryptonightR_instruction159): + xor ebp, esp +FN_PREFIX(CryptonightR_instruction160): + imul ebx, r15d +FN_PREFIX(CryptonightR_instruction161): + imul ebx, r15d +FN_PREFIX(CryptonightR_instruction162): + imul ebx, r15d +FN_PREFIX(CryptonightR_instruction163): + add ebx, r15d + add ebx, 2147483647 +FN_PREFIX(CryptonightR_instruction164): + sub ebx, r15d +FN_PREFIX(CryptonightR_instruction165): + ror ebx, cl +FN_PREFIX(CryptonightR_instruction166): + rol ebx, cl +FN_PREFIX(CryptonightR_instruction167): + xor ebx, r15d +FN_PREFIX(CryptonightR_instruction168): + imul esi, r15d +FN_PREFIX(CryptonightR_instruction169): + imul esi, r15d +FN_PREFIX(CryptonightR_instruction170): + imul esi, r15d +FN_PREFIX(CryptonightR_instruction171): + add esi, r15d + add esi, 2147483647 +FN_PREFIX(CryptonightR_instruction172): + sub esi, r15d +FN_PREFIX(CryptonightR_instruction173): + ror esi, cl +FN_PREFIX(CryptonightR_instruction174): + rol esi, cl +FN_PREFIX(CryptonightR_instruction175): + xor esi, r15d +FN_PREFIX(CryptonightR_instruction176): + imul edi, r15d +FN_PREFIX(CryptonightR_instruction177): + imul edi, r15d +FN_PREFIX(CryptonightR_instruction178): + imul edi, r15d +FN_PREFIX(CryptonightR_instruction179): + add edi, r15d + add edi, 2147483647 +FN_PREFIX(CryptonightR_instruction180): + sub edi, r15d +FN_PREFIX(CryptonightR_instruction181): + ror edi, cl +FN_PREFIX(CryptonightR_instruction182): + rol edi, cl +FN_PREFIX(CryptonightR_instruction183): + xor edi, r15d +FN_PREFIX(CryptonightR_instruction184): + imul ebp, r15d +FN_PREFIX(CryptonightR_instruction185): + imul ebp, r15d +FN_PREFIX(CryptonightR_instruction186): + imul ebp, r15d +FN_PREFIX(CryptonightR_instruction187): + add ebp, r15d + add ebp, 2147483647 +FN_PREFIX(CryptonightR_instruction188): + sub ebp, r15d +FN_PREFIX(CryptonightR_instruction189): + ror ebp, cl +FN_PREFIX(CryptonightR_instruction190): + rol ebp, cl +FN_PREFIX(CryptonightR_instruction191): + xor ebp, r15d +FN_PREFIX(CryptonightR_instruction192): + imul ebx, eax +FN_PREFIX(CryptonightR_instruction193): + imul ebx, eax +FN_PREFIX(CryptonightR_instruction194): + imul ebx, eax +FN_PREFIX(CryptonightR_instruction195): + add ebx, eax + add ebx, 2147483647 +FN_PREFIX(CryptonightR_instruction196): + sub ebx, eax +FN_PREFIX(CryptonightR_instruction197): + ror ebx, cl +FN_PREFIX(CryptonightR_instruction198): + rol ebx, cl +FN_PREFIX(CryptonightR_instruction199): + xor ebx, eax +FN_PREFIX(CryptonightR_instruction200): + imul esi, eax +FN_PREFIX(CryptonightR_instruction201): + imul esi, eax +FN_PREFIX(CryptonightR_instruction202): + imul esi, eax +FN_PREFIX(CryptonightR_instruction203): + add esi, eax + add esi, 2147483647 +FN_PREFIX(CryptonightR_instruction204): + sub esi, eax +FN_PREFIX(CryptonightR_instruction205): + ror esi, cl +FN_PREFIX(CryptonightR_instruction206): + rol esi, cl +FN_PREFIX(CryptonightR_instruction207): + xor esi, eax +FN_PREFIX(CryptonightR_instruction208): + imul edi, eax +FN_PREFIX(CryptonightR_instruction209): + imul edi, eax +FN_PREFIX(CryptonightR_instruction210): + imul edi, eax +FN_PREFIX(CryptonightR_instruction211): + add edi, eax + add edi, 2147483647 +FN_PREFIX(CryptonightR_instruction212): + sub edi, eax +FN_PREFIX(CryptonightR_instruction213): + ror edi, cl +FN_PREFIX(CryptonightR_instruction214): + rol edi, cl +FN_PREFIX(CryptonightR_instruction215): + xor edi, eax +FN_PREFIX(CryptonightR_instruction216): + imul ebp, eax +FN_PREFIX(CryptonightR_instruction217): + imul ebp, eax +FN_PREFIX(CryptonightR_instruction218): + imul ebp, eax +FN_PREFIX(CryptonightR_instruction219): + add ebp, eax + add ebp, 2147483647 +FN_PREFIX(CryptonightR_instruction220): + sub ebp, eax +FN_PREFIX(CryptonightR_instruction221): + ror ebp, cl +FN_PREFIX(CryptonightR_instruction222): + rol ebp, cl +FN_PREFIX(CryptonightR_instruction223): + xor ebp, eax +FN_PREFIX(CryptonightR_instruction224): + imul ebx, edx +FN_PREFIX(CryptonightR_instruction225): + imul ebx, edx +FN_PREFIX(CryptonightR_instruction226): + imul ebx, edx +FN_PREFIX(CryptonightR_instruction227): + add ebx, edx + add ebx, 2147483647 +FN_PREFIX(CryptonightR_instruction228): + sub ebx, edx +FN_PREFIX(CryptonightR_instruction229): + ror ebx, cl +FN_PREFIX(CryptonightR_instruction230): + rol ebx, cl +FN_PREFIX(CryptonightR_instruction231): + xor ebx, edx +FN_PREFIX(CryptonightR_instruction232): + imul esi, edx +FN_PREFIX(CryptonightR_instruction233): + imul esi, edx +FN_PREFIX(CryptonightR_instruction234): + imul esi, edx +FN_PREFIX(CryptonightR_instruction235): + add esi, edx + add esi, 2147483647 +FN_PREFIX(CryptonightR_instruction236): + sub esi, edx +FN_PREFIX(CryptonightR_instruction237): + ror esi, cl +FN_PREFIX(CryptonightR_instruction238): + rol esi, cl +FN_PREFIX(CryptonightR_instruction239): + xor esi, edx +FN_PREFIX(CryptonightR_instruction240): + imul edi, edx +FN_PREFIX(CryptonightR_instruction241): + imul edi, edx +FN_PREFIX(CryptonightR_instruction242): + imul edi, edx +FN_PREFIX(CryptonightR_instruction243): + add edi, edx + add edi, 2147483647 +FN_PREFIX(CryptonightR_instruction244): + sub edi, edx +FN_PREFIX(CryptonightR_instruction245): + ror edi, cl +FN_PREFIX(CryptonightR_instruction246): + rol edi, cl +FN_PREFIX(CryptonightR_instruction247): + xor edi, edx +FN_PREFIX(CryptonightR_instruction248): + imul ebp, edx +FN_PREFIX(CryptonightR_instruction249): + imul ebp, edx +FN_PREFIX(CryptonightR_instruction250): + imul ebp, edx +FN_PREFIX(CryptonightR_instruction251): + add ebp, edx + add ebp, 2147483647 +FN_PREFIX(CryptonightR_instruction252): + sub ebp, edx +FN_PREFIX(CryptonightR_instruction253): + ror ebp, cl +FN_PREFIX(CryptonightR_instruction254): + rol ebp, cl +FN_PREFIX(CryptonightR_instruction255): + xor ebp, edx +FN_PREFIX(CryptonightR_instruction256): + imul ebx, ebx +FN_PREFIX(CryptonightR_instruction_mov0): + +FN_PREFIX(CryptonightR_instruction_mov1): + +FN_PREFIX(CryptonightR_instruction_mov2): + +FN_PREFIX(CryptonightR_instruction_mov3): + +FN_PREFIX(CryptonightR_instruction_mov4): + +FN_PREFIX(CryptonightR_instruction_mov5): + mov ecx, ebx +FN_PREFIX(CryptonightR_instruction_mov6): + mov ecx, ebx +FN_PREFIX(CryptonightR_instruction_mov7): + +FN_PREFIX(CryptonightR_instruction_mov8): + +FN_PREFIX(CryptonightR_instruction_mov9): + +FN_PREFIX(CryptonightR_instruction_mov10): + +FN_PREFIX(CryptonightR_instruction_mov11): + +FN_PREFIX(CryptonightR_instruction_mov12): + +FN_PREFIX(CryptonightR_instruction_mov13): + mov ecx, ebx +FN_PREFIX(CryptonightR_instruction_mov14): + mov ecx, ebx +FN_PREFIX(CryptonightR_instruction_mov15): + +FN_PREFIX(CryptonightR_instruction_mov16): + +FN_PREFIX(CryptonightR_instruction_mov17): + +FN_PREFIX(CryptonightR_instruction_mov18): + +FN_PREFIX(CryptonightR_instruction_mov19): + +FN_PREFIX(CryptonightR_instruction_mov20): + +FN_PREFIX(CryptonightR_instruction_mov21): + mov ecx, ebx +FN_PREFIX(CryptonightR_instruction_mov22): + mov ecx, ebx +FN_PREFIX(CryptonightR_instruction_mov23): + +FN_PREFIX(CryptonightR_instruction_mov24): + +FN_PREFIX(CryptonightR_instruction_mov25): + +FN_PREFIX(CryptonightR_instruction_mov26): + +FN_PREFIX(CryptonightR_instruction_mov27): + +FN_PREFIX(CryptonightR_instruction_mov28): + +FN_PREFIX(CryptonightR_instruction_mov29): + mov ecx, ebx +FN_PREFIX(CryptonightR_instruction_mov30): + mov ecx, ebx +FN_PREFIX(CryptonightR_instruction_mov31): + +FN_PREFIX(CryptonightR_instruction_mov32): + +FN_PREFIX(CryptonightR_instruction_mov33): + +FN_PREFIX(CryptonightR_instruction_mov34): + +FN_PREFIX(CryptonightR_instruction_mov35): + +FN_PREFIX(CryptonightR_instruction_mov36): + +FN_PREFIX(CryptonightR_instruction_mov37): + mov ecx, esi +FN_PREFIX(CryptonightR_instruction_mov38): + mov ecx, esi +FN_PREFIX(CryptonightR_instruction_mov39): + +FN_PREFIX(CryptonightR_instruction_mov40): + +FN_PREFIX(CryptonightR_instruction_mov41): + +FN_PREFIX(CryptonightR_instruction_mov42): + +FN_PREFIX(CryptonightR_instruction_mov43): + +FN_PREFIX(CryptonightR_instruction_mov44): + +FN_PREFIX(CryptonightR_instruction_mov45): + mov ecx, esi +FN_PREFIX(CryptonightR_instruction_mov46): + mov ecx, esi +FN_PREFIX(CryptonightR_instruction_mov47): + +FN_PREFIX(CryptonightR_instruction_mov48): + +FN_PREFIX(CryptonightR_instruction_mov49): + +FN_PREFIX(CryptonightR_instruction_mov50): + +FN_PREFIX(CryptonightR_instruction_mov51): + +FN_PREFIX(CryptonightR_instruction_mov52): + +FN_PREFIX(CryptonightR_instruction_mov53): + mov ecx, esi +FN_PREFIX(CryptonightR_instruction_mov54): + mov ecx, esi +FN_PREFIX(CryptonightR_instruction_mov55): + +FN_PREFIX(CryptonightR_instruction_mov56): + +FN_PREFIX(CryptonightR_instruction_mov57): + +FN_PREFIX(CryptonightR_instruction_mov58): + +FN_PREFIX(CryptonightR_instruction_mov59): + +FN_PREFIX(CryptonightR_instruction_mov60): + +FN_PREFIX(CryptonightR_instruction_mov61): + mov ecx, esi +FN_PREFIX(CryptonightR_instruction_mov62): + mov ecx, esi +FN_PREFIX(CryptonightR_instruction_mov63): + +FN_PREFIX(CryptonightR_instruction_mov64): + +FN_PREFIX(CryptonightR_instruction_mov65): + +FN_PREFIX(CryptonightR_instruction_mov66): + +FN_PREFIX(CryptonightR_instruction_mov67): + +FN_PREFIX(CryptonightR_instruction_mov68): + +FN_PREFIX(CryptonightR_instruction_mov69): + mov ecx, edi +FN_PREFIX(CryptonightR_instruction_mov70): + mov ecx, edi +FN_PREFIX(CryptonightR_instruction_mov71): + +FN_PREFIX(CryptonightR_instruction_mov72): + +FN_PREFIX(CryptonightR_instruction_mov73): + +FN_PREFIX(CryptonightR_instruction_mov74): + +FN_PREFIX(CryptonightR_instruction_mov75): + +FN_PREFIX(CryptonightR_instruction_mov76): + +FN_PREFIX(CryptonightR_instruction_mov77): + mov ecx, edi +FN_PREFIX(CryptonightR_instruction_mov78): + mov ecx, edi +FN_PREFIX(CryptonightR_instruction_mov79): + +FN_PREFIX(CryptonightR_instruction_mov80): + +FN_PREFIX(CryptonightR_instruction_mov81): + +FN_PREFIX(CryptonightR_instruction_mov82): + +FN_PREFIX(CryptonightR_instruction_mov83): + +FN_PREFIX(CryptonightR_instruction_mov84): + +FN_PREFIX(CryptonightR_instruction_mov85): + mov ecx, edi +FN_PREFIX(CryptonightR_instruction_mov86): + mov ecx, edi +FN_PREFIX(CryptonightR_instruction_mov87): + +FN_PREFIX(CryptonightR_instruction_mov88): + +FN_PREFIX(CryptonightR_instruction_mov89): + +FN_PREFIX(CryptonightR_instruction_mov90): + +FN_PREFIX(CryptonightR_instruction_mov91): + +FN_PREFIX(CryptonightR_instruction_mov92): + +FN_PREFIX(CryptonightR_instruction_mov93): + mov ecx, edi +FN_PREFIX(CryptonightR_instruction_mov94): + mov ecx, edi +FN_PREFIX(CryptonightR_instruction_mov95): + +FN_PREFIX(CryptonightR_instruction_mov96): + +FN_PREFIX(CryptonightR_instruction_mov97): + +FN_PREFIX(CryptonightR_instruction_mov98): + +FN_PREFIX(CryptonightR_instruction_mov99): + +FN_PREFIX(CryptonightR_instruction_mov100): + +FN_PREFIX(CryptonightR_instruction_mov101): + mov ecx, ebp +FN_PREFIX(CryptonightR_instruction_mov102): + mov ecx, ebp +FN_PREFIX(CryptonightR_instruction_mov103): + +FN_PREFIX(CryptonightR_instruction_mov104): + +FN_PREFIX(CryptonightR_instruction_mov105): + +FN_PREFIX(CryptonightR_instruction_mov106): + +FN_PREFIX(CryptonightR_instruction_mov107): + +FN_PREFIX(CryptonightR_instruction_mov108): + +FN_PREFIX(CryptonightR_instruction_mov109): + mov ecx, ebp +FN_PREFIX(CryptonightR_instruction_mov110): + mov ecx, ebp +FN_PREFIX(CryptonightR_instruction_mov111): + +FN_PREFIX(CryptonightR_instruction_mov112): + +FN_PREFIX(CryptonightR_instruction_mov113): + +FN_PREFIX(CryptonightR_instruction_mov114): + +FN_PREFIX(CryptonightR_instruction_mov115): + +FN_PREFIX(CryptonightR_instruction_mov116): + +FN_PREFIX(CryptonightR_instruction_mov117): + mov ecx, ebp +FN_PREFIX(CryptonightR_instruction_mov118): + mov ecx, ebp +FN_PREFIX(CryptonightR_instruction_mov119): + +FN_PREFIX(CryptonightR_instruction_mov120): + +FN_PREFIX(CryptonightR_instruction_mov121): + +FN_PREFIX(CryptonightR_instruction_mov122): + +FN_PREFIX(CryptonightR_instruction_mov123): + +FN_PREFIX(CryptonightR_instruction_mov124): + +FN_PREFIX(CryptonightR_instruction_mov125): + mov ecx, ebp +FN_PREFIX(CryptonightR_instruction_mov126): + mov ecx, ebp +FN_PREFIX(CryptonightR_instruction_mov127): + +FN_PREFIX(CryptonightR_instruction_mov128): + +FN_PREFIX(CryptonightR_instruction_mov129): + +FN_PREFIX(CryptonightR_instruction_mov130): + +FN_PREFIX(CryptonightR_instruction_mov131): + +FN_PREFIX(CryptonightR_instruction_mov132): + +FN_PREFIX(CryptonightR_instruction_mov133): + mov ecx, esp +FN_PREFIX(CryptonightR_instruction_mov134): + mov ecx, esp +FN_PREFIX(CryptonightR_instruction_mov135): + +FN_PREFIX(CryptonightR_instruction_mov136): + +FN_PREFIX(CryptonightR_instruction_mov137): + +FN_PREFIX(CryptonightR_instruction_mov138): + +FN_PREFIX(CryptonightR_instruction_mov139): + +FN_PREFIX(CryptonightR_instruction_mov140): + +FN_PREFIX(CryptonightR_instruction_mov141): + mov ecx, esp +FN_PREFIX(CryptonightR_instruction_mov142): + mov ecx, esp +FN_PREFIX(CryptonightR_instruction_mov143): + +FN_PREFIX(CryptonightR_instruction_mov144): + +FN_PREFIX(CryptonightR_instruction_mov145): + +FN_PREFIX(CryptonightR_instruction_mov146): + +FN_PREFIX(CryptonightR_instruction_mov147): + +FN_PREFIX(CryptonightR_instruction_mov148): + +FN_PREFIX(CryptonightR_instruction_mov149): + mov ecx, esp +FN_PREFIX(CryptonightR_instruction_mov150): + mov ecx, esp +FN_PREFIX(CryptonightR_instruction_mov151): + +FN_PREFIX(CryptonightR_instruction_mov152): + +FN_PREFIX(CryptonightR_instruction_mov153): + +FN_PREFIX(CryptonightR_instruction_mov154): + +FN_PREFIX(CryptonightR_instruction_mov155): + +FN_PREFIX(CryptonightR_instruction_mov156): + +FN_PREFIX(CryptonightR_instruction_mov157): + mov ecx, esp +FN_PREFIX(CryptonightR_instruction_mov158): + mov ecx, esp +FN_PREFIX(CryptonightR_instruction_mov159): + +FN_PREFIX(CryptonightR_instruction_mov160): + +FN_PREFIX(CryptonightR_instruction_mov161): + +FN_PREFIX(CryptonightR_instruction_mov162): + +FN_PREFIX(CryptonightR_instruction_mov163): + +FN_PREFIX(CryptonightR_instruction_mov164): + +FN_PREFIX(CryptonightR_instruction_mov165): + mov ecx, r15d +FN_PREFIX(CryptonightR_instruction_mov166): + mov ecx, r15d +FN_PREFIX(CryptonightR_instruction_mov167): + +FN_PREFIX(CryptonightR_instruction_mov168): + +FN_PREFIX(CryptonightR_instruction_mov169): + +FN_PREFIX(CryptonightR_instruction_mov170): + +FN_PREFIX(CryptonightR_instruction_mov171): + +FN_PREFIX(CryptonightR_instruction_mov172): + +FN_PREFIX(CryptonightR_instruction_mov173): + mov ecx, r15d +FN_PREFIX(CryptonightR_instruction_mov174): + mov ecx, r15d +FN_PREFIX(CryptonightR_instruction_mov175): + +FN_PREFIX(CryptonightR_instruction_mov176): + +FN_PREFIX(CryptonightR_instruction_mov177): + +FN_PREFIX(CryptonightR_instruction_mov178): + +FN_PREFIX(CryptonightR_instruction_mov179): + +FN_PREFIX(CryptonightR_instruction_mov180): + +FN_PREFIX(CryptonightR_instruction_mov181): + mov ecx, r15d +FN_PREFIX(CryptonightR_instruction_mov182): + mov ecx, r15d +FN_PREFIX(CryptonightR_instruction_mov183): + +FN_PREFIX(CryptonightR_instruction_mov184): + +FN_PREFIX(CryptonightR_instruction_mov185): + +FN_PREFIX(CryptonightR_instruction_mov186): + +FN_PREFIX(CryptonightR_instruction_mov187): + +FN_PREFIX(CryptonightR_instruction_mov188): + +FN_PREFIX(CryptonightR_instruction_mov189): + mov ecx, r15d +FN_PREFIX(CryptonightR_instruction_mov190): + mov ecx, r15d +FN_PREFIX(CryptonightR_instruction_mov191): + +FN_PREFIX(CryptonightR_instruction_mov192): + +FN_PREFIX(CryptonightR_instruction_mov193): + +FN_PREFIX(CryptonightR_instruction_mov194): + +FN_PREFIX(CryptonightR_instruction_mov195): + +FN_PREFIX(CryptonightR_instruction_mov196): + +FN_PREFIX(CryptonightR_instruction_mov197): + mov ecx, eax +FN_PREFIX(CryptonightR_instruction_mov198): + mov ecx, eax +FN_PREFIX(CryptonightR_instruction_mov199): + +FN_PREFIX(CryptonightR_instruction_mov200): + +FN_PREFIX(CryptonightR_instruction_mov201): + +FN_PREFIX(CryptonightR_instruction_mov202): + +FN_PREFIX(CryptonightR_instruction_mov203): + +FN_PREFIX(CryptonightR_instruction_mov204): + +FN_PREFIX(CryptonightR_instruction_mov205): + mov ecx, eax +FN_PREFIX(CryptonightR_instruction_mov206): + mov ecx, eax +FN_PREFIX(CryptonightR_instruction_mov207): + +FN_PREFIX(CryptonightR_instruction_mov208): + +FN_PREFIX(CryptonightR_instruction_mov209): + +FN_PREFIX(CryptonightR_instruction_mov210): + +FN_PREFIX(CryptonightR_instruction_mov211): + +FN_PREFIX(CryptonightR_instruction_mov212): + +FN_PREFIX(CryptonightR_instruction_mov213): + mov ecx, eax +FN_PREFIX(CryptonightR_instruction_mov214): + mov ecx, eax +FN_PREFIX(CryptonightR_instruction_mov215): + +FN_PREFIX(CryptonightR_instruction_mov216): + +FN_PREFIX(CryptonightR_instruction_mov217): + +FN_PREFIX(CryptonightR_instruction_mov218): + +FN_PREFIX(CryptonightR_instruction_mov219): + +FN_PREFIX(CryptonightR_instruction_mov220): + +FN_PREFIX(CryptonightR_instruction_mov221): + mov ecx, eax +FN_PREFIX(CryptonightR_instruction_mov222): + mov ecx, eax +FN_PREFIX(CryptonightR_instruction_mov223): + +FN_PREFIX(CryptonightR_instruction_mov224): + +FN_PREFIX(CryptonightR_instruction_mov225): + +FN_PREFIX(CryptonightR_instruction_mov226): + +FN_PREFIX(CryptonightR_instruction_mov227): + +FN_PREFIX(CryptonightR_instruction_mov228): + +FN_PREFIX(CryptonightR_instruction_mov229): + mov ecx, edx +FN_PREFIX(CryptonightR_instruction_mov230): + mov ecx, edx +FN_PREFIX(CryptonightR_instruction_mov231): + +FN_PREFIX(CryptonightR_instruction_mov232): + +FN_PREFIX(CryptonightR_instruction_mov233): + +FN_PREFIX(CryptonightR_instruction_mov234): + +FN_PREFIX(CryptonightR_instruction_mov235): + +FN_PREFIX(CryptonightR_instruction_mov236): + +FN_PREFIX(CryptonightR_instruction_mov237): + mov ecx, edx +FN_PREFIX(CryptonightR_instruction_mov238): + mov ecx, edx +FN_PREFIX(CryptonightR_instruction_mov239): + +FN_PREFIX(CryptonightR_instruction_mov240): + +FN_PREFIX(CryptonightR_instruction_mov241): + +FN_PREFIX(CryptonightR_instruction_mov242): + +FN_PREFIX(CryptonightR_instruction_mov243): + +FN_PREFIX(CryptonightR_instruction_mov244): + +FN_PREFIX(CryptonightR_instruction_mov245): + mov ecx, edx +FN_PREFIX(CryptonightR_instruction_mov246): + mov ecx, edx +FN_PREFIX(CryptonightR_instruction_mov247): + +FN_PREFIX(CryptonightR_instruction_mov248): + +FN_PREFIX(CryptonightR_instruction_mov249): + +FN_PREFIX(CryptonightR_instruction_mov250): + +FN_PREFIX(CryptonightR_instruction_mov251): + +FN_PREFIX(CryptonightR_instruction_mov252): + +FN_PREFIX(CryptonightR_instruction_mov253): + mov ecx, edx +FN_PREFIX(CryptonightR_instruction_mov254): + mov ecx, edx +FN_PREFIX(CryptonightR_instruction_mov255): + +FN_PREFIX(CryptonightR_instruction_mov256): diff --git a/src/crypto/CryptonightR_template.h b/src/crypto/CryptonightR_template.h new file mode 100644 index 000000000..57eb92ebe --- /dev/null +++ b/src/crypto/CryptonightR_template.h @@ -0,0 +1,1039 @@ +#ifndef CRYPTONIGHTR_TEMPLATE_H +#define CRYPTONIGHTR_TEMPLATE_H + +void CryptonightR_instruction0(void); +void CryptonightR_instruction1(void); +void CryptonightR_instruction2(void); +void CryptonightR_instruction3(void); +void CryptonightR_instruction4(void); +void CryptonightR_instruction5(void); +void CryptonightR_instruction6(void); +void CryptonightR_instruction7(void); +void CryptonightR_instruction8(void); +void CryptonightR_instruction9(void); +void CryptonightR_instruction10(void); +void CryptonightR_instruction11(void); +void CryptonightR_instruction12(void); +void CryptonightR_instruction13(void); +void CryptonightR_instruction14(void); +void CryptonightR_instruction15(void); +void CryptonightR_instruction16(void); +void CryptonightR_instruction17(void); +void CryptonightR_instruction18(void); +void CryptonightR_instruction19(void); +void CryptonightR_instruction20(void); +void CryptonightR_instruction21(void); +void CryptonightR_instruction22(void); +void CryptonightR_instruction23(void); +void CryptonightR_instruction24(void); +void CryptonightR_instruction25(void); +void CryptonightR_instruction26(void); +void CryptonightR_instruction27(void); +void CryptonightR_instruction28(void); +void CryptonightR_instruction29(void); +void CryptonightR_instruction30(void); +void CryptonightR_instruction31(void); +void CryptonightR_instruction32(void); +void CryptonightR_instruction33(void); +void CryptonightR_instruction34(void); +void CryptonightR_instruction35(void); +void CryptonightR_instruction36(void); +void CryptonightR_instruction37(void); +void CryptonightR_instruction38(void); +void CryptonightR_instruction39(void); +void CryptonightR_instruction40(void); +void CryptonightR_instruction41(void); +void CryptonightR_instruction42(void); +void CryptonightR_instruction43(void); +void CryptonightR_instruction44(void); +void CryptonightR_instruction45(void); +void CryptonightR_instruction46(void); +void CryptonightR_instruction47(void); +void CryptonightR_instruction48(void); +void CryptonightR_instruction49(void); +void CryptonightR_instruction50(void); +void CryptonightR_instruction51(void); +void CryptonightR_instruction52(void); +void CryptonightR_instruction53(void); +void CryptonightR_instruction54(void); +void CryptonightR_instruction55(void); +void CryptonightR_instruction56(void); +void CryptonightR_instruction57(void); +void CryptonightR_instruction58(void); +void CryptonightR_instruction59(void); +void CryptonightR_instruction60(void); +void CryptonightR_instruction61(void); +void CryptonightR_instruction62(void); +void CryptonightR_instruction63(void); +void CryptonightR_instruction64(void); +void CryptonightR_instruction65(void); +void CryptonightR_instruction66(void); +void CryptonightR_instruction67(void); +void CryptonightR_instruction68(void); +void CryptonightR_instruction69(void); +void CryptonightR_instruction70(void); +void CryptonightR_instruction71(void); +void CryptonightR_instruction72(void); +void CryptonightR_instruction73(void); +void CryptonightR_instruction74(void); +void CryptonightR_instruction75(void); +void CryptonightR_instruction76(void); +void CryptonightR_instruction77(void); +void CryptonightR_instruction78(void); +void CryptonightR_instruction79(void); +void CryptonightR_instruction80(void); +void CryptonightR_instruction81(void); +void CryptonightR_instruction82(void); +void CryptonightR_instruction83(void); +void CryptonightR_instruction84(void); +void CryptonightR_instruction85(void); +void CryptonightR_instruction86(void); +void CryptonightR_instruction87(void); +void CryptonightR_instruction88(void); +void CryptonightR_instruction89(void); +void CryptonightR_instruction90(void); +void CryptonightR_instruction91(void); +void CryptonightR_instruction92(void); +void CryptonightR_instruction93(void); +void CryptonightR_instruction94(void); +void CryptonightR_instruction95(void); +void CryptonightR_instruction96(void); +void CryptonightR_instruction97(void); +void CryptonightR_instruction98(void); +void CryptonightR_instruction99(void); +void CryptonightR_instruction100(void); +void CryptonightR_instruction101(void); +void CryptonightR_instruction102(void); +void CryptonightR_instruction103(void); +void CryptonightR_instruction104(void); +void CryptonightR_instruction105(void); +void CryptonightR_instruction106(void); +void CryptonightR_instruction107(void); +void CryptonightR_instruction108(void); +void CryptonightR_instruction109(void); +void CryptonightR_instruction110(void); +void CryptonightR_instruction111(void); +void CryptonightR_instruction112(void); +void CryptonightR_instruction113(void); +void CryptonightR_instruction114(void); +void CryptonightR_instruction115(void); +void CryptonightR_instruction116(void); +void CryptonightR_instruction117(void); +void CryptonightR_instruction118(void); +void CryptonightR_instruction119(void); +void CryptonightR_instruction120(void); +void CryptonightR_instruction121(void); +void CryptonightR_instruction122(void); +void CryptonightR_instruction123(void); +void CryptonightR_instruction124(void); +void CryptonightR_instruction125(void); +void CryptonightR_instruction126(void); +void CryptonightR_instruction127(void); +void CryptonightR_instruction128(void); +void CryptonightR_instruction129(void); +void CryptonightR_instruction130(void); +void CryptonightR_instruction131(void); +void CryptonightR_instruction132(void); +void CryptonightR_instruction133(void); +void CryptonightR_instruction134(void); +void CryptonightR_instruction135(void); +void CryptonightR_instruction136(void); +void CryptonightR_instruction137(void); +void CryptonightR_instruction138(void); +void CryptonightR_instruction139(void); +void CryptonightR_instruction140(void); +void CryptonightR_instruction141(void); +void CryptonightR_instruction142(void); +void CryptonightR_instruction143(void); +void CryptonightR_instruction144(void); +void CryptonightR_instruction145(void); +void CryptonightR_instruction146(void); +void CryptonightR_instruction147(void); +void CryptonightR_instruction148(void); +void CryptonightR_instruction149(void); +void CryptonightR_instruction150(void); +void CryptonightR_instruction151(void); +void CryptonightR_instruction152(void); +void CryptonightR_instruction153(void); +void CryptonightR_instruction154(void); +void CryptonightR_instruction155(void); +void CryptonightR_instruction156(void); +void CryptonightR_instruction157(void); +void CryptonightR_instruction158(void); +void CryptonightR_instruction159(void); +void CryptonightR_instruction160(void); +void CryptonightR_instruction161(void); +void CryptonightR_instruction162(void); +void CryptonightR_instruction163(void); +void CryptonightR_instruction164(void); +void CryptonightR_instruction165(void); +void CryptonightR_instruction166(void); +void CryptonightR_instruction167(void); +void CryptonightR_instruction168(void); +void CryptonightR_instruction169(void); +void CryptonightR_instruction170(void); +void CryptonightR_instruction171(void); +void CryptonightR_instruction172(void); +void CryptonightR_instruction173(void); +void CryptonightR_instruction174(void); +void CryptonightR_instruction175(void); +void CryptonightR_instruction176(void); +void CryptonightR_instruction177(void); +void CryptonightR_instruction178(void); +void CryptonightR_instruction179(void); +void CryptonightR_instruction180(void); +void CryptonightR_instruction181(void); +void CryptonightR_instruction182(void); +void CryptonightR_instruction183(void); +void CryptonightR_instruction184(void); +void CryptonightR_instruction185(void); +void CryptonightR_instruction186(void); +void CryptonightR_instruction187(void); +void CryptonightR_instruction188(void); +void CryptonightR_instruction189(void); +void CryptonightR_instruction190(void); +void CryptonightR_instruction191(void); +void CryptonightR_instruction192(void); +void CryptonightR_instruction193(void); +void CryptonightR_instruction194(void); +void CryptonightR_instruction195(void); +void CryptonightR_instruction196(void); +void CryptonightR_instruction197(void); +void CryptonightR_instruction198(void); +void CryptonightR_instruction199(void); +void CryptonightR_instruction200(void); +void CryptonightR_instruction201(void); +void CryptonightR_instruction202(void); +void CryptonightR_instruction203(void); +void CryptonightR_instruction204(void); +void CryptonightR_instruction205(void); +void CryptonightR_instruction206(void); +void CryptonightR_instruction207(void); +void CryptonightR_instruction208(void); +void CryptonightR_instruction209(void); +void CryptonightR_instruction210(void); +void CryptonightR_instruction211(void); +void CryptonightR_instruction212(void); +void CryptonightR_instruction213(void); +void CryptonightR_instruction214(void); +void CryptonightR_instruction215(void); +void CryptonightR_instruction216(void); +void CryptonightR_instruction217(void); +void CryptonightR_instruction218(void); +void CryptonightR_instruction219(void); +void CryptonightR_instruction220(void); +void CryptonightR_instruction221(void); +void CryptonightR_instruction222(void); +void CryptonightR_instruction223(void); +void CryptonightR_instruction224(void); +void CryptonightR_instruction225(void); +void CryptonightR_instruction226(void); +void CryptonightR_instruction227(void); +void CryptonightR_instruction228(void); +void CryptonightR_instruction229(void); +void CryptonightR_instruction230(void); +void CryptonightR_instruction231(void); +void CryptonightR_instruction232(void); +void CryptonightR_instruction233(void); +void CryptonightR_instruction234(void); +void CryptonightR_instruction235(void); +void CryptonightR_instruction236(void); +void CryptonightR_instruction237(void); +void CryptonightR_instruction238(void); +void CryptonightR_instruction239(void); +void CryptonightR_instruction240(void); +void CryptonightR_instruction241(void); +void CryptonightR_instruction242(void); +void CryptonightR_instruction243(void); +void CryptonightR_instruction244(void); +void CryptonightR_instruction245(void); +void CryptonightR_instruction246(void); +void CryptonightR_instruction247(void); +void CryptonightR_instruction248(void); +void CryptonightR_instruction249(void); +void CryptonightR_instruction250(void); +void CryptonightR_instruction251(void); +void CryptonightR_instruction252(void); +void CryptonightR_instruction253(void); +void CryptonightR_instruction254(void); +void CryptonightR_instruction255(void); +void CryptonightR_instruction256(void); +void CryptonightR_instruction_mov0(void); +void CryptonightR_instruction_mov1(void); +void CryptonightR_instruction_mov2(void); +void CryptonightR_instruction_mov3(void); +void CryptonightR_instruction_mov4(void); +void CryptonightR_instruction_mov5(void); +void CryptonightR_instruction_mov6(void); +void CryptonightR_instruction_mov7(void); +void CryptonightR_instruction_mov8(void); +void CryptonightR_instruction_mov9(void); +void CryptonightR_instruction_mov10(void); +void CryptonightR_instruction_mov11(void); +void CryptonightR_instruction_mov12(void); +void CryptonightR_instruction_mov13(void); +void CryptonightR_instruction_mov14(void); +void CryptonightR_instruction_mov15(void); +void CryptonightR_instruction_mov16(void); +void CryptonightR_instruction_mov17(void); +void CryptonightR_instruction_mov18(void); +void CryptonightR_instruction_mov19(void); +void CryptonightR_instruction_mov20(void); +void CryptonightR_instruction_mov21(void); +void CryptonightR_instruction_mov22(void); +void CryptonightR_instruction_mov23(void); +void CryptonightR_instruction_mov24(void); +void CryptonightR_instruction_mov25(void); +void CryptonightR_instruction_mov26(void); +void CryptonightR_instruction_mov27(void); +void CryptonightR_instruction_mov28(void); +void CryptonightR_instruction_mov29(void); +void CryptonightR_instruction_mov30(void); +void CryptonightR_instruction_mov31(void); +void CryptonightR_instruction_mov32(void); +void CryptonightR_instruction_mov33(void); +void CryptonightR_instruction_mov34(void); +void CryptonightR_instruction_mov35(void); +void CryptonightR_instruction_mov36(void); +void CryptonightR_instruction_mov37(void); +void CryptonightR_instruction_mov38(void); +void CryptonightR_instruction_mov39(void); +void CryptonightR_instruction_mov40(void); +void CryptonightR_instruction_mov41(void); +void CryptonightR_instruction_mov42(void); +void CryptonightR_instruction_mov43(void); +void CryptonightR_instruction_mov44(void); +void CryptonightR_instruction_mov45(void); +void CryptonightR_instruction_mov46(void); +void CryptonightR_instruction_mov47(void); +void CryptonightR_instruction_mov48(void); +void CryptonightR_instruction_mov49(void); +void CryptonightR_instruction_mov50(void); +void CryptonightR_instruction_mov51(void); +void CryptonightR_instruction_mov52(void); +void CryptonightR_instruction_mov53(void); +void CryptonightR_instruction_mov54(void); +void CryptonightR_instruction_mov55(void); +void CryptonightR_instruction_mov56(void); +void CryptonightR_instruction_mov57(void); +void CryptonightR_instruction_mov58(void); +void CryptonightR_instruction_mov59(void); +void CryptonightR_instruction_mov60(void); +void CryptonightR_instruction_mov61(void); +void CryptonightR_instruction_mov62(void); +void CryptonightR_instruction_mov63(void); +void CryptonightR_instruction_mov64(void); +void CryptonightR_instruction_mov65(void); +void CryptonightR_instruction_mov66(void); +void CryptonightR_instruction_mov67(void); +void CryptonightR_instruction_mov68(void); +void CryptonightR_instruction_mov69(void); +void CryptonightR_instruction_mov70(void); +void CryptonightR_instruction_mov71(void); +void CryptonightR_instruction_mov72(void); +void CryptonightR_instruction_mov73(void); +void CryptonightR_instruction_mov74(void); +void CryptonightR_instruction_mov75(void); +void CryptonightR_instruction_mov76(void); +void CryptonightR_instruction_mov77(void); +void CryptonightR_instruction_mov78(void); +void CryptonightR_instruction_mov79(void); +void CryptonightR_instruction_mov80(void); +void CryptonightR_instruction_mov81(void); +void CryptonightR_instruction_mov82(void); +void CryptonightR_instruction_mov83(void); +void CryptonightR_instruction_mov84(void); +void CryptonightR_instruction_mov85(void); +void CryptonightR_instruction_mov86(void); +void CryptonightR_instruction_mov87(void); +void CryptonightR_instruction_mov88(void); +void CryptonightR_instruction_mov89(void); +void CryptonightR_instruction_mov90(void); +void CryptonightR_instruction_mov91(void); +void CryptonightR_instruction_mov92(void); +void CryptonightR_instruction_mov93(void); +void CryptonightR_instruction_mov94(void); +void CryptonightR_instruction_mov95(void); +void CryptonightR_instruction_mov96(void); +void CryptonightR_instruction_mov97(void); +void CryptonightR_instruction_mov98(void); +void CryptonightR_instruction_mov99(void); +void CryptonightR_instruction_mov100(void); +void CryptonightR_instruction_mov101(void); +void CryptonightR_instruction_mov102(void); +void CryptonightR_instruction_mov103(void); +void CryptonightR_instruction_mov104(void); +void CryptonightR_instruction_mov105(void); +void CryptonightR_instruction_mov106(void); +void CryptonightR_instruction_mov107(void); +void CryptonightR_instruction_mov108(void); +void CryptonightR_instruction_mov109(void); +void CryptonightR_instruction_mov110(void); +void CryptonightR_instruction_mov111(void); +void CryptonightR_instruction_mov112(void); +void CryptonightR_instruction_mov113(void); +void CryptonightR_instruction_mov114(void); +void CryptonightR_instruction_mov115(void); +void CryptonightR_instruction_mov116(void); +void CryptonightR_instruction_mov117(void); +void CryptonightR_instruction_mov118(void); +void CryptonightR_instruction_mov119(void); +void CryptonightR_instruction_mov120(void); +void CryptonightR_instruction_mov121(void); +void CryptonightR_instruction_mov122(void); +void CryptonightR_instruction_mov123(void); +void CryptonightR_instruction_mov124(void); +void CryptonightR_instruction_mov125(void); +void CryptonightR_instruction_mov126(void); +void CryptonightR_instruction_mov127(void); +void CryptonightR_instruction_mov128(void); +void CryptonightR_instruction_mov129(void); +void CryptonightR_instruction_mov130(void); +void CryptonightR_instruction_mov131(void); +void CryptonightR_instruction_mov132(void); +void CryptonightR_instruction_mov133(void); +void CryptonightR_instruction_mov134(void); +void CryptonightR_instruction_mov135(void); +void CryptonightR_instruction_mov136(void); +void CryptonightR_instruction_mov137(void); +void CryptonightR_instruction_mov138(void); +void CryptonightR_instruction_mov139(void); +void CryptonightR_instruction_mov140(void); +void CryptonightR_instruction_mov141(void); +void CryptonightR_instruction_mov142(void); +void CryptonightR_instruction_mov143(void); +void CryptonightR_instruction_mov144(void); +void CryptonightR_instruction_mov145(void); +void CryptonightR_instruction_mov146(void); +void CryptonightR_instruction_mov147(void); +void CryptonightR_instruction_mov148(void); +void CryptonightR_instruction_mov149(void); +void CryptonightR_instruction_mov150(void); +void CryptonightR_instruction_mov151(void); +void CryptonightR_instruction_mov152(void); +void CryptonightR_instruction_mov153(void); +void CryptonightR_instruction_mov154(void); +void CryptonightR_instruction_mov155(void); +void CryptonightR_instruction_mov156(void); +void CryptonightR_instruction_mov157(void); +void CryptonightR_instruction_mov158(void); +void CryptonightR_instruction_mov159(void); +void CryptonightR_instruction_mov160(void); +void CryptonightR_instruction_mov161(void); +void CryptonightR_instruction_mov162(void); +void CryptonightR_instruction_mov163(void); +void CryptonightR_instruction_mov164(void); +void CryptonightR_instruction_mov165(void); +void CryptonightR_instruction_mov166(void); +void CryptonightR_instruction_mov167(void); +void CryptonightR_instruction_mov168(void); +void CryptonightR_instruction_mov169(void); +void CryptonightR_instruction_mov170(void); +void CryptonightR_instruction_mov171(void); +void CryptonightR_instruction_mov172(void); +void CryptonightR_instruction_mov173(void); +void CryptonightR_instruction_mov174(void); +void CryptonightR_instruction_mov175(void); +void CryptonightR_instruction_mov176(void); +void CryptonightR_instruction_mov177(void); +void CryptonightR_instruction_mov178(void); +void CryptonightR_instruction_mov179(void); +void CryptonightR_instruction_mov180(void); +void CryptonightR_instruction_mov181(void); +void CryptonightR_instruction_mov182(void); +void CryptonightR_instruction_mov183(void); +void CryptonightR_instruction_mov184(void); +void CryptonightR_instruction_mov185(void); +void CryptonightR_instruction_mov186(void); +void CryptonightR_instruction_mov187(void); +void CryptonightR_instruction_mov188(void); +void CryptonightR_instruction_mov189(void); +void CryptonightR_instruction_mov190(void); +void CryptonightR_instruction_mov191(void); +void CryptonightR_instruction_mov192(void); +void CryptonightR_instruction_mov193(void); +void CryptonightR_instruction_mov194(void); +void CryptonightR_instruction_mov195(void); +void CryptonightR_instruction_mov196(void); +void CryptonightR_instruction_mov197(void); +void CryptonightR_instruction_mov198(void); +void CryptonightR_instruction_mov199(void); +void CryptonightR_instruction_mov200(void); +void CryptonightR_instruction_mov201(void); +void CryptonightR_instruction_mov202(void); +void CryptonightR_instruction_mov203(void); +void CryptonightR_instruction_mov204(void); +void CryptonightR_instruction_mov205(void); +void CryptonightR_instruction_mov206(void); +void CryptonightR_instruction_mov207(void); +void CryptonightR_instruction_mov208(void); +void CryptonightR_instruction_mov209(void); +void CryptonightR_instruction_mov210(void); +void CryptonightR_instruction_mov211(void); +void CryptonightR_instruction_mov212(void); +void CryptonightR_instruction_mov213(void); +void CryptonightR_instruction_mov214(void); +void CryptonightR_instruction_mov215(void); +void CryptonightR_instruction_mov216(void); +void CryptonightR_instruction_mov217(void); +void CryptonightR_instruction_mov218(void); +void CryptonightR_instruction_mov219(void); +void CryptonightR_instruction_mov220(void); +void CryptonightR_instruction_mov221(void); +void CryptonightR_instruction_mov222(void); +void CryptonightR_instruction_mov223(void); +void CryptonightR_instruction_mov224(void); +void CryptonightR_instruction_mov225(void); +void CryptonightR_instruction_mov226(void); +void CryptonightR_instruction_mov227(void); +void CryptonightR_instruction_mov228(void); +void CryptonightR_instruction_mov229(void); +void CryptonightR_instruction_mov230(void); +void CryptonightR_instruction_mov231(void); +void CryptonightR_instruction_mov232(void); +void CryptonightR_instruction_mov233(void); +void CryptonightR_instruction_mov234(void); +void CryptonightR_instruction_mov235(void); +void CryptonightR_instruction_mov236(void); +void CryptonightR_instruction_mov237(void); +void CryptonightR_instruction_mov238(void); +void CryptonightR_instruction_mov239(void); +void CryptonightR_instruction_mov240(void); +void CryptonightR_instruction_mov241(void); +void CryptonightR_instruction_mov242(void); +void CryptonightR_instruction_mov243(void); +void CryptonightR_instruction_mov244(void); +void CryptonightR_instruction_mov245(void); +void CryptonightR_instruction_mov246(void); +void CryptonightR_instruction_mov247(void); +void CryptonightR_instruction_mov248(void); +void CryptonightR_instruction_mov249(void); +void CryptonightR_instruction_mov250(void); +void CryptonightR_instruction_mov251(void); +void CryptonightR_instruction_mov252(void); +void CryptonightR_instruction_mov253(void); +void CryptonightR_instruction_mov254(void); +void CryptonightR_instruction_mov255(void); +void CryptonightR_instruction_mov256(void); + +const void* instructions[257] = { + CryptonightR_instruction0, + CryptonightR_instruction1, + CryptonightR_instruction2, + CryptonightR_instruction3, + CryptonightR_instruction4, + CryptonightR_instruction5, + CryptonightR_instruction6, + CryptonightR_instruction7, + CryptonightR_instruction8, + CryptonightR_instruction9, + CryptonightR_instruction10, + CryptonightR_instruction11, + CryptonightR_instruction12, + CryptonightR_instruction13, + CryptonightR_instruction14, + CryptonightR_instruction15, + CryptonightR_instruction16, + CryptonightR_instruction17, + CryptonightR_instruction18, + CryptonightR_instruction19, + CryptonightR_instruction20, + CryptonightR_instruction21, + CryptonightR_instruction22, + CryptonightR_instruction23, + CryptonightR_instruction24, + CryptonightR_instruction25, + CryptonightR_instruction26, + CryptonightR_instruction27, + CryptonightR_instruction28, + CryptonightR_instruction29, + CryptonightR_instruction30, + CryptonightR_instruction31, + CryptonightR_instruction32, + CryptonightR_instruction33, + CryptonightR_instruction34, + CryptonightR_instruction35, + CryptonightR_instruction36, + CryptonightR_instruction37, + CryptonightR_instruction38, + CryptonightR_instruction39, + CryptonightR_instruction40, + CryptonightR_instruction41, + CryptonightR_instruction42, + CryptonightR_instruction43, + CryptonightR_instruction44, + CryptonightR_instruction45, + CryptonightR_instruction46, + CryptonightR_instruction47, + CryptonightR_instruction48, + CryptonightR_instruction49, + CryptonightR_instruction50, + CryptonightR_instruction51, + CryptonightR_instruction52, + CryptonightR_instruction53, + CryptonightR_instruction54, + CryptonightR_instruction55, + CryptonightR_instruction56, + CryptonightR_instruction57, + CryptonightR_instruction58, + CryptonightR_instruction59, + CryptonightR_instruction60, + CryptonightR_instruction61, + CryptonightR_instruction62, + CryptonightR_instruction63, + CryptonightR_instruction64, + CryptonightR_instruction65, + CryptonightR_instruction66, + CryptonightR_instruction67, + CryptonightR_instruction68, + CryptonightR_instruction69, + CryptonightR_instruction70, + CryptonightR_instruction71, + CryptonightR_instruction72, + CryptonightR_instruction73, + CryptonightR_instruction74, + CryptonightR_instruction75, + CryptonightR_instruction76, + CryptonightR_instruction77, + CryptonightR_instruction78, + CryptonightR_instruction79, + CryptonightR_instruction80, + CryptonightR_instruction81, + CryptonightR_instruction82, + CryptonightR_instruction83, + CryptonightR_instruction84, + CryptonightR_instruction85, + CryptonightR_instruction86, + CryptonightR_instruction87, + CryptonightR_instruction88, + CryptonightR_instruction89, + CryptonightR_instruction90, + CryptonightR_instruction91, + CryptonightR_instruction92, + CryptonightR_instruction93, + CryptonightR_instruction94, + CryptonightR_instruction95, + CryptonightR_instruction96, + CryptonightR_instruction97, + CryptonightR_instruction98, + CryptonightR_instruction99, + CryptonightR_instruction100, + CryptonightR_instruction101, + CryptonightR_instruction102, + CryptonightR_instruction103, + CryptonightR_instruction104, + CryptonightR_instruction105, + CryptonightR_instruction106, + CryptonightR_instruction107, + CryptonightR_instruction108, + CryptonightR_instruction109, + CryptonightR_instruction110, + CryptonightR_instruction111, + CryptonightR_instruction112, + CryptonightR_instruction113, + CryptonightR_instruction114, + CryptonightR_instruction115, + CryptonightR_instruction116, + CryptonightR_instruction117, + CryptonightR_instruction118, + CryptonightR_instruction119, + CryptonightR_instruction120, + CryptonightR_instruction121, + CryptonightR_instruction122, + CryptonightR_instruction123, + CryptonightR_instruction124, + CryptonightR_instruction125, + CryptonightR_instruction126, + CryptonightR_instruction127, + CryptonightR_instruction128, + CryptonightR_instruction129, + CryptonightR_instruction130, + CryptonightR_instruction131, + CryptonightR_instruction132, + CryptonightR_instruction133, + CryptonightR_instruction134, + CryptonightR_instruction135, + CryptonightR_instruction136, + CryptonightR_instruction137, + CryptonightR_instruction138, + CryptonightR_instruction139, + CryptonightR_instruction140, + CryptonightR_instruction141, + CryptonightR_instruction142, + CryptonightR_instruction143, + CryptonightR_instruction144, + CryptonightR_instruction145, + CryptonightR_instruction146, + CryptonightR_instruction147, + CryptonightR_instruction148, + CryptonightR_instruction149, + CryptonightR_instruction150, + CryptonightR_instruction151, + CryptonightR_instruction152, + CryptonightR_instruction153, + CryptonightR_instruction154, + CryptonightR_instruction155, + CryptonightR_instruction156, + CryptonightR_instruction157, + CryptonightR_instruction158, + CryptonightR_instruction159, + CryptonightR_instruction160, + CryptonightR_instruction161, + CryptonightR_instruction162, + CryptonightR_instruction163, + CryptonightR_instruction164, + CryptonightR_instruction165, + CryptonightR_instruction166, + CryptonightR_instruction167, + CryptonightR_instruction168, + CryptonightR_instruction169, + CryptonightR_instruction170, + CryptonightR_instruction171, + CryptonightR_instruction172, + CryptonightR_instruction173, + CryptonightR_instruction174, + CryptonightR_instruction175, + CryptonightR_instruction176, + CryptonightR_instruction177, + CryptonightR_instruction178, + CryptonightR_instruction179, + CryptonightR_instruction180, + CryptonightR_instruction181, + CryptonightR_instruction182, + CryptonightR_instruction183, + CryptonightR_instruction184, + CryptonightR_instruction185, + CryptonightR_instruction186, + CryptonightR_instruction187, + CryptonightR_instruction188, + CryptonightR_instruction189, + CryptonightR_instruction190, + CryptonightR_instruction191, + CryptonightR_instruction192, + CryptonightR_instruction193, + CryptonightR_instruction194, + CryptonightR_instruction195, + CryptonightR_instruction196, + CryptonightR_instruction197, + CryptonightR_instruction198, + CryptonightR_instruction199, + CryptonightR_instruction200, + CryptonightR_instruction201, + CryptonightR_instruction202, + CryptonightR_instruction203, + CryptonightR_instruction204, + CryptonightR_instruction205, + CryptonightR_instruction206, + CryptonightR_instruction207, + CryptonightR_instruction208, + CryptonightR_instruction209, + CryptonightR_instruction210, + CryptonightR_instruction211, + CryptonightR_instruction212, + CryptonightR_instruction213, + CryptonightR_instruction214, + CryptonightR_instruction215, + CryptonightR_instruction216, + CryptonightR_instruction217, + CryptonightR_instruction218, + CryptonightR_instruction219, + CryptonightR_instruction220, + CryptonightR_instruction221, + CryptonightR_instruction222, + CryptonightR_instruction223, + CryptonightR_instruction224, + CryptonightR_instruction225, + CryptonightR_instruction226, + CryptonightR_instruction227, + CryptonightR_instruction228, + CryptonightR_instruction229, + CryptonightR_instruction230, + CryptonightR_instruction231, + CryptonightR_instruction232, + CryptonightR_instruction233, + CryptonightR_instruction234, + CryptonightR_instruction235, + CryptonightR_instruction236, + CryptonightR_instruction237, + CryptonightR_instruction238, + CryptonightR_instruction239, + CryptonightR_instruction240, + CryptonightR_instruction241, + CryptonightR_instruction242, + CryptonightR_instruction243, + CryptonightR_instruction244, + CryptonightR_instruction245, + CryptonightR_instruction246, + CryptonightR_instruction247, + CryptonightR_instruction248, + CryptonightR_instruction249, + CryptonightR_instruction250, + CryptonightR_instruction251, + CryptonightR_instruction252, + CryptonightR_instruction253, + CryptonightR_instruction254, + CryptonightR_instruction255, + CryptonightR_instruction256, +}; + +const void* instructions_mov[257] = { + CryptonightR_instruction_mov0, + CryptonightR_instruction_mov1, + CryptonightR_instruction_mov2, + CryptonightR_instruction_mov3, + CryptonightR_instruction_mov4, + CryptonightR_instruction_mov5, + CryptonightR_instruction_mov6, + CryptonightR_instruction_mov7, + CryptonightR_instruction_mov8, + CryptonightR_instruction_mov9, + CryptonightR_instruction_mov10, + CryptonightR_instruction_mov11, + CryptonightR_instruction_mov12, + CryptonightR_instruction_mov13, + CryptonightR_instruction_mov14, + CryptonightR_instruction_mov15, + CryptonightR_instruction_mov16, + CryptonightR_instruction_mov17, + CryptonightR_instruction_mov18, + CryptonightR_instruction_mov19, + CryptonightR_instruction_mov20, + CryptonightR_instruction_mov21, + CryptonightR_instruction_mov22, + CryptonightR_instruction_mov23, + CryptonightR_instruction_mov24, + CryptonightR_instruction_mov25, + CryptonightR_instruction_mov26, + CryptonightR_instruction_mov27, + CryptonightR_instruction_mov28, + CryptonightR_instruction_mov29, + CryptonightR_instruction_mov30, + CryptonightR_instruction_mov31, + CryptonightR_instruction_mov32, + CryptonightR_instruction_mov33, + CryptonightR_instruction_mov34, + CryptonightR_instruction_mov35, + CryptonightR_instruction_mov36, + CryptonightR_instruction_mov37, + CryptonightR_instruction_mov38, + CryptonightR_instruction_mov39, + CryptonightR_instruction_mov40, + CryptonightR_instruction_mov41, + CryptonightR_instruction_mov42, + CryptonightR_instruction_mov43, + CryptonightR_instruction_mov44, + CryptonightR_instruction_mov45, + CryptonightR_instruction_mov46, + CryptonightR_instruction_mov47, + CryptonightR_instruction_mov48, + CryptonightR_instruction_mov49, + CryptonightR_instruction_mov50, + CryptonightR_instruction_mov51, + CryptonightR_instruction_mov52, + CryptonightR_instruction_mov53, + CryptonightR_instruction_mov54, + CryptonightR_instruction_mov55, + CryptonightR_instruction_mov56, + CryptonightR_instruction_mov57, + CryptonightR_instruction_mov58, + CryptonightR_instruction_mov59, + CryptonightR_instruction_mov60, + CryptonightR_instruction_mov61, + CryptonightR_instruction_mov62, + CryptonightR_instruction_mov63, + CryptonightR_instruction_mov64, + CryptonightR_instruction_mov65, + CryptonightR_instruction_mov66, + CryptonightR_instruction_mov67, + CryptonightR_instruction_mov68, + CryptonightR_instruction_mov69, + CryptonightR_instruction_mov70, + CryptonightR_instruction_mov71, + CryptonightR_instruction_mov72, + CryptonightR_instruction_mov73, + CryptonightR_instruction_mov74, + CryptonightR_instruction_mov75, + CryptonightR_instruction_mov76, + CryptonightR_instruction_mov77, + CryptonightR_instruction_mov78, + CryptonightR_instruction_mov79, + CryptonightR_instruction_mov80, + CryptonightR_instruction_mov81, + CryptonightR_instruction_mov82, + CryptonightR_instruction_mov83, + CryptonightR_instruction_mov84, + CryptonightR_instruction_mov85, + CryptonightR_instruction_mov86, + CryptonightR_instruction_mov87, + CryptonightR_instruction_mov88, + CryptonightR_instruction_mov89, + CryptonightR_instruction_mov90, + CryptonightR_instruction_mov91, + CryptonightR_instruction_mov92, + CryptonightR_instruction_mov93, + CryptonightR_instruction_mov94, + CryptonightR_instruction_mov95, + CryptonightR_instruction_mov96, + CryptonightR_instruction_mov97, + CryptonightR_instruction_mov98, + CryptonightR_instruction_mov99, + CryptonightR_instruction_mov100, + CryptonightR_instruction_mov101, + CryptonightR_instruction_mov102, + CryptonightR_instruction_mov103, + CryptonightR_instruction_mov104, + CryptonightR_instruction_mov105, + CryptonightR_instruction_mov106, + CryptonightR_instruction_mov107, + CryptonightR_instruction_mov108, + CryptonightR_instruction_mov109, + CryptonightR_instruction_mov110, + CryptonightR_instruction_mov111, + CryptonightR_instruction_mov112, + CryptonightR_instruction_mov113, + CryptonightR_instruction_mov114, + CryptonightR_instruction_mov115, + CryptonightR_instruction_mov116, + CryptonightR_instruction_mov117, + CryptonightR_instruction_mov118, + CryptonightR_instruction_mov119, + CryptonightR_instruction_mov120, + CryptonightR_instruction_mov121, + CryptonightR_instruction_mov122, + CryptonightR_instruction_mov123, + CryptonightR_instruction_mov124, + CryptonightR_instruction_mov125, + CryptonightR_instruction_mov126, + CryptonightR_instruction_mov127, + CryptonightR_instruction_mov128, + CryptonightR_instruction_mov129, + CryptonightR_instruction_mov130, + CryptonightR_instruction_mov131, + CryptonightR_instruction_mov132, + CryptonightR_instruction_mov133, + CryptonightR_instruction_mov134, + CryptonightR_instruction_mov135, + CryptonightR_instruction_mov136, + CryptonightR_instruction_mov137, + CryptonightR_instruction_mov138, + CryptonightR_instruction_mov139, + CryptonightR_instruction_mov140, + CryptonightR_instruction_mov141, + CryptonightR_instruction_mov142, + CryptonightR_instruction_mov143, + CryptonightR_instruction_mov144, + CryptonightR_instruction_mov145, + CryptonightR_instruction_mov146, + CryptonightR_instruction_mov147, + CryptonightR_instruction_mov148, + CryptonightR_instruction_mov149, + CryptonightR_instruction_mov150, + CryptonightR_instruction_mov151, + CryptonightR_instruction_mov152, + CryptonightR_instruction_mov153, + CryptonightR_instruction_mov154, + CryptonightR_instruction_mov155, + CryptonightR_instruction_mov156, + CryptonightR_instruction_mov157, + CryptonightR_instruction_mov158, + CryptonightR_instruction_mov159, + CryptonightR_instruction_mov160, + CryptonightR_instruction_mov161, + CryptonightR_instruction_mov162, + CryptonightR_instruction_mov163, + CryptonightR_instruction_mov164, + CryptonightR_instruction_mov165, + CryptonightR_instruction_mov166, + CryptonightR_instruction_mov167, + CryptonightR_instruction_mov168, + CryptonightR_instruction_mov169, + CryptonightR_instruction_mov170, + CryptonightR_instruction_mov171, + CryptonightR_instruction_mov172, + CryptonightR_instruction_mov173, + CryptonightR_instruction_mov174, + CryptonightR_instruction_mov175, + CryptonightR_instruction_mov176, + CryptonightR_instruction_mov177, + CryptonightR_instruction_mov178, + CryptonightR_instruction_mov179, + CryptonightR_instruction_mov180, + CryptonightR_instruction_mov181, + CryptonightR_instruction_mov182, + CryptonightR_instruction_mov183, + CryptonightR_instruction_mov184, + CryptonightR_instruction_mov185, + CryptonightR_instruction_mov186, + CryptonightR_instruction_mov187, + CryptonightR_instruction_mov188, + CryptonightR_instruction_mov189, + CryptonightR_instruction_mov190, + CryptonightR_instruction_mov191, + CryptonightR_instruction_mov192, + CryptonightR_instruction_mov193, + CryptonightR_instruction_mov194, + CryptonightR_instruction_mov195, + CryptonightR_instruction_mov196, + CryptonightR_instruction_mov197, + CryptonightR_instruction_mov198, + CryptonightR_instruction_mov199, + CryptonightR_instruction_mov200, + CryptonightR_instruction_mov201, + CryptonightR_instruction_mov202, + CryptonightR_instruction_mov203, + CryptonightR_instruction_mov204, + CryptonightR_instruction_mov205, + CryptonightR_instruction_mov206, + CryptonightR_instruction_mov207, + CryptonightR_instruction_mov208, + CryptonightR_instruction_mov209, + CryptonightR_instruction_mov210, + CryptonightR_instruction_mov211, + CryptonightR_instruction_mov212, + CryptonightR_instruction_mov213, + CryptonightR_instruction_mov214, + CryptonightR_instruction_mov215, + CryptonightR_instruction_mov216, + CryptonightR_instruction_mov217, + CryptonightR_instruction_mov218, + CryptonightR_instruction_mov219, + CryptonightR_instruction_mov220, + CryptonightR_instruction_mov221, + CryptonightR_instruction_mov222, + CryptonightR_instruction_mov223, + CryptonightR_instruction_mov224, + CryptonightR_instruction_mov225, + CryptonightR_instruction_mov226, + CryptonightR_instruction_mov227, + CryptonightR_instruction_mov228, + CryptonightR_instruction_mov229, + CryptonightR_instruction_mov230, + CryptonightR_instruction_mov231, + CryptonightR_instruction_mov232, + CryptonightR_instruction_mov233, + CryptonightR_instruction_mov234, + CryptonightR_instruction_mov235, + CryptonightR_instruction_mov236, + CryptonightR_instruction_mov237, + CryptonightR_instruction_mov238, + CryptonightR_instruction_mov239, + CryptonightR_instruction_mov240, + CryptonightR_instruction_mov241, + CryptonightR_instruction_mov242, + CryptonightR_instruction_mov243, + CryptonightR_instruction_mov244, + CryptonightR_instruction_mov245, + CryptonightR_instruction_mov246, + CryptonightR_instruction_mov247, + CryptonightR_instruction_mov248, + CryptonightR_instruction_mov249, + CryptonightR_instruction_mov250, + CryptonightR_instruction_mov251, + CryptonightR_instruction_mov252, + CryptonightR_instruction_mov253, + CryptonightR_instruction_mov254, + CryptonightR_instruction_mov255, + CryptonightR_instruction_mov256, +}; + +#endif // CRYPTONIGHTR_TEMPLATE_H diff --git a/src/crypto/chacha.h b/src/crypto/chacha.h index 6e85ad0e9..0610f7051 100644 --- a/src/crypto/chacha.h +++ b/src/crypto/chacha.h @@ -73,18 +73,18 @@ namespace crypto { inline void generate_chacha_key(const void *data, size_t size, chacha_key& key, uint64_t kdf_rounds) { static_assert(sizeof(chacha_key) <= sizeof(hash), "Size of hash must be at least that of chacha_key"); epee::mlocked<tools::scrubbed_arr<char, HASH_SIZE>> pwd_hash; - crypto::cn_slow_hash(data, size, pwd_hash.data(), 0/*variant*/, 0/*prehashed*/); + crypto::cn_slow_hash(data, size, pwd_hash.data(), 0/*variant*/, 0/*prehashed*/, 0/*height*/); for (uint64_t n = 1; n < kdf_rounds; ++n) - crypto::cn_slow_hash(pwd_hash.data(), pwd_hash.size(), pwd_hash.data(), 0/*variant*/, 0/*prehashed*/); + crypto::cn_slow_hash(pwd_hash.data(), pwd_hash.size(), pwd_hash.data(), 0/*variant*/, 0/*prehashed*/, 0/*height*/); memcpy(&unwrap(unwrap(key)), pwd_hash.data(), sizeof(key)); } inline void generate_chacha_key_prehashed(const void *data, size_t size, chacha_key& key, uint64_t kdf_rounds) { static_assert(sizeof(chacha_key) <= sizeof(hash), "Size of hash must be at least that of chacha_key"); epee::mlocked<tools::scrubbed_arr<char, HASH_SIZE>> pwd_hash; - crypto::cn_slow_hash(data, size, pwd_hash.data(), 0/*variant*/, 1/*prehashed*/); + crypto::cn_slow_hash(data, size, pwd_hash.data(), 0/*variant*/, 1/*prehashed*/, 0/*height*/); for (uint64_t n = 1; n < kdf_rounds; ++n) - crypto::cn_slow_hash(pwd_hash.data(), pwd_hash.size(), pwd_hash.data(), 0/*variant*/, 0/*prehashed*/); + crypto::cn_slow_hash(pwd_hash.data(), pwd_hash.size(), pwd_hash.data(), 0/*variant*/, 0/*prehashed*/, 0/*height*/); memcpy(&unwrap(unwrap(key)), pwd_hash.data(), sizeof(key)); } diff --git a/src/crypto/hash-ops.h b/src/crypto/hash-ops.h index 77b52e2d4..ba7ece0f5 100644 --- a/src/crypto/hash-ops.h +++ b/src/crypto/hash-ops.h @@ -79,7 +79,7 @@ enum { }; void cn_fast_hash(const void *data, size_t length, char *hash); -void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed); +void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed, uint64_t height); void hash_extra_blake(const void *data, size_t length, char *hash); void hash_extra_groestl(const void *data, size_t length, char *hash); diff --git a/src/crypto/hash.h b/src/crypto/hash.h index 995e2294e..165fe6bb0 100644 --- a/src/crypto/hash.h +++ b/src/crypto/hash.h @@ -71,12 +71,12 @@ namespace crypto { return h; } - inline void cn_slow_hash(const void *data, std::size_t length, hash &hash, int variant = 0) { - cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant, 0/*prehashed*/); + inline void cn_slow_hash(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0) { + cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant, 0/*prehashed*/, height); } - inline void cn_slow_hash_prehashed(const void *data, std::size_t length, hash &hash, int variant = 0) { - cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant, 1/*prehashed*/); + inline void cn_slow_hash_prehashed(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0) { + cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant, 1/*prehashed*/, height); } inline void tree_hash(const hash *hashes, std::size_t count, hash &root_hash) { diff --git a/src/crypto/slow-hash.c b/src/crypto/slow-hash.c index ae0bd4e98..2a8ddb59c 100644 --- a/src/crypto/slow-hash.c +++ b/src/crypto/slow-hash.c @@ -39,6 +39,11 @@ #include "hash-ops.h" #include "oaes_lib.h" #include "variant2_int_sqrt.h" +#include "variant4_random_math.h" +#include "CryptonightR_JIT.h" + +#include <errno.h> +#include <string.h> #define MEMORY (1 << 21) // 2MB scratchpad #define ITER (1 << 20) @@ -50,6 +55,16 @@ extern void aesb_single_round(const uint8_t *in, uint8_t *out, const uint8_t *expandedKey); extern void aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *expandedKey); +static void local_abort(const char *msg) +{ + fprintf(stderr, "%s\n", msg); +#ifdef NDEBUG + _exit(1); +#else + abort(); +#endif +} + #define VARIANT1_1(p) \ do if (variant == 1) \ { \ @@ -116,48 +131,74 @@ extern void aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *ex #define VARIANT2_SHUFFLE_ADD_SSE2(base_ptr, offset) \ do if (variant >= 2) \ { \ - const __m128i chunk1 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10))); \ + __m128i chunk1 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10))); \ const __m128i chunk2 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20))); \ const __m128i chunk3 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30))); \ _mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10)), _mm_add_epi64(chunk3, _b1)); \ _mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20)), _mm_add_epi64(chunk1, _b)); \ _mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30)), _mm_add_epi64(chunk2, _a)); \ + if (variant >= 4) \ + { \ + chunk1 = _mm_xor_si128(chunk1, chunk2); \ + _c = _mm_xor_si128(_c, chunk3); \ + _c = _mm_xor_si128(_c, chunk1); \ + } \ } while (0) #define VARIANT2_SHUFFLE_ADD_NEON(base_ptr, offset) \ do if (variant >= 2) \ { \ - const uint64x2_t chunk1 = vld1q_u64(U64((base_ptr) + ((offset) ^ 0x10))); \ + uint64x2_t chunk1 = vld1q_u64(U64((base_ptr) + ((offset) ^ 0x10))); \ const uint64x2_t chunk2 = vld1q_u64(U64((base_ptr) + ((offset) ^ 0x20))); \ const uint64x2_t chunk3 = vld1q_u64(U64((base_ptr) + ((offset) ^ 0x30))); \ vst1q_u64(U64((base_ptr) + ((offset) ^ 0x10)), vaddq_u64(chunk3, vreinterpretq_u64_u8(_b1))); \ vst1q_u64(U64((base_ptr) + ((offset) ^ 0x20)), vaddq_u64(chunk1, vreinterpretq_u64_u8(_b))); \ vst1q_u64(U64((base_ptr) + ((offset) ^ 0x30)), vaddq_u64(chunk2, vreinterpretq_u64_u8(_a))); \ + if (variant >= 4) \ + { \ + chunk1 = veorq_u64(chunk1, chunk2); \ + _c = vreinterpretq_u8_u64(veorq_u64(vreinterpretq_u64_u8(_c), chunk3)); \ + _c = vreinterpretq_u8_u64(veorq_u64(vreinterpretq_u64_u8(_c), chunk1)); \ + } \ } while (0) -#define VARIANT2_PORTABLE_SHUFFLE_ADD(base_ptr, offset) \ +#define VARIANT2_PORTABLE_SHUFFLE_ADD(out, a_, base_ptr, offset) \ do if (variant >= 2) \ { \ uint64_t* chunk1 = U64((base_ptr) + ((offset) ^ 0x10)); \ uint64_t* chunk2 = U64((base_ptr) + ((offset) ^ 0x20)); \ uint64_t* chunk3 = U64((base_ptr) + ((offset) ^ 0x30)); \ \ - const uint64_t chunk1_old[2] = { chunk1[0], chunk1[1] }; \ + uint64_t chunk1_old[2] = { SWAP64LE(chunk1[0]), SWAP64LE(chunk1[1]) }; \ + const uint64_t chunk2_old[2] = { SWAP64LE(chunk2[0]), SWAP64LE(chunk2[1]) }; \ + const uint64_t chunk3_old[2] = { SWAP64LE(chunk3[0]), SWAP64LE(chunk3[1]) }; \ \ uint64_t b1[2]; \ memcpy_swap64le(b1, b + 16, 2); \ - chunk1[0] = SWAP64LE(SWAP64LE(chunk3[0]) + b1[0]); \ - chunk1[1] = SWAP64LE(SWAP64LE(chunk3[1]) + b1[1]); \ + chunk1[0] = SWAP64LE(chunk3_old[0] + b1[0]); \ + chunk1[1] = SWAP64LE(chunk3_old[1] + b1[1]); \ \ uint64_t a0[2]; \ - memcpy_swap64le(a0, a, 2); \ - chunk3[0] = SWAP64LE(SWAP64LE(chunk2[0]) + a0[0]); \ - chunk3[1] = SWAP64LE(SWAP64LE(chunk2[1]) + a0[1]); \ + memcpy_swap64le(a0, a_, 2); \ + chunk3[0] = SWAP64LE(chunk2_old[0] + a0[0]); \ + chunk3[1] = SWAP64LE(chunk2_old[1] + a0[1]); \ \ uint64_t b0[2]; \ memcpy_swap64le(b0, b, 2); \ - chunk2[0] = SWAP64LE(SWAP64LE(chunk1_old[0]) + b0[0]); \ + chunk2[0] = SWAP64LE(chunk1_old[0] + b0[0]); \ chunk2[1] = SWAP64LE(SWAP64LE(chunk1_old[1]) + b0[1]); \ + if (variant >= 4) \ + { \ + uint64_t out_copy[2]; \ + memcpy_swap64le(out_copy, out, 2); \ + chunk1_old[0] ^= chunk2_old[0]; \ + chunk1_old[1] ^= chunk2_old[1]; \ + out_copy[0] ^= chunk3_old[0]; \ + out_copy[1] ^= chunk3_old[1]; \ + out_copy[0] ^= chunk1_old[0]; \ + out_copy[1] ^= chunk1_old[1]; \ + memcpy_swap64le(out, out_copy, 2); \ + } \ } while (0) #define VARIANT2_INTEGER_MATH_DIVISION_STEP(b, ptr) \ @@ -172,7 +213,7 @@ extern void aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *ex const uint64_t sqrt_input = SWAP64LE(((uint64_t*)(ptr))[0]) + division_result #define VARIANT2_INTEGER_MATH_SSE2(b, ptr) \ - do if (variant >= 2) \ + do if ((variant == 2) || (variant == 3)) \ { \ VARIANT2_INTEGER_MATH_DIVISION_STEP(b, ptr); \ VARIANT2_INTEGER_MATH_SQRT_STEP_SSE2(); \ @@ -182,7 +223,7 @@ extern void aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *ex #if defined DBL_MANT_DIG && (DBL_MANT_DIG >= 50) // double precision floating point type has enough bits of precision on current platform #define VARIANT2_PORTABLE_INTEGER_MATH(b, ptr) \ - do if (variant >= 2) \ + do if ((variant == 2) || (variant == 3)) \ { \ VARIANT2_INTEGER_MATH_DIVISION_STEP(b, ptr); \ VARIANT2_INTEGER_MATH_SQRT_STEP_FP64(); \ @@ -192,7 +233,7 @@ extern void aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *ex // double precision floating point type is not good enough on current platform // fall back to the reference code (integer only) #define VARIANT2_PORTABLE_INTEGER_MATH(b, ptr) \ - do if (variant >= 2) \ + do if ((variant == 2) || (variant == 3)) \ { \ VARIANT2_INTEGER_MATH_DIVISION_STEP(b, ptr); \ VARIANT2_INTEGER_MATH_SQRT_STEP_REF(); \ @@ -200,13 +241,13 @@ extern void aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *ex #endif #define VARIANT2_2_PORTABLE() \ - if (variant >= 2) { \ + if (variant == 2 || variant == 3) { \ xor_blocks(long_state + (j ^ 0x10), d); \ xor_blocks(d, long_state + (j ^ 0x20)); \ } #define VARIANT2_2() \ - do if (variant >= 2) \ + do if (variant == 2 || variant == 3) \ { \ *U64(hp_state + (j ^ 0x10)) ^= SWAP64LE(hi); \ *(U64(hp_state + (j ^ 0x10)) + 1) ^= SWAP64LE(lo); \ @@ -214,6 +255,68 @@ extern void aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *ex lo ^= SWAP64LE(*(U64(hp_state + (j ^ 0x20)) + 1)); \ } while (0) +#define V4_REG_LOAD(dst, src) \ + do { \ + memcpy((dst), (src), sizeof(v4_reg)); \ + if (sizeof(v4_reg) == sizeof(uint32_t)) \ + *(dst) = SWAP32LE(*(dst)); \ + else \ + *(dst) = SWAP64LE(*(dst)); \ + } while (0) + +#define VARIANT4_RANDOM_MATH_INIT() \ + v4_reg r[9]; \ + struct V4_Instruction code[NUM_INSTRUCTIONS_MAX + 1]; \ + int jit = use_v4_jit(); \ + do if (variant >= 4) \ + { \ + for (int i = 0; i < 4; ++i) \ + V4_REG_LOAD(r + i, (uint8_t*)(state.hs.w + 12) + sizeof(v4_reg) * i); \ + v4_random_math_init(code, height); \ + if (jit) \ + { \ + int ret = v4_generate_JIT_code(code, hp_jitfunc, 4096); \ + if (ret < 0) \ + local_abort("Error generating CryptonightR code"); \ + } \ + } while (0) + +#define VARIANT4_RANDOM_MATH(a, b, r, _b, _b1) \ + do if (variant >= 4) \ + { \ + uint64_t t[2]; \ + memcpy(t, b, sizeof(uint64_t)); \ + \ + if (sizeof(v4_reg) == sizeof(uint32_t)) \ + t[0] ^= SWAP64LE((r[0] + r[1]) | ((uint64_t)(r[2] + r[3]) << 32)); \ + else \ + t[0] ^= SWAP64LE((r[0] + r[1]) ^ (r[2] + r[3])); \ + \ + memcpy(b, t, sizeof(uint64_t)); \ + \ + V4_REG_LOAD(r + 4, a); \ + V4_REG_LOAD(r + 5, (uint64_t*)(a) + 1); \ + V4_REG_LOAD(r + 6, _b); \ + V4_REG_LOAD(r + 7, _b1); \ + V4_REG_LOAD(r + 8, (uint64_t*)(_b1) + 1); \ + \ + if (jit) \ + (*hp_jitfunc)(r); \ + else \ + v4_random_math(code, r); \ + \ + memcpy(t, a, sizeof(uint64_t) * 2); \ + \ + if (sizeof(v4_reg) == sizeof(uint32_t)) { \ + t[0] ^= SWAP64LE(r[2] | ((uint64_t)(r[3]) << 32)); \ + t[1] ^= SWAP64LE(r[0] | ((uint64_t)(r[1]) << 32)); \ + } else { \ + t[0] ^= SWAP64LE(r[2] ^ r[3]); \ + t[1] ^= SWAP64LE(r[0] ^ r[1]); \ + } \ + memcpy(a, t, sizeof(uint64_t) * 2); \ + } while (0) + #if !defined NO_AES && (defined(__x86_64__) || (defined(_MSC_VER) && defined(_WIN64))) // Optimised code below, uses x86-specific intrinsics, SSE2, AES-NI @@ -298,6 +401,7 @@ extern void aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *ex p = U64(&hp_state[j]); \ b[0] = p[0]; b[1] = p[1]; \ VARIANT2_INTEGER_MATH_SSE2(b, c); \ + VARIANT4_RANDOM_MATH(a, b, r, &_b, &_b1); \ __mul(); \ VARIANT2_2(); \ VARIANT2_SHUFFLE_ADD_SSE2(hp_state, j); \ @@ -329,6 +433,9 @@ union cn_slow_hash_state THREADV uint8_t *hp_state = NULL; THREADV int hp_allocated = 0; +THREADV v4_random_math_JIT_func hp_jitfunc = NULL; +THREADV uint8_t *hp_jitfunc_memory = NULL; +THREADV int hp_jitfunc_allocated = 0; #if defined(_MSC_VER) #define cpuid(info,x) __cpuidex(info,x,0) @@ -387,6 +494,31 @@ STATIC INLINE int force_software_aes(void) return use; } +volatile int use_v4_jit_flag = -1; + +STATIC INLINE int use_v4_jit(void) +{ +#if defined(__x86_64__) + + if (use_v4_jit_flag != -1) + return use_v4_jit_flag; + + const char *env = getenv("MONERO_USE_CNV4_JIT"); + if (!env) { + use_v4_jit_flag = 0; + } + else if (!strcmp(env, "0") || !strcmp(env, "no")) { + use_v4_jit_flag = 0; + } + else { + use_v4_jit_flag = 1; + } + return use_v4_jit_flag; +#else + return 0; +#endif +} + STATIC INLINE int check_aes_hw(void) { int cpuid_results[4]; @@ -638,6 +770,33 @@ void slow_hash_allocate_state(void) hp_allocated = 0; hp_state = (uint8_t *) malloc(MEMORY); } + + +#if defined(_MSC_VER) || defined(__MINGW32__) + hp_jitfunc_memory = (uint8_t *) VirtualAlloc(hp_jitfunc_memory, 4096 + 4095, + MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); +#else +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \ + defined(__DragonFly__) || defined(__NetBSD__) + hp_jitfunc_memory = mmap(0, 4096 + 4095, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANON, 0, 0); +#else + hp_jitfunc_memory = mmap(0, 4096 + 4095, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); +#endif + if(hp_jitfunc_memory == MAP_FAILED) + hp_jitfunc_memory = NULL; +#endif + hp_jitfunc_allocated = 1; + if (hp_jitfunc_memory == NULL) + { + hp_jitfunc_allocated = 0; + hp_jitfunc_memory = malloc(4096 + 4095); + } + hp_jitfunc = (v4_random_math_JIT_func)((size_t)(hp_jitfunc_memory + 4095) & ~4095); +#if !(defined(_MSC_VER) || defined(__MINGW32__)) + mprotect(hp_jitfunc, 4096, PROT_READ | PROT_WRITE | PROT_EXEC); +#endif } /** @@ -660,8 +819,22 @@ void slow_hash_free_state(void) #endif } + if(!hp_jitfunc_allocated) + free(hp_jitfunc_memory); + else + { +#if defined(_MSC_VER) || defined(__MINGW32__) + VirtualFree(hp_jitfunc_memory, 0, MEM_RELEASE); +#else + munmap(hp_jitfunc_memory, 4096 + 4095); +#endif + } + hp_state = NULL; hp_allocated = 0; + hp_jitfunc = NULL; + hp_jitfunc_memory = NULL; + hp_jitfunc_allocated = 0; } /** @@ -694,7 +867,7 @@ void slow_hash_free_state(void) * @param length the length in bytes of the data * @param hash a pointer to a buffer in which the final 256 bit hash will be stored */ -void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed) +void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed, uint64_t height) { RDATA_ALIGN16 uint8_t expandedKey[240]; /* These buffers are aligned to use later with SSE functions */ @@ -730,6 +903,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int VARIANT1_INIT64(); VARIANT2_INIT64(); + VARIANT4_RANDOM_MATH_INIT(); /* CryptoNight Step 2: Iteratively encrypt the results from Keccak to fill * the 2MB large random access buffer. @@ -901,6 +1075,7 @@ union cn_slow_hash_state p = U64(&hp_state[j]); \ b[0] = p[0]; b[1] = p[1]; \ VARIANT2_PORTABLE_INTEGER_MATH(b, c); \ + VARIANT4_RANDOM_MATH(a, b, r, &_b, &_b1); \ __mul(); \ VARIANT2_2(); \ VARIANT2_SHUFFLE_ADD_NEON(hp_state, j); \ @@ -1063,7 +1238,7 @@ STATIC INLINE void aligned_free(void *ptr) } #endif /* FORCE_USE_HEAP */ -void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed) +void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed, uint64_t height) { RDATA_ALIGN16 uint8_t expandedKey[240]; @@ -1100,6 +1275,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int VARIANT1_INIT64(); VARIANT2_INIT64(); + VARIANT4_RANDOM_MATH_INIT(); /* CryptoNight Step 2: Iteratively encrypt the results from Keccak to fill * the 2MB large random access buffer. @@ -1278,10 +1454,11 @@ STATIC INLINE void xor_blocks(uint8_t* a, const uint8_t* b) U64(a)[1] ^= U64(b)[1]; } -void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed) +void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed, uint64_t height) { uint8_t text[INIT_SIZE_BYTE]; uint8_t a[AES_BLOCK_SIZE]; + uint8_t a1[AES_BLOCK_SIZE]; uint8_t b[AES_BLOCK_SIZE * 2]; uint8_t c[AES_BLOCK_SIZE]; uint8_t c1[AES_BLOCK_SIZE]; @@ -1317,6 +1494,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int VARIANT1_INIT64(); VARIANT2_INIT64(); + VARIANT4_RANDOM_MATH_INIT(); // use aligned data memcpy(expandedKey, aes_ctx->key->exp_data, aes_ctx->key->exp_data_len); @@ -1340,10 +1518,10 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int // Iteration 1 j = state_index(a); p = &long_state[j]; - aesb_single_round(p, p, a); - copy_block(c1, p); + aesb_single_round(p, c1, a); - VARIANT2_PORTABLE_SHUFFLE_ADD(long_state, j); + VARIANT2_PORTABLE_SHUFFLE_ADD(c1, a, long_state, j); + copy_block(p, c1); xor_blocks(p, b); VARIANT1_1(p); @@ -1352,13 +1530,15 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int p = &long_state[j]; copy_block(c, p); + copy_block(a1, a); VARIANT2_PORTABLE_INTEGER_MATH(c, c1); + VARIANT4_RANDOM_MATH(a1, c, r, b, b + AES_BLOCK_SIZE); mul(c1, c, d); VARIANT2_2_PORTABLE(); - VARIANT2_PORTABLE_SHUFFLE_ADD(long_state, j); - sum_half_blocks(a, d); - swap_blocks(a, c); - xor_blocks(a, c); + VARIANT2_PORTABLE_SHUFFLE_ADD(c1, a, long_state, j); + sum_half_blocks(a1, d); + swap_blocks(a1, c); + xor_blocks(a1, c); VARIANT1_2(U64(c) + 1); copy_block(p, c); @@ -1366,6 +1546,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int copy_block(b + AES_BLOCK_SIZE, b); } copy_block(b, c1); + copy_block(a, a1); } memcpy(text, state.init, INIT_SIZE_BYTE); @@ -1476,7 +1657,7 @@ union cn_slow_hash_state { }; #pragma pack(pop) -void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed) { +void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed, uint64_t height) { #ifndef FORCE_USE_HEAP uint8_t long_state[MEMORY]; #else @@ -1486,6 +1667,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int union cn_slow_hash_state state; uint8_t text[INIT_SIZE_BYTE]; uint8_t a[AES_BLOCK_SIZE]; + uint8_t a1[AES_BLOCK_SIZE]; uint8_t b[AES_BLOCK_SIZE * 2]; uint8_t c1[AES_BLOCK_SIZE]; uint8_t c2[AES_BLOCK_SIZE]; @@ -1505,6 +1687,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int VARIANT1_PORTABLE_INIT(); VARIANT2_PORTABLE_INIT(); + VARIANT4_RANDOM_MATH_INIT(); oaes_key_import_data(aes_ctx, aes_key, AES_KEY_SIZE); for (i = 0; i < MEMORY / INIT_SIZE_BYTE; i++) { @@ -1528,7 +1711,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int j = e2i(a, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE; copy_block(c1, &long_state[j]); aesb_single_round(c1, c1, a); - VARIANT2_PORTABLE_SHUFFLE_ADD(long_state, j); + VARIANT2_PORTABLE_SHUFFLE_ADD(c1, a, long_state, j); copy_block(&long_state[j], c1); xor_blocks(&long_state[j], b); assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE); @@ -1536,22 +1719,22 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int /* Iteration 2 */ j = e2i(c1, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE; copy_block(c2, &long_state[j]); + copy_block(a1, a); VARIANT2_PORTABLE_INTEGER_MATH(c2, c1); + VARIANT4_RANDOM_MATH(a1, c2, r, b, b + AES_BLOCK_SIZE); mul(c1, c2, d); VARIANT2_2_PORTABLE(); - VARIANT2_PORTABLE_SHUFFLE_ADD(long_state, j); - swap_blocks(a, c1); - sum_half_blocks(c1, d); - swap_blocks(c1, c2); - xor_blocks(c1, c2); + VARIANT2_PORTABLE_SHUFFLE_ADD(c1, a, long_state, j); + sum_half_blocks(a1, d); + swap_blocks(a1, c2); + xor_blocks(a1, c2); VARIANT1_2(c2 + 8); copy_block(&long_state[j], c2); - assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE); if (variant >= 2) { copy_block(b + AES_BLOCK_SIZE, b); } - copy_block(b, a); - copy_block(a, c1); + copy_block(b, c1); + copy_block(a, a1); } memcpy(text, state.init, INIT_SIZE_BYTE); diff --git a/src/crypto/variant4_random_math.h b/src/crypto/variant4_random_math.h new file mode 100644 index 000000000..f3e41a001 --- /dev/null +++ b/src/crypto/variant4_random_math.h @@ -0,0 +1,441 @@ +#ifndef VARIANT4_RANDOM_MATH_H +#define VARIANT4_RANDOM_MATH_H + +// Register size can be configured to either 32 bit (uint32_t) or 64 bit (uint64_t) +typedef uint32_t v4_reg; + +enum V4_Settings +{ + // Generate code with minimal theoretical latency = 45 cycles, which is equivalent to 15 multiplications + TOTAL_LATENCY = 15 * 3, + + // Always generate at least 60 instructions + NUM_INSTRUCTIONS_MIN = 60, + + // Never generate more than 70 instructions (final RET instruction doesn't count here) + NUM_INSTRUCTIONS_MAX = 70, + + // Available ALUs for MUL + // Modern CPUs typically have only 1 ALU which can do multiplications + ALU_COUNT_MUL = 1, + + // Total available ALUs + // Modern CPUs have 4 ALUs, but we use only 3 because random math executes together with other main loop code + ALU_COUNT = 3, +}; + +enum V4_InstructionList +{ + MUL, // a*b + ADD, // a+b + C, C is an unsigned 32-bit constant + SUB, // a-b + ROR, // rotate right "a" by "b & 31" bits + ROL, // rotate left "a" by "b & 31" bits + XOR, // a^b + RET, // finish execution + V4_INSTRUCTION_COUNT = RET, +}; + +// V4_InstructionDefinition is used to generate code from random data +// Every random sequence of bytes is a valid code +// +// There are 9 registers in total: +// - 4 variable registers +// - 5 constant registers initialized from loop variables +// This is why dst_index is 2 bits +enum V4_InstructionDefinition +{ + V4_OPCODE_BITS = 3, + V4_DST_INDEX_BITS = 2, + V4_SRC_INDEX_BITS = 3, +}; + +struct V4_Instruction +{ + uint8_t opcode; + uint8_t dst_index; + uint8_t src_index; + uint32_t C; +}; + +#ifndef FORCEINLINE +#if defined(__GNUC__) +#define FORCEINLINE __attribute__((always_inline)) inline +#elif defined(_MSC_VER) +#define FORCEINLINE __forceinline +#else +#define FORCEINLINE inline +#endif +#endif + +#ifndef UNREACHABLE_CODE +#if defined(__GNUC__) +#define UNREACHABLE_CODE __builtin_unreachable() +#elif defined(_MSC_VER) +#define UNREACHABLE_CODE __assume(false) +#else +#define UNREACHABLE_CODE +#endif +#endif + +// Random math interpreter's loop is fully unrolled and inlined to achieve 100% branch prediction on CPU: +// every switch-case will point to the same destination on every iteration of Cryptonight main loop +// +// This is about as fast as it can get without using low-level machine code generation +static FORCEINLINE void v4_random_math(const struct V4_Instruction* code, v4_reg* r) +{ + enum + { + REG_BITS = sizeof(v4_reg) * 8, + }; + +#define V4_EXEC(i) \ + { \ + const struct V4_Instruction* op = code + i; \ + const v4_reg src = r[op->src_index]; \ + v4_reg* dst = r + op->dst_index; \ + switch (op->opcode) \ + { \ + case MUL: \ + *dst *= src; \ + break; \ + case ADD: \ + *dst += src + op->C; \ + break; \ + case SUB: \ + *dst -= src; \ + break; \ + case ROR: \ + { \ + const uint32_t shift = src % REG_BITS; \ + *dst = (*dst >> shift) | (*dst << ((REG_BITS - shift) % REG_BITS)); \ + } \ + break; \ + case ROL: \ + { \ + const uint32_t shift = src % REG_BITS; \ + *dst = (*dst << shift) | (*dst >> ((REG_BITS - shift) % REG_BITS)); \ + } \ + break; \ + case XOR: \ + *dst ^= src; \ + break; \ + case RET: \ + return; \ + default: \ + UNREACHABLE_CODE; \ + break; \ + } \ + } + +#define V4_EXEC_10(j) \ + V4_EXEC(j + 0) \ + V4_EXEC(j + 1) \ + V4_EXEC(j + 2) \ + V4_EXEC(j + 3) \ + V4_EXEC(j + 4) \ + V4_EXEC(j + 5) \ + V4_EXEC(j + 6) \ + V4_EXEC(j + 7) \ + V4_EXEC(j + 8) \ + V4_EXEC(j + 9) + + // Generated program can have 60 + a few more (usually 2-3) instructions to achieve required latency + // I've checked all block heights < 10,000,000 and here is the distribution of program sizes: + // + // 60 27960 + // 61 105054 + // 62 2452759 + // 63 5115997 + // 64 1022269 + // 65 1109635 + // 66 153145 + // 67 8550 + // 68 4529 + // 69 102 + + // Unroll 70 instructions here + V4_EXEC_10(0); // instructions 0-9 + V4_EXEC_10(10); // instructions 10-19 + V4_EXEC_10(20); // instructions 20-29 + V4_EXEC_10(30); // instructions 30-39 + V4_EXEC_10(40); // instructions 40-49 + V4_EXEC_10(50); // instructions 50-59 + V4_EXEC_10(60); // instructions 60-69 + +#undef V4_EXEC_10 +#undef V4_EXEC +} + +// If we don't have enough data available, generate more +static FORCEINLINE void check_data(size_t* data_index, const size_t bytes_needed, int8_t* data, const size_t data_size) +{ + if (*data_index + bytes_needed > data_size) + { + hash_extra_blake(data, data_size, (char*) data); + *data_index = 0; + } +} + +// Generates as many random math operations as possible with given latency and ALU restrictions +// "code" array must have space for NUM_INSTRUCTIONS_MAX+1 instructions +static inline int v4_random_math_init(struct V4_Instruction* code, const uint64_t height) +{ + // MUL is 3 cycles, 3-way addition and rotations are 2 cycles, SUB/XOR are 1 cycle + // These latencies match real-life instruction latencies for Intel CPUs starting from Sandy Bridge and up to Skylake/Coffee lake + // + // AMD Ryzen has the same latencies except 1-cycle ROR/ROL, so it'll be a bit faster than Intel Sandy Bridge and newer processors + // Surprisingly, Intel Nehalem also has 1-cycle ROR/ROL, so it'll also be faster than Intel Sandy Bridge and newer processors + // AMD Bulldozer has 4 cycles latency for MUL (slower than Intel) and 1 cycle for ROR/ROL (faster than Intel), so average performance will be the same + // Source: https://www.agner.org/optimize/instruction_tables.pdf + const int op_latency[V4_INSTRUCTION_COUNT] = { 3, 2, 1, 2, 2, 1 }; + + // Instruction latencies for theoretical ASIC implementation + const int asic_op_latency[V4_INSTRUCTION_COUNT] = { 3, 1, 1, 1, 1, 1 }; + + // Available ALUs for each instruction + const int op_ALUs[V4_INSTRUCTION_COUNT] = { ALU_COUNT_MUL, ALU_COUNT, ALU_COUNT, ALU_COUNT, ALU_COUNT, ALU_COUNT }; + + int8_t data[32]; + memset(data, 0, sizeof(data)); + uint64_t tmp = SWAP64LE(height); + memcpy(data, &tmp, sizeof(uint64_t)); + data[20] = -38; // change seed + + // Set data_index past the last byte in data + // to trigger full data update with blake hash + // before we start using it + size_t data_index = sizeof(data); + + int code_size; + + // There is a small chance (1.8%) that register R8 won't be used in the generated program + // So we keep track of it and try again if it's not used + bool r8_used; + do { + int latency[9]; + int asic_latency[9]; + + // Tracks previous instruction and value of the source operand for registers R0-R3 throughout code execution + // byte 0: current value of the destination register + // byte 1: instruction opcode + // byte 2: current value of the source register + // + // Registers R4-R8 are constant and are treated as having the same value because when we do + // the same operation twice with two constant source registers, it can be optimized into a single operation + uint32_t inst_data[9] = { 0, 1, 2, 3, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF }; + + bool alu_busy[TOTAL_LATENCY + 1][ALU_COUNT]; + bool is_rotation[V4_INSTRUCTION_COUNT]; + bool rotated[4]; + int rotate_count = 0; + + memset(latency, 0, sizeof(latency)); + memset(asic_latency, 0, sizeof(asic_latency)); + memset(alu_busy, 0, sizeof(alu_busy)); + memset(is_rotation, 0, sizeof(is_rotation)); + memset(rotated, 0, sizeof(rotated)); + is_rotation[ROR] = true; + is_rotation[ROL] = true; + + int num_retries = 0; + code_size = 0; + + int total_iterations = 0; + r8_used = false; + + // Generate random code to achieve minimal required latency for our abstract CPU + // Try to get this latency for all 4 registers + while (((latency[0] < TOTAL_LATENCY) || (latency[1] < TOTAL_LATENCY) || (latency[2] < TOTAL_LATENCY) || (latency[3] < TOTAL_LATENCY)) && (num_retries < 64)) + { + // Fail-safe to guarantee loop termination + ++total_iterations; + if (total_iterations > 256) + break; + + check_data(&data_index, 1, data, sizeof(data)); + + const uint8_t c = ((uint8_t*)data)[data_index++]; + + // MUL = opcodes 0-2 + // ADD = opcode 3 + // SUB = opcode 4 + // ROR/ROL = opcode 5, shift direction is selected randomly + // XOR = opcodes 6-7 + uint8_t opcode = c & ((1 << V4_OPCODE_BITS) - 1); + if (opcode == 5) + { + check_data(&data_index, 1, data, sizeof(data)); + opcode = (data[data_index++] >= 0) ? ROR : ROL; + } + else if (opcode >= 6) + { + opcode = XOR; + } + else + { + opcode = (opcode <= 2) ? MUL : (opcode - 2); + } + + uint8_t dst_index = (c >> V4_OPCODE_BITS) & ((1 << V4_DST_INDEX_BITS) - 1); + uint8_t src_index = (c >> (V4_OPCODE_BITS + V4_DST_INDEX_BITS)) & ((1 << V4_SRC_INDEX_BITS) - 1); + + const int a = dst_index; + int b = src_index; + + // Don't do ADD/SUB/XOR with the same register + if (((opcode == ADD) || (opcode == SUB) || (opcode == XOR)) && (a == b)) + { + // Use register R8 as source instead + b = 8; + src_index = 8; + } + + // Don't do rotation with the same destination twice because it's equal to a single rotation + if (is_rotation[opcode] && rotated[a]) + { + continue; + } + + // Don't do the same instruction (except MUL) with the same source value twice because all other cases can be optimized: + // 2xADD(a, b, C) = ADD(a, b*2, C1+C2), same for SUB and rotations + // 2xXOR(a, b) = NOP + if ((opcode != MUL) && ((inst_data[a] & 0xFFFF00) == (opcode << 8) + ((inst_data[b] & 255) << 16))) + { + continue; + } + + // Find which ALU is available (and when) for this instruction + int next_latency = (latency[a] > latency[b]) ? latency[a] : latency[b]; + int alu_index = -1; + while (next_latency < TOTAL_LATENCY) + { + for (int i = op_ALUs[opcode] - 1; i >= 0; --i) + { + if (!alu_busy[next_latency][i]) + { + // ADD is implemented as two 1-cycle instructions on a real CPU, so do an additional availability check + if ((opcode == ADD) && alu_busy[next_latency + 1][i]) + { + continue; + } + + // Rotation can only start when previous rotation is finished, so do an additional availability check + if (is_rotation[opcode] && (next_latency < rotate_count * op_latency[opcode])) + { + continue; + } + + alu_index = i; + break; + } + } + if (alu_index >= 0) + { + break; + } + ++next_latency; + } + + // Don't generate instructions that leave some register unchanged for more than 7 cycles + if (next_latency > latency[a] + 7) + { + continue; + } + + next_latency += op_latency[opcode]; + + if (next_latency <= TOTAL_LATENCY) + { + if (is_rotation[opcode]) + { + ++rotate_count; + } + + // Mark ALU as busy only for the first cycle when it starts executing the instruction because ALUs are fully pipelined + alu_busy[next_latency - op_latency[opcode]][alu_index] = true; + latency[a] = next_latency; + + // ASIC is supposed to have enough ALUs to run as many independent instructions per cycle as possible, so latency calculation for ASIC is simple + asic_latency[a] = ((asic_latency[a] > asic_latency[b]) ? asic_latency[a] : asic_latency[b]) + asic_op_latency[opcode]; + + rotated[a] = is_rotation[opcode]; + + inst_data[a] = code_size + (opcode << 8) + ((inst_data[b] & 255) << 16); + + code[code_size].opcode = opcode; + code[code_size].dst_index = dst_index; + code[code_size].src_index = src_index; + code[code_size].C = 0; + + if (src_index == 8) + { + r8_used = true; + } + + if (opcode == ADD) + { + // ADD instruction is implemented as two 1-cycle instructions on a real CPU, so mark ALU as busy for the next cycle too + alu_busy[next_latency - op_latency[opcode] + 1][alu_index] = true; + + // ADD instruction requires 4 more random bytes for 32-bit constant "C" in "a = a + b + C" + check_data(&data_index, sizeof(uint32_t), data, sizeof(data)); + uint32_t t; + memcpy(&t, data + data_index, sizeof(uint32_t)); + code[code_size].C = SWAP32LE(t); + data_index += sizeof(uint32_t); + } + + ++code_size; + if (code_size >= NUM_INSTRUCTIONS_MIN) + { + break; + } + } + else + { + ++num_retries; + } + } + + // ASIC has more execution resources and can extract as much parallelism from the code as possible + // We need to add a few more MUL and ROR instructions to achieve minimal required latency for ASIC + // Get this latency for at least 1 of the 4 registers + const int prev_code_size = code_size; + while ((code_size < NUM_INSTRUCTIONS_MAX) && (asic_latency[0] < TOTAL_LATENCY) && (asic_latency[1] < TOTAL_LATENCY) && (asic_latency[2] < TOTAL_LATENCY) && (asic_latency[3] < TOTAL_LATENCY)) + { + int min_idx = 0; + int max_idx = 0; + for (int i = 1; i < 4; ++i) + { + if (asic_latency[i] < asic_latency[min_idx]) min_idx = i; + if (asic_latency[i] > asic_latency[max_idx]) max_idx = i; + } + + const uint8_t pattern[3] = { ROR, MUL, MUL }; + const uint8_t opcode = pattern[(code_size - prev_code_size) % 3]; + latency[min_idx] = latency[max_idx] + op_latency[opcode]; + asic_latency[min_idx] = asic_latency[max_idx] + asic_op_latency[opcode]; + + code[code_size].opcode = opcode; + code[code_size].dst_index = min_idx; + code[code_size].src_index = max_idx; + code[code_size].C = 0; + ++code_size; + } + + // There is ~98.15% chance that loop condition is false, so this loop will execute only 1 iteration most of the time + // It never does more than 4 iterations for all block heights < 10,000,000 + } while (!r8_used || (code_size < NUM_INSTRUCTIONS_MIN) || (code_size > NUM_INSTRUCTIONS_MAX)); + + // It's guaranteed that NUM_INSTRUCTIONS_MIN <= code_size <= NUM_INSTRUCTIONS_MAX here + // Add final instruction to stop the interpreter + code[code_size].opcode = RET; + code[code_size].dst_index = 0; + code[code_size].src_index = 0; + code[code_size].C = 0; + + return code_size; +} + +#endif diff --git a/src/cryptonote_basic/blobdatatype.h b/src/cryptonote_basic/blobdatatype.h index 7d6ff0187..82484c0a8 100644 --- a/src/cryptonote_basic/blobdatatype.h +++ b/src/cryptonote_basic/blobdatatype.h @@ -30,7 +30,11 @@ #pragma once +#include <string> +#include "span.h" + namespace cryptonote { typedef std::string blobdata; + typedef epee::span<const char> blobdata_ref; } diff --git a/src/cryptonote_basic/connection_context.h b/src/cryptonote_basic/connection_context.h index eb73ab0ea..112c13049 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_request_time(boost::posix_time::microsec_clock::universal_time()), m_callback_request_count(0), m_last_known_hash(crypto::null_hash) {} + m_last_request_time(boost::date_time::not_a_date_time), m_callback_request_count(0), m_last_known_hash(crypto::null_hash), m_pruning_seed(0), m_anchor(false) {} enum state { @@ -59,6 +59,8 @@ namespace cryptonote boost::posix_time::ptime m_last_request_time; epee::copyable_atomic m_callback_request_count; //in debug purpose: problem with double callback rise crypto::hash m_last_known_hash; + uint32_t m_pruning_seed; + bool m_anchor; //size_t m_score; TODO: add score calculations }; @@ -81,4 +83,23 @@ namespace cryptonote } } + inline char get_protocol_state_char(cryptonote_connection_context::state s) + { + switch (s) + { + case cryptonote_connection_context::state_before_handshake: + return 'h'; + case cryptonote_connection_context::state_synchronizing: + return 's'; + case cryptonote_connection_context::state_standby: + return 'w'; + case cryptonote_connection_context::state_idle: + return 'i'; + case cryptonote_connection_context::state_normal: + return 'n'; + default: + return 'u'; + } + } + } diff --git a/src/cryptonote_basic/cryptonote_basic.h b/src/cryptonote_basic/cryptonote_basic.h index 196b20e2a..c9c783a56 100644 --- a/src/cryptonote_basic/cryptonote_basic.h +++ b/src/cryptonote_basic/cryptonote_basic.h @@ -201,9 +201,11 @@ namespace cryptonote mutable crypto::hash hash; mutable size_t blob_size; + bool pruned; + transaction(); - transaction(const transaction &t): transaction_prefix(t), hash_valid(false), blob_size_valid(false), signatures(t.signatures), rct_signatures(t.rct_signatures) { if (t.is_hash_valid()) { hash = t.hash; set_hash_valid(true); } if (t.is_blob_size_valid()) { blob_size = t.blob_size; set_blob_size_valid(true); } } - transaction &operator=(const transaction &t) { transaction_prefix::operator=(t); set_hash_valid(false); set_blob_size_valid(false); signatures = t.signatures; rct_signatures = t.rct_signatures; if (t.is_hash_valid()) { hash = t.hash; set_hash_valid(true); } if (t.is_blob_size_valid()) { blob_size = t.blob_size; set_blob_size_valid(true); } return *this; } + transaction(const transaction &t): transaction_prefix(t), hash_valid(false), blob_size_valid(false), signatures(t.signatures), rct_signatures(t.rct_signatures), pruned(t.pruned) { if (t.is_hash_valid()) { hash = t.hash; set_hash_valid(true); } if (t.is_blob_size_valid()) { blob_size = t.blob_size; set_blob_size_valid(true); } } + transaction &operator=(const transaction &t) { transaction_prefix::operator=(t); set_hash_valid(false); set_blob_size_valid(false); signatures = t.signatures; rct_signatures = t.rct_signatures; if (t.is_hash_valid()) { hash = t.hash; set_hash_valid(true); } if (t.is_blob_size_valid()) { blob_size = t.blob_size; set_blob_size_valid(true); } pruned = t.pruned; return *this; } virtual ~transaction(); void set_null(); void invalidate_hashes(); @@ -232,7 +234,7 @@ namespace cryptonote if (!signatures_not_expected && vin.size() != signatures.size()) return false; - for (size_t i = 0; i < vin.size(); ++i) + if (!pruned) for (size_t i = 0; i < vin.size(); ++i) { size_t signature_size = get_signature_size(vin[i]); if (signatures_not_expected) @@ -263,7 +265,7 @@ namespace cryptonote bool r = rct_signatures.serialize_rctsig_base(ar, vin.size(), vout.size()); if (!r || !ar.stream().good()) return false; ar.end_object(); - if (rct_signatures.type != rct::RCTTypeNull) + if (!pruned && rct_signatures.type != rct::RCTTypeNull) { ar.tag("rctsig_prunable"); ar.begin_object(); @@ -274,6 +276,8 @@ namespace cryptonote } } } + if (!typename Archive<W>::is_saving()) + pruned = false; END_SERIALIZE() template<bool W, template <bool> class Archive> @@ -295,6 +299,8 @@ namespace cryptonote ar.end_object(); } } + if (!typename Archive<W>::is_saving()) + pruned = true; return true; } @@ -322,6 +328,7 @@ namespace cryptonote rct_signatures.type = rct::RCTTypeNull; set_hash_valid(false); set_blob_size_valid(false); + pruned = false; } inline diff --git a/src/cryptonote_basic/cryptonote_boost_serialization.h b/src/cryptonote_basic/cryptonote_boost_serialization.h index 0725a2bb8..d1e321994 100644 --- a/src/cryptonote_basic/cryptonote_boost_serialization.h +++ b/src/cryptonote_basic/cryptonote_boost_serialization.h @@ -249,7 +249,6 @@ namespace boost { a & x.mask; a & x.amount; - // a & x.senderPk; // not serialized, as we do not use it in monero currently } template <class Archive> @@ -295,7 +294,7 @@ namespace boost a & x.type; if (x.type == rct::RCTTypeNull) return; - if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof) + if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof && x.type != rct::RCTTypeBulletproof2) throw boost::archive::archive_exception(boost::archive::archive_exception::other_exception, "Unsupported rct type"); // a & x.message; message is not serialized, as it can be reconstructed from the tx data // a & x.mixRing; mixRing is not serialized, as it can be reconstructed from the offsets @@ -323,7 +322,7 @@ namespace boost a & x.type; if (x.type == rct::RCTTypeNull) return; - if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof) + if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof && x.type != rct::RCTTypeBulletproof2) throw boost::archive::archive_exception(boost::archive::archive_exception::other_exception, "Unsupported rct type"); // a & x.message; message is not serialized, as it can be reconstructed from the tx data // a & x.mixRing; mixRing is not serialized, as it can be reconstructed from the offsets @@ -337,7 +336,7 @@ namespace boost if (x.p.rangeSigs.empty()) a & x.p.bulletproofs; a & x.p.MGs; - if (x.type == rct::RCTTypeBulletproof) + if (x.type == rct::RCTTypeBulletproof || x.type == rct::RCTTypeBulletproof2) a & x.p.pseudoOuts; } } diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index 82428f196..10fb5444c 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -196,6 +196,7 @@ namespace cryptonote bool r = tx.serialize_base(ba); CHECK_AND_ASSERT_MES(r, false, "Failed to parse transaction from blob"); CHECK_AND_ASSERT_MES(expand_transaction_1(tx, true), false, "Failed to expand transaction data"); + tx.invalidate_hashes(); return true; } //--------------------------------------------------------------- @@ -225,6 +226,22 @@ namespace cryptonote return true; } //--------------------------------------------------------------- + bool is_v1_tx(const blobdata_ref& tx_blob) + { + uint64_t version; + const char* begin = static_cast<const char*>(tx_blob.data()); + const char* end = begin + tx_blob.size(); + int read = tools::read_varint(begin, end, version); + if (read <= 0) + throw std::runtime_error("Internal error getting transaction version"); + return version <= 1; + } + //--------------------------------------------------------------- + bool is_v1_tx(const blobdata& tx_blob) + { + return is_v1_tx(blobdata_ref{tx_blob.data(), tx_blob.size()}); + } + //--------------------------------------------------------------- bool generate_key_image_helper(const account_keys& ack, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, const crypto::public_key& out_key, const crypto::public_key& tx_public_key, const std::vector<crypto::public_key>& additional_tx_public_keys, size_t real_output_index, keypair& in_ephemeral, crypto::key_image& ki, hw::device &hwdev) { crypto::key_derivation recv_derivation = AUTO_VAL_INIT(recv_derivation); @@ -1157,7 +1174,7 @@ namespace cryptonote } blobdata bd = get_block_hashing_blob(b); const int cn_variant = b.major_version >= 7 ? b.major_version - 6 : 0; - crypto::cn_slow_hash(bd.data(), bd.size(), res, cn_variant); + crypto::cn_slow_hash(bd.data(), bd.size(), res, cn_variant, height); return true; } //--------------------------------------------------------------- diff --git a/src/cryptonote_basic/cryptonote_format_utils.h b/src/cryptonote_basic/cryptonote_format_utils.h index 8d33b1ca4..994978c10 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.h +++ b/src/cryptonote_basic/cryptonote_format_utils.h @@ -53,6 +53,8 @@ namespace cryptonote bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx, crypto::hash& tx_hash, crypto::hash& tx_prefix_hash); bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx); bool parse_and_validate_tx_base_from_blob(const blobdata& tx_blob, transaction& tx); + bool is_v1_tx(const blobdata_ref& tx_blob); + bool is_v1_tx(const blobdata& tx_blob); template<typename T> bool find_tx_extra_field_by_type(const std::vector<tx_extra_field>& tx_extra_fields, T& field, size_t index = 0) diff --git a/src/cryptonote_basic/hardfork.cpp b/src/cryptonote_basic/hardfork.cpp index 447d79aee..d1d836fcb 100644 --- a/src/cryptonote_basic/hardfork.cpp +++ b/src/cryptonote_basic/hardfork.cpp @@ -332,7 +332,7 @@ int HardFork::get_voted_fork_index(uint64_t height) const { CRITICAL_REGION_LOCAL(lock); uint32_t accumulated_votes = 0; - for (unsigned int n = heights.size() - 1; n > current_fork_index; --n) { + for (int n = heights.size() - 1; n >= 0; --n) { uint8_t v = heights[n].version; accumulated_votes += last_versions[v]; uint32_t threshold = (window_size * heights[n].threshold + 99) / 100; diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index 496678b5e..d6edb23c2 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -59,6 +59,8 @@ #define CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 60000 //size of block (bytes) after which reward for block calculated using block size #define CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1 20000 //size of block (bytes) after which reward for block calculated using block size - before first fork #define CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 300000 //size of block (bytes) after which reward for block calculated using block size - second change, from v5 +#define CRYPTONOTE_LONG_TERM_BLOCK_WEIGHT_WINDOW_SIZE 100000 // size in blocks of the long term block weight median window +#define CRYPTONOTE_SHORT_TERM_BLOCK_WEIGHT_SURGE_FACTOR 50 #define CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE 600 #define CRYPTONOTE_DISPLAY_DECIMAL_POINT 12 // COIN - number of smallest units in one coin @@ -108,6 +110,7 @@ #define P2P_DEFAULT_PACKET_MAX_SIZE 50000000 //50000000 bytes maximum packet size #define P2P_DEFAULT_PEERS_IN_HANDSHAKE 250 #define P2P_DEFAULT_CONNECTION_TIMEOUT 5000 //5 seconds +#define P2P_DEFAULT_TOR_CONNECT_TIMEOUT 20 // seconds #define P2P_DEFAULT_PING_CONNECTION_TIMEOUT 2000 //2 seconds #define P2P_DEFAULT_INVOKE_TIMEOUT 60*2*1000 //2 minutes #define P2P_DEFAULT_HANDSHAKE_INVOKE_TIMEOUT 5000 //5 seconds @@ -141,6 +144,8 @@ #define HF_VERSION_MIN_MIXIN_10 8 #define HF_VERSION_ENFORCE_RCT 6 #define HF_VERSION_PER_BYTE_FEE 8 +#define HF_VERSION_SMALLER_BP 10 +#define HF_VERSION_LONG_TERM_BLOCK_WEIGHT 10 #define PER_KB_FEE_QUANTIZATION_DECIMALS 8 @@ -150,6 +155,11 @@ #define BULLETPROOF_MAX_OUTPUTS 16 +#define CRYPTONOTE_PRUNING_STRIPE_SIZE 4096 // the smaller, the smoother the increase +#define CRYPTONOTE_PRUNING_LOG_STRIPES 3 // the higher, the more space saved +#define CRYPTONOTE_PRUNING_TIP_BLOCKS 5500 // the smaller, the more space saved +//#define CRYPTONOTE_PRUNING_DEBUG_SPOOF_SEED + // New constants are intended to go here namespace config { diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index a108124a8..b0dbe1eb5 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -53,6 +53,8 @@ #include "ringct/rctSigs.h" #include "common/perf_timer.h" #include "common/notify.h" +#include "common/varint.h" +#include "common/pruning.h" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "blockchain" @@ -113,6 +115,12 @@ static const struct { // version 9 starts from block 1686275, which is on or around the 19th of October, 2018. Fork time finalised on 2018-09-02. { 9, 1686275, 0, 1535889548 }, + + // version 10 starts from block 1788000, which is on or around the 9th of March, 2019. Fork time finalised on 2019-02-10. + { 10, 1788000, 0, 1549792439 }, + + // version 11 starts from block 1788720, which is on or around the 10th of March, 2019. Fork time finalised on 2019-02-15. + { 11, 1788720, 0, 1550225678 }, }; static const uint64_t mainnet_hard_fork_version_1_till = 1009826; @@ -137,6 +145,8 @@ static const struct { { 7, 1057027, 0, 1512211236 }, { 8, 1057058, 0, 1533211200 }, { 9, 1057778, 0, 1533297600 }, + { 10, 1154318, 0, 1550153694 }, + { 11, 1155038, 0, 1550225678 }, }; static const uint64_t testnet_hard_fork_version_1_till = 624633; @@ -158,12 +168,16 @@ static const struct { { 7, 37000, 0, 1521600000 }, { 8, 176456, 0, 1537821770 }, { 9, 177176, 0, 1537821771 }, + { 10, 269000, 0, 1550153694 }, + { 11, 269720, 0, 1550225678 }, }; //------------------------------------------------------------------ Blockchain::Blockchain(tx_memory_pool& tx_pool) : m_db(), m_tx_pool(tx_pool), m_hardfork(NULL), m_timestamps_and_difficulties_height(0), m_current_block_cumul_weight_limit(0), m_current_block_cumul_weight_median(0), m_enforce_dns_checkpoints(false), m_max_prepare_blocks_threads(4), m_db_sync_on_blocks(true), m_db_sync_threshold(1), m_db_sync_mode(db_async), m_db_default_sync(false), m_fast_sync(true), m_show_time_stats(false), m_sync_counter(0), m_bytes_to_sync(0), m_cancel(false), + m_long_term_block_weights_window(CRYPTONOTE_LONG_TERM_BLOCK_WEIGHT_WINDOW_SIZE), + m_long_term_effective_median_block_weight(0), m_difficulty_for_next_block_top_hash(crypto::null_hash), m_difficulty_for_next_block(1), m_btc_valid(false) @@ -498,7 +512,11 @@ bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline m_tx_pool.on_blockchain_dec(m_db->height()-1, get_tail_id()); } - update_next_cumulative_weight_limit(); + if (test_options && test_options->long_term_block_weight_window) + m_long_term_block_weights_window = test_options->long_term_block_weight_window; + + if (!update_next_cumulative_weight_limit()) + return false; return true; } //------------------------------------------------------------------ @@ -646,8 +664,14 @@ block Blockchain::pop_block_from_blockchain() m_hardfork->on_block_popped(1); // return transactions from popped block to the tx_pool + size_t pruned = 0; for (transaction& tx : popped_txs) { + if (tx.pruned) + { + ++pruned; + continue; + } if (!is_coinbase(tx)) { cryptonote::tx_verification_context tvc = AUTO_VAL_INIT(tvc); @@ -669,13 +693,15 @@ block Blockchain::pop_block_from_blockchain() } } } + if (pruned) + MWARNING(pruned << " pruned txes could not be added back to the txpool"); m_blocks_longhash_table.clear(); m_scan_table.clear(); m_blocks_txs_check.clear(); m_check_txin_table.clear(); - update_next_cumulative_weight_limit(); + CHECK_AND_ASSERT_THROW_MES(update_next_cumulative_weight_limit(), "Error updating next cumulative weight limit"); m_tx_pool.on_blockchain_dec(m_db->height()-1, get_tail_id()); invalidate_block_template_cache(); @@ -694,7 +720,8 @@ bool Blockchain::reset_and_set_genesis_block(const block& b) block_verification_context bvc = boost::value_initialized<block_verification_context>(); add_new_block(b, bvc); - update_next_cumulative_weight_limit(); + if (!update_next_cumulative_weight_limit()) + return false; return bvc.m_added_to_main_chain && !bvc.m_verifivation_failed; } //------------------------------------------------------------------ @@ -1039,6 +1066,7 @@ bool Blockchain::switch_to_alternative_blockchain(std::list<blocks_ext_by_hash:: } // if we're to keep the disconnected blocks, add them as alternates + const size_t discarded_blocks = disconnected_chain.size(); if(!discard_disconnected_chain) { //pushing old chain as alternative chain @@ -1063,6 +1091,11 @@ bool Blockchain::switch_to_alternative_blockchain(std::list<blocks_ext_by_hash:: m_hardfork->reorganize_from_chain_height(split_height); + std::shared_ptr<tools::Notify> reorg_notify = m_reorg_notify; + if (reorg_notify) + reorg_notify->notify("%s", std::to_string(split_height).c_str(), "%h", std::to_string(m_db->height()).c_str(), + "%n", std::to_string(m_db->height() - split_height).c_str(), "%d", std::to_string(discarded_blocks).c_str(), NULL); + MGINFO_GREEN("REORGANIZE SUCCESS! on height: " << split_height << ", new blockchain size: " << m_db->height()); return true; } @@ -1187,7 +1220,7 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl } } - std::vector<size_t> last_blocks_weights; + std::vector<uint64_t> last_blocks_weights; get_last_n_blocks_weights(last_blocks_weights, CRYPTONOTE_REWARD_BLOCKS_WINDOW); if (!get_block_reward(epee::misc_utils::median(last_blocks_weights), cumulative_block_weight, already_generated_coins, base_reward, version)) { @@ -1222,7 +1255,7 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl } //------------------------------------------------------------------ // get the block weights of the last <count> blocks, and return by reference <sz>. -void Blockchain::get_last_n_blocks_weights(std::vector<size_t>& weights, size_t count) const +void Blockchain::get_last_n_blocks_weights(std::vector<uint64_t>& weights, size_t count) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -2044,6 +2077,51 @@ bool Blockchain::get_transactions_blobs(const t_ids_container& txs_ids, t_tx_con return true; } //------------------------------------------------------------------ +size_t get_transaction_version(const cryptonote::blobdata &bd) +{ + size_t version; + const char* begin = static_cast<const char*>(bd.data()); + const char* end = begin + bd.size(); + int read = tools::read_varint(begin, end, version); + if (read <= 0) + throw std::runtime_error("Internal error getting transaction version"); + return version; +} +//------------------------------------------------------------------ +template<class t_ids_container, class t_tx_container, class t_missed_container> +bool Blockchain::get_split_transactions_blobs(const t_ids_container& txs_ids, t_tx_container& txs, t_missed_container& missed_txs) const +{ + LOG_PRINT_L3("Blockchain::" << __func__); + CRITICAL_REGION_LOCAL(m_blockchain_lock); + + reserve_container(txs, txs_ids.size()); + for (const auto& tx_hash : txs_ids) + { + try + { + cryptonote::blobdata tx; + if (m_db->get_pruned_tx_blob(tx_hash, tx)) + { + txs.push_back(std::make_tuple(tx_hash, std::move(tx), crypto::null_hash, cryptonote::blobdata())); + if (!is_v1_tx(std::get<1>(txs.back())) && !m_db->get_prunable_tx_hash(tx_hash, std::get<2>(txs.back()))) + { + MERROR("Prunable data hash not found for " << tx_hash); + return false; + } + if (!m_db->get_prunable_tx_blob(tx_hash, std::get<3>(txs.back()))) + std::get<3>(txs.back()).clear(); + } + else + missed_txs.push_back(tx_hash); + } + catch (const std::exception& e) + { + return false; + } + } + return true; +} +//------------------------------------------------------------------ template<class t_ids_container, class t_tx_container, class t_missed_container> bool Blockchain::get_transactions(const t_ids_container& txs_ids, t_tx_container& txs, t_missed_container& missed_txs) const { @@ -2092,9 +2170,12 @@ bool Blockchain::find_blockchain_supplement(const std::list<crypto::hash>& qbloc m_db->block_txn_start(true); current_height = get_current_blockchain_height(); + const uint32_t pruning_seed = get_blockchain_pruning_seed(); + start_height = tools::get_next_unpruned_block_height(start_height, current_height, pruning_seed); + uint64_t stop_height = tools::get_next_pruned_block_height(start_height, current_height, pruning_seed); size_t count = 0; - hashes.reserve(std::max((size_t)(current_height - start_height), (size_t)BLOCKS_IDS_SYNCHRONIZING_DEFAULT_COUNT)); - for(size_t i = start_height; i < current_height && count < BLOCKS_IDS_SYNCHRONIZING_DEFAULT_COUNT; i++, count++) + hashes.reserve(std::min((size_t)(stop_height - start_height), (size_t)BLOCKS_IDS_SYNCHRONIZING_DEFAULT_COUNT)); + for(size_t i = start_height; i < stop_height && count < BLOCKS_IDS_SYNCHRONIZING_DEFAULT_COUNT; i++, count++) { hashes.push_back(m_db->get_block_hash_from_height(i)); } @@ -2459,6 +2540,30 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context } } + // from v10, allow bulletproofs v2 + if (hf_version < HF_VERSION_SMALLER_BP) { + if (tx.version >= 2) { + if (tx.rct_signatures.type == rct::RCTTypeBulletproof2) + { + MERROR_VER("Ringct type " << (unsigned)rct::RCTTypeBulletproof2 << " is not allowed before v" << HF_VERSION_SMALLER_BP); + tvc.m_invalid_output = true; + return false; + } + } + } + + // from v11, allow only bulletproofs v2 + if (hf_version > HF_VERSION_SMALLER_BP) { + if (tx.version >= 2) { + if (tx.rct_signatures.type == rct::RCTTypeBulletproof) + { + MERROR_VER("Ringct type " << (unsigned)rct::RCTTypeBulletproof << " is not allowed from v" << (HF_VERSION_SMALLER_BP + 1)); + tvc.m_invalid_output = true; + return false; + } + } + } + return true; } //------------------------------------------------------------------ @@ -2499,7 +2604,7 @@ bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_pr } } } - else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof) + else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof || rv.type == rct::RCTTypeBulletproof2) { CHECK_AND_ASSERT_MES(!pubkeys.empty() && !pubkeys[0].empty(), false, "empty pubkeys"); rv.mixRing.resize(pubkeys.size()); @@ -2525,7 +2630,7 @@ bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_pr for (size_t n = 0; n < tx.vin.size(); ++n) rv.p.MGs[0].II[n] = rct::ki2rct(boost::get<txin_to_key>(tx.vin[n]).k_image); } - else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof) + else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof || rv.type == rct::RCTTypeBulletproof2) { CHECK_AND_ASSERT_MES(rv.p.MGs.size() == tx.vin.size(), false, "Bad MGs size"); for (size_t n = 0; n < tx.vin.size(); ++n) @@ -2799,6 +2904,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc, } case rct::RCTTypeSimple: case rct::RCTTypeBulletproof: + case rct::RCTTypeBulletproof2: { // check all this, either reconstructed (so should really pass), or not { @@ -3007,6 +3113,7 @@ uint64_t Blockchain::get_dynamic_base_fee(uint64_t block_reward, size_t median_b bool Blockchain::check_fee(size_t tx_weight, uint64_t fee) const { const uint8_t version = get_current_hard_fork_version(); + const uint64_t blockchain_height = m_db->height(); uint64_t median = 0; uint64_t already_generated_coins = 0; @@ -3014,7 +3121,7 @@ bool Blockchain::check_fee(size_t tx_weight, uint64_t fee) const if (version >= HF_VERSION_DYNAMIC_FEE) { median = m_current_block_cumul_weight_limit / 2; - already_generated_coins = m_db->height() ? m_db->get_block_already_generated_coins(m_db->height() - 1) : 0; + already_generated_coins = blockchain_height ? m_db->get_block_already_generated_coins(blockchain_height - 1) : 0; if (!get_block_reward(median, 1, already_generated_coins, base_reward, version)) return false; } @@ -3022,7 +3129,8 @@ bool Blockchain::check_fee(size_t tx_weight, uint64_t fee) const uint64_t needed_fee; if (version >= HF_VERSION_PER_BYTE_FEE) { - uint64_t fee_per_byte = get_dynamic_base_fee(base_reward, median, version); + const bool use_long_term_median_in_fee = version >= HF_VERSION_LONG_TERM_BLOCK_WEIGHT; + uint64_t fee_per_byte = get_dynamic_base_fee(base_reward, use_long_term_median_in_fee ? m_long_term_effective_median_block_weight : median, version); MDEBUG("Using " << print_money(fee_per_byte) << "/byte fee"); needed_fee = tx_weight * fee_per_byte; // quantize fee up to 8 decimals @@ -3059,6 +3167,7 @@ bool Blockchain::check_fee(size_t tx_weight, uint64_t fee) const uint64_t Blockchain::get_dynamic_base_fee_estimate(uint64_t grace_blocks) const { const uint8_t version = get_current_hard_fork_version(); + const uint64_t db_height = m_db->height(); if (version < HF_VERSION_DYNAMIC_FEE) return FEE_PER_KB; @@ -3067,7 +3176,7 @@ uint64_t Blockchain::get_dynamic_base_fee_estimate(uint64_t grace_blocks) const grace_blocks = CRYPTONOTE_REWARD_BLOCKS_WINDOW - 1; const uint64_t min_block_weight = get_min_block_weight(version); - std::vector<size_t> weights; + std::vector<uint64_t> weights; get_last_n_blocks_weights(weights, CRYPTONOTE_REWARD_BLOCKS_WINDOW - grace_blocks); weights.reserve(grace_blocks); for (size_t i = 0; i < grace_blocks; ++i) @@ -3077,7 +3186,7 @@ uint64_t Blockchain::get_dynamic_base_fee_estimate(uint64_t grace_blocks) const if(median <= min_block_weight) median = min_block_weight; - uint64_t already_generated_coins = m_db->height() ? m_db->get_block_already_generated_coins(m_db->height() - 1) : 0; + uint64_t already_generated_coins = db_height ? m_db->get_block_already_generated_coins(db_height - 1) : 0; uint64_t base_reward; if (!get_block_reward(median, 1, already_generated_coins, base_reward, version)) { @@ -3085,7 +3194,8 @@ uint64_t Blockchain::get_dynamic_base_fee_estimate(uint64_t grace_blocks) const base_reward = BLOCK_REWARD_OVERESTIMATE; } - uint64_t fee = get_dynamic_base_fee(base_reward, median, version); + const bool use_long_term_median_in_fee = version >= HF_VERSION_LONG_TERM_BLOCK_WEIGHT; + uint64_t fee = get_dynamic_base_fee(base_reward, use_long_term_median_in_fee ? m_long_term_effective_median_block_weight : median, version); const bool per_byte = version < HF_VERSION_PER_BYTE_FEE; MDEBUG("Estimating " << grace_blocks << "-block fee at " << print_money(fee) << "/" << (per_byte ? "byte" : "kB")); return fee; @@ -3369,7 +3479,7 @@ leave: { if (memcmp(&hash, &expected_hash, sizeof(hash)) != 0) { - MERROR_VER("Block with id is INVALID: " << id); + MERROR_VER("Block with id is INVALID: " << id << ", expected " << expected_hash); bvc.m_verifivation_failed = true; goto leave; } @@ -3582,7 +3692,8 @@ leave: { try { - new_height = m_db->add_block(bl, block_weight, cumulative_difficulty, already_generated_coins, txs); + uint64_t long_term_block_weight = get_next_long_term_block_weight(block_weight); + new_height = m_db->add_block(bl, block_weight, long_term_block_weight, cumulative_difficulty, already_generated_coins, txs); } catch (const KEY_IMAGE_EXISTS& e) { @@ -3608,7 +3719,12 @@ leave: TIME_MEASURE_FINISH(addblock); // do this after updating the hard fork state since the weight limit may change due to fork - update_next_cumulative_weight_limit(); + if (!update_next_cumulative_weight_limit()) + { + MERROR("Failed to update next cumulative weight limit"); + pop_block_from_blockchain(); + return false; + } MINFO("+++++ BLOCK SUCCESSFULLY ADDED" << std::endl << "id:\t" << id << std::endl << "PoW:\t" << proof_of_work << std::endl << "HEIGHT " << new_height-1 << ", difficulty:\t" << current_diffic << std::endl << "block reward: " << print_money(fee_summary + base_reward) << "(" << print_money(base_reward) << " + " << print_money(fee_summary) << "), coinbase_weight: " << coinbase_weight << ", cumulative weight: " << cumulative_block_weight << ", " << block_processing_time << "(" << target_calculating_time << "/" << longhash_calculating_time << ")ms"); if(m_show_time_stats) @@ -3630,25 +3746,134 @@ leave: std::shared_ptr<tools::Notify> block_notify = m_block_notify; if (block_notify) - block_notify->notify(epee::string_tools::pod_to_hex(id).c_str()); + block_notify->notify("%s", epee::string_tools::pod_to_hex(id).c_str(), NULL); return true; } //------------------------------------------------------------------ -bool Blockchain::update_next_cumulative_weight_limit() +bool Blockchain::prune_blockchain(uint32_t pruning_seed) +{ + uint8_t hf_version = m_hardfork->get_current_version(); + if (hf_version < 10) + { + MERROR("Most of the network will only be ready for pruned blockchains from v10, not pruning"); + return false; + } + return m_db->prune_blockchain(pruning_seed); +} +//------------------------------------------------------------------ +bool Blockchain::update_blockchain_pruning() +{ + m_tx_pool.lock(); + epee::misc_utils::auto_scope_leave_caller unlocker = epee::misc_utils::create_scope_leave_handler([&](){m_tx_pool.unlock();}); + CRITICAL_REGION_LOCAL(m_blockchain_lock); + + return m_db->update_pruning(); +} +//------------------------------------------------------------------ +bool Blockchain::check_blockchain_pruning() +{ + m_tx_pool.lock(); + epee::misc_utils::auto_scope_leave_caller unlocker = epee::misc_utils::create_scope_leave_handler([&](){m_tx_pool.unlock();}); + CRITICAL_REGION_LOCAL(m_blockchain_lock); + + return m_db->check_pruning(); +} +//------------------------------------------------------------------ +uint64_t Blockchain::get_next_long_term_block_weight(uint64_t block_weight) const { - uint64_t full_reward_zone = get_min_block_weight(get_current_hard_fork_version()); + PERF_TIMER(get_next_long_term_block_weight); + + const uint64_t db_height = m_db->height(); + const uint64_t nblocks = std::min<uint64_t>(m_long_term_block_weights_window, db_height); + + const uint8_t hf_version = get_current_hard_fork_version(); + if (hf_version < HF_VERSION_LONG_TERM_BLOCK_WEIGHT) + return block_weight; + + std::vector<uint64_t> weights; + weights.resize(nblocks); + for (uint64_t h = 0; h < nblocks; ++h) + weights[h] = m_db->get_block_long_term_weight(db_height - nblocks + h); + uint64_t long_term_median = epee::misc_utils::median(weights); + uint64_t long_term_effective_median_block_weight = std::max<uint64_t>(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5, long_term_median); + + uint64_t short_term_constraint = long_term_effective_median_block_weight + long_term_effective_median_block_weight * 2 / 5; + uint64_t long_term_block_weight = std::min<uint64_t>(block_weight, short_term_constraint); + + return long_term_block_weight; +} +//------------------------------------------------------------------ +bool Blockchain::update_next_cumulative_weight_limit(uint64_t *long_term_effective_median_block_weight) +{ + PERF_TIMER(update_next_cumulative_weight_limit); LOG_PRINT_L3("Blockchain::" << __func__); - std::vector<size_t> weights; - get_last_n_blocks_weights(weights, CRYPTONOTE_REWARD_BLOCKS_WINDOW); - uint64_t median = epee::misc_utils::median(weights); - m_current_block_cumul_weight_median = median; - if(median <= full_reward_zone) - median = full_reward_zone; + // when we reach this, the last hf version is not yet written to the db + const uint64_t db_height = m_db->height(); + const uint8_t hf_version = get_current_hard_fork_version(); + uint64_t full_reward_zone = get_min_block_weight(hf_version); + uint64_t long_term_block_weight; + + if (hf_version < HF_VERSION_LONG_TERM_BLOCK_WEIGHT) + { + std::vector<uint64_t> weights; + get_last_n_blocks_weights(weights, CRYPTONOTE_REWARD_BLOCKS_WINDOW); + m_current_block_cumul_weight_median = epee::misc_utils::median(weights); + long_term_block_weight = weights.back(); + } + else + { + const uint64_t block_weight = m_db->get_block_weight(db_height - 1); + + std::vector<uint64_t> weights, new_weights; + uint64_t long_term_median; + if (db_height == 1) + { + long_term_median = CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5; + } + else + { + uint64_t nblocks = std::min<uint64_t>(m_long_term_block_weights_window, db_height); + if (nblocks == db_height) + --nblocks; + weights.resize(nblocks); + for (uint64_t h = 0; h < nblocks; ++h) + weights[h] = m_db->get_block_long_term_weight(db_height - nblocks + h - 1); + new_weights = weights; + long_term_median = epee::misc_utils::median(weights); + } + + m_long_term_effective_median_block_weight = std::max<uint64_t>(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5, long_term_median); + + uint64_t short_term_constraint = m_long_term_effective_median_block_weight + m_long_term_effective_median_block_weight * 2 / 5; + long_term_block_weight = std::min<uint64_t>(block_weight, short_term_constraint); + + if (new_weights.empty()) + new_weights.resize(1); + new_weights[0] = long_term_block_weight; + long_term_median = epee::misc_utils::median(new_weights); + m_long_term_effective_median_block_weight = std::max<uint64_t>(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5, long_term_median); + short_term_constraint = m_long_term_effective_median_block_weight + m_long_term_effective_median_block_weight * 2 / 5; + + weights.clear(); + get_last_n_blocks_weights(weights, CRYPTONOTE_REWARD_BLOCKS_WINDOW); + + uint64_t short_term_median = epee::misc_utils::median(weights); + uint64_t effective_median_block_weight = std::min<uint64_t>(std::max<uint64_t>(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5, short_term_median), CRYPTONOTE_SHORT_TERM_BLOCK_WEIGHT_SURGE_FACTOR * m_long_term_effective_median_block_weight); + + m_current_block_cumul_weight_median = effective_median_block_weight; + } + + if (m_current_block_cumul_weight_median <= full_reward_zone) + m_current_block_cumul_weight_median = full_reward_zone; + + m_current_block_cumul_weight_limit = m_current_block_cumul_weight_median * 2; + + if (long_term_effective_median_block_weight) + *long_term_effective_median_block_weight = m_long_term_effective_median_block_weight; - m_current_block_cumul_weight_limit = median*2; return true; } //------------------------------------------------------------------ @@ -3848,6 +4073,8 @@ bool Blockchain::cleanup_handle_incoming_blocks(bool force_sync) CRITICAL_REGION_END(); m_tx_pool.unlock(); + update_blockchain_pruning(); + return success; } @@ -4621,4 +4848,5 @@ void Blockchain::cache_block_template(const block &b, const cryptonote::account_ namespace cryptonote { template bool Blockchain::get_transactions(const std::vector<crypto::hash>&, std::vector<transaction>&, std::vector<crypto::hash>&) const; template bool Blockchain::get_transactions_blobs(const std::vector<crypto::hash>&, std::vector<cryptonote::blobdata>&, std::vector<crypto::hash>&, bool) const; +template bool Blockchain::get_split_transactions_blobs(const std::vector<crypto::hash>&, std::vector<std::tuple<crypto::hash, cryptonote::blobdata, crypto::hash, cryptonote::blobdata>>&, std::vector<crypto::hash>&) const; } diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index 5a1c4b9ad..92aef1278 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -37,6 +37,7 @@ #include <boost/multi_index/global_fun.hpp> #include <boost/multi_index/hashed_index.hpp> #include <boost/multi_index/member.hpp> +#include <boost/circular_buffer.hpp> #include <atomic> #include <functional> #include <unordered_map> @@ -631,6 +632,13 @@ namespace cryptonote uint64_t get_current_cumulative_block_weight_limit() const; /** + * @brief gets the long term block weight for a new block + * + * @return the long term block weight + */ + uint64_t get_next_long_term_block_weight(uint64_t block_weight) const; + + /** * @brief gets the block weight median based on recent blocks (same window as for the limit) * * @return the median @@ -677,6 +685,8 @@ namespace cryptonote template<class t_ids_container, class t_tx_container, class t_missed_container> bool get_transactions_blobs(const t_ids_container& txs_ids, t_tx_container& txs, t_missed_container& missed_txs, bool pruned = false) const; template<class t_ids_container, class t_tx_container, class t_missed_container> + bool get_split_transactions_blobs(const t_ids_container& txs_ids, t_tx_container& txs, t_missed_container& missed_txs) const; + template<class t_ids_container, class t_tx_container, class t_missed_container> bool get_transactions(const t_ids_container& txs_ids, t_tx_container& txs, t_missed_container& missed_txs) const; //debug functions @@ -729,11 +739,18 @@ namespace cryptonote /** * @brief sets a block notify object to call for every new block * - * @param notify the notify object to cal at every new block + * @param notify the notify object to call at every new block */ void set_block_notify(const std::shared_ptr<tools::Notify> ¬ify) { m_block_notify = notify; } /** + * @brief sets a reorg notify object to call for every reorg + * + * @param notify the notify object to call at every reorg + */ + void set_reorg_notify(const std::shared_ptr<tools::Notify> ¬ify) { m_reorg_notify = notify; } + + /** * @brief Put DB in safe sync mode */ void safesyncmode(const bool onoff); @@ -956,6 +973,10 @@ namespace cryptonote bool is_within_compiled_block_hash_area(uint64_t height) const; bool is_within_compiled_block_hash_area() const { return is_within_compiled_block_hash_area(m_db->height()); } uint64_t prevalidate_block_hashes(uint64_t height, const std::vector<crypto::hash> &hashes); + uint32_t get_blockchain_pruning_seed() const { return m_db->get_blockchain_pruning_seed(); } + bool prune_blockchain(uint32_t pruning_seed = 0); + bool update_blockchain_pruning(); + bool check_blockchain_pruning(); void lock(); void unlock(); @@ -981,7 +1002,9 @@ namespace cryptonote */ void pop_blocks(uint64_t nblocks); +#ifndef IN_UNIT_TESTS private: +#endif // TODO: evaluate whether or not each of these typedefs are left over from blockchain_storage typedef std::unordered_map<crypto::hash, size_t> blocks_by_id_index; @@ -1034,6 +1057,8 @@ namespace cryptonote std::vector<uint64_t> m_timestamps; std::vector<difficulty_type> m_difficulties; uint64_t m_timestamps_and_difficulties_height; + uint64_t m_long_term_block_weights_window; + uint64_t m_long_term_effective_median_block_weight; epee::critical_section m_difficulty_lock; crypto::hash m_difficulty_for_next_block_top_hash; @@ -1071,6 +1096,7 @@ namespace cryptonote bool m_btc_valid; std::shared_ptr<tools::Notify> m_block_notify; + std::shared_ptr<tools::Notify> m_reorg_notify; /** * @brief collects the keys for all outputs being "spent" as an input @@ -1266,7 +1292,7 @@ namespace cryptonote * @param sz return-by-reference the list of weights * @param count the number of blocks to get weights for */ - void get_last_n_blocks_weights(std::vector<size_t>& weights, size_t count) const; + void get_last_n_blocks_weights(std::vector<uint64_t>& weights, size_t count) const; /** * @brief checks if a transaction is unlocked (its outputs spendable) @@ -1365,9 +1391,11 @@ namespace cryptonote /** * @brief calculate the block weight limit for the next block to be added * + * @param long_term_effective_median_block_weight optionally return that value + * * @return true */ - bool update_next_cumulative_weight_limit(); + bool update_next_cumulative_weight_limit(uint64_t *long_term_effective_median_block_weight = NULL); void return_tx_to_pool(std::vector<transaction> &txs); /** diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 1fa6969a6..599f42774 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -105,6 +105,11 @@ namespace cryptonote "disable-dns-checkpoints" , "Do not retrieve checkpoints from DNS" }; + const command_line::arg_descriptor<size_t> arg_block_download_max_size = { + "block-download-max-size" + , "Set maximum size of block download queue in bytes (0 for default)" + , 0 + }; static const command_line::arg_descriptor<bool> arg_test_drop_download = { "test-drop-download" @@ -175,6 +180,31 @@ namespace cryptonote , "Run a program for each new block, '%s' will be replaced by the block hash" , "" }; + static const command_line::arg_descriptor<bool> arg_prune_blockchain = { + "prune-blockchain" + , "Prune blockchain" + , false + }; + static const command_line::arg_descriptor<std::string> arg_reorg_notify = { + "reorg-notify" + , "Run a program for each reorg, '%s' will be replaced by the split height, " + "'%h' will be replaced by the new blockchain height, '%n' will be " + "replaced by the number of new blocks in the new chain, and '%d' will be " + "replaced by the number of blocks discarded from the old chain" + , "" + }; + static const command_line::arg_descriptor<std::string> arg_block_rate_notify = { + "block-rate-notify" + , "Run a program when the block rate undergoes large fluctuations. This might " + "be a sign of large amounts of hash rate going on and off the Monero network, " + "and thus be of potential interest in predicting attacks. %t will be replaced " + "by the number of minutes for the observation window, %b by the number of " + "blocks observed within that window, and %e by the number of blocks that was " + "expected in that window. It is suggested that this notification is used to " + "automatically increase the number of confirmations required before a payment " + "is acted upon." + , "" + }; //----------------------------------------------------------------------------------------------- core::core(i_cryptonote_protocol* pprotocol): @@ -285,9 +315,13 @@ namespace cryptonote command_line::add_arg(desc, arg_test_dbg_lock_sleep); command_line::add_arg(desc, arg_offline); command_line::add_arg(desc, arg_disable_dns_checkpoints); + command_line::add_arg(desc, arg_block_download_max_size); command_line::add_arg(desc, arg_max_txpool_weight); command_line::add_arg(desc, arg_pad_transactions); command_line::add_arg(desc, arg_block_notify); + command_line::add_arg(desc, arg_prune_blockchain); + command_line::add_arg(desc, arg_reorg_notify); + command_line::add_arg(desc, arg_block_rate_notify); miner::init_options(desc); BlockchainDB::init_options(desc); @@ -374,6 +408,11 @@ namespace cryptonote return m_blockchain_storage.get_transactions_blobs(txs_ids, txs, missed_txs); } //----------------------------------------------------------------------------------------------- + bool core::get_split_transactions_blobs(const std::vector<crypto::hash>& txs_ids, std::vector<std::tuple<crypto::hash, cryptonote::blobdata, crypto::hash, cryptonote::blobdata>>& txs, std::vector<crypto::hash>& missed_txs) const + { + return m_blockchain_storage.get_split_transactions_blobs(txs_ids, txs, missed_txs); + } + //----------------------------------------------------------------------------------------------- bool core::get_txpool_backlog(std::vector<tx_backlog_entry>& backlog) const { m_mempool.get_transaction_backlog(backlog); @@ -413,6 +452,7 @@ namespace cryptonote uint64_t blocks_threads = command_line::get_arg(vm, arg_prep_blocks_threads); std::string check_updates_string = command_line::get_arg(vm, arg_check_updates); size_t max_txpool_weight = command_line::get_arg(vm, arg_max_txpool_weight); + bool prune_blockchain = command_line::get_arg(vm, arg_prune_blockchain); boost::filesystem::path folder(m_config_folder); if (m_nettype == FAKECHAIN) @@ -561,12 +601,33 @@ namespace cryptonote } catch (const std::exception &e) { - MERROR("Failed to parse block notify spec"); + MERROR("Failed to parse block notify spec: " << e.what()); + } + + try + { + if (!command_line::is_arg_defaulted(vm, arg_reorg_notify)) + m_blockchain_storage.set_reorg_notify(std::shared_ptr<tools::Notify>(new tools::Notify(command_line::get_arg(vm, arg_reorg_notify).c_str()))); + } + catch (const std::exception &e) + { + MERROR("Failed to parse reorg notify spec: " << e.what()); + } + + try + { + if (!command_line::is_arg_defaulted(vm, arg_block_rate_notify)) + m_block_rate_notify.reset(new tools::Notify(command_line::get_arg(vm, arg_block_rate_notify).c_str())); + } + catch (const std::exception &e) + { + MERROR("Failed to parse block rate notify spec: " << e.what()); } const std::pair<uint8_t, uint64_t> regtest_hard_forks[3] = {std::make_pair(1, 0), std::make_pair(Blockchain::get_hard_fork_heights(MAINNET).back().version, 1), std::make_pair(0, 0)}; const cryptonote::test_options regtest_test_options = { - regtest_hard_forks + regtest_hard_forks, + 0 }; const difficulty_type fixed_difficulty = command_line::get_arg(vm, arg_fixed_difficulty); r = m_blockchain_storage.init(db.release(), m_nettype, m_offline, regtest ? ®test_test_options : test_options, fixed_difficulty, get_checkpoints); @@ -607,6 +668,14 @@ namespace cryptonote r = m_miner.init(vm, m_nettype); CHECK_AND_ASSERT_MES(r, false, "Failed to initialize miner instance"); + if (prune_blockchain) + { + // display a message if the blockchain is not pruned yet + if (m_blockchain_storage.get_current_blockchain_height() > 1 && !m_blockchain_storage.get_blockchain_pruning_seed()) + MGINFO("Pruning blockchain..."); + CHECK_AND_ASSERT_MES(m_blockchain_storage.prune_blockchain(), false, "Failed to prune blockchain"); + } + return load_state_data(); } //----------------------------------------------------------------------------------------------- @@ -790,6 +859,7 @@ namespace cryptonote } break; case rct::RCTTypeBulletproof: + case rct::RCTTypeBulletproof2: if (!is_canonical_bulletproof_layout(rv.p.bulletproofs)) { MERROR_VER("Bulletproof does not have canonical form"); @@ -817,7 +887,7 @@ namespace cryptonote { if (!tx_info[n].result) continue; - if (tx_info[n].tx->rct_signatures.type != rct::RCTTypeBulletproof) + if (tx_info[n].tx->rct_signatures.type != rct::RCTTypeBulletproof && tx_info[n].tx->rct_signatures.type != rct::RCTTypeBulletproof2) continue; if (assumed_bad || !rct::verRctSemanticsSimple(tx_info[n].tx->rct_signatures)) { @@ -1501,6 +1571,7 @@ namespace cryptonote m_check_updates_interval.do_call(boost::bind(&core::check_updates, this)); m_check_disk_space_interval.do_call(boost::bind(&core::check_disk_space, this)); m_block_rate_interval.do_call(boost::bind(&core::check_block_rate, this)); + m_blockchain_pruning_interval.do_call(boost::bind(&core::update_blockchain_pruning, this)); m_miner.on_idle(); m_mempool.on_idle(); return true; @@ -1718,7 +1789,7 @@ namespace cryptonote const time_t now = time(NULL); const std::vector<time_t> timestamps = m_blockchain_storage.get_last_block_timestamps(60); - static const unsigned int seconds[] = { 5400, 1800, 600 }; + static const unsigned int seconds[] = { 5400, 3600, 1800, 1200, 600 }; for (size_t n = 0; n < sizeof(seconds)/sizeof(seconds[0]); ++n) { unsigned int b = 0; @@ -1729,6 +1800,14 @@ namespace cryptonote if (p < threshold) { MWARNING("There were " << b << " blocks in the last " << seconds[n] / 60 << " minutes, there might be large hash rate changes, or we might be partitioned, cut off from the Monero network or under attack. Or it could be just sheer bad luck."); + + std::shared_ptr<tools::Notify> block_rate_notify = m_block_rate_notify; + if (block_rate_notify) + { + auto expected = seconds[n] / DIFFICULTY_TARGET_V2; + block_rate_notify->notify("%t", std::to_string(seconds[n] / 60).c_str(), "%b", std::to_string(b).c_str(), "%e", std::to_string(expected).c_str(), NULL); + } + break; // no need to look further } } @@ -1736,6 +1815,16 @@ namespace cryptonote return true; } //----------------------------------------------------------------------------------------------- + bool core::update_blockchain_pruning() + { + return m_blockchain_storage.update_blockchain_pruning(); + } + //----------------------------------------------------------------------------------------------- + bool core::check_blockchain_pruning() + { + return m_blockchain_storage.check_blockchain_pruning(); + } + //----------------------------------------------------------------------------------------------- void core::set_target_blockchain_height(uint64_t target_blockchain_height) { m_target_blockchain_height = target_blockchain_height; @@ -1758,6 +1847,16 @@ namespace cryptonote return si.available; } //----------------------------------------------------------------------------------------------- + uint32_t core::get_blockchain_pruning_seed() const + { + return get_blockchain_storage().get_blockchain_pruning_seed(); + } + //----------------------------------------------------------------------------------------------- + bool core::prune_blockchain(uint32_t pruning_seed) + { + return get_blockchain_storage().prune_blockchain(pruning_seed); + } + //----------------------------------------------------------------------------------------------- std::time_t core::get_start_time() const { return start_time; diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index fe86f8d39..79d06662e 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -54,6 +54,7 @@ namespace cryptonote { struct test_options { const std::pair<uint8_t, uint64_t> *hard_forks; + const size_t long_term_block_weight_window; }; extern const command_line::arg_descriptor<std::string, false, true, 2> arg_data_dir; @@ -62,6 +63,7 @@ namespace cryptonote extern const command_line::arg_descriptor<bool, false> arg_regtest_on; extern const command_line::arg_descriptor<difficulty_type> arg_fixed_difficulty; extern const command_line::arg_descriptor<bool> arg_offline; + extern const command_line::arg_descriptor<size_t> arg_block_download_max_size; /************************************************************************/ /* */ @@ -359,6 +361,13 @@ namespace cryptonote * * @note see Blockchain::get_transactions */ + bool get_split_transactions_blobs(const std::vector<crypto::hash>& txs_ids, std::vector<std::tuple<crypto::hash, cryptonote::blobdata, crypto::hash, cryptonote::blobdata>>& txs, std::vector<crypto::hash>& missed_txs) const; + + /** + * @copydoc Blockchain::get_transactions + * + * @note see Blockchain::get_transactions + */ bool get_transactions(const std::vector<crypto::hash>& txs_ids, std::vector<transaction>& txs, std::vector<crypto::hash>& missed_txs) const; /** @@ -783,6 +792,36 @@ namespace cryptonote */ bool offline() const { return m_offline; } + /** + * @brief get the blockchain pruning seed + * + * @return the blockchain pruning seed + */ + uint32_t get_blockchain_pruning_seed() const; + + /** + * @brief prune the blockchain + * + * @param pruning_seed the seed to use to prune the chain (0 for default, highly recommended) + * + * @return true iff success + */ + bool prune_blockchain(uint32_t pruning_seed = 0); + + /** + * @brief incrementally prunes blockchain + * + * @return true on success, false otherwise + */ + bool update_blockchain_pruning(); + + /** + * @brief checks the blockchain pruning if enabled + * + * @return true on success, false otherwise + */ + bool check_blockchain_pruning(); + private: /** @@ -985,6 +1024,7 @@ namespace cryptonote epee::math_helper::once_a_time_seconds<60*60*12, true> m_check_updates_interval; //!< interval for checking for new versions epee::math_helper::once_a_time_seconds<60*10, true> m_check_disk_space_interval; //!< interval for checking for disk space epee::math_helper::once_a_time_seconds<90, false> m_block_rate_interval; //!< interval for checking block rate + epee::math_helper::once_a_time_seconds<60*60*5, true> m_blockchain_pruning_interval; //!< interval for incremental blockchain pruning std::atomic<bool> m_starter_message_showed; //!< has the "daemon will sync now" message been shown? @@ -1022,6 +1062,8 @@ namespace cryptonote bool m_fluffy_blocks_enabled; bool m_offline; bool m_pad_transactions; + + std::shared_ptr<tools::Notify> m_block_rate_notify; }; } diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp index b8ede32cf..c138c7854 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.cpp +++ b/src/cryptonote_core/cryptonote_tx_utils.cpp @@ -198,7 +198,7 @@ namespace cryptonote return addr.m_view_public_key; } //--------------------------------------------------------------- - bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct, rct::RangeProofType range_proof_type, rct::multisig_out *msout, bool shuffle_outs) + bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, rct::multisig_out *msout, bool shuffle_outs) { hw::device &hwdev = sender_account_keys.get_device(); @@ -405,49 +405,12 @@ namespace cryptonote for(const tx_destination_entry& dst_entr: destinations) { CHECK_AND_ASSERT_MES(dst_entr.amount > 0 || tx.version > 1, false, "Destination with wrong amount: " << dst_entr.amount); - crypto::key_derivation derivation; crypto::public_key out_eph_public_key; - // make additional tx pubkey if necessary - keypair additional_txkey; - if (need_additional_txkeys) - { - additional_txkey.sec = additional_tx_keys[output_index]; - if (dst_entr.is_subaddress) - additional_txkey.pub = rct::rct2pk(hwdev.scalarmultKey(rct::pk2rct(dst_entr.addr.m_spend_public_key), rct::sk2rct(additional_txkey.sec))); - else - additional_txkey.pub = rct::rct2pk(hwdev.scalarmultBase(rct::sk2rct(additional_txkey.sec))); - } - - bool r; - if (change_addr && dst_entr.addr == *change_addr) - { - // sending change to yourself; derivation = a*R - r = hwdev.generate_key_derivation(txkey_pub, sender_account_keys.m_view_secret_key, derivation); - CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation(" << txkey_pub << ", " << sender_account_keys.m_view_secret_key << ")"); - } - else - { - // sending to the recipient; derivation = r*A (or s*C in the subaddress scheme) - r = hwdev.generate_key_derivation(dst_entr.addr.m_view_public_key, dst_entr.is_subaddress && need_additional_txkeys ? additional_txkey.sec : tx_key, derivation); - CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation(" << dst_entr.addr.m_view_public_key << ", " << (dst_entr.is_subaddress && need_additional_txkeys ? additional_txkey.sec : tx_key) << ")"); - } - - if (need_additional_txkeys) - { - additional_tx_public_keys.push_back(additional_txkey.pub); - } - - if (tx.version > 1) - { - crypto::secret_key scalar1; - hwdev.derivation_to_scalar(derivation, output_index, scalar1); - amount_keys.push_back(rct::sk2rct(scalar1)); - } - r = hwdev.derive_public_key(derivation, output_index, dst_entr.addr.m_spend_public_key, out_eph_public_key); - CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to derive_public_key(" << derivation << ", " << output_index << ", "<< dst_entr.addr.m_spend_public_key << ")"); - - hwdev.add_output_key_mapping(dst_entr.addr.m_view_public_key, dst_entr.addr.m_spend_public_key, dst_entr.is_subaddress, output_index, amount_keys.back(), out_eph_public_key); + hwdev.generate_output_ephemeral_keys(tx.version,sender_account_keys, txkey_pub, tx_key, + dst_entr, change_addr, output_index, + need_additional_txkeys, additional_tx_keys, + additional_tx_public_keys, amount_keys, out_eph_public_key); tx_out out; out.amount = dst_entr.amount; @@ -531,7 +494,7 @@ namespace cryptonote // the non-simple version is slightly smaller, but assumes all real inputs // are on the same index, so can only be used if there just one ring. - bool use_simple_rct = sources.size() > 1 || range_proof_type != rct::RangeProofBorromean; + bool use_simple_rct = sources.size() > 1 || rct_config.range_proof_type != rct::RangeProofBorromean; if (!use_simple_rct) { @@ -629,9 +592,9 @@ namespace cryptonote get_transaction_prefix_hash(tx, tx_prefix_hash); rct::ctkeyV outSk; if (use_simple_rct) - tx.rct_signatures = rct::genRctSimple(rct::hash2rct(tx_prefix_hash), inSk, destinations, inamounts, outamounts, amount_in - amount_out, mixRing, amount_keys, msout ? &kLRki : NULL, msout, index, outSk, range_proof_type, hwdev); + tx.rct_signatures = rct::genRctSimple(rct::hash2rct(tx_prefix_hash), inSk, destinations, inamounts, outamounts, amount_in - amount_out, mixRing, amount_keys, msout ? &kLRki : NULL, msout, index, outSk, rct_config, hwdev); else - tx.rct_signatures = rct::genRct(rct::hash2rct(tx_prefix_hash), inSk, destinations, outamounts, mixRing, amount_keys, msout ? &kLRki[0] : NULL, msout, sources[0].real_output, outSk, hwdev); // same index assumption + tx.rct_signatures = rct::genRct(rct::hash2rct(tx_prefix_hash), inSk, destinations, outamounts, mixRing, amount_keys, msout ? &kLRki[0] : NULL, msout, sources[0].real_output, outSk, rct_config, hwdev); // same index assumption memwipe(inSk.data(), inSk.size() * sizeof(rct::ctkey)); CHECK_AND_ASSERT_MES(tx.vout.size() == outSk.size(), false, "outSk size does not match vout"); @@ -644,7 +607,7 @@ namespace cryptonote return true; } //--------------------------------------------------------------- - bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct, rct::RangeProofType range_proof_type, rct::multisig_out *msout) + bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, rct::multisig_out *msout) { hw::device &hwdev = sender_account_keys.get_device(); hwdev.open_tx(tx_key); @@ -662,7 +625,7 @@ namespace cryptonote additional_tx_keys.push_back(keypair::generate(sender_account_keys.get_device()).sec); } - bool r = construct_tx_with_tx_key(sender_account_keys, subaddresses, sources, destinations, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, range_proof_type, msout); + bool r = construct_tx_with_tx_key(sender_account_keys, subaddresses, sources, destinations, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, rct_config, msout); hwdev.close_tx(); return r; } @@ -674,7 +637,7 @@ namespace cryptonote crypto::secret_key tx_key; std::vector<crypto::secret_key> additional_tx_keys; std::vector<tx_destination_entry> destinations_copy = destinations; - return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, rct::RangeProofBorromean, NULL); + return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, { rct::RangeProofBorromean, 0}, NULL); } //--------------------------------------------------------------- bool generate_genesis_block( diff --git a/src/cryptonote_core/cryptonote_tx_utils.h b/src/cryptonote_core/cryptonote_tx_utils.h index 7fbd184fa..ad3297951 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.h +++ b/src/cryptonote_core/cryptonote_tx_utils.h @@ -95,8 +95,14 @@ namespace cryptonote //--------------------------------------------------------------- crypto::public_key get_destination_view_key_pub(const std::vector<tx_destination_entry> &destinations, const boost::optional<cryptonote::account_public_address>& change_addr); bool construct_tx(const account_keys& sender_account_keys, std::vector<tx_source_entry> &sources, const std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time); - bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, rct::RangeProofType range_proof_type = rct::RangeProofBorromean, rct::multisig_out *msout = NULL, bool shuffle_outs = true); - bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, rct::RangeProofType range_proof_type = rct::RangeProofBorromean, rct::multisig_out *msout = NULL); + bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, rct::multisig_out *msout = NULL, bool shuffle_outs = true); + bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, rct::multisig_out *msout = NULL); + bool generate_output_ephemeral_keys(const size_t tx_version, const cryptonote::account_keys &sender_account_keys, const crypto::public_key &txkey_pub, const crypto::secret_key &tx_key, + const cryptonote::tx_destination_entry &dst_entr, const boost::optional<cryptonote::account_public_address> &change_addr, const size_t output_index, + const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys, + std::vector<crypto::public_key> &additional_tx_public_keys, + std::vector<rct::key> &amount_keys, + crypto::public_key &out_eph_public_key) ; bool generate_genesis_block( block& bl diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h index 670d70d77..8dd0337f0 100644 --- a/src/cryptonote_core/tx_pool.h +++ b/src/cryptonote_core/tx_pool.h @@ -61,7 +61,7 @@ namespace cryptonote class txCompare { public: - bool operator()(const tx_by_fee_and_receive_time_entry& a, const tx_by_fee_and_receive_time_entry& b) + bool operator()(const tx_by_fee_and_receive_time_entry& a, const tx_by_fee_and_receive_time_entry& b) const { // sort by greatest first, not least if (a.first.first > b.first.first) return true; diff --git a/src/cryptonote_protocol/block_queue.cpp b/src/cryptonote_protocol/block_queue.cpp index c1989f093..716b0c8ba 100644 --- a/src/cryptonote_protocol/block_queue.cpp +++ b/src/cryptonote_protocol/block_queue.cpp @@ -34,6 +34,7 @@ #include <boost/uuid/uuid_io.hpp> #include "string_tools.h" #include "cryptonote_protocol_defs.h" +#include "common/pruning.h" #include "block_queue.h" #undef MONERO_DEFAULT_LOG_CATEGORY @@ -60,7 +61,10 @@ void block_queue::add_blocks(uint64_t height, std::vector<cryptonote::block_comp if (has_hashes) { for (const crypto::hash &h: hashes) + { requested_hashes.insert(h); + have_blocks.insert(h); + } set_span_hashes(height, connection_id, hashes); } } @@ -90,7 +94,10 @@ void block_queue::erase_block(block_map::iterator j) { CHECK_AND_ASSERT_THROW_MES(j != blocks.end(), "Invalid iterator"); for (const crypto::hash &h: j->hashes) + { requested_hashes.erase(h); + have_blocks.erase(h); + } blocks.erase(j); } @@ -98,12 +105,10 @@ void block_queue::flush_stale_spans(const std::set<boost::uuids::uuid> &live_con { boost::unique_lock<boost::recursive_mutex> lock(mutex); block_map::iterator i = blocks.begin(); - if (i != blocks.end() && is_blockchain_placeholder(*i)) - ++i; while (i != blocks.end()) { block_map::iterator j = i++; - if (live_connections.find(j->connection_id) == live_connections.end() && j->blocks.size() == 0) + if (j->blocks.empty() && live_connections.find(j->connection_id) == live_connections.end()) { erase_block(j); } @@ -152,23 +157,56 @@ uint64_t block_queue::get_max_block_height() const return height; } +uint64_t block_queue::get_next_needed_height(uint64_t blockchain_height) const +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + if (blocks.empty()) + return blockchain_height; + uint64_t last_needed_height = blockchain_height; + bool first = true; + for (const auto &span: blocks) + { + if (span.start_block_height + span.nblocks - 1 < blockchain_height) + continue; + if (span.start_block_height != last_needed_height || (first && span.blocks.empty())) + return last_needed_height; + last_needed_height = span.start_block_height + span.nblocks; + first = false; + } + return last_needed_height; +} + void block_queue::print() const { boost::unique_lock<boost::recursive_mutex> lock(mutex); MDEBUG("Block queue has " << blocks.size() << " spans"); for (const auto &span: blocks) - MDEBUG(" " << span.start_block_height << " - " << (span.start_block_height+span.nblocks-1) << " (" << span.nblocks << ") - " << (is_blockchain_placeholder(span) ? "blockchain" : span.blocks.empty() ? "scheduled" : "filled ") << " " << span.connection_id << " (" << ((unsigned)(span.rate*10/1024.f))/10.f << " kB/s)"); + MDEBUG(" " << span.start_block_height << " - " << (span.start_block_height+span.nblocks-1) << " (" << span.nblocks << ") - " << (span.blocks.empty() ? "scheduled" : "filled ") << " " << span.connection_id << " (" << ((unsigned)(span.rate*10/1024.f))/10.f << " kB/s)"); } -std::string block_queue::get_overview() const +std::string block_queue::get_overview(uint64_t blockchain_height) const { boost::unique_lock<boost::recursive_mutex> lock(mutex); if (blocks.empty()) return "[]"; block_map::const_iterator i = blocks.begin(); - std::string s = std::string("[") + std::to_string(i->start_block_height + i->nblocks - 1) + ":"; - while (++i != blocks.end()) - s += i->blocks.empty() ? "." : "o"; + std::string s = std::string("["); + uint64_t expected = blockchain_height; + while (i != blocks.end()) + { + if (expected > i->start_block_height) + { + s += "<"; + } + else + { + if (expected < i->start_block_height) + s += std::string(std::max((uint64_t)1, (i->start_block_height - expected) / (i->nblocks ? i->nblocks : 1)), '_'); + s += i->blocks.empty() ? "." : i->start_block_height == blockchain_height ? "m" : "o"; + expected = i->start_block_height + i->nblocks; + } + ++i; + } s += "]"; return s; } @@ -184,16 +222,31 @@ bool block_queue::requested(const crypto::hash &hash) const return requested_internal(hash); } -std::pair<uint64_t, uint64_t> block_queue::reserve_span(uint64_t first_block_height, uint64_t last_block_height, uint64_t max_blocks, const boost::uuids::uuid &connection_id, const std::vector<crypto::hash> &block_hashes, boost::posix_time::ptime time) +bool block_queue::have(const crypto::hash &hash) const +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + return have_blocks.find(hash) != have_blocks.end(); +} + +std::pair<uint64_t, uint64_t> block_queue::reserve_span(uint64_t first_block_height, uint64_t last_block_height, uint64_t max_blocks, const boost::uuids::uuid &connection_id, uint32_t pruning_seed, uint64_t blockchain_height, const std::vector<crypto::hash> &block_hashes, boost::posix_time::ptime time) { boost::unique_lock<boost::recursive_mutex> lock(mutex); + MDEBUG("reserve_span: first_block_height " << first_block_height << ", last_block_height " << last_block_height + << ", max " << max_blocks << ", seed " << epee::string_tools::to_string_hex(pruning_seed) << ", blockchain_height " << + blockchain_height << ", block hashes size " << block_hashes.size()); if (last_block_height < first_block_height || max_blocks == 0) { MDEBUG("reserve_span: early out: first_block_height " << first_block_height << ", last_block_height " << last_block_height << ", max_blocks " << max_blocks); return std::make_pair(0, 0); } + if (block_hashes.size() > last_block_height) + { + MDEBUG("reserve_span: more block hashes than fit within last_block_height: " << block_hashes.size() << " and " << last_block_height); + return std::make_pair(0, 0); + } + // skip everything we've already requested uint64_t span_start_height = last_block_height - block_hashes.size() + 1; std::vector<crypto::hash>::const_iterator i = block_hashes.begin(); while (i != block_hashes.end() && requested_internal(*i)) @@ -201,55 +254,57 @@ std::pair<uint64_t, uint64_t> block_queue::reserve_span(uint64_t first_block_hei ++i; ++span_start_height; } + + // if the peer's pruned for the starting block and its unpruned stripe comes next, start downloading from there + const uint32_t next_unpruned_height = tools::get_next_unpruned_block_height(span_start_height, blockchain_height, pruning_seed); + MDEBUG("reserve_span: next_unpruned_height " << next_unpruned_height << " from " << span_start_height << " and seed " + << epee::string_tools::to_string_hex(pruning_seed) << ", limit " << span_start_height + CRYPTONOTE_PRUNING_STRIPE_SIZE); + if (next_unpruned_height > span_start_height && next_unpruned_height < span_start_height + CRYPTONOTE_PRUNING_STRIPE_SIZE) + { + MDEBUG("We can download from next span: ideal height " << span_start_height << ", next unpruned height " << next_unpruned_height << + "(+" << next_unpruned_height - span_start_height << "), current seed " << pruning_seed); + span_start_height = next_unpruned_height; + } + MDEBUG("span_start_height: " <<span_start_height); + const uint64_t block_hashes_start_height = last_block_height - block_hashes.size() + 1; + if (span_start_height >= block_hashes.size() + block_hashes_start_height) + { + MDEBUG("Out of hashes, cannot reserve"); + return std::make_pair(0, 0); + } + + i = block_hashes.begin() + span_start_height - block_hashes_start_height; + while (i != block_hashes.end() && requested_internal(*i)) + { + ++i; + ++span_start_height; + } + uint64_t span_length = 0; std::vector<crypto::hash> hashes; - while (i != block_hashes.end() && span_length < max_blocks) + while (i != block_hashes.end() && span_length < max_blocks && tools::has_unpruned_block(span_start_height + span_length, blockchain_height, pruning_seed)) { hashes.push_back(*i); ++i; ++span_length; } if (span_length == 0) + { + MDEBUG("span_length 0, cannot reserve"); return std::make_pair(0, 0); + } MDEBUG("Reserving span " << span_start_height << " - " << (span_start_height + span_length - 1) << " for " << connection_id); add_blocks(span_start_height, span_length, connection_id, time); set_span_hashes(span_start_height, connection_id, hashes); return std::make_pair(span_start_height, span_length); } -bool block_queue::is_blockchain_placeholder(const span &span) const -{ - return span.connection_id == boost::uuids::nil_uuid(); -} - -std::pair<uint64_t, uint64_t> block_queue::get_start_gap_span() const -{ - boost::unique_lock<boost::recursive_mutex> lock(mutex); - if (blocks.empty()) - return std::make_pair(0, 0); - block_map::const_iterator i = blocks.begin(); - if (!is_blockchain_placeholder(*i)) - return std::make_pair(0, 0); - uint64_t current_height = i->start_block_height + i->nblocks - 1; - ++i; - if (i == blocks.end()) - return std::make_pair(0, 0); - uint64_t first_span_height = i->start_block_height; - if (first_span_height <= current_height + 1) - return std::make_pair(0, 0); - MDEBUG("Found gap at start of spans: last blockchain block height " << current_height << ", first span's block height " << first_span_height); - print(); - return std::make_pair(current_height + 1, first_span_height - current_height - 1); -} - std::pair<uint64_t, uint64_t> block_queue::get_next_span_if_scheduled(std::vector<crypto::hash> &hashes, boost::uuids::uuid &connection_id, boost::posix_time::ptime &time) const { boost::unique_lock<boost::recursive_mutex> lock(mutex); if (blocks.empty()) return std::make_pair(0, 0); block_map::const_iterator i = blocks.begin(); - if (is_blockchain_placeholder(*i)) - ++i; if (i == blocks.end()) return std::make_pair(0, 0); if (!i->blocks.empty()) @@ -260,6 +315,16 @@ std::pair<uint64_t, uint64_t> block_queue::get_next_span_if_scheduled(std::vecto return std::make_pair(i->start_block_height, i->nblocks); } +void block_queue::reset_next_span_time(boost::posix_time::ptime t) +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + CHECK_AND_ASSERT_THROW_MES(!blocks.empty(), "No next span to reset time"); + block_map::iterator i = blocks.begin(); + CHECK_AND_ASSERT_THROW_MES(i != blocks.end(), "No next span to reset time"); + CHECK_AND_ASSERT_THROW_MES(i->blocks.empty(), "Next span is not empty"); + (boost::posix_time::ptime&)i->time = t; // sod off, time doesn't influence sorting +} + void block_queue::set_span_hashes(uint64_t start_height, const boost::uuids::uuid &connection_id, std::vector<crypto::hash> hashes) { boost::unique_lock<boost::recursive_mutex> lock(mutex); @@ -284,8 +349,6 @@ bool block_queue::get_next_span(uint64_t &height, std::vector<cryptonote::block_ if (blocks.empty()) return false; block_map::const_iterator i = blocks.begin(); - if (is_blockchain_placeholder(*i)) - ++i; for (; i != blocks.end(); ++i) { if (!filled || !i->blocks.empty()) @@ -299,19 +362,34 @@ bool block_queue::get_next_span(uint64_t &height, std::vector<cryptonote::block_ return false; } -bool block_queue::has_next_span(const boost::uuids::uuid &connection_id, bool &filled) const +bool block_queue::has_next_span(const boost::uuids::uuid &connection_id, bool &filled, boost::posix_time::ptime &time) const { boost::unique_lock<boost::recursive_mutex> lock(mutex); if (blocks.empty()) return false; block_map::const_iterator i = blocks.begin(); - if (is_blockchain_placeholder(*i)) - ++i; if (i == blocks.end()) return false; if (i->connection_id != connection_id) return false; filled = !i->blocks.empty(); + time = i->time; + return true; +} + +bool block_queue::has_next_span(uint64_t height, bool &filled, boost::posix_time::ptime &time, boost::uuids::uuid &connection_id) const +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + if (blocks.empty()) + return false; + block_map::const_iterator i = blocks.begin(); + if (i == blocks.end()) + return false; + if (i->start_block_height > height) + return false; + filled = !i->blocks.empty(); + time = i->time; + connection_id = i->connection_id; return true; } @@ -331,8 +409,6 @@ size_t block_queue::get_num_filled_spans_prefix() const if (blocks.empty()) return 0; block_map::const_iterator i = blocks.begin(); - if (is_blockchain_placeholder(*i)) - ++i; size_t size = 0; while (i != blocks.end() && !i->blocks.empty()) { @@ -417,12 +493,35 @@ float block_queue::get_speed(const boost::uuids::uuid &connection_id) const return speed; } -bool block_queue::foreach(std::function<bool(const span&)> f, bool include_blockchain_placeholder) const +float block_queue::get_download_rate(const boost::uuids::uuid &connection_id) const +{ + boost::unique_lock<boost::recursive_mutex> lock(mutex); + float conn_rate = -1.f; + for (const auto &span: blocks) + { + if (span.blocks.empty()) + continue; + if (span.connection_id != connection_id) + continue; + // note that the average below does not average over the whole set, but over the + // previous pseudo average and the latest rate: this gives much more importance + // to the latest measurements, which is fine here + if (conn_rate < 0.f) + conn_rate = span.rate; + else + conn_rate = (conn_rate + span.rate) / 2; + } + + if (conn_rate < 0) + conn_rate = 0.0f; + MTRACE("Download rate for " << connection_id << ": " << conn_rate << " b/s"); + return conn_rate; +} + +bool block_queue::foreach(std::function<bool(const span&)> f) const { boost::unique_lock<boost::recursive_mutex> lock(mutex); block_map::const_iterator i = blocks.begin(); - if (!include_blockchain_placeholder && i != blocks.end() && is_blockchain_placeholder(*i)) - ++i; while (i != blocks.end()) if (!f(*i++)) return false; diff --git a/src/cryptonote_protocol/block_queue.h b/src/cryptonote_protocol/block_queue.h index 9cce95075..c7d3af7ac 100644 --- a/src/cryptonote_protocol/block_queue.h +++ b/src/cryptonote_protocol/block_queue.h @@ -76,22 +76,26 @@ namespace cryptonote void remove_spans(const boost::uuids::uuid &connection_id, uint64_t start_block_height); uint64_t get_max_block_height() const; void print() const; - std::string get_overview() const; - std::pair<uint64_t, uint64_t> reserve_span(uint64_t first_block_height, uint64_t last_block_height, uint64_t max_blocks, const boost::uuids::uuid &connection_id, const std::vector<crypto::hash> &block_hashes, boost::posix_time::ptime time = boost::posix_time::microsec_clock::universal_time()); - bool is_blockchain_placeholder(const span &span) const; - std::pair<uint64_t, uint64_t> get_start_gap_span() const; + std::string get_overview(uint64_t blockchain_height) const; + bool has_unpruned_height(uint64_t block_height, uint64_t blockchain_height, uint32_t pruning_seed) const; + std::pair<uint64_t, uint64_t> reserve_span(uint64_t first_block_height, uint64_t last_block_height, uint64_t max_blocks, const boost::uuids::uuid &connection_id, uint32_t pruning_seed, uint64_t blockchain_height, const std::vector<crypto::hash> &block_hashes, boost::posix_time::ptime time = boost::posix_time::microsec_clock::universal_time()); + uint64_t get_next_needed_height(uint64_t blockchain_height) const; std::pair<uint64_t, uint64_t> get_next_span_if_scheduled(std::vector<crypto::hash> &hashes, boost::uuids::uuid &connection_id, boost::posix_time::ptime &time) const; + void reset_next_span_time(boost::posix_time::ptime t = boost::posix_time::microsec_clock::universal_time()); void set_span_hashes(uint64_t start_height, const boost::uuids::uuid &connection_id, std::vector<crypto::hash> hashes); bool get_next_span(uint64_t &height, std::vector<cryptonote::block_complete_entry> &bcel, boost::uuids::uuid &connection_id, bool filled = true) const; - bool has_next_span(const boost::uuids::uuid &connection_id, bool &filled) const; + bool has_next_span(const boost::uuids::uuid &connection_id, bool &filled, boost::posix_time::ptime &time) const; + bool has_next_span(uint64_t height, bool &filled, boost::posix_time::ptime &time, boost::uuids::uuid &connection_id) const; size_t get_data_size() const; size_t get_num_filled_spans_prefix() const; size_t get_num_filled_spans() const; crypto::hash get_last_known_hash(const boost::uuids::uuid &connection_id) const; bool has_spans(const boost::uuids::uuid &connection_id) const; float get_speed(const boost::uuids::uuid &connection_id) const; - bool foreach(std::function<bool(const span&)> f, bool include_blockchain_placeholder = false) const; + float get_download_rate(const boost::uuids::uuid &connection_id) const; + bool foreach(std::function<bool(const span&)> f) const; bool requested(const crypto::hash &hash) const; + bool have(const crypto::hash &hash) const; private: void erase_block(block_map::iterator j); @@ -101,5 +105,6 @@ namespace cryptonote block_map blocks; mutable boost::recursive_mutex mutex; std::unordered_set<crypto::hash> requested_hashes; + std::unordered_set<crypto::hash> have_blocks; }; } diff --git a/src/cryptonote_protocol/cryptonote_protocol_defs.h b/src/cryptonote_protocol/cryptonote_protocol_defs.h index d5bb50930..2d5d10d67 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_defs.h +++ b/src/cryptonote_protocol/cryptonote_protocol_defs.h @@ -48,6 +48,7 @@ namespace cryptonote bool incoming; bool localhost; bool local_ip; + bool ssl; std::string address; std::string host; @@ -78,6 +79,8 @@ namespace cryptonote uint64_t height; + uint32_t pruning_seed; + BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(incoming) KV_SERIALIZE(localhost) @@ -100,6 +103,7 @@ namespace cryptonote KV_SERIALIZE(support_flags) KV_SERIALIZE(connection_id) KV_SERIALIZE(height) + KV_SERIALIZE(pruning_seed) END_KV_SERIALIZE_MAP() }; @@ -200,12 +204,14 @@ namespace cryptonote uint64_t cumulative_difficulty; crypto::hash top_id; uint8_t top_version; + uint32_t pruning_seed; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(current_height) KV_SERIALIZE(cumulative_difficulty) KV_SERIALIZE_VAL_POD_AS_BLOB(top_id) KV_SERIALIZE_OPT(top_version, (uint8_t)0) + KV_SERIALIZE_OPT(pruning_seed, (uint32_t)0) END_KV_SERIALIZE_MAP() }; diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.h b/src/cryptonote_protocol/cryptonote_protocol_handler.h index 3c5b22b4a..efd986b53 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.h +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.h @@ -43,6 +43,7 @@ #include "cryptonote_protocol_defs.h" #include "cryptonote_protocol_handler_common.h" #include "block_queue.h" +#include "common/perf_timer.h" #include "cryptonote_basic/connection_context.h" #include "cryptonote_basic/cryptonote_stat_info.h" #include <boost/circular_buffer.hpp> @@ -109,6 +110,10 @@ namespace cryptonote const block_queue &get_block_queue() const { return m_block_queue; } void stop(); void on_connection_close(cryptonote_connection_context &context); + void set_max_out_peers(unsigned int max) { m_max_out_peers = max; } + std::string get_peers_overview() const; + std::pair<uint32_t, uint32_t> get_next_needed_pruning_stripe() const; + bool needs_new_sync_connections() const; private: //----------------- commands handlers ---------------------------------------------- int handle_notify_new_block(int command, NOTIFY_NEW_BLOCK::request& arg, cryptonote_connection_context& context); @@ -125,14 +130,17 @@ namespace cryptonote virtual bool relay_transactions(NOTIFY_NEW_TRANSACTIONS::request& arg, cryptonote_connection_context& exclude_context); //---------------------------------------------------------------------------------- //bool get_payload_sync_data(HANDSHAKE_DATA::request& hshd, cryptonote_connection_context& context); + bool should_drop_connection(cryptonote_connection_context& context, uint32_t next_stripe); bool request_missing_objects(cryptonote_connection_context& context, bool check_having_blocks, bool force_next_span = false); size_t get_synchronizing_connections_count(); bool on_connection_synchronized(); - bool should_download_next_span(cryptonote_connection_context& context) const; + bool should_download_next_span(cryptonote_connection_context& context, bool standby); void drop_connection(cryptonote_connection_context &context, bool add_fail, bool flush_all_spans); bool kick_idle_peers(); bool check_standby_peers(); int try_add_next_blocks(cryptonote_connection_context &context); + void notify_new_stripe(cryptonote_connection_context &context, uint32_t stripe); + void skip_unneeded_hashes(cryptonote_connection_context& context, bool check_block_queue) const; t_core& m_core; @@ -145,6 +153,12 @@ namespace cryptonote block_queue m_block_queue; epee::math_helper::once_a_time_seconds<30> m_idle_peer_kicker; epee::math_helper::once_a_time_milliseconds<100> m_standby_checker; + std::atomic<unsigned int> m_max_out_peers; + tools::PerformanceTimer m_sync_timer, m_add_timer; + uint64_t m_last_add_end_time; + uint64_t m_sync_spans_downloaded, m_sync_old_spans_downloaded, m_sync_bad_spans_downloaded; + uint64_t m_sync_download_chain_size, m_sync_download_objects_size; + size_t m_block_download_max_size; boost::mutex m_buffer_mutex; double get_avg_block_size(); @@ -159,15 +173,6 @@ namespace cryptonote //handler_response_blocks_now(blob.size()); // XXX return m_p2p->invoke_notify_to_peer(t_parameter::ID, epee::strspan<uint8_t>(blob), context); } - - template<class t_parameter> - bool relay_post_notify(typename t_parameter::request& arg, cryptonote_connection_context& exclude_context) - { - LOG_PRINT_L2("[" << epee::net_utils::print_connection_context_short(exclude_context) << "] post relay " << typeid(t_parameter).name() << " -->"); - std::string arg_buff; - epee::serialization::store_t_to_binary(arg, arg_buff); - return m_p2p->relay_notify_to_all(t_parameter::ID, epee::strspan<uint8_t>(arg_buff), exclude_context); - } }; } // namespace diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index 01f70cba1..018ef4ab2 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -42,17 +42,24 @@ #include "cryptonote_basic/cryptonote_format_utils.h" #include "profile_tools.h" #include "net/network_throttle-detail.hpp" +#include "common/pruning.h" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "net.cn" #define MLOG_P2P_MESSAGE(x) MCINFO("net.p2p.msg", context << x) +#define MLOG_PEER_STATE(x) \ + MCINFO(MONERO_DEFAULT_LOG_CATEGORY, context << "[" << epee::string_tools::to_string_hex(context.m_pruning_seed) << "] state: " << x << " in state " << cryptonote::get_protocol_state_string(context.m_state)) -#define BLOCK_QUEUE_NBLOCKS_THRESHOLD 10 // chunks of N blocks +#define BLOCK_QUEUE_NSPANS_THRESHOLD 10 // chunks of N blocks #define BLOCK_QUEUE_SIZE_THRESHOLD (100*1024*1024) // MB -#define REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD (5 * 1000000) // microseconds +#define BLOCK_QUEUE_FORCE_DOWNLOAD_NEAR_BLOCKS 1000 +#define REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD_STANDBY (5 * 1000000) // microseconds +#define REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD (30 * 1000000) // microseconds #define IDLE_PEER_KICK_TIME (600 * 1000000) // microseconds #define PASSIVE_PEER_KICK_TIME (60 * 1000000) // microseconds +#define DROP_ON_SYNC_WEDGE_THRESHOLD (30 * 1000000000ull) // nanoseconds +#define LAST_ACTIVITY_STALL_THRESHOLD (2.0f) // seconds namespace cryptonote { @@ -75,6 +82,19 @@ namespace cryptonote template<class t_core> bool t_cryptonote_protocol_handler<t_core>::init(const boost::program_options::variables_map& vm) { + m_sync_timer.pause(); + m_sync_timer.reset(); + m_add_timer.pause(); + m_add_timer.reset(); + m_last_add_end_time = 0; + m_sync_spans_downloaded = 0; + m_sync_old_spans_downloaded = 0; + m_sync_bad_spans_downloaded = 0; + m_sync_download_chain_size = 0; + m_sync_download_objects_size = 0; + + m_block_download_max_size = command_line::get_arg(vm, cryptonote::arg_block_download_max_size); + return true; } //------------------------------------------------------------------------------------------------------------------------ @@ -103,9 +123,12 @@ namespace cryptonote if(context.m_state == cryptonote_connection_context::state_synchronizing) { NOTIFY_REQUEST_CHAIN::request r = boost::value_initialized<NOTIFY_REQUEST_CHAIN::request>(); + context.m_needed_objects.clear(); m_core.get_short_chain_history(r.block_ids); - LOG_PRINT_CCONTEXT_L2("-->>NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() ); + handler_request_blocks_history( r.block_ids ); // change the limit(?), sleep(?) + MLOG_P2P_MESSAGE("-->>NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() ); post_notify<NOTIFY_REQUEST_CHAIN>(r, context); + MLOG_PEER_STATE("requesting chain"); } else if(context.m_state == cryptonote_connection_context::state_standby) { @@ -203,7 +226,7 @@ namespace cryptonote cnx.host = cntxt.m_remote_address.host_str(); cnx.ip = ""; cnx.port = ""; - if (cntxt.m_remote_address.get_type_id() == epee::net_utils::ipv4_network_address::ID) + if (cntxt.m_remote_address.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id()) { cnx.ip = cnx.host; cnx.port = std::to_string(cntxt.m_remote_address.as<epee::net_utils::ipv4_network_address>().port()); @@ -245,8 +268,10 @@ namespace cryptonote cnx.current_upload = cntxt.m_current_speed_up / 1024; cnx.connection_id = epee::string_tools::pod_to_hex(cntxt.m_connection_id); + cnx.ssl = cntxt.m_ssl; cnx.height = cntxt.m_remote_blockchain_height; + cnx.pruning_seed = cntxt.m_pruning_seed; connections.push_back(cnx); @@ -279,7 +304,23 @@ namespace cryptonote } } + // reject weird pruning schemes + if (hshd.pruning_seed) + { + const uint32_t log_stripes = tools::get_pruning_log_stripes(hshd.pruning_seed); + if (log_stripes != CRYPTONOTE_PRUNING_LOG_STRIPES || tools::get_pruning_stripe(hshd.pruning_seed) > (1u << log_stripes)) + { + MWARNING(context << " peer claim unexpected pruning seed " << epee::string_tools::to_string_hex(hshd.pruning_seed) << ", disconnecting"); + return false; + } + } + context.m_remote_blockchain_height = hshd.current_height; + context.m_pruning_seed = hshd.pruning_seed; +#ifdef CRYPTONOTE_PRUNING_DEBUG_SPOOF_SEED + context.m_pruning_seed = tools::make_pruning_seed(1 + (context.m_remote_address.as<epee::net_utils::ipv4_network_address>().ip()) % (1 << CRYPTONOTE_PRUNING_LOG_STRIPES), CRYPTONOTE_PRUNING_LOG_STRIPES); + LOG_INFO_CC(context, "New connection posing as pruning seed " << epee::string_tools::to_string_hex(context.m_pruning_seed) << ", seed address " << &context.m_pruning_seed); +#endif uint64_t target = m_core.get_target_blockchain_height(); if (target == 0) @@ -293,12 +334,18 @@ namespace cryptonote return true; } + // No chain synchronization over hidden networks (tor, i2p, etc.) + if(context.m_remote_address.get_zone() != epee::net_utils::zone::public_) + { + context.m_state = cryptonote_connection_context::state_normal; + return true; + } + if (hshd.current_height > target) { /* As I don't know if accessing hshd from core could be a good practice, I prefer pushing target height to the core at the same time it is pushed to the user. Nz. */ - m_core.set_target_blockchain_height((hshd.current_height)); int64_t diff = static_cast<int64_t>(hshd.current_height) - static_cast<int64_t>(m_core.get_current_blockchain_height()); uint64_t abs_diff = std::abs(diff); uint64_t max_block_height = std::max(hshd.current_height,m_core.get_current_blockchain_height()); @@ -309,14 +356,31 @@ namespace cryptonote << (0 <= diff ? std::string("behind") : std::string("ahead")) << "] " << ENDL << "SYNCHRONIZATION started"); if (hshd.current_height >= m_core.get_current_blockchain_height() + 5) // don't switch to unsafe mode just for a few blocks + { m_core.safesyncmode(false); + } + if (m_core.get_target_blockchain_height() == 0) // only when sync starts + { + m_sync_timer.resume(); + m_sync_timer.reset(); + m_add_timer.pause(); + m_add_timer.reset(); + m_last_add_end_time = 0; + m_sync_spans_downloaded = 0; + m_sync_old_spans_downloaded = 0; + m_sync_bad_spans_downloaded = 0; + m_sync_download_chain_size = 0; + m_sync_download_objects_size = 0; + } + m_core.set_target_blockchain_height((hshd.current_height)); } - LOG_PRINT_L1("Remote blockchain height: " << hshd.current_height << ", id: " << hshd.top_id); + MINFO(context << "Remote blockchain height: " << hshd.current_height << ", id: " << hshd.top_id); context.m_state = cryptonote_connection_context::state_synchronizing; //let the socket to send response to handshake, but request callback, to let send request data after response LOG_PRINT_CCONTEXT_L2("requesting callback"); ++context.m_callback_request_count; m_p2p->request_callback(context); + MLOG_PEER_STATE("requesting callback"); return true; } //------------------------------------------------------------------------------------------------------------------------ @@ -327,6 +391,7 @@ namespace cryptonote hshd.top_version = m_core.get_ideal_hard_fork_version(hshd.current_height); hshd.cumulative_difficulty = m_core.get_block_cumulative_difficulty(hshd.current_height); hshd.current_height +=1; + hshd.pruning_seed = m_core.get_blockchain_pruning_seed(); return true; } //------------------------------------------------------------------------------------------------------------------------ @@ -389,11 +454,14 @@ namespace cryptonote relay_block(arg, context); }else if(bvc.m_marked_as_orphaned) { + context.m_needed_objects.clear(); context.m_state = cryptonote_connection_context::state_synchronizing; NOTIFY_REQUEST_CHAIN::request r = boost::value_initialized<NOTIFY_REQUEST_CHAIN::request>(); m_core.get_short_chain_history(r.block_ids); - LOG_PRINT_CCONTEXT_L2("-->>NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() ); + handler_request_blocks_history( r.block_ids ); // change the limit(?), sleep(?) + MLOG_P2P_MESSAGE("-->>NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() ); post_notify<NOTIFY_REQUEST_CHAIN>(r, context); + MLOG_PEER_STATE("requesting chain"); } return 1; @@ -616,6 +684,7 @@ namespace cryptonote missing_tx_req.missing_tx_indices = std::move(need_tx_indices); m_core.resume_mine(); + MLOG_P2P_MESSAGE("-->>NOTIFY_REQUEST_FLUFFY_MISSING_TX: missing_tx_indices.size()=" << missing_tx_req.missing_tx_indices.size() ); post_notify<NOTIFY_REQUEST_FLUFFY_MISSING_TX>(missing_tx_req, context); } else // whoo-hoo we've got em all .. @@ -656,11 +725,14 @@ namespace cryptonote } else if( bvc.m_marked_as_orphaned ) { + context.m_needed_objects.clear(); context.m_state = cryptonote_connection_context::state_synchronizing; NOTIFY_REQUEST_CHAIN::request r = boost::value_initialized<NOTIFY_REQUEST_CHAIN::request>(); m_core.get_short_chain_history(r.block_ids); - LOG_PRINT_CCONTEXT_L2("-->>NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() ); + handler_request_blocks_history( r.block_ids ); // change the limit(?), sleep(?) + MLOG_P2P_MESSAGE("-->>NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() ); post_notify<NOTIFY_REQUEST_CHAIN>(r, context); + MLOG_PEER_STATE("requesting chain"); } } } @@ -747,7 +819,7 @@ namespace cryptonote fluffy_response.b.txs.push_back(t_serializable_object_to_blob(tx)); } - LOG_PRINT_CCONTEXT_L2 + MLOG_P2P_MESSAGE ( "-->>NOTIFY_RESPONSE_FLUFFY_MISSING_TX: " << ", txs.size()=" << fluffy_response.b.txs.size() @@ -811,7 +883,7 @@ namespace cryptonote drop_connection(context, false, false); return 1; } - LOG_PRINT_CCONTEXT_L2("-->>NOTIFY_RESPONSE_GET_OBJECTS: blocks.size()=" << rsp.blocks.size() << ", txs.size()=" << rsp.txs.size() + MLOG_P2P_MESSAGE("-->>NOTIFY_RESPONSE_GET_OBJECTS: blocks.size()=" << rsp.blocks.size() << ", txs.size()=" << rsp.txs.size() << ", rsp.m_current_blockchain_height=" << rsp.current_blockchain_height << ", missed_ids.size()=" << rsp.missed_ids.size()); post_notify<NOTIFY_RESPONSE_GET_OBJECTS>(rsp, context); //handler_response_blocks_now(sizeof(rsp)); // XXX @@ -834,11 +906,14 @@ namespace cryptonote return avg / m_avg_buffer.size(); } - template<class t_core> int t_cryptonote_protocol_handler<t_core>::handle_response_get_objects(int command, NOTIFY_RESPONSE_GET_OBJECTS::request& arg, cryptonote_connection_context& context) { MLOG_P2P_MESSAGE("Received NOTIFY_RESPONSE_GET_OBJECTS (" << arg.blocks.size() << " blocks, " << arg.txs.size() << " txes)"); + MLOG_PEER_STATE("received objects"); + + boost::posix_time::ptime request_time = context.m_last_request_time; + context.m_last_request_time = boost::date_time::not_a_date_time; // calculate size of request size_t size = 0; @@ -860,6 +935,8 @@ namespace cryptonote CRITICAL_REGION_LOCAL(m_buffer_mutex); m_avg_buffer.push_back(size); } + ++m_sync_spans_downloaded; + m_sync_download_objects_size += size; MDEBUG(context << " downloaded " << size << " bytes worth of blocks"); /*using namespace boost::chrono; @@ -874,6 +951,7 @@ namespace cryptonote LOG_ERROR_CCONTEXT("sent wrong NOTIFY_HAVE_OBJECTS: arg.m_current_blockchain_height=" << arg.current_blockchain_height << " < m_last_response_height=" << context.m_last_response_height << ", dropping connection"); drop_connection(context, false, false); + ++m_sync_bad_spans_downloaded; return 1; } @@ -898,6 +976,7 @@ namespace cryptonote LOG_ERROR_CCONTEXT("sent wrong block: failed to parse and validate block: " << epee::string_tools::buff_to_hex_nodelimer(block_entry.block) << ", dropping connection"); drop_connection(context, false, false); + ++m_sync_bad_spans_downloaded; return 1; } if (b.miner_tx.vin.size() != 1 || b.miner_tx.vin.front().type() != typeid(txin_gen)) @@ -905,6 +984,7 @@ namespace cryptonote LOG_ERROR_CCONTEXT("sent wrong block: block: miner tx does not have exactly one txin_gen input" << epee::string_tools::buff_to_hex_nodelimer(block_entry.block) << ", dropping connection"); drop_connection(context, false, false); + ++m_sync_bad_spans_downloaded; return 1; } if (start_height == std::numeric_limits<uint64_t>::max()) @@ -917,6 +997,7 @@ namespace cryptonote LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_GET_OBJECTS: block with id=" << epee::string_tools::pod_to_hex(get_blob_hash(block_entry.block)) << " wasn't requested, dropping connection"); drop_connection(context, false, false); + ++m_sync_bad_spans_downloaded; return 1; } if(b.tx_hashes.size() != block_entry.txs.size()) @@ -924,6 +1005,7 @@ namespace cryptonote LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_GET_OBJECTS: block with id=" << epee::string_tools::pod_to_hex(get_blob_hash(block_entry.block)) << ", tx_hashes.size()=" << b.tx_hashes.size() << " mismatch with block_complete_entry.m_txs.size()=" << block_entry.txs.size() << ", dropping connection"); drop_connection(context, false, false); + ++m_sync_bad_spans_downloaded; return 1; } @@ -931,34 +1013,27 @@ namespace cryptonote block_hashes.push_back(block_hash); } - if(context.m_requested_objects.size()) + if(!context.m_requested_objects.empty()) { - MERROR("returned not all requested objects (context.m_requested_objects.size()=" + MERROR(context << "returned not all requested objects (context.m_requested_objects.size()=" << context.m_requested_objects.size() << "), dropping connection"); drop_connection(context, false, false); + ++m_sync_bad_spans_downloaded; return 1; } - // get the last parsed block, which should be the highest one - const crypto::hash last_block_hash = cryptonote::get_block_hash(b); - if(m_core.have_block(last_block_hash)) - { - const uint64_t subchain_height = start_height + arg.blocks.size(); - LOG_DEBUG_CC(context, "These are old blocks, ignoring: blocks " << start_height << " - " << (subchain_height-1) << ", blockchain height " << m_core.get_current_blockchain_height()); - m_block_queue.remove_spans(context.m_connection_id, start_height); - goto skip; - } - { MLOG_YELLOW(el::Level::Debug, context << " Got NEW BLOCKS inside of " << __FUNCTION__ << ": size: " << arg.blocks.size() - << ", blocks: " << start_height << " - " << (start_height + arg.blocks.size() - 1)); + << ", blocks: " << start_height << " - " << (start_height + arg.blocks.size() - 1) << + " (pruning seed " << epee::string_tools::to_string_hex(context.m_pruning_seed) << ")"); // add that new span to the block queue - const boost::posix_time::time_duration dt = now - context.m_last_request_time; + const boost::posix_time::time_duration dt = now - request_time; const float rate = size * 1e6 / (dt.total_microseconds() + 1); - MDEBUG(context << " adding span: " << arg.blocks.size() << " at height " << start_height << ", " << dt.total_microseconds()/1e6 << " seconds, " << (rate/1e3) << " kB/s, size now " << (m_block_queue.get_data_size() + blocks_size) / 1048576.f << " MB"); + MDEBUG(context << " adding span: " << arg.blocks.size() << " at height " << start_height << ", " << dt.total_microseconds()/1e6 << " seconds, " << (rate/1024) << " kB/s, size now " << (m_block_queue.get_data_size() + blocks_size) / 1048576.f << " MB"); m_block_queue.add_blocks(start_height, arg.blocks, context.m_connection_id, rate, blocks_size); + const crypto::hash last_block_hash = cryptonote::get_block_hash(b); context.m_last_known_hash = last_block_hash; if (!m_core.get_test_drop_download() || !m_core.get_test_drop_download_height()) { // DISCARD BLOCKS for testing @@ -966,7 +1041,6 @@ namespace cryptonote } } -skip: try_add_next_blocks(context); return 1; } @@ -983,15 +1057,22 @@ skip: const boost::unique_lock<boost::mutex> sync{m_sync_lock, boost::try_to_lock}; if (!sync.owns_lock()) { - MINFO("Failed to lock m_sync_lock, going back to download"); + MINFO(context << "Failed to lock m_sync_lock, going back to download"); goto skip; } MDEBUG(context << " lock m_sync_lock, adding blocks to chain..."); + MLOG_PEER_STATE("adding blocks"); { m_core.pause_mine(); - epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler( - boost::bind(&t_core::resume_mine, &m_core)); + m_add_timer.resume(); + bool starting = true; + epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler([this, &starting]() { + m_add_timer.pause(); + m_core.resume_mine(); + if (!starting) + m_last_add_end_time = tools::get_tick_count(); + }); while (1) { @@ -1004,22 +1085,38 @@ skip: MDEBUG(context << " no next span found, going back to download"); break; } - MDEBUG(context << " next span in the queue has blocks " << start_height << "-" << (start_height + blocks.size() - 1) - << ", we need " << previous_height); if (blocks.empty()) { - MERROR("Next span has no blocks"); + MERROR(context << "Next span has no blocks"); m_block_queue.remove_spans(span_connection_id, start_height); - break; + continue; } + MDEBUG(context << " next span in the queue has blocks " << start_height << "-" << (start_height + blocks.size() - 1) + << ", we need " << previous_height); + block new_block; + if (!parse_and_validate_block_from_blob(blocks.back().block, new_block)) + { + MERROR(context << "Failed to parse block, but it should already have been parsed"); + m_block_queue.remove_spans(span_connection_id, start_height); + continue; + } + const crypto::hash last_block_hash = cryptonote::get_block_hash(new_block); + if (m_core.have_block(last_block_hash)) + { + const uint64_t subchain_height = start_height + blocks.size(); + LOG_DEBUG_CC(context, "These are old blocks, ignoring: blocks " << start_height << " - " << (subchain_height-1) << ", blockchain height " << m_core.get_current_blockchain_height()); + m_block_queue.remove_spans(span_connection_id, start_height); + ++m_sync_old_spans_downloaded; + continue; + } if (!parse_and_validate_block_from_blob(blocks.front().block, new_block)) { - MERROR("Failed to parse block, but it should already have been parsed"); + MERROR(context << "Failed to parse block, but it should already have been parsed"); m_block_queue.remove_spans(span_connection_id, start_height); - break; + continue; } bool parent_known = m_core.have_block(new_block.prev_id); if (!parent_known) @@ -1032,6 +1129,24 @@ skip: bool parent_requested = m_block_queue.requested(new_block.prev_id); if (!parent_requested) { + // we might be able to ask for that block directly, as we now can request out of order, + // otherwise we continue out of order, unless this block is the one we need, in which + // case we request block hashes, though it might be safer to disconnect ? + if (start_height > previous_height) + { + if (should_drop_connection(context, get_next_needed_pruning_stripe().first)) + { + MDEBUG(context << "Got block with unknown parent which was not requested, but peer does not have that block - dropping connection"); + if (!context.m_is_income) + m_p2p->add_used_stripe_peer(context); + drop_connection(context, false, true); + return 1; + } + MDEBUG(context << "Got block with unknown parent which was not requested, but peer does not have that block - back to download"); + + goto skip; + } + // this can happen if a connection was sicced onto a late span, if it did not have those blocks, // since we don't know that at the sic time LOG_ERROR_CCONTEXT("Got block with unknown parent which was not requested - querying block hashes"); @@ -1047,7 +1162,17 @@ skip: } const boost::posix_time::ptime start = boost::posix_time::microsec_clock::universal_time(); - context.m_last_request_time = start; + + if (starting) + { + starting = false; + if (m_last_add_end_time) + { + const uint64_t tnow = tools::get_tick_count(); + const uint64_t ns = tools::ticks_to_ns(tnow - m_last_add_end_time); + MINFO("Restarting adding block after idle for " << ns/1e9 << " seconds"); + } + } m_core.prepare_handle_incoming_blocks(blocks); @@ -1150,7 +1275,7 @@ skip: } // each download block - MCINFO("sync-info", "Block process time (" << blocks.size() << " blocks, " << num_txs << " txs): " << block_process_time_full + transactions_process_time_full << " (" << transactions_process_time_full << "/" << block_process_time_full << ") ms"); + MDEBUG(context << "Block process time (" << blocks.size() << " blocks, " << num_txs << " txs): " << block_process_time_full + transactions_process_time_full << " (" << transactions_process_time_full << "/" << block_process_time_full << ") ms"); if (!m_core.cleanup_handle_incoming_blocks()) { @@ -1160,40 +1285,54 @@ skip: m_block_queue.remove_spans(span_connection_id, start_height); - if (m_core.get_current_blockchain_height() > previous_height) + const uint64_t current_blockchain_height = m_core.get_current_blockchain_height(); + if (current_blockchain_height > previous_height) { + const uint64_t target_blockchain_height = m_core.get_target_blockchain_height(); const boost::posix_time::time_duration dt = boost::posix_time::microsec_clock::universal_time() - start; + std::string progress_message = ""; + if (current_blockchain_height < target_blockchain_height) + { + uint64_t completion_percent = (current_blockchain_height * 100 / target_blockchain_height); + if (completion_percent == 100) // never show 100% if not actually up to date + completion_percent = 99; + progress_message = " (" + std::to_string(completion_percent) + "%, " + + std::to_string(target_blockchain_height - current_blockchain_height) + " left)"; + } + const uint32_t previous_stripe = tools::get_pruning_stripe(previous_height, target_blockchain_height, CRYPTONOTE_PRUNING_LOG_STRIPES); + const uint32_t current_stripe = tools::get_pruning_stripe(current_blockchain_height, target_blockchain_height, CRYPTONOTE_PRUNING_LOG_STRIPES); std::string timing_message = ""; if (ELPP->vRegistry()->allowed(el::Level::Info, "sync-info")) timing_message = std::string(" (") + std::to_string(dt.total_microseconds()/1e6) + " sec, " - + std::to_string((m_core.get_current_blockchain_height() - previous_height) * 1e6 / dt.total_microseconds()) - + " blocks/sec), " + std::to_string(m_block_queue.get_data_size() / 1048576.f) + " MB queued"; + + std::to_string((current_blockchain_height - previous_height) * 1e6 / dt.total_microseconds()) + + " blocks/sec), " + std::to_string(m_block_queue.get_data_size() / 1048576.f) + " MB queued in " + + std::to_string(m_block_queue.get_num_filled_spans()) + " spans, stripe " + + std::to_string(previous_stripe) + " -> " + std::to_string(current_stripe); if (ELPP->vRegistry()->allowed(el::Level::Debug, "sync-info")) - timing_message += std::string(": ") + m_block_queue.get_overview(); - if(m_core.get_target_blockchain_height() == 0){ - MGINFO_YELLOW(context << " Synced " << m_core.get_current_blockchain_height() << "/" << m_core.get_target_blockchain_height() - << timing_message); - } else { - const int completition_percent = (m_core.get_current_blockchain_height() * 100 / m_core.get_target_blockchain_height()); - if(completition_percent < 99) {//printing completion percent only if % is < of 99 cause for 99 >= this is useless - MGINFO_YELLOW(context << " Synced " << m_core.get_current_blockchain_height() << "/" << m_core.get_target_blockchain_height() - << " (" << completition_percent << "% " << (m_core.get_target_blockchain_height() - m_core.get_current_blockchain_height()) - << " blocks remaining)" << timing_message); - } else { - MGINFO_YELLOW(context << " Synced " << m_core.get_current_blockchain_height() << "/" << m_core.get_target_blockchain_height() - << timing_message); - } - } + timing_message += std::string(": ") + m_block_queue.get_overview(current_blockchain_height); + MGINFO_YELLOW("Synced " << current_blockchain_height << "/" << target_blockchain_height + << progress_message << timing_message); + if (previous_stripe != current_stripe) + notify_new_stripe(context, current_stripe); } } } - if (should_download_next_span(context)) + MLOG_PEER_STATE("stopping adding blocks"); + + if (should_download_next_span(context, false)) { - context.m_needed_objects.clear(); - context.m_last_response_height = 0; force_next_span = true; } + else if (should_drop_connection(context, get_next_needed_pruning_stripe().first)) + { + if (!context.m_is_income) + { + m_p2p->add_used_stripe_peer(context); + drop_connection(context, false, false); + } + return 1; + } } skip: @@ -1207,6 +1346,28 @@ skip: } //------------------------------------------------------------------------------------------------------------------------ template<class t_core> + void t_cryptonote_protocol_handler<t_core>::notify_new_stripe(cryptonote_connection_context& cntxt, uint32_t stripe) + { + m_p2p->for_each_connection([&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)->bool + { + if (cntxt.m_connection_id == context.m_connection_id) + return true; + if (context.m_state == cryptonote_connection_context::state_normal) + { + const uint32_t peer_stripe = tools::get_pruning_stripe(context.m_pruning_seed); + if (stripe && peer_stripe && peer_stripe != stripe) + return true; + context.m_state = cryptonote_connection_context::state_synchronizing; + LOG_PRINT_CCONTEXT_L2("requesting callback"); + ++context.m_callback_request_count; + m_p2p->request_callback(context); + MLOG_PEER_STATE("requesting callback"); + } + return true; + }); + } + //------------------------------------------------------------------------------------------------------------------------ + template<class t_core> bool t_cryptonote_protocol_handler<t_core>::on_idle() { m_idle_peer_kicker.do_call(boost::bind(&t_cryptonote_protocol_handler<t_core>::kick_idle_peers, this)); @@ -1218,30 +1379,24 @@ skip: bool t_cryptonote_protocol_handler<t_core>::kick_idle_peers() { MTRACE("Checking for idle peers..."); - std::vector<boost::uuids::uuid> kick_connections; m_p2p->for_each_connection([&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)->bool { - if (context.m_state == cryptonote_connection_context::state_synchronizing || context.m_state == cryptonote_connection_context::state_before_handshake) + if (context.m_state == cryptonote_connection_context::state_synchronizing && context.m_last_request_time != boost::date_time::not_a_date_time) { - const bool passive = context.m_state == cryptonote_connection_context::state_before_handshake; const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); const boost::posix_time::time_duration dt = now - context.m_last_request_time; - const int64_t threshold = passive ? PASSIVE_PEER_KICK_TIME : IDLE_PEER_KICK_TIME; - if (dt.total_microseconds() > threshold) + if (dt.total_microseconds() > IDLE_PEER_KICK_TIME) { - MINFO(context << " kicking " << (passive ? "passive" : "idle") << " peer"); - kick_connections.push_back(context.m_connection_id); + MINFO(context << " kicking idle peer, last update " << (dt.total_microseconds() / 1.e6) << " seconds ago"); + LOG_PRINT_CCONTEXT_L2("requesting callback"); + context.m_last_request_time = boost::date_time::not_a_date_time; + context.m_state = cryptonote_connection_context::state_standby; // we'll go back to adding, then (if we can't), download + ++context.m_callback_request_count; + m_p2p->request_callback(context); } } return true; }); - for (const boost::uuids::uuid &conn_id: kick_connections) - { - m_p2p->for_connection(conn_id, [this](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags) { - drop_connection(context, false, false); - return true; - }); - } return true; } //------------------------------------------------------------------------------------------------------------------------ @@ -1272,75 +1427,174 @@ skip: drop_connection(context, false, false); return 1; } - LOG_PRINT_CCONTEXT_L2("-->>NOTIFY_RESPONSE_CHAIN_ENTRY: m_start_height=" << r.start_height << ", m_total_height=" << r.total_height << ", m_block_ids.size()=" << r.m_block_ids.size()); + MLOG_P2P_MESSAGE("-->>NOTIFY_RESPONSE_CHAIN_ENTRY: m_start_height=" << r.start_height << ", m_total_height=" << r.total_height << ", m_block_ids.size()=" << r.m_block_ids.size()); post_notify<NOTIFY_RESPONSE_CHAIN_ENTRY>(r, context); return 1; } //------------------------------------------------------------------------------------------------------------------------ template<class t_core> - bool t_cryptonote_protocol_handler<t_core>::should_download_next_span(cryptonote_connection_context& context) const + bool t_cryptonote_protocol_handler<t_core>::should_download_next_span(cryptonote_connection_context& context, bool standby) { std::vector<crypto::hash> hashes; boost::uuids::uuid span_connection_id; boost::posix_time::ptime request_time; + boost::uuids::uuid connection_id; std::pair<uint64_t, uint64_t> span; + bool filled; - span = m_block_queue.get_start_gap_span(); - if (span.second > 0) - { - MDEBUG(context << " we should download it as there is a gap"); - return true; - } - - // if the next span is not scheduled (or there is none) - span = m_block_queue.get_next_span_if_scheduled(hashes, span_connection_id, request_time); - if (span.second == 0) + const uint64_t blockchain_height = m_core.get_current_blockchain_height(); + if (context.m_remote_blockchain_height <= blockchain_height) + return false; + const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); + const bool has_next_block = tools::has_unpruned_block(blockchain_height, context.m_remote_blockchain_height, context.m_pruning_seed); + if (has_next_block) { - // we might be in a weird case where there is a filled next span, - // but it starts higher than the current height - uint64_t height; - std::vector<cryptonote::block_complete_entry> bcel; - if (!m_block_queue.get_next_span(height, bcel, span_connection_id, true)) - return false; - if (height > m_core.get_current_blockchain_height()) + if (!m_block_queue.has_next_span(blockchain_height, filled, request_time, connection_id)) { - MDEBUG(context << " we should download it as the next block isn't scheduled"); + MDEBUG(context << " we should download it as no peer reserved it"); return true; } + if (!filled) + { + const long dt = (now - request_time).total_microseconds(); + if (dt >= REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD) + { + MDEBUG(context << " we should download it as it's not been received yet after " << dt/1e6); + return true; + } + + // in standby, be ready to double download early since we're idling anyway + // let the fastest peer trigger first + long threshold; + const double dl_speed = context.m_max_speed_down; + if (standby && dt >= REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD_STANDBY && dl_speed > 0) + { + bool download = false; + if (m_p2p->for_connection(connection_id, [&](cryptonote_connection_context& ctx, nodetool::peerid_type peer_id, uint32_t f)->bool{ + const time_t nowt = time(NULL); + const time_t time_since_last_recv = nowt - ctx.m_last_recv; + const float last_activity = std::min((float)time_since_last_recv, dt/1e6f); + const bool stalled = last_activity > LAST_ACTIVITY_STALL_THRESHOLD; + if (stalled) + { + MDEBUG(context << " we should download it as the downloading peer is stalling for " << nowt - ctx.m_last_recv << " seconds"); + download = true; + return true; + } + + // estimate the standby peer can give us 80% of its max speed + // and let it download if that speed is > N times as fast as the current one + // N starts at 10 after REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD_STANDBY, + // decreases to 1.25 at REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD, + // so that at times goes without the download being done, a retry becomes easier + const float max_multiplier = 10.f; + const float min_multiplier = 1.25f; + float multiplier = max_multiplier; + if (dt/1e6 >= REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD_STANDBY) + { + multiplier = max_multiplier - (dt/1e6-REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD_STANDBY) * (max_multiplier - min_multiplier) / (REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD - REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD_STANDBY); + multiplier = std::min(max_multiplier, std::max(min_multiplier, multiplier)); + } + if (dl_speed * .8f > ctx.m_current_speed_down * multiplier) + { + MDEBUG(context << " we should download it as we are substantially faster (" << dl_speed << " vs " + << ctx.m_current_speed_down << ", multiplier " << multiplier << " after " << dt/1e6 << " seconds)"); + download = true; + return true; + } + return true; + })) + { + if (download) + return true; + } + else + { + MWARNING(context << " we should download it as the downloading peer is unexpectedly not known to us"); + return true; + } + } + } + } + + return false; + } + //------------------------------------------------------------------------------------------------------------------------ + template<class t_core> + bool t_cryptonote_protocol_handler<t_core>::should_drop_connection(cryptonote_connection_context& context, uint32_t next_stripe) + { + if (context.m_anchor) + { + MDEBUG(context << "This is an anchor peer, not dropping"); return false; } - // if it was scheduled by this particular peer - if (span_connection_id == context.m_connection_id) + if (context.m_pruning_seed == 0) + { + MDEBUG(context << "This peer is not striped, not dropping"); return false; + } - float span_speed = m_block_queue.get_speed(span_connection_id); - float speed = m_block_queue.get_speed(context.m_connection_id); - MDEBUG(context << " next span is scheduled for " << span_connection_id << ", speed " << span_speed << ", ours " << speed); - - // we try for that span too if: - // - we're substantially faster, or: - // - we're the fastest and the other one isn't (avoids a peer being waaaay slow but yet unmeasured) - // - the other one asked at least 5 seconds ago - if (span_speed < .25 && speed > .75f) + const uint32_t peer_stripe = tools::get_pruning_stripe(context.m_pruning_seed); + if (next_stripe == peer_stripe) { - MDEBUG(context << " we should download it as we're substantially faster"); - return true; + MDEBUG(context << "This peer has needed stripe " << peer_stripe << ", not dropping"); + return false; } - if (speed == 1.0f && span_speed != 1.0f) + + if (!context.m_needed_objects.empty()) { - MDEBUG(context << " we should download it as we're the fastest peer"); - return true; + const uint64_t next_available_block_height = context.m_last_response_height - context.m_needed_objects.size() + 1; + if (tools::has_unpruned_block(next_available_block_height, context.m_remote_blockchain_height, context.m_pruning_seed)) + { + MDEBUG(context << "This peer has unpruned next block at height " << next_available_block_height << ", not dropping"); + return false; + } } - const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); - if ((now - request_time).total_microseconds() > REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD) + + if (next_stripe > 0) { - MDEBUG(context << " we should download it as this span was requested long ago"); - return true; + unsigned int n_out_peers = 0, n_peers_on_next_stripe = 0; + m_p2p->for_each_connection([&](cryptonote_connection_context& ctx, nodetool::peerid_type peer_id, uint32_t support_flags)->bool{ + if (!ctx.m_is_income) + ++n_out_peers; + if (ctx.m_state >= cryptonote_connection_context::state_synchronizing && tools::get_pruning_stripe(ctx.m_pruning_seed) == next_stripe) + ++n_peers_on_next_stripe; + return true; + }); + const uint32_t distance = (peer_stripe + (1<<CRYPTONOTE_PRUNING_LOG_STRIPES) - next_stripe) % (1<<CRYPTONOTE_PRUNING_LOG_STRIPES); + if ((n_out_peers >= m_max_out_peers && n_peers_on_next_stripe == 0) || (distance > 1 && n_peers_on_next_stripe <= 2) || distance > 2) + { + MDEBUG(context << "we want seed " << next_stripe << ", and either " << n_out_peers << " is at max out peers (" + << m_max_out_peers << ") or distance " << distance << " from " << next_stripe << " to " << peer_stripe << + " is too large and we have only " << n_peers_on_next_stripe << " peers on next seed, dropping connection to make space"); + return true; + } } + MDEBUG(context << "End of checks, not dropping"); return false; } //------------------------------------------------------------------------------------------------------------------------ template<class t_core> + void t_cryptonote_protocol_handler<t_core>::skip_unneeded_hashes(cryptonote_connection_context& context, bool check_block_queue) const + { + // take out blocks we already have + size_t skip = 0; + while (skip < context.m_needed_objects.size() && (m_core.have_block(context.m_needed_objects[skip]) || (check_block_queue && m_block_queue.have(context.m_needed_objects[skip])))) + { + // if we're popping the last hash, record it so we can ask again from that hash, + // this prevents never being able to progress on peers we get old hash lists from + if (skip + 1 == context.m_needed_objects.size()) + context.m_last_known_hash = context.m_needed_objects[skip]; + ++skip; + } + if (skip > 0) + { + MDEBUG(context << "skipping " << skip << "/" << context.m_needed_objects.size() << " blocks"); + context.m_needed_objects = std::vector<crypto::hash>(context.m_needed_objects.begin() + skip, context.m_needed_objects.end()); + } + } + //------------------------------------------------------------------------------------------------------------------------ + template<class t_core> bool t_cryptonote_protocol_handler<t_core>::request_missing_objects(cryptonote_connection_context& context, bool check_having_blocks, bool force_next_span) { // flush stale spans @@ -1357,47 +1611,102 @@ skip: { do { - size_t nblocks = m_block_queue.get_num_filled_spans(); + size_t nspans = m_block_queue.get_num_filled_spans(); size_t size = m_block_queue.get_data_size(); - if (nblocks < BLOCK_QUEUE_NBLOCKS_THRESHOLD || size < BLOCK_QUEUE_SIZE_THRESHOLD) + const uint64_t bc_height = m_core.get_current_blockchain_height(); + const auto next_needed_pruning_stripe = get_next_needed_pruning_stripe(); + const uint32_t add_stripe = tools::get_pruning_stripe(bc_height, context.m_remote_blockchain_height, CRYPTONOTE_PRUNING_LOG_STRIPES); + const uint32_t peer_stripe = tools::get_pruning_stripe(context.m_pruning_seed); + const size_t block_queue_size_threshold = m_block_download_max_size ? m_block_download_max_size : BLOCK_QUEUE_SIZE_THRESHOLD; + bool queue_proceed = nspans < BLOCK_QUEUE_NSPANS_THRESHOLD || size < block_queue_size_threshold; + // get rid of blocks we already requested, or already have + skip_unneeded_hashes(context, true); + uint64_t next_needed_height = m_block_queue.get_next_needed_height(bc_height); + uint64_t next_block_height; + if (context.m_needed_objects.empty()) + next_block_height = next_needed_height; + else + next_block_height = context.m_last_response_height - context.m_needed_objects.size() + 1; + bool stripe_proceed_main = (add_stripe == 0 || peer_stripe == 0 || add_stripe == peer_stripe) && (next_block_height < bc_height + BLOCK_QUEUE_FORCE_DOWNLOAD_NEAR_BLOCKS || next_needed_height < bc_height + BLOCK_QUEUE_FORCE_DOWNLOAD_NEAR_BLOCKS); + bool stripe_proceed_secondary = tools::has_unpruned_block(next_block_height, context.m_remote_blockchain_height, context.m_pruning_seed); + bool proceed = stripe_proceed_main || (queue_proceed && stripe_proceed_secondary); + if (!stripe_proceed_main && !stripe_proceed_secondary && should_drop_connection(context, tools::get_pruning_stripe(next_block_height, context.m_remote_blockchain_height, CRYPTONOTE_PRUNING_LOG_STRIPES))) + { + if (!context.m_is_income) + m_p2p->add_used_stripe_peer(context); + return false; // drop outgoing connections + } + + MDEBUG(context << "proceed " << proceed << " (queue " << queue_proceed << ", stripe " << stripe_proceed_main << "/" << + stripe_proceed_secondary << "), " << next_needed_pruning_stripe.first << "-" << next_needed_pruning_stripe.second << + " needed, bc add stripe " << add_stripe << ", we have " << peer_stripe << "), bc_height " << bc_height); + MDEBUG(context << " - next_block_height " << next_block_height << ", seed " << epee::string_tools::to_string_hex(context.m_pruning_seed) << + ", next_needed_height "<< next_needed_height); + MDEBUG(context << " - last_response_height " << context.m_last_response_height << ", m_needed_objects size " << context.m_needed_objects.size()); + + // if we're waiting for next span, try to get it before unblocking threads below, + // or a runaway downloading of future spans might happen + if (stripe_proceed_main && should_download_next_span(context, true)) + { + MDEBUG(context << " we should try for that next span too, we think we could get it faster, resuming"); + force_next_span = true; + MLOG_PEER_STATE("resuming"); + break; + } + + if (proceed) { if (context.m_state != cryptonote_connection_context::state_standby) { - LOG_DEBUG_CC(context, "Block queue is " << nblocks << " and " << size << ", resuming"); + LOG_DEBUG_CC(context, "Block queue is " << nspans << " and " << size << ", resuming"); + MLOG_PEER_STATE("resuming"); } break; } // this one triggers if all threads are in standby, which should not happen, // but happened at least once, so we unblock at least one thread if so - const boost::unique_lock<boost::mutex> sync{m_sync_lock, boost::try_to_lock}; + boost::unique_lock<boost::mutex> sync{m_sync_lock, boost::try_to_lock}; if (sync.owns_lock()) { - LOG_DEBUG_CC(context, "No other thread is adding blocks, resuming"); - break; - } + bool filled = false; + boost::posix_time::ptime time; + boost::uuids::uuid connection_id; + if (m_block_queue.has_next_span(m_core.get_current_blockchain_height(), filled, time, connection_id) && filled) + { + LOG_DEBUG_CC(context, "No other thread is adding blocks, and next span needed is ready, resuming"); + MLOG_PEER_STATE("resuming"); + context.m_state = cryptonote_connection_context::state_standby; + ++context.m_callback_request_count; + m_p2p->request_callback(context); + return true; + } + else + { + sync.unlock(); - if (should_download_next_span(context)) - { - MDEBUG(context << " we should try for that next span too, we think we could get it faster, resuming"); - force_next_span = true; - break; + // if this has gone on for too long, drop incoming connection to guard against some wedge state + if (!context.m_is_income) + { + const uint64_t now = tools::get_tick_count(); + const uint64_t dt = now - m_last_add_end_time; + if (tools::ticks_to_ns(dt) >= DROP_ON_SYNC_WEDGE_THRESHOLD) + { + MDEBUG(context << "Block addition seems to have wedged, dropping connection"); + return false; + } + } + } } if (context.m_state != cryptonote_connection_context::state_standby) { - LOG_DEBUG_CC(context, "Block queue is " << nblocks << " and " << size << ", pausing"); + if (!queue_proceed) + LOG_DEBUG_CC(context, "Block queue is " << nspans << " and " << size << ", pausing"); + else if (!stripe_proceed_main && !stripe_proceed_secondary) + LOG_DEBUG_CC(context, "We do not have the stripe required to download another block, pausing"); context.m_state = cryptonote_connection_context::state_standby; - } - - // this needs doing after we went to standby, so the callback knows what to do - bool filled; - if (m_block_queue.has_next_span(context.m_connection_id, filled) && !filled) - { - MDEBUG(context << " we have the next span, and it is scheduled, resuming"); - ++context.m_callback_request_count; - m_p2p->request_callback(context); - return true; + MLOG_PEER_STATE("pausing"); } return true; @@ -1405,7 +1714,9 @@ skip: context.m_state = cryptonote_connection_context::state_synchronizing; } - MDEBUG(context << " request_missing_objects: check " << check_having_blocks << ", force_next_span " << force_next_span << ", m_needed_objects " << context.m_needed_objects.size() << " lrh " << context.m_last_response_height << ", chain " << m_core.get_current_blockchain_height()); + MDEBUG(context << " request_missing_objects: check " << check_having_blocks << ", force_next_span " << force_next_span + << ", m_needed_objects " << context.m_needed_objects.size() << " lrh " << context.m_last_response_height << ", chain " + << m_core.get_current_blockchain_height() << ", pruning seed " << epee::string_tools::to_string_hex(context.m_pruning_seed)); if(context.m_needed_objects.size() || force_next_span) { //we know objects that we need, request this objects @@ -1414,28 +1725,6 @@ skip: size_t count = 0; const size_t count_limit = m_core.get_block_sync_size(m_core.get_current_blockchain_height()); std::pair<uint64_t, uint64_t> span = std::make_pair(0, 0); - { - MDEBUG(context << " checking for gap"); - span = m_block_queue.get_start_gap_span(); - if (span.second > 0) - { - const uint64_t first_block_height_known = context.m_last_response_height - context.m_needed_objects.size() + 1; - const uint64_t last_block_height_known = context.m_last_response_height; - const uint64_t first_block_height_needed = span.first; - const uint64_t last_block_height_needed = span.first + std::min(span.second, (uint64_t)count_limit) - 1; - MDEBUG(context << " gap found, span: " << span.first << " - " << span.first + span.second - 1 << " (" << last_block_height_needed << ")"); - MDEBUG(context << " current known hashes from " << first_block_height_known << " to " << last_block_height_known); - if (first_block_height_needed < first_block_height_known || last_block_height_needed > last_block_height_known) - { - MDEBUG(context << " we are missing some of the necessary hashes for this gap, requesting chain again"); - context.m_needed_objects.clear(); - context.m_last_response_height = 0; - start_from_current_chain = true; - goto skip; - } - MDEBUG(context << " we have the hashes for this gap"); - } - } if (force_next_span) { if (span.second == 0) @@ -1452,6 +1741,7 @@ skip: req.blocks.push_back(hash); context.m_requested_objects.insert(hash); } + m_block_queue.reset_next_span_time(); } } } @@ -1465,22 +1755,20 @@ skip: context.m_last_response_height = 0; goto skip; } - // take out blocks we already have - size_t skip = 0; - while (skip < context.m_needed_objects.size() && m_core.have_block(context.m_needed_objects[skip])) - { - // if we're popping the last hash, record it so we can ask again from that hash, - // this prevents never being able to progress on peers we get old hash lists from - if (skip + 1 == context.m_needed_objects.size()) - context.m_last_known_hash = context.m_needed_objects[skip]; - ++skip; - } - if (skip > 0) - context.m_needed_objects = std::vector<crypto::hash>(context.m_needed_objects.begin() + skip, context.m_needed_objects.end()); + skip_unneeded_hashes(context, false); const uint64_t first_block_height = context.m_last_response_height - context.m_needed_objects.size() + 1; - span = m_block_queue.reserve_span(first_block_height, context.m_last_response_height, count_limit, context.m_connection_id, context.m_needed_objects); + span = m_block_queue.reserve_span(first_block_height, context.m_last_response_height, count_limit, context.m_connection_id, context.m_pruning_seed, context.m_remote_blockchain_height, context.m_needed_objects); MDEBUG(context << " span from " << first_block_height << ": " << span.first << "/" << span.second); + if (span.second > 0) + { + const uint32_t stripe = tools::get_pruning_stripe(span.first, context.m_remote_blockchain_height, CRYPTONOTE_PRUNING_LOG_STRIPES); + if (context.m_pruning_seed && stripe != tools::get_pruning_stripe(context.m_pruning_seed)) + { + MDEBUG(context << " starting early on next seed (" << span.first << " with stripe " << stripe << + ", context seed " << epee::string_tools::to_string_hex(context.m_pruning_seed) << ")"); + } + } } if (span.second == 0 && !force_next_span) { @@ -1489,6 +1777,8 @@ skip: boost::uuids::uuid span_connection_id; boost::posix_time::ptime time; span = m_block_queue.get_next_span_if_scheduled(hashes, span_connection_id, time); + if (span.second > 0 && !tools::has_unpruned_block(span.first, context.m_remote_blockchain_height, context.m_pruning_seed)) + span = std::make_pair(0, 0); if (span.second > 0) { is_next = true; @@ -1534,17 +1824,67 @@ skip: } context.m_last_request_time = boost::posix_time::microsec_clock::universal_time(); - LOG_PRINT_CCONTEXT_L1("-->>NOTIFY_REQUEST_GET_OBJECTS: blocks.size()=" << req.blocks.size() << ", txs.size()=" << req.txs.size() + MLOG_P2P_MESSAGE("-->>NOTIFY_REQUEST_GET_OBJECTS: blocks.size()=" << req.blocks.size() << ", txs.size()=" << req.txs.size() << "requested blocks count=" << count << " / " << count_limit << " from " << span.first << ", first hash " << req.blocks.front()); //epee::net_utils::network_throttle_manager::get_global_throttle_inreq().logger_handle_net("log/dr-monero/net/req-all.data", sec, get_avg_block_size()); post_notify<NOTIFY_REQUEST_GET_OBJECTS>(req, context); + MLOG_PEER_STATE("requesting objects"); + return true; + } + + // if we're still around, we might be at a point where the peer is pruned, so we could either + // drop it to make space for other peers, or ask for a span further down the line + const uint32_t next_stripe = get_next_needed_pruning_stripe().first; + const uint32_t peer_stripe = tools::get_pruning_stripe(context.m_pruning_seed); + if (next_stripe && peer_stripe && next_stripe != peer_stripe) + { + // at this point, we have to either close the connection, or start getting blocks past the + // current point, or become dormant + MDEBUG(context << "this peer is pruned at seed " << epee::string_tools::to_string_hex(context.m_pruning_seed) << + ", next stripe needed is " << next_stripe); + if (!context.m_is_income) + { + if (should_drop_connection(context, next_stripe)) + { + m_p2p->add_used_stripe_peer(context); + return false; // drop outgoing connections + } + } + // we'll get back stuck waiting for the go ahead + context.m_state = cryptonote_connection_context::state_normal; + MLOG_PEER_STATE("Nothing to do for now, switching to normal state"); return true; } } skip: context.m_needed_objects.clear(); + + // we might have been called from the "received chain entry" handler, and end up + // here because we can't use any of those blocks (maybe because all of them are + // actually already requested). In this case, if we can add blocks instead, do so + if (m_core.get_current_blockchain_height() < m_core.get_target_blockchain_height()) + { + const boost::unique_lock<boost::mutex> sync{m_sync_lock, boost::try_to_lock}; + if (sync.owns_lock()) + { + uint64_t start_height; + std::vector<cryptonote::block_complete_entry> blocks; + boost::uuids::uuid span_connection_id; + bool filled = false; + if (m_block_queue.get_next_span(start_height, blocks, span_connection_id, filled) && filled) + { + LOG_DEBUG_CC(context, "No other thread is adding blocks, resuming"); + MLOG_PEER_STATE("will try to add blocks next"); + context.m_state = cryptonote_connection_context::state_standby; + ++context.m_callback_request_count; + m_p2p->request_callback(context); + return true; + } + } + } + if(context.m_last_response_height < context.m_remote_blockchain_height-1) {//we have to fetch more objects ids, request blockchain entry @@ -1567,8 +1907,9 @@ skip: //LOG_PRINT_CCONTEXT_L1("r = " << 200); context.m_last_request_time = boost::posix_time::microsec_clock::universal_time(); - LOG_PRINT_CCONTEXT_L1("-->>NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() << ", start_from_current_chain " << start_from_current_chain); + MLOG_P2P_MESSAGE("-->>NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() << ", start_from_current_chain " << start_from_current_chain); post_notify<NOTIFY_REQUEST_CHAIN>(r, context); + MLOG_PEER_STATE("requesting chain"); }else { CHECK_AND_ASSERT_MES(context.m_last_response_height == context.m_remote_blockchain_height-1 @@ -1608,9 +1949,25 @@ skip: << ENDL << "Use the \"help\" command to see the list of available commands." << ENDL << "**********************************************************************"); + m_sync_timer.pause(); + if (ELPP->vRegistry()->allowed(el::Level::Info, "sync-info")) + { + const uint64_t sync_time = m_sync_timer.value(); + const uint64_t add_time = m_add_timer.value(); + if (sync_time && add_time) + { + MCLOG_YELLOW(el::Level::Info, "sync-info", "Sync time: " << sync_time/1e9/60 << " min, idle time " << + (100.f * (1.0f - add_time / (float)sync_time)) << "%" << ", " << + (10 * m_sync_download_objects_size / 1024 / 1024) / 10.f << " + " << + (10 * m_sync_download_chain_size / 1024 / 1024) / 10.f << " MB downloaded, " << + 100.0f * m_sync_old_spans_downloaded / m_sync_spans_downloaded << "% old spans, " << + 100.0f * m_sync_bad_spans_downloaded / m_sync_spans_downloaded << "% bad spans"); + } + } m_core.on_synchronized(); } m_core.safesyncmode(true); + m_p2p->clear_used_stripe_peers(); return true; } //------------------------------------------------------------------------------------------------------------------------ @@ -1631,6 +1988,11 @@ skip: { MLOG_P2P_MESSAGE("Received NOTIFY_RESPONSE_CHAIN_ENTRY: m_block_ids.size()=" << arg.m_block_ids.size() << ", m_start_height=" << arg.start_height << ", m_total_height=" << arg.total_height); + MLOG_PEER_STATE("received chain"); + + context.m_last_request_time = boost::date_time::not_a_date_time; + + m_sync_download_chain_size += arg.m_block_ids.size() * sizeof(crypto::hash); if(!arg.m_block_ids.size()) { @@ -1644,7 +2006,14 @@ skip: drop_connection(context, true, false); return 1; } + MDEBUG(context << "first block hash " << arg.m_block_ids.front() << ", last " << arg.m_block_ids.back()); + if (arg.total_height >= CRYPTONOTE_MAX_BLOCK_NUMBER || arg.m_block_ids.size() >= CRYPTONOTE_MAX_BLOCK_NUMBER) + { + LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_CHAIN_ENTRY, with total_height=" << arg.total_height << " and block_ids=" << arg.m_block_ids.size()); + drop_connection(context, false, false); + return 1; + } context.m_remote_blockchain_height = arg.total_height; context.m_last_response_height = arg.start_height + arg.m_block_ids.size()-1; if(context.m_last_response_height > context.m_remote_blockchain_height) @@ -1664,6 +2033,7 @@ skip: return 1; } + context.m_needed_objects.clear(); uint64_t added = 0; for(auto& bl_id: arg.m_block_ids) { @@ -1696,20 +2066,20 @@ skip: fluffy_arg.b.txs = fluffy_txs; // sort peers between fluffy ones and others - std::list<boost::uuids::uuid> fullConnections, fluffyConnections; + std::vector<std::pair<epee::net_utils::zone, boost::uuids::uuid>> fullConnections, fluffyConnections; m_p2p->for_each_connection([this, &exclude_context, &fullConnections, &fluffyConnections](connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags) { - if (peer_id && exclude_context.m_connection_id != context.m_connection_id) + if (peer_id && exclude_context.m_connection_id != context.m_connection_id && context.m_remote_address.get_zone() == epee::net_utils::zone::public_) { if(m_core.fluffy_blocks_enabled() && (support_flags & P2P_SUPPORT_FLAG_FLUFFY_BLOCKS)) { LOG_DEBUG_CC(context, "PEER SUPPORTS FLUFFY BLOCKS - RELAYING THIN/COMPACT WHATEVER BLOCK"); - fluffyConnections.push_back(context.m_connection_id); + fluffyConnections.push_back({context.m_remote_address.get_zone(), context.m_connection_id}); } else { LOG_DEBUG_CC(context, "PEER DOESN'T SUPPORT FLUFFY BLOCKS - RELAYING FULL BLOCK"); - fullConnections.push_back(context.m_connection_id); + fullConnections.push_back({context.m_remote_address.get_zone(), context.m_connection_id}); } } return true; @@ -1720,13 +2090,13 @@ skip: { std::string fluffyBlob; epee::serialization::store_t_to_binary(fluffy_arg, fluffyBlob); - m_p2p->relay_notify_to_list(NOTIFY_NEW_FLUFFY_BLOCK::ID, epee::strspan<uint8_t>(fluffyBlob), fluffyConnections); + m_p2p->relay_notify_to_list(NOTIFY_NEW_FLUFFY_BLOCK::ID, epee::strspan<uint8_t>(fluffyBlob), std::move(fluffyConnections)); } if (!fullConnections.empty()) { std::string fullBlob; epee::serialization::store_t_to_binary(arg, fullBlob); - m_p2p->relay_notify_to_list(NOTIFY_NEW_BLOCK::ID, epee::strspan<uint8_t>(fullBlob), fullConnections); + m_p2p->relay_notify_to_list(NOTIFY_NEW_BLOCK::ID, epee::strspan<uint8_t>(fullBlob), std::move(fullConnections)); } return true; @@ -1735,6 +2105,12 @@ skip: template<class t_core> bool t_cryptonote_protocol_handler<t_core>::relay_transactions(NOTIFY_NEW_TRANSACTIONS::request& arg, cryptonote_connection_context& exclude_context) { + const bool hide_tx_broadcast = + 1 < m_p2p->get_zone_count() && exclude_context.m_remote_address.get_zone() == epee::net_utils::zone::invalid; + + if (hide_tx_broadcast) + MDEBUG("Attempting to conceal origin of tx via anonymity network connection(s)"); + // no check for success, so tell core they're relayed unconditionally const bool pad_transactions = m_core.pad_transactions(); size_t bytes = pad_transactions ? 9 /* header */ + 4 /* 1 + 'txs' */ + tools::get_varint_data(arg.txs.size()).size() : 0; @@ -1769,14 +2145,112 @@ skip: // if the size of _ moved enough, we might lose byte in size encoding, we don't care } - return relay_post_notify<NOTIFY_NEW_TRANSACTIONS>(arg, exclude_context); + std::vector<std::pair<epee::net_utils::zone, boost::uuids::uuid>> connections; + m_p2p->for_each_connection([hide_tx_broadcast, &exclude_context, &connections](connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags) + { + const epee::net_utils::zone current_zone = context.m_remote_address.get_zone(); + const bool broadcast_to_peer = + peer_id && + (hide_tx_broadcast != bool(current_zone == epee::net_utils::zone::public_)) && + exclude_context.m_connection_id != context.m_connection_id; + + if (broadcast_to_peer) + connections.push_back({current_zone, context.m_connection_id}); + + return true; + }); + + if (connections.empty()) + MERROR("Transaction not relayed - no" << (hide_tx_broadcast ? " privacy": "") << " peers available"); + else + { + std::string fullBlob; + epee::serialization::store_t_to_binary(arg, fullBlob); + m_p2p->relay_notify_to_list(NOTIFY_NEW_TRANSACTIONS::ID, epee::strspan<uint8_t>(fullBlob), std::move(connections)); + } + return true; + } + //------------------------------------------------------------------------------------------------------------------------ + template<class t_core> + std::string t_cryptonote_protocol_handler<t_core>::get_peers_overview() const + { + std::stringstream ss; + const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); + m_p2p->for_each_connection([&](const connection_context &ctx, nodetool::peerid_type peer_id, uint32_t support_flags) { + const uint32_t stripe = tools::get_pruning_stripe(ctx.m_pruning_seed); + char state_char = cryptonote::get_protocol_state_char(ctx.m_state); + ss << stripe + state_char; + if (ctx.m_last_request_time != boost::date_time::not_a_date_time) + ss << (((now - ctx.m_last_request_time).total_microseconds() > IDLE_PEER_KICK_TIME) ? "!" : "?"); + ss << + " "; + return true; + }); + return ss.str(); + } + //------------------------------------------------------------------------------------------------------------------------ + template<class t_core> + std::pair<uint32_t, uint32_t> t_cryptonote_protocol_handler<t_core>::get_next_needed_pruning_stripe() const + { + const uint64_t want_height_from_blockchain = m_core.get_current_blockchain_height(); + const uint64_t want_height_from_block_queue = m_block_queue.get_next_needed_height(want_height_from_blockchain); + const uint64_t want_height = std::max(want_height_from_blockchain, want_height_from_block_queue); + uint64_t blockchain_height = m_core.get_target_blockchain_height(); + // if we don't know the remote chain size yet, assume infinitely large so we get the right stripe if we're not near the tip + if (blockchain_height == 0) + blockchain_height = CRYPTONOTE_MAX_BLOCK_NUMBER; + const uint32_t next_pruning_stripe = tools::get_pruning_stripe(want_height, blockchain_height, CRYPTONOTE_PRUNING_LOG_STRIPES); + if (next_pruning_stripe == 0) + return std::make_pair(0, 0); + // if we already have a few peers on this stripe, but none on next one, try next one + unsigned int n_next = 0, n_subsequent = 0, n_others = 0; + const uint32_t subsequent_pruning_stripe = 1 + next_pruning_stripe % (1<<CRYPTONOTE_PRUNING_LOG_STRIPES); + m_p2p->for_each_connection([&](const connection_context &context, nodetool::peerid_type peer_id, uint32_t support_flags) { + if (context.m_state >= cryptonote_connection_context::state_synchronizing) + { + if (context.m_pruning_seed == 0 || tools::get_pruning_stripe(context.m_pruning_seed) == next_pruning_stripe) + ++n_next; + else if (tools::get_pruning_stripe(context.m_pruning_seed) == subsequent_pruning_stripe) + ++n_subsequent; + else + ++n_others; + } + return true; + }); + const bool use_next = (n_next > m_max_out_peers / 2 && n_subsequent <= 1) || (n_next > 2 && n_subsequent == 0); + const uint32_t ret_stripe = use_next ? subsequent_pruning_stripe: next_pruning_stripe; + MIDEBUG(const std::string po = get_peers_overview(), "get_next_needed_pruning_stripe: want height " << want_height << " (" << + want_height_from_blockchain << " from blockchain, " << want_height_from_block_queue << " from block queue), stripe " << + next_pruning_stripe << " (" << n_next << "/" << m_max_out_peers << " on it and " << n_subsequent << " on " << + subsequent_pruning_stripe << ", " << n_others << " others) -> " << ret_stripe << " (+" << + (ret_stripe - next_pruning_stripe + (1 << CRYPTONOTE_PRUNING_LOG_STRIPES)) % (1 << CRYPTONOTE_PRUNING_LOG_STRIPES) << + "), current peers " << po); + return std::make_pair(next_pruning_stripe, ret_stripe); + } + //------------------------------------------------------------------------------------------------------------------------ + template<class t_core> + bool t_cryptonote_protocol_handler<t_core>::needs_new_sync_connections() const + { + const uint64_t target = m_core.get_target_blockchain_height(); + const uint64_t height = m_core.get_current_blockchain_height(); + if (target && target <= height) + return false; + size_t n_out_peers = 0; + m_p2p->for_each_connection([&](cryptonote_connection_context& ctx, nodetool::peerid_type peer_id, uint32_t support_flags)->bool{ + if (!ctx.m_is_income) + ++n_out_peers; + return true; + }); + if (n_out_peers >= m_max_out_peers) + return false; + return true; } //------------------------------------------------------------------------------------------------------------------------ template<class t_core> void t_cryptonote_protocol_handler<t_core>::drop_connection(cryptonote_connection_context &context, bool add_fail, bool flush_all_spans) { - LOG_DEBUG_CC(context, "dropping connection id " << context.m_connection_id << - ", add_fail " << add_fail << ", flush_all_spans " << flush_all_spans); + LOG_DEBUG_CC(context, "dropping connection id " << context.m_connection_id << " (pruning seed " << + epee::string_tools::to_string_hex(context.m_pruning_seed) << + "), add_fail " << add_fail << ", flush_all_spans " << flush_all_spans); if (add_fail) m_p2p->add_host_fail(context.m_remote_address); @@ -1803,6 +2277,7 @@ skip: } m_block_queue.flush_spans(context.m_connection_id, false); + MLOG_PEER_STATE("closed"); } //------------------------------------------------------------------------------------------------------------------------ diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp index b5b747e97..73f33a674 100644 --- a/src/daemon/command_parser_executor.cpp +++ b/src/daemon/command_parser_executor.cpp @@ -48,9 +48,34 @@ t_command_parser_executor::t_command_parser_executor( bool t_command_parser_executor::print_peer_list(const std::vector<std::string>& args) { - if (!args.empty()) return false; + if (args.size() > 3) + { + std::cout << "use: print_pl [white] [gray] [<limit>]" << std::endl; + return true; + } - return m_executor.print_peer_list(); + bool white = false; + bool gray = false; + size_t limit = 0; + for (size_t i = 0; i < args.size(); ++i) + { + if (args[i] == "white") + { + white = true; + } + else if (args[i] == "gray") + { + gray = true; + } + else if (!epee::string_tools::get_xtype_from_string(limit, args[i])) + { + std::cout << "unexpected argument: " << args[i] << std::endl; + return true; + } + } + + const bool print_both = !white && !gray; + return m_executor.print_peer_list(white | print_both, gray | print_both, limit); } bool t_command_parser_executor::print_peer_list_stats(const std::vector<std::string>& args) @@ -717,4 +742,27 @@ bool t_command_parser_executor::version(const std::vector<std::string>& args) return true; } +bool t_command_parser_executor::prune_blockchain(const std::vector<std::string>& args) +{ + if (args.size() > 1) return false; + + if (args.empty() || args[0] != "confirm") + { + std::cout << "Warning: pruning from within monerod will not shrink the database file size." << std::endl; + std::cout << "Instead, parts of the file will be marked as free, so the file will not grow" << std::endl; + std::cout << "until that newly free space is used up. If you want a smaller file size now," << std::endl; + std::cout << "exit monerod and run monero-blockchain-prune (you will temporarily need more" << std::endl; + std::cout << "disk space for the database conversion though). If you are OK with the database" << std::endl; + std::cout << "file keeping the same size, re-run this command with the \"confirm\" parameter." << std::endl; + return true; + } + + return m_executor.prune_blockchain(); +} + +bool t_command_parser_executor::check_blockchain_pruning(const std::vector<std::string>& args) +{ + return m_executor.check_blockchain_pruning(); +} + } // namespace daemonize diff --git a/src/daemon/command_parser_executor.h b/src/daemon/command_parser_executor.h index e2844e8b7..5b8927908 100644 --- a/src/daemon/command_parser_executor.h +++ b/src/daemon/command_parser_executor.h @@ -142,6 +142,10 @@ public: bool pop_blocks(const std::vector<std::string>& args); bool version(const std::vector<std::string>& args); + + bool prune_blockchain(const std::vector<std::string>& args); + + bool check_blockchain_pruning(const std::vector<std::string>& args); }; } // namespace daemonize diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp index 527ed2cf1..96dea76b6 100644 --- a/src/daemon/command_server.cpp +++ b/src/daemon/command_server.cpp @@ -64,6 +64,7 @@ t_command_server::t_command_server( m_command_lookup.set_handler( "print_pl" , std::bind(&t_command_parser_executor::print_peer_list, &m_parser, p::_1) + , "print_pl [white] [gray] [<limit>]" , "Print the current peer list." ); m_command_lookup.set_handler( @@ -292,6 +293,16 @@ t_command_server::t_command_server( , std::bind(&t_command_parser_executor::version, &m_parser, p::_1) , "Print version information." ); + m_command_lookup.set_handler( + "prune_blockchain" + , std::bind(&t_command_parser_executor::prune_blockchain, &m_parser, p::_1) + , "Prune the blockchain." + ); + m_command_lookup.set_handler( + "check_blockchain_pruning" + , std::bind(&t_command_parser_executor::check_blockchain_pruning, &m_parser, p::_1) + , "Check the blockchain pruning." + ); } bool t_command_server::process_command_str(const std::string& cmd) diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index 4c7d68686..0a35dcef9 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -31,6 +31,7 @@ #include "string_tools.h" #include "common/password.h" #include "common/scoped_message_writer.h" +#include "common/pruning.h" #include "daemon/rpc_command_executor.h" #include "rpc/core_rpc_server_commands_defs.h" #include "cryptonote_core/cryptonote_core.h" @@ -60,7 +61,8 @@ namespace { peer_id_str >> id_str; epee::string_tools::xtype_to_string(peer.port, port_str); std::string addr_str = ip_str + ":" + port_str; - tools::msg_writer() << boost::format("%-10s %-25s %-25s %s") % prefix % id_str % addr_str % elapsed; + std::string pruning_seed = epee::string_tools::to_string_hex(peer.pruning_seed); + tools::msg_writer() << boost::format("%-10s %-25s %-25s %-4s %s") % prefix % id_str % addr_str % pruning_seed % elapsed; } void print_block_header(cryptonote::block_header_response const & header) @@ -77,6 +79,7 @@ namespace { << "POW hash: " << header.pow_hash << std::endl << "block size: " << header.block_size << std::endl << "block weight: " << header.block_weight << std::endl + << "long term weight: " << header.long_term_weight << std::endl << "num txes: " << header.num_txes << std::endl << "reward: " << cryptonote::print_money(header.reward); } @@ -154,7 +157,7 @@ t_rpc_command_executor::~t_rpc_command_executor() } } -bool t_rpc_command_executor::print_peer_list() { +bool t_rpc_command_executor::print_peer_list(bool white, bool gray, size_t limit) { cryptonote::COMMAND_RPC_GET_PEER_LIST::request req; cryptonote::COMMAND_RPC_GET_PEER_LIST::response res; @@ -175,14 +178,24 @@ bool t_rpc_command_executor::print_peer_list() { } } - for (auto & peer : res.white_list) + if (white) { - print_peer("white", peer); + auto peer = res.white_list.cbegin(); + const auto end = limit ? peer + std::min(limit, res.white_list.size()) : res.white_list.cend(); + for (; peer != end; ++peer) + { + print_peer("white", *peer); + } } - for (auto & peer : res.gray_list) + if (gray) { - print_peer("gray", peer); + auto peer = res.gray_list.cbegin(); + const auto end = limit ? peer + std::min(limit, res.gray_list.size()) : res.gray_list.cend(); + for (; peer != end; ++peer) + { + print_peer("gray", *peer); + } } return true; @@ -498,6 +511,7 @@ bool t_rpc_command_executor::print_connections() { } tools::msg_writer() << std::setw(30) << std::left << "Remote Host" + << std::setw(6) << "SSL" << std::setw(20) << "Peer id" << std::setw(20) << "Support Flags" << std::setw(30) << "Recv/Sent (inactive,sec)" @@ -517,6 +531,7 @@ bool t_rpc_command_executor::print_connections() { tools::msg_writer() //<< std::setw(30) << std::left << in_out << std::setw(30) << std::left << address + << std::setw(6) << (info.ssl ? "yes" : "no") << std::setw(20) << epee::string_tools::pad_string(info.peer_id, 16, '0', true) << std::setw(20) << info.support_flags << std::setw(30) << std::to_string(info.recv_count) + "(" + std::to_string(info.recv_idle_time) + ")/" + std::to_string(info.send_count) + "(" + std::to_string(info.send_idle_time) + ")" @@ -741,6 +756,7 @@ bool t_rpc_command_executor::print_transaction(crypto::hash transaction_hash, req.txs_hashes.push_back(epee::string_tools::pod_to_hex(transaction_hash)); req.decode_as_json = false; + req.split = true; req.prune = false; if (m_is_rpc) { @@ -766,13 +782,25 @@ bool t_rpc_command_executor::print_transaction(crypto::hash transaction_hash, if (res.txs.front().in_pool) tools::success_msg_writer() << "Found in pool"; else - tools::success_msg_writer() << "Found in blockchain at height " << res.txs.front().block_height; + tools::success_msg_writer() << "Found in blockchain at height " << res.txs.front().block_height << (res.txs.front().prunable_as_hex.empty() ? " (pruned)" : ""); } const std::string &as_hex = (1 == res.txs.size()) ? res.txs.front().as_hex : res.txs_as_hex.front(); + const std::string &pruned_as_hex = (1 == res.txs.size()) ? res.txs.front().pruned_as_hex : ""; + const std::string &prunable_as_hex = (1 == res.txs.size()) ? res.txs.front().prunable_as_hex : ""; // Print raw hex if requested if (include_hex) - tools::success_msg_writer() << as_hex << std::endl; + { + if (!as_hex.empty()) + { + tools::success_msg_writer() << as_hex << std::endl; + } + else + { + std::string output = pruned_as_hex + prunable_as_hex; + tools::success_msg_writer() << output << std::endl; + } + } // Print json if requested if (include_json) @@ -780,17 +808,27 @@ bool t_rpc_command_executor::print_transaction(crypto::hash transaction_hash, crypto::hash tx_hash, tx_prefix_hash; cryptonote::transaction tx; cryptonote::blobdata blob; - if (!string_tools::parse_hexstr_to_binbuff(as_hex, blob)) + std::string source = as_hex.empty() ? pruned_as_hex + prunable_as_hex : as_hex; + bool pruned = !pruned_as_hex.empty() && prunable_as_hex.empty(); + if (!string_tools::parse_hexstr_to_binbuff(source, blob)) { tools::fail_msg_writer() << "Failed to parse tx to get json format"; } - else if (!cryptonote::parse_and_validate_tx_from_blob(blob, tx, tx_hash, tx_prefix_hash)) - { - tools::fail_msg_writer() << "Failed to parse tx blob to get json format"; - } else { - tools::success_msg_writer() << cryptonote::obj_to_json_str(tx) << std::endl; + bool ret; + if (pruned) + ret = cryptonote::parse_and_validate_tx_base_from_blob(blob, tx); + else + ret = cryptonote::parse_and_validate_tx_from_blob(blob, tx); + if (!ret) + { + tools::fail_msg_writer() << "Failed to parse tx blob to get json format"; + } + else + { + tools::success_msg_writer() << cryptonote::obj_to_json_str(tx) << std::endl; + } } } } @@ -853,7 +891,7 @@ bool t_rpc_command_executor::print_transaction_pool_long() { } else { - if (!m_rpc_server->on_get_transaction_pool(req, res, false) || res.status != CORE_RPC_STATUS_OK) + if (!m_rpc_server->on_get_transaction_pool(req, res) || res.status != CORE_RPC_STATUS_OK) { tools::fail_msg_writer() << make_error(fail_message, res.status); return true; @@ -939,7 +977,7 @@ bool t_rpc_command_executor::print_transaction_pool_short() { } else { - if (!m_rpc_server->on_get_transaction_pool(req, res, false) || res.status != CORE_RPC_STATUS_OK) + if (!m_rpc_server->on_get_transaction_pool(req, res) || res.status != CORE_RPC_STATUS_OK) { tools::fail_msg_writer() << make_error(fail_message, res.status); return true; @@ -997,7 +1035,7 @@ bool t_rpc_command_executor::print_transaction_pool_stats() { else { res.pool_stats = {}; - if (!m_rpc_server->on_get_transaction_pool_stats(req, res, false) || res.status != CORE_RPC_STATUS_OK) + if (!m_rpc_server->on_get_transaction_pool_stats(req, res) || res.status != CORE_RPC_STATUS_OK) { tools::fail_msg_writer() << make_error(fail_message, res.status); return true; @@ -1939,6 +1977,8 @@ bool t_rpc_command_executor::sync_info() for (const auto &p: res.peers) current_download += p.info.current_download; tools::success_msg_writer() << "Downloading at " << current_download << " kB/s"; + if (res.next_needed_pruning_seed) + tools::success_msg_writer() << "Next needed pruning seed: " << res.next_needed_pruning_seed; tools::success_msg_writer() << std::to_string(res.peers.size()) << " peers"; for (const auto &p: res.peers) @@ -1946,25 +1986,30 @@ bool t_rpc_command_executor::sync_info() std::string address = epee::string_tools::pad_string(p.info.address, 24); uint64_t nblocks = 0, size = 0; for (const auto &s: res.spans) - if (s.rate > 0.0f && s.connection_id == p.info.connection_id) + if (s.connection_id == p.info.connection_id) nblocks += s.nblocks, size += s.size; - tools::success_msg_writer() << address << " " << epee::string_tools::pad_string(p.info.peer_id, 16, '0', true) << " " << epee::string_tools::pad_string(p.info.state, 16) << " " << p.info.height << " " << p.info.current_download << " kB/s, " << nblocks << " blocks / " << size/1e6 << " MB queued"; + tools::success_msg_writer() << address << " " << epee::string_tools::pad_string(p.info.peer_id, 16, '0', true) << " " << + epee::string_tools::pad_string(p.info.state, 16) << " " << + epee::string_tools::pad_string(epee::string_tools::to_string_hex(p.info.pruning_seed), 8) << " " << p.info.height << " " << + p.info.current_download << " kB/s, " << nblocks << " blocks / " << size/1e6 << " MB queued"; } uint64_t total_size = 0; for (const auto &s: res.spans) total_size += s.size; tools::success_msg_writer() << std::to_string(res.spans.size()) << " spans, " << total_size/1e6 << " MB"; + tools::success_msg_writer() << res.overview; for (const auto &s: res.spans) { std::string address = epee::string_tools::pad_string(s.remote_address, 24); + std::string pruning_seed = epee::string_tools::to_string_hex(tools::get_pruning_seed(s.start_block_height, std::numeric_limits<uint64_t>::max(), CRYPTONOTE_PRUNING_LOG_STRIPES)); if (s.size == 0) { - tools::success_msg_writer() << address << " " << s.nblocks << " (" << s.start_block_height << " - " << (s.start_block_height + s.nblocks - 1) << ") -"; + tools::success_msg_writer() << address << " " << s.nblocks << "/" << pruning_seed << " (" << s.start_block_height << " - " << (s.start_block_height + s.nblocks - 1) << ") -"; } else { - tools::success_msg_writer() << address << " " << s.nblocks << " (" << s.start_block_height << " - " << (s.start_block_height + s.nblocks - 1) << ", " << (uint64_t)(s.size/1e3) << " kB) " << (unsigned)(s.rate/1e3) << " kB/s (" << s.speed/100.0f << ")"; + tools::success_msg_writer() << address << " " << s.nblocks << "/" << pruning_seed << " (" << s.start_block_height << " - " << (s.start_block_height + s.nblocks - 1) << ", " << (uint64_t)(s.size/1e3) << " kB) " << (unsigned)(s.rate/1e3) << " kB/s (" << s.speed/100.0f << ")"; } } @@ -1998,4 +2043,69 @@ bool t_rpc_command_executor::pop_blocks(uint64_t num_blocks) return true; } +bool t_rpc_command_executor::prune_blockchain() +{ + cryptonote::COMMAND_RPC_PRUNE_BLOCKCHAIN::request req; + cryptonote::COMMAND_RPC_PRUNE_BLOCKCHAIN::response res; + std::string fail_message = "Unsuccessful"; + epee::json_rpc::error error_resp; + + req.check = false; + + if (m_is_rpc) + { + if (!m_rpc_client->json_rpc_request(req, res, "prune_blockchain", fail_message.c_str())) + { + return true; + } + } + else + { + if (!m_rpc_server->on_prune_blockchain(req, res, error_resp) || res.status != CORE_RPC_STATUS_OK) + { + tools::fail_msg_writer() << make_error(fail_message, res.status); + return true; + } + } + + tools::success_msg_writer() << "Blockchain pruned: seed " << epee::string_tools::to_string_hex(res.pruning_seed); + return true; +} + +bool t_rpc_command_executor::check_blockchain_pruning() +{ + cryptonote::COMMAND_RPC_PRUNE_BLOCKCHAIN::request req; + cryptonote::COMMAND_RPC_PRUNE_BLOCKCHAIN::response res; + std::string fail_message = "Unsuccessful"; + epee::json_rpc::error error_resp; + + req.check = true; + + if (m_is_rpc) + { + if (!m_rpc_client->json_rpc_request(req, res, "prune_blockchain", fail_message.c_str())) + { + return true; + } + } + else + { + if (!m_rpc_server->on_prune_blockchain(req, res, error_resp) || res.status != CORE_RPC_STATUS_OK) + { + tools::fail_msg_writer() << make_error(fail_message, res.status); + return true; + } + } + + if (res.pruning_seed) + { + tools::success_msg_writer() << "Blockchain pruning checked"; + } + else + { + tools::success_msg_writer() << "Blockchain is not pruned"; + } + return true; +} + }// namespace daemonize diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h index 1541a1a8e..b1e9828a0 100644 --- a/src/daemon/rpc_command_executor.h +++ b/src/daemon/rpc_command_executor.h @@ -67,7 +67,7 @@ public: ~t_rpc_command_executor(); - bool print_peer_list(); + bool print_peer_list(bool white = true, bool gray = true, size_t limit = 0); bool print_peer_list_stats(); @@ -154,6 +154,10 @@ public: bool sync_info(); bool pop_blocks(uint64_t num_blocks); + + bool prune_blockchain(); + + bool check_blockchain_pruning(); }; } // namespace daemonize diff --git a/src/debug_utilities/cn_deserialize.cpp b/src/debug_utilities/cn_deserialize.cpp index 83422083b..f08f2b928 100644 --- a/src/debug_utilities/cn_deserialize.cpp +++ b/src/debug_utilities/cn_deserialize.cpp @@ -180,11 +180,9 @@ int main(int argc, char* argv[]) } else if (cryptonote::parse_and_validate_tx_from_blob(blob, tx) || cryptonote::parse_and_validate_tx_base_from_blob(blob, tx)) { -/* if (tx.pruned) std::cout << "Parsed pruned transaction:" << std::endl; else -*/ std::cout << "Parsed transaction:" << std::endl; std::cout << cryptonote::obj_to_json_str(tx) << std::endl; diff --git a/src/device/device.hpp b/src/device/device.hpp index 399648f01..408f64c8b 100644 --- a/src/device/device.hpp +++ b/src/device/device.hpp @@ -69,6 +69,7 @@ namespace cryptonote struct account_public_address; struct account_keys; struct subaddress_index; + struct tx_destination_entry; } namespace hw { @@ -208,12 +209,15 @@ namespace hw { return encrypt_payment_id(payment_id, public_key, secret_key); } - virtual bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec) = 0; - virtual bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec) = 0; - - virtual bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index, - const rct::key &amount_key, const crypto::public_key &out_eph_public_key) = 0; + virtual bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec, bool short_amount) = 0; + virtual bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec, bool short_amount) = 0; + virtual bool generate_output_ephemeral_keys(const size_t tx_version, const cryptonote::account_keys &sender_account_keys, const crypto::public_key &txkey_pub, const crypto::secret_key &tx_key, + const cryptonote::tx_destination_entry &dst_entr, const boost::optional<cryptonote::account_public_address> &change_addr, const size_t output_index, + const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys, + std::vector<crypto::public_key> &additional_tx_public_keys, + std::vector<rct::key> &amount_keys, + crypto::public_key &out_eph_public_key) = 0; virtual bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) = 0; virtual bool mlsag_prepare(const rct::key &H, const rct::key &xx, rct::key &a, rct::key &aG, rct::key &aHP, rct::key &rvII) = 0; diff --git a/src/device/device_default.cpp b/src/device/device_default.cpp index 2286998a4..fd15717a7 100644 --- a/src/device/device_default.cpp +++ b/src/device/device_default.cpp @@ -34,8 +34,10 @@ #include "int-util.h" #include "cryptonote_basic/account.h" #include "cryptonote_basic/subaddress_index.h" +#include "cryptonote_core/cryptonote_tx_utils.h" #include "ringct/rctOps.h" +#include "log.hpp" #define ENCRYPTED_PAYMENT_ID_TAIL 0x8d #define CHACHA8_KEY_TAIL 0x8c @@ -278,10 +280,55 @@ namespace hw { return true; } + bool device_default::generate_output_ephemeral_keys(const size_t tx_version, + const cryptonote::account_keys &sender_account_keys, const crypto::public_key &txkey_pub, const crypto::secret_key &tx_key, + const cryptonote::tx_destination_entry &dst_entr, const boost::optional<cryptonote::account_public_address> &change_addr, const size_t output_index, + const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys, + std::vector<crypto::public_key> &additional_tx_public_keys, + std::vector<rct::key> &amount_keys, crypto::public_key &out_eph_public_key) { - bool device_default::add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index, - const rct::key &amount_key, const crypto::public_key &out_eph_public_key) { - return true; + crypto::key_derivation derivation; + + // make additional tx pubkey if necessary + cryptonote::keypair additional_txkey; + if (need_additional_txkeys) + { + additional_txkey.sec = additional_tx_keys[output_index]; + if (dst_entr.is_subaddress) + additional_txkey.pub = rct::rct2pk(rct::scalarmultKey(rct::pk2rct(dst_entr.addr.m_spend_public_key), rct::sk2rct(additional_txkey.sec))); + else + additional_txkey.pub = rct::rct2pk(rct::scalarmultBase(rct::sk2rct(additional_txkey.sec))); + } + + bool r; + if (change_addr && dst_entr.addr == *change_addr) + { + // sending change to yourself; derivation = a*R + r = generate_key_derivation(txkey_pub, sender_account_keys.m_view_secret_key, derivation); + CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation(" << txkey_pub << ", " << sender_account_keys.m_view_secret_key << ")"); + } + else + { + // sending to the recipient; derivation = r*A (or s*C in the subaddress scheme) + r = generate_key_derivation(dst_entr.addr.m_view_public_key, dst_entr.is_subaddress && need_additional_txkeys ? additional_txkey.sec : tx_key, derivation); + CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation(" << dst_entr.addr.m_view_public_key << ", " << (dst_entr.is_subaddress && need_additional_txkeys ? additional_txkey.sec : tx_key) << ")"); + } + + if (need_additional_txkeys) + { + additional_tx_public_keys.push_back(additional_txkey.pub); + } + + if (tx_version > 1) + { + crypto::secret_key scalar1; + derivation_to_scalar(derivation, output_index, scalar1); + amount_keys.push_back(rct::sk2rct(scalar1)); + } + r = derive_public_key(derivation, output_index, dst_entr.addr.m_spend_public_key, out_eph_public_key); + CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to derive_public_key(" << derivation << ", " << output_index << ", "<< dst_entr.addr.m_spend_public_key << ")"); + + return r; } bool device_default::encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) { @@ -302,13 +349,13 @@ namespace hw { return true; } - bool device_default::ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec) { - rct::ecdhEncode(unmasked, sharedSec); + bool device_default::ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec, bool short_amount) { + rct::ecdhEncode(unmasked, sharedSec, short_amount); return true; } - bool device_default::ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec) { - rct::ecdhDecode(masked, sharedSec); + bool device_default::ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec, bool short_amount) { + rct::ecdhDecode(masked, sharedSec, short_amount); return true; } diff --git a/src/device/device_default.hpp b/src/device/device_default.hpp index 5c59a9066..04b9b4234 100644 --- a/src/device/device_default.hpp +++ b/src/device/device_default.hpp @@ -111,12 +111,15 @@ namespace hw { bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) override; - bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec) override; - bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec) override; - - bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index, - const rct::key &amount_key, const crypto::public_key &out_eph_public_key) override; - + bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec, bool short_amount) override; + bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec, bool short_amount) override; + + bool generate_output_ephemeral_keys(const size_t tx_version, const cryptonote::account_keys &sender_account_keys, const crypto::public_key &txkey_pub, const crypto::secret_key &tx_key, + const cryptonote::tx_destination_entry &dst_entr, const boost::optional<cryptonote::account_public_address> &change_addr, const size_t output_index, + const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys, + std::vector<crypto::public_key> &additional_tx_public_keys, + std::vector<rct::key> &amount_keys, + crypto::public_key &out_eph_public_key) override; bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) override; bool mlsag_prepare(const rct::key &H, const rct::key &xx, rct::key &a, rct::key &aG, rct::key &aHP, rct::key &rvII) override; diff --git a/src/device/device_io.hpp b/src/device/device_io.hpp index 96163a211..1d5e3564c 100644 --- a/src/device/device_io.hpp +++ b/src/device/device_io.hpp @@ -50,7 +50,7 @@ namespace hw { virtual void disconnect() = 0; virtual bool connected() const = 0; - virtual int exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len) = 0; + virtual int exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len, bool user_input) = 0; }; }; }; diff --git a/src/device/device_io_hid.cpp b/src/device/device_io_hid.cpp index 1aadfb9ea..36c7a241b 100644 --- a/src/device/device_io_hid.cpp +++ b/src/device/device_io_hid.cpp @@ -148,7 +148,7 @@ namespace hw { return this->usb_device != NULL; } - int device_io_hid::exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len) { + int device_io_hid::exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len, bool user_input) { unsigned char buffer[400]; unsigned char padding_buffer[MAX_BLOCK+1]; unsigned int result; @@ -177,7 +177,11 @@ namespace hw { //get first response memset(buffer, 0, sizeof(buffer)); - hid_ret = hid_read_timeout(this->usb_device, buffer, MAX_BLOCK, this->timeout); + if (!user_input) { + hid_ret = hid_read_timeout(this->usb_device, buffer, MAX_BLOCK, this->timeout); + } else { + hid_ret = hid_read(this->usb_device, buffer, MAX_BLOCK); + } ASSERT_X(hid_ret>=0, "Unable to read hidapi response. Error "+std::to_string(result)+": "+ safe_hid_error(this->usb_device)); result = (unsigned int)hid_ret; io_hid_log(1, buffer, result); diff --git a/src/device/device_io_hid.hpp b/src/device/device_io_hid.hpp index bb0f0a814..c47eefad2 100644 --- a/src/device/device_io_hid.hpp +++ b/src/device/device_io_hid.hpp @@ -100,7 +100,7 @@ namespace hw { void connect(void *params); void connect(unsigned int vid, unsigned int pid, boost::optional<int> interface_number, boost::optional<unsigned short> usage_page); bool connected() const; - int exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len); + int exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len, bool user_input); void disconnect(); void release(); }; diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp index bfb41bbe4..1f91427f0 100644 --- a/src/device/device_ledger.cpp +++ b/src/device/device_ledger.cpp @@ -32,6 +32,7 @@ #include "ringct/rctOps.h" #include "cryptonote_basic/account.h" #include "cryptonote_basic/subaddress_index.h" +#include "cryptonote_core/cryptonote_tx_utils.h" #include <boost/thread/locks.hpp> #include <boost/thread/lock_guard.hpp> @@ -67,10 +68,12 @@ namespace hw { /* === Keymap ==== */ /* ===================================================================== */ - ABPkeys::ABPkeys(const rct::key& A, const rct::key& B, const bool is_subaddr, const size_t real_output_index, const rct::key& P, const rct::key& AK) { + ABPkeys::ABPkeys(const rct::key& A, const rct::key& B, const bool is_subaddr, const bool is_change, const bool need_additional_txkeys, const size_t real_output_index, const rct::key& P, const rct::key& AK) { Aout = A; Bout = B; is_subaddress = is_subaddr; + is_change_address = is_change; + additional_key = need_additional_txkeys; index = real_output_index; Pout = P; AKout = AK; @@ -80,6 +83,8 @@ namespace hw { Aout = keys.Aout; Bout = keys.Bout; is_subaddress = keys.is_subaddress; + is_change_address = keys.is_change_address; + additional_key = keys.additional_key; index = keys.index; Pout = keys.Pout; AKout = keys.AKout; @@ -137,6 +142,8 @@ namespace hw { static int device_id = 0; + #define PROTOCOL_VERSION 2 + #define INS_NONE 0x00 #define INS_RESET 0x02 @@ -168,6 +175,7 @@ namespace hw { #define INS_STEALTH 0x76 #define INS_BLIND 0x78 #define INS_UNBLIND 0x7A + #define INS_GEN_TXOUT_KEYS 0x7B #define INS_VALIDATE 0x7C #define INS_MLSAG 0x7E #define INS_CLOSE_TX 0x80 @@ -176,7 +184,7 @@ namespace hw { #define INS_GET_RESPONSE 0xc0 - device_ledger::device_ledger(): hw_device(0x0101, 0x05, 64, 120000) { + device_ledger::device_ledger(): hw_device(0x0101, 0x05, 64, 2000) { this->id = device_id++; this->reset_buffer(); this->mode = NONE; @@ -235,6 +243,9 @@ namespace hw { /* IO */ /* ======================================================================= */ + #define IO_SW_DENY 0x6982 + #define IO_SECRET_KEY 0x02 + void device_ledger::logCMD() { if (apdu_verbose) { char strbuffer[1024]; @@ -265,7 +276,7 @@ namespace hw { int device_ledger::set_command_header(unsigned char ins, unsigned char p1, unsigned char p2) { reset_buffer(); int offset = 0; - this->buffer_send[0] = 0x00; + this->buffer_send[0] = PROTOCOL_VERSION; this->buffer_send[1] = ins; this->buffer_send[2] = p1; this->buffer_send[3] = p2; @@ -283,7 +294,12 @@ namespace hw { void device_ledger::send_simple(unsigned char ins, unsigned char p1) { this->length_send = set_command_header_noopt(ins, p1); - this->exchange(); + if (ins == INS_GET_KEY && p1 == IO_SECRET_KEY) { + // export view key user input + this->exchange_wait_on_input(); + } else { + this->exchange(); + } } bool device_ledger::reset() { @@ -294,7 +310,7 @@ namespace hw { unsigned int device_ledger::exchange(unsigned int ok, unsigned int mask) { logCMD(); - this->length_recv = hw_device.exchange(this->buffer_send, this->length_send, this->buffer_recv, BUFFER_SEND_SIZE); + this->length_recv = hw_device.exchange(this->buffer_send, this->length_send, this->buffer_recv, BUFFER_SEND_SIZE, false); ASSERT_X(this->length_recv>=2, "Communication error, less than tow bytes received"); this->length_recv -= 2; @@ -305,6 +321,25 @@ namespace hw { return this->sw; } + unsigned int device_ledger::exchange_wait_on_input(unsigned int ok, unsigned int mask) { + logCMD(); + unsigned int deny = 0; + this->length_recv = hw_device.exchange(this->buffer_send, this->length_send, this->buffer_recv, BUFFER_SEND_SIZE, true); + ASSERT_X(this->length_recv>=2, "Communication error, less than two bytes received"); + + this->length_recv -= 2; + this->sw = (this->buffer_recv[length_recv]<<8) | this->buffer_recv[length_recv+1]; + if (this->sw == IO_SW_DENY) { + // cancel on device + deny = 1; + } else { + ASSERT_SW(this->sw,ok,msk); + } + + logRESP(); + return deny; + } + void device_ledger::reset_buffer() { this->length_send = 0; memset(this->buffer_send, 0, BUFFER_SEND_SIZE); @@ -322,7 +357,7 @@ namespace hw { } const std::string device_ledger::get_name() const { - if (this->full_name.empty() || !this->connected()) { + if (!this->connected()) { return std::string("<disconnected:").append(this->name).append(">"); } return this->name; @@ -481,11 +516,11 @@ namespace hw { } const std::size_t output_index_x = output_index; crypto::public_key derived_pub_x; - hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] pub ", pub_x.data, 32); - hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] derivation", derivation_x.data, 32); - hw::ledger::log_message ("derive_subaddress_public_key: [[IN]] index ", std::to_string((int)output_index_x)); + log_hexbuffer("derive_subaddress_public_key: [[IN]] pub ", pub_x.data, 32); + log_hexbuffer("derive_subaddress_public_key: [[IN]] derivation", derivation_x.data, 32); + log_message ("derive_subaddress_public_key: [[IN]] index ", std::to_string((int)output_index_x)); this->controle_device->derive_subaddress_public_key(pub_x, derivation_x,output_index_x,derived_pub_x); - hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[OUT]] derived_pub", derived_pub_x.data, 32); + log_hexbuffer("derive_subaddress_public_key: [[OUT]] derived_pub", derived_pub_x.data, 32); #endif if ((this->mode == TRANSACTION_PARSE) && has_view_key) { @@ -531,11 +566,11 @@ namespace hw { const cryptonote::account_keys keys_x = hw::ledger::decrypt(keys); const cryptonote::subaddress_index index_x = index; crypto::public_key D_x; - hw::ledger::log_hexbuffer("get_subaddress_spend_public_key: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data,32); - hw::ledger::log_hexbuffer("get_subaddress_spend_public_key: [[IN]] keys.m_spend_secret_key", keys_x.m_spend_secret_key.data,32); - hw::ledger::log_message ("get_subaddress_spend_public_key: [[IN]] index ", std::to_string(index_x.major)+"."+std::to_string(index_x.minor)); + log_hexbuffer("get_subaddress_spend_public_key: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data,32); + log_hexbuffer("get_subaddress_spend_public_key: [[IN]] keys.m_spend_secret_key", keys_x.m_spend_secret_key.data,32); + log_message ("get_subaddress_spend_public_key: [[IN]] index ", std::to_string(index_x.major)+"."+std::to_string(index_x.minor)); D_x = this->controle_device->get_subaddress_spend_public_key(keys_x, index_x); - hw::ledger::log_hexbuffer("get_subaddress_spend_public_key: [[OUT]] derivation ", D_x.data, 32); + log_hexbuffer("get_subaddress_spend_public_key: [[OUT]] derivation ", D_x.data, 32); #endif if (index.is_zero()) { @@ -582,14 +617,14 @@ namespace hw { const cryptonote::account_keys keys_x = hw::ledger::decrypt(keys); const cryptonote::subaddress_index index_x = index; cryptonote::account_public_address address_x; - hw::ledger::log_hexbuffer("get_subaddress: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data, 32); - hw::ledger::log_hexbuffer("get_subaddress: [[IN]] keys.m_view_public_key", keys_x.m_account_address.m_view_public_key.data, 32); - hw::ledger::log_hexbuffer("get_subaddress: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data, 32); - hw::ledger::log_hexbuffer("get_subaddress: [[IN]] keys.m_spend_public_key", keys_x.m_account_address.m_spend_public_key.data, 32); - hw::ledger::log_message ("get_subaddress: [[IN]] index ", std::to_string(index_x.major)+"."+std::to_string(index_x.minor)); + log_hexbuffer("get_subaddress: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data, 32); + log_hexbuffer("get_subaddress: [[IN]] keys.m_view_public_key", keys_x.m_account_address.m_view_public_key.data, 32); + log_hexbuffer("get_subaddress: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data, 32); + log_hexbuffer("get_subaddress: [[IN]] keys.m_spend_public_key", keys_x.m_account_address.m_spend_public_key.data, 32); + log_message ("get_subaddress: [[IN]] index ", std::to_string(index_x.major)+"."+std::to_string(index_x.minor)); address_x = this->controle_device->get_subaddress(keys_x, index_x); - hw::ledger::log_hexbuffer("get_subaddress: [[OUT]] keys.m_view_public_key ", address_x.m_view_public_key.data, 32); - hw::ledger::log_hexbuffer("get_subaddress: [[OUT]] keys.m_spend_public_key", address_x.m_spend_public_key.data, 32); + log_hexbuffer("get_subaddress: [[OUT]] keys.m_view_public_key ", address_x.m_view_public_key.data, 32); + log_hexbuffer("get_subaddress: [[OUT]] keys.m_spend_public_key", address_x.m_spend_public_key.data, 32); #endif if (index.is_zero()) { @@ -625,10 +660,10 @@ namespace hw { const crypto::secret_key sec_x = hw::ledger::decrypt(sec); const cryptonote::subaddress_index index_x = index; crypto::secret_key sub_sec_x; - hw::ledger::log_message ("get_subaddress_secret_key: [[IN]] index ", std::to_string(index.major)+"."+std::to_string(index.minor)); - hw::ledger::log_hexbuffer("get_subaddress_secret_key: [[IN]] sec ", sec_x.data, 32); + log_message ("get_subaddress_secret_key: [[IN]] index ", std::to_string(index.major)+"."+std::to_string(index.minor)); + log_hexbuffer("get_subaddress_secret_key: [[IN]] sec ", sec_x.data, 32); sub_sec_x = this->controle_device->get_subaddress_secret_key(sec_x, index_x); - hw::ledger::log_hexbuffer("get_subaddress_secret_key: [[OUT]] sub_sec", sub_sec_x.data, 32); + log_hexbuffer("get_subaddress_secret_key: [[OUT]] sub_sec", sub_sec_x.data, 32); #endif int offset = set_command_header_noopt(INS_GET_SUBADDRESS_SECRET_KEY); @@ -690,10 +725,10 @@ namespace hw { const rct::key P_x = P; const rct::key a_x = hw::ledger::decrypt(a); rct::key aP_x; - hw::ledger::log_hexbuffer("scalarmultKey: [[IN]] P ", (char*)P_x.bytes, 32); - hw::ledger::log_hexbuffer("scalarmultKey: [[IN]] a ", (char*)a_x.bytes, 32); + log_hexbuffer("scalarmultKey: [[IN]] P ", (char*)P_x.bytes, 32); + log_hexbuffer("scalarmultKey: [[IN]] a ", (char*)a_x.bytes, 32); this->controle_device->scalarmultKey(aP_x, P_x, a_x); - hw::ledger::log_hexbuffer("scalarmultKey: [[OUT]] aP", (char*)aP_x.bytes, 32); + log_hexbuffer("scalarmultKey: [[OUT]] aP", (char*)aP_x.bytes, 32); #endif int offset = set_command_header_noopt(INS_SECRET_SCAL_MUL_KEY); @@ -725,9 +760,9 @@ namespace hw { #ifdef DEBUG_HWDEVICE const rct::key a_x = hw::ledger::decrypt(a); rct::key aG_x; - hw::ledger::log_hexbuffer("scalarmultKey: [[IN]] a ", (char*)a_x.bytes, 32); + log_hexbuffer("scalarmultKey: [[IN]] a ", (char*)a_x.bytes, 32); this->controle_device->scalarmultBase(aG_x, a_x); - hw::ledger::log_hexbuffer("scalarmultKey: [[OUT]] aG", (char*)aG_x.bytes, 32); + log_hexbuffer("scalarmultKey: [[OUT]] aG", (char*)aG_x.bytes, 32); #endif int offset = set_command_header_noopt(INS_SECRET_SCAL_MUL_BASE); @@ -818,10 +853,10 @@ namespace hw { const crypto::public_key pub_x = pub; const crypto::secret_key sec_x = hw::ledger::decrypt(sec); crypto::key_derivation derivation_x; - hw::ledger::log_hexbuffer("generate_key_derivation: [[IN]] pub ", pub_x.data, 32); - hw::ledger::log_hexbuffer("generate_key_derivation: [[IN]] sec ", sec_x.data, 32); + log_hexbuffer("generate_key_derivation: [[IN]] pub ", pub_x.data, 32); + log_hexbuffer("generate_key_derivation: [[IN]] sec ", sec_x.data, 32); this->controle_device->generate_key_derivation(pub_x, sec_x, derivation_x); - hw::ledger::log_hexbuffer("generate_key_derivation: [[OUT]] derivation", derivation_x.data, 32); + log_hexbuffer("generate_key_derivation: [[OUT]] derivation", derivation_x.data, 32); #endif if ((this->mode == TRANSACTION_PARSE) && has_view_key) { @@ -887,10 +922,10 @@ namespace hw { const crypto::key_derivation derivation_x = hw::ledger::decrypt(derivation); const size_t output_index_x = output_index; crypto::ec_scalar res_x; - hw::ledger::log_hexbuffer("derivation_to_scalar: [[IN]] derivation ", derivation_x.data, 32); - hw::ledger::log_message ("derivation_to_scalar: [[IN]] output_index ", std::to_string(output_index_x)); + log_hexbuffer("derivation_to_scalar: [[IN]] derivation ", derivation_x.data, 32); + log_message ("derivation_to_scalar: [[IN]] output_index ", std::to_string(output_index_x)); this->controle_device->derivation_to_scalar(derivation_x, output_index_x, res_x); - hw::ledger::log_hexbuffer("derivation_to_scalar: [[OUT]] res ", res_x.data, 32); + log_hexbuffer("derivation_to_scalar: [[OUT]] res ", res_x.data, 32); #endif int offset = set_command_header_noopt(INS_DERIVATION_TO_SCALAR); @@ -927,11 +962,11 @@ namespace hw { const std::size_t output_index_x = output_index; const crypto::secret_key sec_x = hw::ledger::decrypt(sec); crypto::secret_key derived_sec_x; - hw::ledger::log_hexbuffer("derive_secret_key: [[IN]] derivation ", derivation_x.data, 32); - hw::ledger::log_message ("derive_secret_key: [[IN]] index ", std::to_string(output_index_x)); - hw::ledger::log_hexbuffer("derive_secret_key: [[IN]] sec ", sec_x.data, 32); + log_hexbuffer("derive_secret_key: [[IN]] derivation ", derivation_x.data, 32); + log_message ("derive_secret_key: [[IN]] index ", std::to_string(output_index_x)); + log_hexbuffer("derive_secret_key: [[IN]] sec ", sec_x.data, 32); this->controle_device->derive_secret_key(derivation_x, output_index_x, sec_x, derived_sec_x); - hw::ledger::log_hexbuffer("derive_secret_key: [[OUT]] derived_sec", derived_sec_x.data, 32); + log_hexbuffer("derive_secret_key: [[OUT]] derived_sec", derived_sec_x.data, 32); #endif int offset = set_command_header_noopt(INS_DERIVE_SECRET_KEY); @@ -971,11 +1006,11 @@ namespace hw { const std::size_t output_index_x = output_index; const crypto::public_key pub_x = pub; crypto::public_key derived_pub_x; - hw::ledger::log_hexbuffer("derive_public_key: [[IN]] derivation ", derivation_x.data, 32); - hw::ledger::log_message ("derive_public_key: [[IN]] output_index", std::to_string(output_index_x)); - hw::ledger::log_hexbuffer("derive_public_key: [[IN]] pub ", pub_x.data, 32); + log_hexbuffer("derive_public_key: [[IN]] derivation ", derivation_x.data, 32); + log_message ("derive_public_key: [[IN]] output_index", std::to_string(output_index_x)); + log_hexbuffer("derive_public_key: [[IN]] pub ", pub_x.data, 32); this->controle_device->derive_public_key(derivation_x, output_index_x, pub_x, derived_pub_x); - hw::ledger::log_hexbuffer("derive_public_key: [[OUT]] derived_pub ", derived_pub_x.data, 32); + log_hexbuffer("derive_public_key: [[OUT]] derived_pub ", derived_pub_x.data, 32); #endif int offset = set_command_header_noopt(INS_DERIVE_PUBLIC_KEY); @@ -1012,11 +1047,11 @@ namespace hw { #ifdef DEBUG_HWDEVICE const crypto::secret_key sec_x = hw::ledger::decrypt(sec); crypto::public_key pub_x; - hw::ledger::log_hexbuffer("secret_key_to_public_key: [[IN]] sec ", sec_x.data, 32); + log_hexbuffer("secret_key_to_public_key: [[IN]] sec ", sec_x.data, 32); bool rc = this->controle_device->secret_key_to_public_key(sec_x, pub_x); - hw::ledger::log_hexbuffer("secret_key_to_public_key: [[OUT]] pub", pub_x.data, 32); + log_hexbuffer("secret_key_to_public_key: [[OUT]] pub", pub_x.data, 32); if (!rc){ - hw::ledger::log_message("secret_key_to_public_key", "secret_key rejected"); + log_message("secret_key_to_public_key", "secret_key rejected"); } #endif @@ -1046,10 +1081,10 @@ namespace hw { const crypto::public_key pub_x = pub; const crypto::secret_key sec_x = hw::ledger::decrypt(sec); crypto::key_image image_x; - hw::ledger::log_hexbuffer("generate_key_image: [[IN]] pub ", pub_x.data, 32); - hw::ledger::log_hexbuffer("generate_key_image: [[IN]] sec ", sec_x.data, 32); + log_hexbuffer("generate_key_image: [[IN]] pub ", pub_x.data, 32); + log_hexbuffer("generate_key_image: [[IN]] sec ", sec_x.data, 32); this->controle_device->generate_key_image(pub_x, sec_x, image_x); - hw::ledger::log_hexbuffer("generate_key_image: [[OUT]] image ", image_x.data, 32); + log_hexbuffer("generate_key_image: [[OUT]] image ", image_x.data, 32); #endif int offset = set_command_header_noopt(INS_GEN_KEY_IMAGE); @@ -1133,23 +1168,155 @@ namespace hw { return true; } - bool device_ledger::add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index, - const rct::key &amount_key, const crypto::public_key &out_eph_public_key) { - AUTO_LOCK_CMD(); - key_map.add(ABPkeys(rct::pk2rct(Aout),rct::pk2rct(Bout), is_subaddress, real_output_index, rct::pk2rct(out_eph_public_key), amount_key)); + + bool device_ledger::generate_output_ephemeral_keys(const size_t tx_version, const cryptonote::account_keys &sender_account_keys, const crypto::public_key &txkey_pub, const crypto::secret_key &tx_key, + const cryptonote::tx_destination_entry &dst_entr, const boost::optional<cryptonote::account_public_address> &change_addr, const size_t output_index, + const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys, + std::vector<crypto::public_key> &additional_tx_public_keys, + std::vector<rct::key> &amount_keys, + crypto::public_key &out_eph_public_key) { + AUTO_LOCK_CMD(); + + #ifdef DEBUG_HWDEVICE + const size_t &tx_version_x = tx_version; + const cryptonote::account_keys sender_account_keys_x = sender_account_keys; + memmove((void*)sender_account_keys_x.m_view_secret_key.data, dbg_viewkey.data, 32); + + const crypto::public_key &txkey_pub_x = txkey_pub; + const crypto::secret_key &tx_key_x = tx_key; + const cryptonote::tx_destination_entry &dst_entr_x = dst_entr; + const boost::optional<cryptonote::account_public_address> &change_addr_x = change_addr; + const size_t &output_index_x = output_index; + const bool &need_additional_txkeys_x = need_additional_txkeys; + const std::vector<crypto::secret_key> &additional_tx_keys_x = additional_tx_keys; + std::vector<crypto::public_key> additional_tx_public_keys_x; + std::vector<rct::key> amount_keys_x; + crypto::public_key out_eph_public_key_x; + this->controle_device->generate_output_ephemeral_keys(tx_version_x, sender_account_keys_x, txkey_pub_x, tx_key_x, dst_entr_x, change_addr_x, output_index_x, need_additional_txkeys_x, additional_tx_keys_x, + additional_tx_public_keys_x, amount_keys_x, out_eph_public_key_x); + #endif + + // make additional tx pubkey if necessary + cryptonote::keypair additional_txkey; + if (need_additional_txkeys) { + additional_txkey.sec = additional_tx_keys[output_index]; + } + + //compute derivation, out_eph_public_key, and amount key in one shot on device, to ensure checkable link + const crypto::secret_key *sec; + bool is_change; + + if (change_addr && dst_entr.addr == *change_addr) + { + // sending change to yourself; derivation = a*R + is_change = true; + sec = &sender_account_keys.m_view_secret_key; + } + else + { + is_change = false; + if (dst_entr.is_subaddress && need_additional_txkeys) { + sec = &additional_txkey.sec; + } else { + sec = &tx_key; + } + } + + int offset = set_command_header_noopt(INS_GEN_TXOUT_KEYS); + //tx_version + this->buffer_send[offset+0] = tx_version>>24; + this->buffer_send[offset+1] = tx_version>>16; + this->buffer_send[offset+2] = tx_version>>8; + this->buffer_send[offset+3] = tx_version>>0; + offset += 4; + //tx_sec + memmove(&this->buffer_send[offset], sec->data, 32); + offset += 32; + //Aout + memmove(&this->buffer_send[offset], dst_entr.addr.m_view_public_key.data, 32); + offset += 32; + //Bout + memmove(&this->buffer_send[offset], dst_entr.addr.m_spend_public_key.data, 32); + offset += 32; + //output index + this->buffer_send[offset+0] = output_index>>24; + this->buffer_send[offset+1] = output_index>>16; + this->buffer_send[offset+2] = output_index>>8; + this->buffer_send[offset+3] = output_index>>0; + offset += 4; + //is_change, + this->buffer_send[offset] = is_change; + offset++; + //is_subaddress + this->buffer_send[offset] = dst_entr.is_subaddress; + offset++; + //need_additional_key + this->buffer_send[offset] = need_additional_txkeys; + offset++; + + this->buffer_send[4] = offset-5; + this->length_send = offset; + this->exchange(); + + offset = 0; + unsigned int recv_len = this->length_recv; + if (need_additional_txkeys) + { + ASSERT_X(recv_len>=32, "Not enought data from device"); + memmove(additional_txkey.pub.data, &this->buffer_recv[offset], 32); + additional_tx_public_keys.push_back(additional_txkey.pub); + offset += 32; + recv_len -= 32; + } + if (tx_version > 1) + { + ASSERT_X(recv_len>=32, "Not enought data from device"); + crypto::secret_key scalar1; + memmove(scalar1.data, &this->buffer_recv[offset],32); + amount_keys.push_back(rct::sk2rct(scalar1)); + offset += 32; + recv_len -= 32; + } + ASSERT_X(recv_len>=32, "Not enought data from device"); + memmove(out_eph_public_key.data, &this->buffer_recv[offset], 32); + recv_len -= 32; + + // add ABPkeys + this->add_output_key_mapping(dst_entr.addr.m_view_public_key, dst_entr.addr.m_spend_public_key, dst_entr.is_subaddress, is_change, + need_additional_txkeys, output_index, + amount_keys.back(), out_eph_public_key); + + #ifdef DEBUG_HWDEVICE + hw::ledger::check32("generate_output_ephemeral_keys", "amount_key", (const char*)amount_keys_x.back().bytes, (const char*)hw::ledger::decrypt(amount_keys.back()).bytes); + if (need_additional_txkeys) { + hw::ledger::check32("generate_output_ephemeral_keys", "additional_tx_key", additional_tx_keys_x.back().data, additional_tx_keys.back().data); + } + hw::ledger::check32("generate_output_ephemeral_keys", "out_eph_public_key", out_eph_public_key_x.data, out_eph_public_key.data); + #endif + + return true; + } + + bool device_ledger::add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const bool is_change, + const bool need_additional, const size_t real_output_index, + const rct::key &amount_key, const crypto::public_key &out_eph_public_key) { + key_map.add(ABPkeys(rct::pk2rct(Aout),rct::pk2rct(Bout), is_subaddress, is_change, need_additional, real_output_index, rct::pk2rct(out_eph_public_key), amount_key)); return true; } - bool device_ledger::ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & AKout) { + bool device_ledger::ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & AKout, bool short_amount) { AUTO_LOCK_CMD(); #ifdef DEBUG_HWDEVICE const rct::key AKout_x = hw::ledger::decrypt(AKout); rct::ecdhTuple unmasked_x = unmasked; - this->controle_device->ecdhEncode(unmasked_x, AKout_x); + this->controle_device->ecdhEncode(unmasked_x, AKout_x, short_amount); #endif - int offset = set_command_header_noopt(INS_BLIND); + int offset = set_command_header(INS_BLIND); + //options + this->buffer_send[offset] = short_amount?0x02:0x00; + offset += 1; // AKout memmove(this->buffer_send+offset, AKout.bytes, 32); offset += 32; @@ -1171,23 +1338,25 @@ namespace hw { hw::ledger::check32("ecdhEncode", "amount", (char*)unmasked_x.amount.bytes, (char*)unmasked.amount.bytes); hw::ledger::check32("ecdhEncode", "mask", (char*)unmasked_x.mask.bytes, (char*)unmasked.mask.bytes); - hw::ledger::log_hexbuffer("Blind AKV input", (char*)&this->buffer_recv[64], 3*32); + log_hexbuffer("Blind AKV input", (char*)&this->buffer_recv[64], 3*32); #endif return true; } - bool device_ledger::ecdhDecode(rct::ecdhTuple & masked, const rct::key & AKout) { + bool device_ledger::ecdhDecode(rct::ecdhTuple & masked, const rct::key & AKout, bool short_amount) { AUTO_LOCK_CMD(); #ifdef DEBUG_HWDEVICE const rct::key AKout_x = hw::ledger::decrypt(AKout); rct::ecdhTuple masked_x = masked; - this->controle_device->ecdhDecode(masked_x, AKout_x); + this->controle_device->ecdhDecode(masked_x, AKout_x, short_amount); #endif - int offset = set_command_header_noopt(INS_UNBLIND); - + int offset = set_command_header(INS_UNBLIND); + //options + this->buffer_send[offset] = short_amount?0x02:0x00; + offset += 1; // AKout memmove(this->buffer_send+offset, AKout.bytes, 32); offset += 32; @@ -1260,7 +1429,8 @@ namespace hw { this->buffer_send[4] = offset-5; this->length_send = offset; - this->exchange(); + // check fee user input + CHECK_AND_ASSERT_THROW_MES(this->exchange_wait_on_input() == 0, "Fee denied on device."); //pseudoOuts if (type == rct::RCTTypeSimple) { @@ -1282,7 +1452,11 @@ namespace hw { // ====== Aout, Bout, AKout, C, v, k ====== kv_offset = data_offset; - C_offset = kv_offset+ (32*2)*outputs_size; + if (type==rct::RCTTypeBulletproof2) { + C_offset = kv_offset+ (8)*outputs_size; + } else { + C_offset = kv_offset+ (32+32)*outputs_size; + } for ( i = 0; i < outputs_size; i++) { ABPkeys outKeys; bool found; @@ -1295,11 +1469,15 @@ namespace hw { offset = set_command_header(INS_VALIDATE, 0x02, i+1); //options this->buffer_send[offset] = (i==outputs_size-1)? 0x00:0x80 ; + this->buffer_send[offset] |= (type==rct::RCTTypeBulletproof2)?0x02:0x00; offset += 1; if (found) { //is_subaddress this->buffer_send[offset] = outKeys.is_subaddress; offset++; + //is_change_address + this->buffer_send[offset] = outKeys.is_change_address; + offset++; //Aout memmove(this->buffer_send+offset, outKeys.Aout.bytes, 32); offset+=32; @@ -1311,26 +1489,38 @@ namespace hw { offset+=32; } else { // dummy: is_subaddress Aout Bout AKout - offset += 1+32*3; + offset += 2+32*3; } //C memmove(this->buffer_send+offset, data+C_offset,32); offset += 32; C_offset += 32; - //k - memmove(this->buffer_send+offset, data+kv_offset,32); - offset += 32; - //v - kv_offset += 32; - memmove(this->buffer_send+offset, data+kv_offset,32); - offset += 32; - kv_offset += 32; + if (type==rct::RCTTypeBulletproof2) { + //k + memset(this->buffer_send+offset, 0, 32); + offset += 32; + //v + memset(this->buffer_send+offset, 0, 32); + memmove(this->buffer_send+offset, data+kv_offset,8); + offset += 32; + kv_offset += 8; + } else { + //k + memmove(this->buffer_send+offset, data+kv_offset,32); + offset += 32; + kv_offset += 32; + //v + memmove(this->buffer_send+offset, data+kv_offset,32); + offset += 32; + kv_offset += 32; + } this->buffer_send[4] = offset-5; this->length_send = offset; - this->exchange(); + // check transaction user input + CHECK_AND_ASSERT_THROW_MES(this->exchange_wait_on_input() == 0, "Transaction denied on device."); #ifdef DEBUG_HWDEVICE - hw::ledger::log_hexbuffer("Prehash AKV input", (char*)&this->buffer_recv[64], 3*32); + log_hexbuffer("Prehash AKV input", (char*)&this->buffer_recv[64], 3*32); #endif } diff --git a/src/device/device_ledger.hpp b/src/device/device_ledger.hpp index 2f5beb044..3f470ee7c 100644 --- a/src/device/device_ledger.hpp +++ b/src/device/device_ledger.hpp @@ -56,12 +56,14 @@ namespace hw { rct::key Aout; rct::key Bout; bool is_subaddress; + bool is_change_address; + bool additional_key ; size_t index; rct::key Pout; rct::key AKout; - ABPkeys(const rct::key& A, const rct::key& B, const bool is_subaddr, size_t index, const rct::key& P,const rct::key& AK); + ABPkeys(const rct::key& A, const rct::key& B, const bool is_subaddr, bool is_subaddress, bool is_change_address, size_t index, const rct::key& P,const rct::key& AK); ABPkeys(const ABPkeys& keys) ; - ABPkeys() {index=0;is_subaddress=false;} + ABPkeys() {index=0;is_subaddress=false;is_subaddress=false;is_change_address=false;} }; class Keymap { @@ -85,7 +87,6 @@ namespace hw { //IO hw::io::device_io_hid hw_device; - std::string full_name; unsigned int length_send; unsigned char buffer_send[BUFFER_SEND_SIZE]; unsigned int length_recv; @@ -95,6 +96,7 @@ namespace hw { void logCMD(void); void logRESP(void); unsigned int exchange(unsigned int ok=0x9000, unsigned int mask=0xFFFF); + unsigned int exchange_wait_on_input(unsigned int ok=0x9000, unsigned int mask=0xFFFF); void reset_buffer(void); int set_command_header(unsigned char ins, unsigned char p1 = 0x00, unsigned char p2 = 0x00); int set_command_header_noopt(unsigned char ins, unsigned char p1 = 0x00, unsigned char p2 = 0x00); @@ -105,7 +107,9 @@ namespace hw { device_mode mode; // map public destination key to ephemeral destination key Keymap key_map; - + bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const bool is_change, + const bool need_additional, const size_t real_output_index, + const rct::key &amount_key, const crypto::public_key &out_eph_public_key); // To speed up blockchain parsing the view key maybe handle here. crypto::secret_key viewkey; bool has_view_key; @@ -191,12 +195,15 @@ namespace hw { bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) override; - bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec) override; - bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec) override; - - bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index, - const rct::key &amount_key, const crypto::public_key &out_eph_public_key) override; + bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec, bool short_format) override; + bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec, bool short_format) override; + bool generate_output_ephemeral_keys(const size_t tx_version, const cryptonote::account_keys &sender_account_keys, const crypto::public_key &txkey_pub, const crypto::secret_key &tx_key, + const cryptonote::tx_destination_entry &dst_entr, const boost::optional<cryptonote::account_public_address> &change_addr, const size_t output_index, + const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys, + std::vector<crypto::public_key> &additional_tx_public_keys, + std::vector<rct::key> &amount_keys, + crypto::public_key &out_eph_public_key) override; bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) override; bool mlsag_prepare(const rct::key &H, const rct::key &xx, rct::key &a, rct::key &aG, rct::key &aHP, rct::key &rvII) override; diff --git a/src/device/log.cpp b/src/device/log.cpp index c9d3b551b..87505798b 100644 --- a/src/device/log.cpp +++ b/src/device/log.cpp @@ -66,7 +66,7 @@ namespace hw { void decrypt(char* buf, size_t len) { - #ifdef IODUMMYCRYPT_HWDEVICE + #if defined(IODUMMYCRYPT_HWDEVICE) || defined(IONOCRYPT_HWDEVICE) size_t i; if (len == 32) { //view key? @@ -86,11 +86,13 @@ namespace hw { return; } } + #if defined(IODUMMYCRYPT_HWDEVICE) //std decrypt: XOR.55h for (i = 0; i<len;i++) { buf[i] ^= 0x55; } #endif + #endif } crypto::key_derivation decrypt(const crypto::key_derivation &derivation) { diff --git a/src/device_trezor/trezor/protocol.hpp b/src/device_trezor/trezor/protocol.hpp index 99211efed..ce0361640 100644 --- a/src/device_trezor/trezor/protocol.hpp +++ b/src/device_trezor/trezor/protocol.hpp @@ -270,7 +270,7 @@ namespace tx { throw std::invalid_argument("RV not initialized"); } auto tp = m_ct.rv->type; - return tp == rct::RCTTypeBulletproof; + return tp == rct::RCTTypeBulletproof || tp == rct::RCTTypeBulletproof2; } bool is_offloading() const { diff --git a/src/device_trezor/trezor/transport.hpp b/src/device_trezor/trezor/transport.hpp index 50c31cf73..1cf0daa85 100644 --- a/src/device_trezor/trezor/transport.hpp +++ b/src/device_trezor/trezor/transport.hpp @@ -162,7 +162,7 @@ namespace trezor { m_session(boost::none), m_device_info(boost::none) { - m_http_client.set_server(m_bridge_host, boost::none, false); + m_http_client.set_server(m_bridge_host, boost::none, epee::net_utils::ssl_support_t::e_ssl_support_disabled); } virtual ~BridgeTransport() = default; diff --git a/src/mnemonics/electrum-words.cpp b/src/mnemonics/electrum-words.cpp index b1e3bdcd5..68d5b84d3 100644 --- a/src/mnemonics/electrum-words.cpp +++ b/src/mnemonics/electrum-words.cpp @@ -76,8 +76,8 @@ namespace crypto namespace { uint32_t create_checksum_index(const std::vector<epee::wipeable_string> &word_list, - uint32_t unique_prefix_length); - bool checksum_test(std::vector<epee::wipeable_string> seed, uint32_t unique_prefix_length); + const Language::Base *language); + bool checksum_test(std::vector<epee::wipeable_string> seed, const Language::Base *language); /*! * \brief Finds the word list that contains the seed words and puts the indices @@ -116,8 +116,8 @@ namespace for (std::vector<Language::Base*>::iterator it1 = language_instances.begin(); it1 != language_instances.end(); it1++) { - const std::unordered_map<epee::wipeable_string, uint32_t> &word_map = (*it1)->get_word_map(); - const std::unordered_map<epee::wipeable_string, uint32_t> &trimmed_word_map = (*it1)->get_trimmed_word_map(); + const std::unordered_map<epee::wipeable_string, uint32_t, Language::WordHash, Language::WordEqual> &word_map = (*it1)->get_word_map(); + const std::unordered_map<epee::wipeable_string, uint32_t, Language::WordHash, Language::WordEqual> &trimmed_word_map = (*it1)->get_trimmed_word_map(); // To iterate through seed words bool full_match = true; @@ -151,7 +151,7 @@ namespace // if we were using prefix only, and we have a checksum, check it now // to avoid false positives due to prefix set being too common if (has_checksum) - if (!checksum_test(seed, (*it1)->get_unique_prefix_length())) + if (!checksum_test(seed, *it1)) { fallback = *it1; full_match = false; @@ -190,20 +190,20 @@ namespace * \return Checksum index */ uint32_t create_checksum_index(const std::vector<epee::wipeable_string> &word_list, - uint32_t unique_prefix_length) + const Language::Base *language) { - epee::wipeable_string trimmed_words = ""; + epee::wipeable_string trimmed_words = "", word; + const auto &word_map = language->get_word_map(); + const auto &trimmed_word_map = language->get_trimmed_word_map(); + const uint32_t unique_prefix_length = language->get_unique_prefix_length(); for (std::vector<epee::wipeable_string>::const_iterator it = word_list.begin(); it != word_list.end(); it++) { - if (it->length() > unique_prefix_length) - { - trimmed_words += Language::utf8prefix(*it, unique_prefix_length); - } - else - { - trimmed_words += *it; - } + word = Language::utf8prefix(*it, unique_prefix_length); + auto it2 = trimmed_word_map.find(word); + if (it2 == trimmed_word_map.end()) + throw std::runtime_error("Word \"" + std::string(word.data(), word.size()) + "\" not found in trimmed word map in " + language->get_english_language_name()); + trimmed_words += it2->first; } boost::crc_32_type result; result.process_bytes(trimmed_words.data(), trimmed_words.length()); @@ -216,7 +216,7 @@ namespace * \param unique_prefix_length the prefix length of each word to use for checksum * \return True if the test passed false if not. */ - bool checksum_test(std::vector<epee::wipeable_string> seed, uint32_t unique_prefix_length) + bool checksum_test(std::vector<epee::wipeable_string> seed, const Language::Base *language) { if (seed.empty()) return false; @@ -224,13 +224,16 @@ namespace epee::wipeable_string last_word = seed.back(); seed.pop_back(); - epee::wipeable_string checksum = seed[create_checksum_index(seed, unique_prefix_length)]; + const uint32_t unique_prefix_length = language->get_unique_prefix_length(); + + auto idx = create_checksum_index(seed, language); + epee::wipeable_string checksum = seed[idx]; epee::wipeable_string trimmed_checksum = checksum.length() > unique_prefix_length ? Language::utf8prefix(checksum, unique_prefix_length) : checksum; epee::wipeable_string trimmed_last_word = last_word.length() > unique_prefix_length ? Language::utf8prefix(last_word, unique_prefix_length) : last_word; - bool ret = trimmed_checksum == trimmed_last_word; + bool ret = Language::WordEqual()(trimmed_checksum, trimmed_last_word); MINFO("Checksum is " << (ret ? "valid" : "invalid")); return ret; } @@ -301,7 +304,7 @@ namespace crypto if (has_checksum) { - if (!checksum_test(seed, language->get_unique_prefix_length())) + if (!checksum_test(seed, language)) { // Checksum fail MERROR("Invalid seed: invalid checksum"); @@ -424,7 +427,7 @@ namespace crypto memwipe(w, sizeof(w)); } - words += words_store[create_checksum_index(words_store, language->get_unique_prefix_length())]; + words += words_store[create_checksum_index(words_store, language)]; return true; } diff --git a/src/mnemonics/language_base.h b/src/mnemonics/language_base.h index 52e784cef..a6f969604 100644 --- a/src/mnemonics/language_base.h +++ b/src/mnemonics/language_base.h @@ -38,7 +38,9 @@ #include <vector>
#include <unordered_map>
#include <string>
+#include <boost/algorithm/string.hpp>
#include "misc_log_ex.h"
+#include "fnv1.h"
/*!
* \namespace Language
@@ -71,6 +73,92 @@ namespace Language return prefix;
}
+ template<typename T>
+ inline T utf8canonical(const T &s)
+ {
+ T sc = "";
+ size_t avail = s.size();
+ const char *ptr = s.data();
+ wint_t cp = 0;
+ int bytes = 1;
+ char wbuf[8], *wptr;
+ while (avail--)
+ {
+ if ((*ptr & 0x80) == 0)
+ {
+ cp = *ptr++;
+ bytes = 1;
+ }
+ else if ((*ptr & 0xe0) == 0xc0)
+ {
+ if (avail < 1)
+ throw std::runtime_error("Invalid UTF-8");
+ cp = (*ptr++ & 0x1f) << 6;
+ cp |= *ptr++ & 0x3f;
+ --avail;
+ bytes = 2;
+ }
+ else if ((*ptr & 0xf0) == 0xe0)
+ {
+ if (avail < 2)
+ throw std::runtime_error("Invalid UTF-8");
+ cp = (*ptr++ & 0xf) << 12;
+ cp |= (*ptr++ & 0x3f) << 6;
+ cp |= *ptr++ & 0x3f;
+ avail -= 2;
+ bytes = 3;
+ }
+ else if ((*ptr & 0xf8) == 0xf0)
+ {
+ if (avail < 3)
+ throw std::runtime_error("Invalid UTF-8");
+ cp = (*ptr++ & 0x7) << 18;
+ cp |= (*ptr++ & 0x3f) << 12;
+ cp |= (*ptr++ & 0x3f) << 6;
+ cp |= *ptr++ & 0x3f;
+ avail -= 3;
+ bytes = 4;
+ }
+ else
+ throw std::runtime_error("Invalid UTF-8");
+
+ cp = std::towlower(cp);
+ wptr = wbuf;
+ switch (bytes)
+ {
+ case 1: *wptr++ = cp; break;
+ case 2: *wptr++ = 0xc0 | (cp >> 6); *wptr++ = 0x80 | (cp & 0x3f); break;
+ case 3: *wptr++ = 0xe0 | (cp >> 12); *wptr++ = 0x80 | ((cp >> 6) & 0x3f); *wptr++ = 0x80 | (cp & 0x3f); break;
+ case 4: *wptr++ = 0xf0 | (cp >> 18); *wptr += 0x80 | ((cp >> 12) & 0x3f); *wptr++ = 0x80 | ((cp >> 6) & 0x3f); *wptr++ = 0x80 | (cp & 0x3f); break;
+ default: throw std::runtime_error("Invalid UTF-8");
+ }
+ *wptr = 0;
+ sc += T(wbuf, bytes);
+ cp = 0;
+ bytes = 1;
+ }
+ return sc;
+ }
+
+ struct WordHash
+ {
+ std::size_t operator()(const epee::wipeable_string &s) const
+ {
+ const epee::wipeable_string sc = utf8canonical(s);
+ return epee::fnv::FNV1a(sc.data(), sc.size());
+ }
+ };
+
+ struct WordEqual
+ {
+ bool operator()(const epee::wipeable_string &s0, const epee::wipeable_string &s1) const
+ {
+ const epee::wipeable_string s0c = utf8canonical(s0);
+ const epee::wipeable_string s1c = utf8canonical(s1);
+ return s0c == s1c;
+ }
+ };
+
/*!
* \class Base
* \brief A base language class which all languages have to inherit from for
@@ -87,8 +175,8 @@ namespace Language NWORDS = 1626
};
std::vector<std::string> word_list; /*!< A pointer to the array of words */
- std::unordered_map<epee::wipeable_string, uint32_t> word_map; /*!< hash table to find word's index */
- std::unordered_map<epee::wipeable_string, uint32_t> trimmed_word_map; /*!< hash table to find word's trimmed index */
+ std::unordered_map<epee::wipeable_string, uint32_t, WordHash, WordEqual> word_map; /*!< hash table to find word's index */
+ std::unordered_map<epee::wipeable_string, uint32_t, WordHash, WordEqual> trimmed_word_map; /*!< hash table to find word's trimmed index */
std::string language_name; /*!< Name of language */
std::string english_language_name; /*!< Name of language */
uint32_t unique_prefix_length; /*!< Number of unique starting characters to trim the wordlist to when matching */
@@ -159,7 +247,7 @@ namespace Language * \brief Returns a pointer to the word map.
* \return A pointer to the word map.
*/
- const std::unordered_map<epee::wipeable_string, uint32_t>& get_word_map() const
+ const std::unordered_map<epee::wipeable_string, uint32_t, WordHash, WordEqual>& get_word_map() const
{
return word_map;
}
@@ -167,7 +255,7 @@ namespace Language * \brief Returns a pointer to the trimmed word map.
* \return A pointer to the trimmed word map.
*/
- const std::unordered_map<epee::wipeable_string, uint32_t>& get_trimmed_word_map() const
+ const std::unordered_map<epee::wipeable_string, uint32_t, WordHash, WordEqual>& get_trimmed_word_map() const
{
return trimmed_word_map;
}
diff --git a/src/net/CMakeLists.txt b/src/net/CMakeLists.txt new file mode 100644 index 000000000..a81372125 --- /dev/null +++ b/src/net/CMakeLists.txt @@ -0,0 +1,34 @@ +# Copyright (c) 2018, The Monero Project +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other +# materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be +# used to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set(net_sources error.cpp parse.cpp socks.cpp tor_address.cpp) +set(net_headers error.h parse.h socks.h tor_address.h) + +monero_add_library(net ${net_sources} ${net_headers}) +target_link_libraries(net epee ${Boost_ASIO_LIBRARY}) + diff --git a/src/net/error.cpp b/src/net/error.cpp new file mode 100644 index 000000000..037f44d52 --- /dev/null +++ b/src/net/error.cpp @@ -0,0 +1,92 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "error.h" + +#include <string> + +namespace +{ + struct net_category : std::error_category + { + net_category() noexcept + : std::error_category() + {} + + const char* name() const noexcept override + { + return "net::error_category"; + } + + std::string message(int value) const override + { + switch (net::error(value)) + { + case net::error::expected_tld: + return "Expected top-level domain"; + case net::error::invalid_host: + return "Host value is not valid"; + case net::error::invalid_i2p_address: + return "Invalid I2P address"; + case net::error::invalid_port: + return "Invalid port value (expected 0-65535)"; + case net::error::invalid_tor_address: + return "Invalid Tor address"; + case net::error::unsupported_address: + return "Network address not supported"; + default: + break; + } + + return "Unknown net::error"; + } + + std::error_condition default_error_condition(int value) const noexcept override + { + switch (net::error(value)) + { + case net::error::invalid_port: + return std::errc::result_out_of_range; + case net::error::expected_tld: + case net::error::invalid_tor_address: + default: + break; + } + return std::error_condition{value, *this}; + } + }; +} // anonymous + +namespace net +{ + std::error_category const& error_category() noexcept + { + static const net_category instance{}; + return instance; + } +} diff --git a/src/net/error.h b/src/net/error.h new file mode 100644 index 000000000..c8338f7e2 --- /dev/null +++ b/src/net/error.h @@ -0,0 +1,64 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include <system_error> +#include <type_traits> + +namespace net +{ + //! General net errors + enum class error : int + { + // 0 reserved for success (as per expect<T>) + expected_tld = 1, //!< Expected a tld + invalid_host, //!< Hostname is not valid + invalid_i2p_address, + invalid_port, //!< Outside of 0-65535 range + invalid_tor_address,//!< Invalid base32 or length + unsupported_address //!< Type not supported by `get_network_address` + }; + + //! \return `std::error_category` for `net` namespace. + std::error_category const& error_category() noexcept; + + //! \return `net::error` as a `std::error_code` value. + inline std::error_code make_error_code(error value) noexcept + { + return std::error_code{int(value), error_category()}; + } +} + +namespace std +{ + template<> + struct is_error_code_enum<::net::error> + : true_type + {}; +} diff --git a/src/net/fwd.h b/src/net/fwd.h new file mode 100644 index 000000000..ee7c539b0 --- /dev/null +++ b/src/net/fwd.h @@ -0,0 +1,45 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include <cstdint> + +namespace net +{ + enum class error : int; + class tor_address; + + namespace socks + { + class client; + template<typename> class connect_handler; + enum class error : int; + enum class version : std::uint8_t; + } +} diff --git a/src/net/parse.cpp b/src/net/parse.cpp new file mode 100644 index 000000000..ebf91eeff --- /dev/null +++ b/src/net/parse.cpp @@ -0,0 +1,60 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "parse.h" + +#include "net/tor_address.h" +#include "string_tools.h" + +namespace net +{ + expect<epee::net_utils::network_address> + get_network_address(const boost::string_ref address, const std::uint16_t default_port) + { + const boost::string_ref host = address.substr(0, address.rfind(':')); + + if (host.empty()) + return make_error_code(net::error::invalid_host); + if (host.ends_with(".onion")) + return tor_address::make(address, default_port); + if (host.ends_with(".i2p")) + return make_error_code(net::error::invalid_i2p_address); // not yet implemented (prevent public DNS lookup) + + std::uint16_t port = default_port; + if (host.size() < address.size()) + { + if (!epee::string_tools::get_xtype_from_string(port, std::string{address.substr(host.size() + 1)})) + return make_error_code(net::error::invalid_port); + } + + std::uint32_t ip = 0; + if (epee::string_tools::get_ip_int32_from_string(ip, std::string{host})) + return {epee::net_utils::ipv4_network_address{ip, port}}; + return make_error_code(net::error::unsupported_address); + } +} diff --git a/src/net/parse.h b/src/net/parse.h new file mode 100644 index 000000000..9195ddc2b --- /dev/null +++ b/src/net/parse.h @@ -0,0 +1,54 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include <boost/utility/string_ref.hpp> +#include <cstdint> + +#include "common/expect.h" +#include "net/net_utils_base.h" + +namespace net +{ + /*! + Identifies onion and IPv4 addresses and returns them as a generic + `network_address`. If the type is unsupported, it might be a hostname, + and `error() == net::error::kUnsupportedAddress` is returned. + + \param address An onion address, ipv4 address or hostname. Hostname + will return an error. + \param default_port If `address` does not specify a port, this value + will be used. + + \return A tor or IPv4 address, else error. + */ + expect<epee::net_utils::network_address> + get_network_address(boost::string_ref address, std::uint16_t default_port); +} + diff --git a/src/net/socks.cpp b/src/net/socks.cpp new file mode 100644 index 000000000..f31efc8c1 --- /dev/null +++ b/src/net/socks.cpp @@ -0,0 +1,308 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "socks.h" + +#include <algorithm> +#include <boost/asio/buffer.hpp> +#include <boost/asio/read.hpp> +#include <boost/asio/write.hpp> +#include <boost/endian/arithmetic.hpp> +#include <boost/endian/conversion.hpp> +#include <cstring> +#include <limits> +#include <string> + +#include "net/net_utils_base.h" +#include "net/tor_address.h" + +namespace net +{ +namespace socks +{ + namespace + { + constexpr const unsigned v4_reply_size = 8; + constexpr const std::uint8_t v4_connect_command = 1; + constexpr const std::uint8_t v4tor_resolve_command = 0xf0; + constexpr const std::uint8_t v4_request_granted = 90; + + struct v4_header + { + std::uint8_t version; + std::uint8_t command_code; + boost::endian::big_uint16_t port; + boost::endian::big_uint32_t ip; + }; + + std::size_t write_domain_header(epee::span<std::uint8_t> out, const std::uint8_t command, const std::uint16_t port, const boost::string_ref domain) + { + if (std::numeric_limits<std::size_t>::max() - sizeof(v4_header) - 2 < domain.size()) + return 0; + + const std::size_t buf_size = sizeof(v4_header) + domain.size() + 2; + if (out.size() < buf_size) + return 0; + + // version 4, 1 indicates invalid ip for domain extension + const v4_header temp{4, command, port, std::uint32_t(1)}; + std::memcpy(out.data(), std::addressof(temp), sizeof(temp)); + out.remove_prefix(sizeof(temp)); + + *(out.data()) = 0; + out.remove_prefix(1); + + std::memcpy(out.data(), domain.data(), domain.size()); + out.remove_prefix(domain.size()); + + *(out.data()) = 0; + return buf_size; + } + + struct socks_category : boost::system::error_category + { + explicit socks_category() noexcept + : boost::system::error_category() + {} + + const char* name() const noexcept override + { + return "net::socks::error_category"; + } + + virtual std::string message(int value) const override + { + switch (socks::error(value)) + { + case socks::error::rejected: + return "Socks request rejected or failed"; + case socks::error::identd_connection: + return "Socks request rejected because server cannot connect to identd on the client"; + case socks::error::identd_user: + return "Socks request rejected because the client program and identd report different user-ids"; + + case socks::error::bad_read: + return "Socks boost::async_read read fewer bytes than expected"; + case socks::error::bad_write: + return "Socks boost::async_write wrote fewer bytes than expected"; + case socks::error::unexpected_version: + return "Socks server returned unexpected version in reply"; + + default: + break; + } + return "Unknown net::socks::error"; + } + + boost::system::error_condition default_error_condition(int value) const noexcept override + { + switch (socks::error(value)) + { + case socks::error::bad_read: + case socks::error::bad_write: + return boost::system::errc::io_error; + case socks::error::unexpected_version: + return boost::system::errc::protocol_error; + default: + break; + }; + if (1 <= value && value <= 256) + return boost::system::errc::protocol_error; + + return boost::system::error_condition{value, *this}; + } + }; + } + + const boost::system::error_category& error_category() noexcept + { + static const socks_category instance{}; + return instance; + } + + struct client::completed + { + std::shared_ptr<client> self_; + + void operator()(const boost::system::error_code error, const std::size_t bytes) const + { + static_assert(1 < sizeof(self_->buffer_), "buffer too small for v4 response"); + + if (self_) + { + client& self = *self_; + self.buffer_size_ = std::min(bytes, sizeof(self.buffer_)); + + if (error) + self.done(error, std::move(self_)); + else if (self.buffer().size() < sizeof(v4_header)) + self.done(socks::error::bad_read, std::move(self_)); + else if (self.buffer_[0] != 0) // response version + self.done(socks::error::unexpected_version, std::move(self_)); + else if (self.buffer_[1] != v4_request_granted) + self.done(socks::error(int(self.buffer_[1]) + 1), std::move(self_)); + else + self.done(boost::system::error_code{}, std::move(self_)); + } + } + }; + + struct client::read + { + std::shared_ptr<client> self_; + + static boost::asio::mutable_buffers_1 get_buffer(client& self) noexcept + { + static_assert(sizeof(v4_header) <= sizeof(self.buffer_), "buffer too small for v4 response"); + return boost::asio::buffer(self.buffer_, sizeof(v4_header)); + } + + void operator()(const boost::system::error_code error, const std::size_t bytes) + { + if (self_) + { + client& self = *self_; + if (error) + self.done(error, std::move(self_)); + else if (bytes < self.buffer().size()) + self.done(socks::error::bad_write, std::move(self_)); + else + boost::asio::async_read(self.proxy_, get_buffer(self), completed{std::move(self_)}); + } + } + }; + + struct client::write + { + std::shared_ptr<client> self_; + + static boost::asio::const_buffers_1 get_buffer(client const& self) noexcept + { + return boost::asio::buffer(self.buffer_, self.buffer_size_); + } + + void operator()(const boost::system::error_code error) + { + if (self_) + { + client& self = *self_; + if (error) + self.done(error, std::move(self_)); + else + boost::asio::async_write(self.proxy_, get_buffer(self), read{std::move(self_)}); + } + } + }; + + client::client(stream_type::socket&& proxy, socks::version ver) + : proxy_(std::move(proxy)), buffer_size_(0), buffer_(), ver_(ver) + {} + + client::~client() {} + + bool client::set_connect_command(const epee::net_utils::ipv4_network_address& address) + { + switch (socks_version()) + { + case version::v4: + case version::v4a: + case version::v4a_tor: + break; + default: + return false; + } + + static_assert(sizeof(v4_header) < sizeof(buffer_), "buffer size too small for request"); + static_assert(0 < sizeof(buffer_), "buffer size too small for null termination"); + + // version 4 + const v4_header temp{4, v4_connect_command, address.port(), boost::endian::big_to_native(address.ip())}; + std::memcpy(std::addressof(buffer_), std::addressof(temp), sizeof(temp)); + buffer_[sizeof(temp)] = 0; + buffer_size_ = sizeof(temp) + 1; + + return true; + } + + bool client::set_connect_command(const boost::string_ref domain, std::uint16_t port) + { + switch (socks_version()) + { + case version::v4a: + case version::v4a_tor: + break; + + default: + return false; + } + + const std::size_t buf_used = write_domain_header(buffer_, v4_connect_command, port, domain); + buffer_size_ = buf_used; + return buf_used != 0; + } + + bool client::set_connect_command(const net::tor_address& address) + { + if (!address.is_unknown()) + return set_connect_command(address.host_str(), address.port()); + return false; + } + + bool client::set_resolve_command(boost::string_ref domain) + { + if (socks_version() != version::v4a_tor) + return false; + + const std::size_t buf_used = write_domain_header(buffer_, v4tor_resolve_command, 0, domain); + buffer_size_ = buf_used; + return buf_used != 0; + } + + bool client::connect_and_send(std::shared_ptr<client> self, const stream_type::endpoint& proxy_address) + { + if (self && !self->buffer().empty()) + { + client& alias = *self; + alias.proxy_.async_connect(proxy_address, write{std::move(self)}); + return true; + } + return false; + } + + bool client::send(std::shared_ptr<client> self) + { + if (self && !self->buffer().empty()) + { + client& alias = *self; + boost::asio::async_write(alias.proxy_, write::get_buffer(alias), read{std::move(self)}); + return true; + } + return false; + } +} // socks +} // net diff --git a/src/net/socks.h b/src/net/socks.h new file mode 100644 index 000000000..d29a51ccb --- /dev/null +++ b/src/net/socks.h @@ -0,0 +1,225 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include <cstdint> +#include <boost/asio/ip/tcp.hpp> +#include <boost/asio/io_service.hpp> +#include <boost/system/error_code.hpp> +#include <boost/type_traits/integral_constant.hpp> +#include <boost/utility/string_ref.hpp> +#include <memory> +#include <utility> + +#include "net/fwd.h" +#include "span.h" + +namespace epee +{ +namespace net_utils +{ + class ipv4_network_address; +} +} + +namespace net +{ +namespace socks +{ + //! Supported socks variants. + enum class version : std::uint8_t + { + v4 = 0, + v4a, + v4a_tor //!< Extensions defined in Tor codebase + }; + + //! Possible errors with socks communication. Defined in https://www.openssh.com/txt/socks4.protocol + enum class error : int + { + // 0 is reserved for success value + // 1-256 -> reserved for error values from socks server (+1 from wire value). + rejected = 92, + identd_connection, + identd_user, + // Specific to application + bad_read = 257, + bad_write, + unexpected_version + }; + + /* boost::system::error_code is extended for easier compatibility with + boost::asio errors. If std::error_code is needed (with expect<T> for + instance), then upgrade to boost 1.65+ or use conversion code in + develop branch at boost/system/detail/std_interoperability.hpp */ + + //! \return boost::system::error_category for net::socks namespace + const boost::system::error_category& error_category() noexcept; + + //! \return net::socks::error as a boost::system::error_code. + inline boost::system::error_code make_error_code(error value) noexcept + { + return boost::system::error_code{int(value), socks::error_category()}; + } + + //! Client support for socks connect and resolve commands. + class client + { + boost::asio::ip::tcp::socket proxy_; + std::uint16_t buffer_size_; + std::uint8_t buffer_[1024]; + socks::version ver_; + + /*! + Only invoked after `*send(...)` function completes or fails. + `bool(error) == false` indicates success; `self.get()` is always + `this` and allows implementations to skip + `std::enable_shared_from_this<T>` (ASIO callbacks need shared_ptr). + The design saves space and reduces cycles (everything uses moves, + so no atomic operations are ever necessary). + + \param error when processing last command (if any). + \param self `shared_ptr<client>` handle to `this`. + */ + virtual void done(boost::system::error_code error, std::shared_ptr<client> self) = 0; + + public: + using stream_type = boost::asio::ip::tcp; + + // defined in cpp + struct write; + struct read; + struct completed; + + /*! + \param proxy ownership is passed into `this`. Does not have to be + in connected state. + \param ver socks version for the connection. + */ + explicit client(stream_type::socket&& proxy, socks::version ver); + + client(const client&) = delete; + virtual ~client(); + client& operator=(const client&) = delete; + + //! \return Ownership of socks client socket object. + stream_type::socket take_socket() + { + return stream_type::socket{std::move(proxy_)}; + } + + //! \return Socks version. + socks::version socks_version() const noexcept { return ver_; } + + //! \return Contents of internal buffer. + epee::span<const std::uint8_t> buffer() const noexcept + { + return {buffer_, buffer_size_}; + } + + //! \post `buffer.empty()`. + void clear_command() noexcept { buffer_size_ = 0; } + + //! Try to set `address` as remote connection request. + bool set_connect_command(const epee::net_utils::ipv4_network_address& address); + + //! Try to set `domain` + `port` as remote connection request. + bool set_connect_command(boost::string_ref domain, std::uint16_t port); + + //! Try to set `address` as remote Tor hidden service connection request. + bool set_connect_command(const net::tor_address& address); + + //! Try to set `domain` as remote DNS A record lookup request. + bool set_resolve_command(boost::string_ref domain); + + /*! + Asynchronously connect to `proxy_address` then issue command in + `buffer()`. The `done(...)` method will be invoked upon completion + with `self` and potential `error`s. + + \note Must use one of the `self->set_*_command` calls before using + this function. + + \param self ownership of object is given to function. + \param proxy_address of the socks server. + \return False if `self->buffer().empty()` (no command set). + */ + static bool connect_and_send(std::shared_ptr<client> self, const stream_type::endpoint& proxy_address); + + /*! + Assume existing connection to proxy server; asynchronously issue + command in `buffer()`. The `done(...)` method will be invoked + upon completion with `self` and potential `error`s. + + \note Must use one of the `self->set_*_command` calls before using + the function. + + \param self ownership of object is given to function. + \return False if `self->buffer().empty()` (no command set). + */ + static bool send(std::shared_ptr<client> self); + }; + + template<typename Handler> + class connect_client : public client + { + Handler handler_; + + virtual void done(boost::system::error_code error, std::shared_ptr<client>) override + { + handler_(error, take_socket()); + } + + public: + explicit connect_client(stream_type::socket&& proxy, socks::version ver, Handler&& handler) + : client(std::move(proxy), ver), handler_(std::move(handler)) + {} + + virtual ~connect_client() override {} + }; + + template<typename Handler> + inline std::shared_ptr<client> + make_connect_client(client::stream_type::socket&& proxy, socks::version ver, Handler handler) + { + return std::make_shared<connect_client<Handler>>(std::move(proxy), ver, std::move(handler)); + } +} // socks +} // net + +namespace boost +{ +namespace system +{ + template<> + struct is_error_code_enum<net::socks::error> + : true_type + {}; +} // system +} // boost diff --git a/src/net/tor_address.cpp b/src/net/tor_address.cpp new file mode 100644 index 000000000..904a9a0fc --- /dev/null +++ b/src/net/tor_address.cpp @@ -0,0 +1,203 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "tor_address.h" + +#include <algorithm> +#include <boost/spirit/include/karma_generate.hpp> +#include <boost/spirit/include/karma_uint.hpp> +#include <cassert> +#include <cstring> +#include <limits> + +#include "net/error.h" +#include "serialization/keyvalue_serialization.h" +#include "storages/portable_storage.h" +#include "string_tools.h" + +namespace net +{ + namespace + { + constexpr const char tld[] = u8".onion"; + constexpr const char unknown_host[] = "<unknown tor host>"; + + constexpr const unsigned v2_length = 16; + constexpr const unsigned v3_length = 56; + + constexpr const char base32_alphabet[] = + u8"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz234567"; + + expect<void> host_check(boost::string_ref host) noexcept + { + if (!host.ends_with(tld)) + return {net::error::expected_tld}; + + host.remove_suffix(sizeof(tld) - 1); + + //! \TODO v3 has checksum, base32 decoding is required to verify it + if (host.size() != v2_length && host.size() != v3_length) + return {net::error::invalid_tor_address}; + if (host.find_first_not_of(base32_alphabet) != boost::string_ref::npos) + return {net::error::invalid_tor_address}; + + return success(); + } + + struct tor_serialized + { + std::string host; + std::uint16_t port; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(host) + KV_SERIALIZE(port) + END_KV_SERIALIZE_MAP() + }; + } + + tor_address::tor_address(const boost::string_ref host, const std::uint16_t port) noexcept + : port_(port) + { + // this is a private constructor, throw if moved to public + assert(host.size() < sizeof(host_)); + + const std::size_t length = std::min(sizeof(host_) - 1, host.size()); + std::memcpy(host_, host.data(), length); + std::memset(host_ + length, 0, sizeof(host_) - length); + } + + const char* tor_address::unknown_str() noexcept + { + return unknown_host; + } + + tor_address::tor_address() noexcept + : port_(0) + { + static_assert(sizeof(unknown_host) <= sizeof(host_), "bad buffer size"); + std::memcpy(host_, unknown_host, sizeof(unknown_host)); + std::memset(host_ + sizeof(unknown_host), 0, sizeof(host_) - sizeof(unknown_host)); + } + + expect<tor_address> tor_address::make(const boost::string_ref address, const std::uint16_t default_port) + { + boost::string_ref host = address.substr(0, address.rfind(':')); + const boost::string_ref port = + address.substr(host.size() + (host.size() == address.size() ? 0 : 1)); + + MONERO_CHECK(host_check(host)); + + std::uint16_t porti = default_port; + if (!port.empty() && !epee::string_tools::get_xtype_from_string(porti, std::string{port})) + return {net::error::invalid_port}; + + static_assert(v2_length <= v3_length, "bad internal host size"); + static_assert(v3_length + sizeof(tld) == sizeof(tor_address::host_), "bad internal host size"); + return tor_address{host, porti}; + } + + bool tor_address::_load(epee::serialization::portable_storage& src, epee::serialization::section* hparent) + { + tor_serialized in{}; + if (in._load(src, hparent) && in.host.size() < sizeof(host_) && (in.host == unknown_host || !host_check(in.host).has_error())) + { + std::memcpy(host_, in.host.data(), in.host.size()); + std::memset(host_ + in.host.size(), 0, sizeof(host_) - in.host.size()); + port_ = in.port; + return true; + } + static_assert(sizeof(unknown_host) <= sizeof(host_), "bad buffer size"); + std::memcpy(host_, unknown_host, sizeof(unknown_host)); // include null terminator + port_ = 0; + return false; + } + + bool tor_address::store(epee::serialization::portable_storage& dest, epee::serialization::section* hparent) const + { + const tor_serialized out{std::string{host_}, port_}; + return out.store(dest, hparent); + } + + tor_address::tor_address(const tor_address& rhs) noexcept + : port_(rhs.port_) + { + std::memcpy(host_, rhs.host_, sizeof(host_)); + } + + tor_address& tor_address::operator=(const tor_address& rhs) noexcept + { + if (this != std::addressof(rhs)) + { + port_ = rhs.port_; + std::memcpy(host_, rhs.host_, sizeof(host_)); + } + return *this; + } + + bool tor_address::is_unknown() const noexcept + { + static_assert(1 <= sizeof(host_), "host size too small"); + return host_[0] == '<'; // character is not allowed otherwise + } + + bool tor_address::equal(const tor_address& rhs) const noexcept + { + return port_ == rhs.port_ && is_same_host(rhs); + } + + bool tor_address::less(const tor_address& rhs) const noexcept + { + return std::strcmp(host_str(), rhs.host_str()) < 0 || port() < rhs.port(); + } + + bool tor_address::is_same_host(const tor_address& rhs) const noexcept + { + //! \TODO v2 and v3 should be comparable - requires base32 + return std::strcmp(host_str(), rhs.host_str()) == 0; + } + + std::string tor_address::str() const + { + const std::size_t host_length = std::strlen(host_str()); + const std::size_t port_length = + port_ == 0 ? 0 : std::numeric_limits<std::uint16_t>::digits10 + 2; + + std::string out{}; + out.reserve(host_length + port_length); + out.assign(host_str(), host_length); + + if (port_ != 0) + { + out.push_back(':'); + namespace karma = boost::spirit::karma; + karma::generate(std::back_inserter(out), karma::ushort_, port()); + } + return out; + } +} diff --git a/src/net/tor_address.h b/src/net/tor_address.h new file mode 100644 index 000000000..22d8cc119 --- /dev/null +++ b/src/net/tor_address.h @@ -0,0 +1,140 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include <boost/utility/string_ref.hpp> +#include <cstdint> +#include <string> + +#include "common/expect.h" +#include "net/enums.h" +#include "net/error.h" + +namespace epee +{ +namespace serialization +{ + class portable_storage; + struct section; +} +} + +namespace net +{ + //! Tor onion address; internal format not condensed/decoded. + class tor_address + { + std::uint16_t port_; + char host_[63]; // null-terminated + + //! Keep in private, `host.size()` has no runtime check + tor_address(boost::string_ref host, std::uint16_t port) noexcept; + + public: + //! \return Size of internal buffer for host. + static constexpr std::size_t buffer_size() noexcept { return sizeof(host_); } + + //! \return `<unknown tor host>`. + static const char* unknown_str() noexcept; + + //! An object with `port() == 0` and `host_str() == unknown_str()`. + tor_address() noexcept; + + //! \return A default constructed `tor_address` object. + static tor_address unknown() noexcept { return tor_address{}; } + + /*! + Parse `address` in onion v2 or v3 format with (i.e. x.onion:80) + with `default_port` being used iff port is not specified in + `address`. + */ + static expect<tor_address> make(boost::string_ref address, std::uint16_t default_port = 0); + + //! Load from epee p2p format, and \return false if not valid tor address + bool _load(epee::serialization::portable_storage& src, epee::serialization::section* hparent); + + //! Store in epee p2p format + bool store(epee::serialization::portable_storage& dest, epee::serialization::section* hparent) const; + + // Moves and copies are currently identical + + tor_address(const tor_address& rhs) noexcept; + ~tor_address() = default; + tor_address& operator=(const tor_address& rhs) noexcept; + + //! \return True if default constructed or via `unknown()`. + bool is_unknown() const noexcept; + + bool equal(const tor_address& rhs) const noexcept; + bool less(const tor_address& rhs) const noexcept; + + //! \return True if onion addresses are identical. + bool is_same_host(const tor_address& rhs) const noexcept; + + //! \return `x.onion` or `x.onion:z` if `port() != 0`. + std::string str() const; + + //! \return Null-terminated `x.onion` value or `unknown_str()`. + const char* host_str() const noexcept { return host_; } + + //! \return Port value or `0` if unspecified. + std::uint16_t port() const noexcept { return port_; } + + static constexpr bool is_loopback() noexcept { return false; } + static constexpr bool is_local() noexcept { return false; } + + static constexpr epee::net_utils::address_type get_type_id() noexcept + { + return epee::net_utils::address_type::tor; + } + + static constexpr epee::net_utils::zone get_zone() noexcept + { + return epee::net_utils::zone::tor; + } + + //! \return `!is_unknown()`. + bool is_blockable() const noexcept { return !is_unknown(); } + }; + + inline bool operator==(const tor_address& lhs, const tor_address& rhs) noexcept + { + return lhs.equal(rhs); + } + + inline bool operator!=(const tor_address& lhs, const tor_address& rhs) noexcept + { + return !lhs.equal(rhs); + } + + inline bool operator<(const tor_address& lhs, const tor_address& rhs) noexcept + { + return lhs.less(rhs); + } +} // net diff --git a/src/p2p/CMakeLists.txt b/src/p2p/CMakeLists.txt index 9b924907e..9a1730b8a 100644 --- a/src/p2p/CMakeLists.txt +++ b/src/p2p/CMakeLists.txt @@ -40,6 +40,7 @@ target_link_libraries(p2p PUBLIC version cryptonote_core + net ${UPNP_LIBRARIES} ${Boost_CHRONO_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} diff --git a/src/p2p/net_node.cpp b/src/p2p/net_node.cpp index 7cad6e077..8639fdb3b 100644 --- a/src/p2p/net_node.cpp +++ b/src/p2p/net_node.cpp @@ -28,9 +28,79 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers +#include <boost/algorithm/string/find_iterator.hpp> +#include <boost/algorithm/string/finder.hpp> +#include <boost/chrono/duration.hpp> +#include <boost/endian/conversion.hpp> +#include <boost/optional/optional.hpp> +#include <boost/thread/future.hpp> +#include <boost/utility/string_ref.hpp> +#include <chrono> +#include <utility> + #include "common/command_line.h" #include "cryptonote_core/cryptonote_core.h" +#include "cryptonote_protocol/cryptonote_protocol_defs.h" #include "net_node.h" +#include "net/net_utils_base.h" +#include "net/socks.h" +#include "net/parse.h" +#include "net/tor_address.h" +#include "p2p/p2p_protocol_defs.h" +#include "string_tools.h" + +namespace +{ + constexpr const boost::chrono::milliseconds future_poll_interval{500}; + constexpr const std::chrono::seconds tor_connect_timeout{P2P_DEFAULT_TOR_CONNECT_TIMEOUT}; + + std::int64_t get_max_connections(const boost::iterator_range<boost::string_ref::const_iterator> value) noexcept + { + // -1 is default, 0 is error + if (value.empty()) + return -1; + + std::uint32_t out = 0; + if (epee::string_tools::get_xtype_from_string(out, std::string{value.begin(), value.end()})) + return out; + return 0; + } + + template<typename T> + epee::net_utils::network_address get_address(const boost::string_ref value) + { + expect<T> address = T::make(value); + if (!address) + { + MERROR( + "Failed to parse " << epee::net_utils::zone_to_string(T::get_zone()) << " address \"" << value << "\": " << address.error().message() + ); + return {}; + } + return {std::move(*address)}; + } + + bool start_socks(std::shared_ptr<net::socks::client> client, const boost::asio::ip::tcp::endpoint& proxy, const epee::net_utils::network_address& remote) + { + CHECK_AND_ASSERT_MES(client != nullptr, false, "Unexpected null client"); + + bool set = false; + switch (remote.get_type_id()) + { + case net::tor_address::get_type_id(): + set = client->set_connect_command(remote.as<net::tor_address>()); + break; + default: + MERROR("Unsupported network address in socks_connect"); + return false; + } + + const bool sent = + set && net::socks::client::connect_and_send(std::move(client), proxy); + CHECK_AND_ASSERT_MES(sent, false, "Unexpected failure to init socks client"); + return true; + } +} namespace nodetool { @@ -55,6 +125,8 @@ namespace nodetool const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_add_exclusive_node = {"add-exclusive-node", "Specify list of peers to connect to only." " If this option is given the options add-priority-node and seed-node are ignored"}; const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_seed_node = {"seed-node", "Connect to a node to retrieve peer addresses, and disconnect"}; + const command_line::arg_descriptor<std::vector<std::string> > arg_proxy = {"proxy", "<network-type>,<socks-ip:port>[,max_connections] i.e. \"tor,127.0.0.1:9050,100\""}; + const command_line::arg_descriptor<std::vector<std::string> > arg_anonymous_inbound = {"anonymous-inbound", "<hidden-service-address>,<[bind-ip:]port>[,max_connections] i.e. \"x.onion,127.0.0.1:18083,100\""}; const command_line::arg_descriptor<bool> arg_p2p_hide_my_port = {"hide-my-port", "Do not announce yourself as peerlist candidate", false, true}; const command_line::arg_descriptor<bool> arg_no_igd = {"no-igd", "Disable UPnP port mapping"}; @@ -67,4 +139,196 @@ namespace nodetool const command_line::arg_descriptor<int64_t> arg_limit_rate = {"limit-rate", "set limit-rate [kB/s]", -1}; const command_line::arg_descriptor<bool> arg_save_graph = {"save-graph", "Save data for dr monero", false}; + + boost::optional<std::vector<proxy>> get_proxies(boost::program_options::variables_map const& vm) + { + namespace ip = boost::asio::ip; + + std::vector<proxy> proxies{}; + + const std::vector<std::string> args = command_line::get_arg(vm, arg_proxy); + proxies.reserve(args.size()); + + for (const boost::string_ref arg : args) + { + proxies.emplace_back(); + + auto next = boost::algorithm::make_split_iterator(arg, boost::algorithm::first_finder(",")); + CHECK_AND_ASSERT_MES(!next.eof() && !next->empty(), boost::none, "No network type for --" << arg_proxy.name); + const boost::string_ref zone{next->begin(), next->size()}; + + ++next; + CHECK_AND_ASSERT_MES(!next.eof() && !next->empty(), boost::none, "No ipv4:port given for --" << arg_proxy.name); + const boost::string_ref proxy{next->begin(), next->size()}; + + ++next; + if (!next.eof()) + { + proxies.back().max_connections = get_max_connections(*next); + if (proxies.back().max_connections == 0) + { + MERROR("Invalid max connections given to --" << arg_proxy.name); + return boost::none; + } + } + + switch (epee::net_utils::zone_from_string(zone)) + { + case epee::net_utils::zone::tor: + proxies.back().zone = epee::net_utils::zone::tor; + break; + default: + MERROR("Invalid network for --" << arg_proxy.name); + return boost::none; + } + + std::uint32_t ip = 0; + std::uint16_t port = 0; + if (!epee::string_tools::parse_peer_from_string(ip, port, std::string{proxy}) || port == 0) + { + MERROR("Invalid ipv4:port given for --" << arg_proxy.name); + return boost::none; + } + proxies.back().address = ip::tcp::endpoint{ip::address_v4{boost::endian::native_to_big(ip)}, port}; + } + + return proxies; + } + + boost::optional<std::vector<anonymous_inbound>> get_anonymous_inbounds(boost::program_options::variables_map const& vm) + { + std::vector<anonymous_inbound> inbounds{}; + + const std::vector<std::string> args = command_line::get_arg(vm, arg_anonymous_inbound); + inbounds.reserve(args.size()); + + for (const boost::string_ref arg : args) + { + inbounds.emplace_back(); + + auto next = boost::algorithm::make_split_iterator(arg, boost::algorithm::first_finder(",")); + CHECK_AND_ASSERT_MES(!next.eof() && !next->empty(), boost::none, "No inbound address for --" << arg_anonymous_inbound.name); + const boost::string_ref address{next->begin(), next->size()}; + + ++next; + CHECK_AND_ASSERT_MES(!next.eof() && !next->empty(), boost::none, "No local ipv4:port given for --" << arg_anonymous_inbound.name); + const boost::string_ref bind{next->begin(), next->size()}; + + const std::size_t colon = bind.find_first_of(':'); + CHECK_AND_ASSERT_MES(colon < bind.size(), boost::none, "No local port given for --" << arg_anonymous_inbound.name); + + ++next; + if (!next.eof()) + { + inbounds.back().max_connections = get_max_connections(*next); + if (inbounds.back().max_connections == 0) + { + MERROR("Invalid max connections given to --" << arg_proxy.name); + return boost::none; + } + } + + expect<epee::net_utils::network_address> our_address = net::get_network_address(address, 0); + switch (our_address ? our_address->get_type_id() : epee::net_utils::address_type::invalid) + { + case net::tor_address::get_type_id(): + inbounds.back().our_address = std::move(*our_address); + inbounds.back().default_remote = net::tor_address::unknown(); + break; + default: + MERROR("Invalid inbound address (" << address << ") for --" << arg_anonymous_inbound.name << ": " << (our_address ? "invalid type" : our_address.error().message())); + return boost::none; + } + + // get_address returns default constructed address on error + if (inbounds.back().our_address == epee::net_utils::network_address{}) + return boost::none; + + std::uint32_t ip = 0; + std::uint16_t port = 0; + if (!epee::string_tools::parse_peer_from_string(ip, port, std::string{bind})) + { + MERROR("Invalid ipv4:port given for --" << arg_anonymous_inbound.name); + return boost::none; + } + inbounds.back().local_ip = std::string{bind.substr(0, colon)}; + inbounds.back().local_port = std::string{bind.substr(colon + 1)}; + } + + return inbounds; + } + + bool is_filtered_command(const epee::net_utils::network_address& address, int command) + { + switch (command) + { + case nodetool::COMMAND_HANDSHAKE_T<cryptonote::CORE_SYNC_DATA>::ID: + case nodetool::COMMAND_TIMED_SYNC_T<cryptonote::CORE_SYNC_DATA>::ID: + case cryptonote::NOTIFY_NEW_TRANSACTIONS::ID: + return false; + default: + break; + } + + if (address.get_zone() == epee::net_utils::zone::public_) + return false; + + MWARNING("Filtered command (#" << command << ") to/from " << address.str()); + return true; + } + + boost::optional<boost::asio::ip::tcp::socket> + socks_connect_internal(const std::atomic<bool>& stop_signal, boost::asio::io_service& service, const boost::asio::ip::tcp::endpoint& proxy, const epee::net_utils::network_address& remote) + { + using socket_type = net::socks::client::stream_type::socket; + using client_result = std::pair<boost::system::error_code, socket_type>; + + struct notify + { + boost::promise<client_result> socks_promise; + + void operator()(boost::system::error_code error, socket_type&& sock) + { + socks_promise.set_value(std::make_pair(error, std::move(sock))); + } + }; + + boost::unique_future<client_result> socks_result{}; + { + boost::promise<client_result> socks_promise{}; + socks_result = socks_promise.get_future(); + + auto client = net::socks::make_connect_client( + boost::asio::ip::tcp::socket{service}, net::socks::version::v4a, notify{std::move(socks_promise)} + ); + if (!start_socks(std::move(client), proxy, remote)) + return boost::none; + } + + const auto start = std::chrono::steady_clock::now(); + while (socks_result.wait_for(future_poll_interval) == boost::future_status::timeout) + { + if (tor_connect_timeout < std::chrono::steady_clock::now() - start) + { + MERROR("Timeout on socks connect (" << proxy << " to " << remote.str() << ")"); + return boost::none; + } + + if (stop_signal) + return boost::none; + } + + try + { + auto result = socks_result.get(); + if (!result.first) + return {std::move(result.second)}; + + MERROR("Failed to make socks connection to " << remote.str() << " (via " << proxy << "): " << result.first.message()); + } + catch (boost::broken_promise const&) + {} + + return boost::none; + } } diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h index 0ef2dbb30..58e3c8857 100644 --- a/src/p2p/net_node.h +++ b/src/p2p/net_node.h @@ -29,12 +29,18 @@ // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers #pragma once +#include <array> +#include <atomic> +#include <boost/asio/io_service.hpp> +#include <boost/asio/ip/tcp.hpp> #include <boost/thread.hpp> +#include <boost/optional/optional_fwd.hpp> #include <boost/program_options/options_description.hpp> #include <boost/program_options/variables_map.hpp> -#include <boost/serialization/version.hpp> #include <boost/uuid/uuid.hpp> -#include <boost/serialization/map.hpp> +#include <functional> +#include <utility> +#include <vector> #include "cryptonote_config.h" #include "warnings.h" @@ -46,6 +52,8 @@ #include "net_peerlist.h" #include "math_helper.h" #include "net_node_common.h" +#include "net/enums.h" +#include "net/fwd.h" #include "common/command_line.h" PUSH_WARNINGS @@ -53,6 +61,47 @@ DISABLE_VS_WARNINGS(4355) namespace nodetool { + struct proxy + { + proxy() + : max_connections(-1), + address(), + zone(epee::net_utils::zone::invalid) + {} + + std::int64_t max_connections; + boost::asio::ip::tcp::endpoint address; + epee::net_utils::zone zone; + }; + + struct anonymous_inbound + { + anonymous_inbound() + : max_connections(-1), + local_ip(), + local_port(), + our_address(), + default_remote() + {} + + std::int64_t max_connections; + std::string local_ip; + std::string local_port; + epee::net_utils::network_address our_address; + epee::net_utils::network_address default_remote; + }; + + boost::optional<std::vector<proxy>> get_proxies(const boost::program_options::variables_map& vm); + boost::optional<std::vector<anonymous_inbound>> get_anonymous_inbounds(const boost::program_options::variables_map& vm); + + //! \return True if `commnd` is filtered (ignored/dropped) for `address` + bool is_filtered_command(epee::net_utils::network_address const& address, int command); + + // hides boost::future and chrono stuff from mondo template file + boost::optional<boost::asio::ip::tcp::socket> + socks_connect_internal(const std::atomic<bool>& stop_signal, boost::asio::io_service& service, const boost::asio::ip::tcp::endpoint& proxy, const epee::net_utils::network_address& remote); + + template<class base_type> struct p2p_connection_context_t: base_type //t_payload_net_handler::connection_context //public net_utils::connection_context_base { @@ -77,56 +126,132 @@ namespace nodetool typedef COMMAND_HANDSHAKE_T<typename t_payload_net_handler::payload_type> COMMAND_HANDSHAKE; typedef COMMAND_TIMED_SYNC_T<typename t_payload_net_handler::payload_type> COMMAND_TIMED_SYNC; + typedef epee::net_utils::boosted_tcp_server<epee::levin::async_protocol_handler<p2p_connection_context>> net_server; + + struct network_zone; + using connect_func = boost::optional<p2p_connection_context>(network_zone&, epee::net_utils::network_address const&, epee::net_utils::ssl_support_t); + + struct config + { + config() + : m_net_config(), + m_peer_id(crypto::rand<uint64_t>()), + m_support_flags(0) + {} + + network_config m_net_config; + uint64_t m_peer_id; + uint32_t m_support_flags; + }; + + struct network_zone + { + network_zone() + : m_connect(nullptr), + m_net_server(epee::net_utils::e_connection_type_P2P), + m_bind_ip(), + m_port(), + m_our_address(), + m_peerlist(), + m_config{}, + m_proxy_address(), + m_current_number_of_out_peers(0), + m_current_number_of_in_peers(0), + m_can_pingback(false) + { + set_config_defaults(); + } + + network_zone(boost::asio::io_service& public_service) + : m_connect(nullptr), + m_net_server(public_service, epee::net_utils::e_connection_type_P2P), + m_bind_ip(), + m_port(), + m_our_address(), + m_peerlist(), + m_config{}, + m_proxy_address(), + m_current_number_of_out_peers(0), + m_current_number_of_in_peers(0), + m_can_pingback(false) + { + set_config_defaults(); + } + + connect_func* m_connect; + net_server m_net_server; + std::string m_bind_ip; + std::string m_port; + epee::net_utils::network_address m_our_address; // in anonymity networks + peerlist_manager m_peerlist; + config m_config; + boost::asio::ip::tcp::endpoint m_proxy_address; + std::atomic<unsigned int> m_current_number_of_out_peers; + std::atomic<unsigned int> m_current_number_of_in_peers; + bool m_can_pingback; + + private: + void set_config_defaults() noexcept + { + // at this moment we have a hardcoded config + m_config.m_net_config.handshake_interval = P2P_DEFAULT_HANDSHAKE_INTERVAL; + m_config.m_net_config.packet_max_size = P2P_DEFAULT_PACKET_MAX_SIZE; + m_config.m_net_config.config_id = 0; + m_config.m_net_config.connection_timeout = P2P_DEFAULT_CONNECTION_TIMEOUT; + m_config.m_net_config.ping_connection_timeout = P2P_DEFAULT_PING_CONNECTION_TIMEOUT; + m_config.m_net_config.send_peerlist_sz = P2P_DEFAULT_PEERS_IN_HANDSHAKE; + m_config.m_support_flags = 0; // only set in public zone + } + }; + public: typedef t_payload_net_handler payload_net_handler; node_server(t_payload_net_handler& payload_handler) - :m_payload_handler(payload_handler), - m_current_number_of_out_peers(0), - m_current_number_of_in_peers(0), - m_allow_local_ip(false), - m_hide_my_port(false), - m_no_igd(false), - m_offline(false), - m_save_graph(false), - is_closing(false), - m_net_server( epee::net_utils::e_connection_type_P2P ) // this is a P2P connection of the main p2p node server, because this is class node_server<> - {} - virtual ~node_server() + : m_payload_handler(payload_handler), + m_external_port(0), + m_allow_local_ip(false), + m_hide_my_port(false), + m_no_igd(false), + m_offline(false), + m_save_graph(false), + is_closing(false), + m_network_id() {} + virtual ~node_server(); static void init_options(boost::program_options::options_description& desc); bool run(); + network_zone& add_zone(epee::net_utils::zone zone); bool init(const boost::program_options::variables_map& vm); bool deinit(); bool send_stop_signal(); uint32_t get_this_peer_port(){return m_listening_port;} t_payload_net_handler& get_payload_object(); - template <class Archive, class t_version_type> - void serialize(Archive &a, const t_version_type ver) - { - a & m_peerlist; - if (ver == 0) - { - // from v1, we do not store the peer id anymore - peerid_type peer_id = AUTO_VAL_INIT (peer_id); - a & peer_id; - } - } // debug functions bool log_peerlist(); bool log_connections(); - virtual uint64_t get_connections_count(); - size_t get_outgoing_connections_count(); - size_t get_incoming_connections_count(); - peerlist_manager& get_peerlist_manager(){return m_peerlist;} - void delete_out_connections(size_t count); - void delete_in_connections(size_t count); + + // These functions only return information for the "public" zone + virtual uint64_t get_public_connections_count(); + size_t get_public_outgoing_connections_count(); + size_t get_public_white_peers_count(); + size_t get_public_gray_peers_count(); + void get_public_peerlist(std::vector<peerlist_entry>& gray, std::vector<peerlist_entry>& white); + size_t get_zone_count() const { return m_network_zones.size(); } + + void change_max_out_public_peers(size_t count); + void change_max_in_public_peers(size_t count); virtual bool block_host(const epee::net_utils::network_address &adress, time_t seconds = P2P_IP_BLOCKTIME); virtual bool unblock_host(const epee::net_utils::network_address &address); virtual std::map<std::string, time_t> get_blocked_hosts() { CRITICAL_REGION_LOCAL(m_blocked_hosts_lock); return m_blocked_hosts; } + + virtual void add_used_stripe_peer(const typename t_payload_net_handler::connection_context &context); + virtual void remove_used_stripe_peer(const typename t_payload_net_handler::connection_context &context); + virtual void clear_used_stripe_peers(); + private: const std::vector<std::string> m_seed_nodes_list = { "seeds.moneroseeds.se" @@ -144,6 +269,9 @@ namespace nodetool CHAIN_LEVIN_NOTIFY_MAP2(p2p_connection_context); //move levin_commands_handler interface notify(...) callbacks into nothing BEGIN_INVOKE_MAP2(node_server) + if (is_filtered_command(context.m_remote_address, command)) + return LEVIN_ERROR_CONNECTION_HANDLER_NOT_DEFINED; + HANDLE_INVOKE_T2(COMMAND_HANDSHAKE, &node_server::handle_handshake) HANDLE_INVOKE_T2(COMMAND_TIMED_SYNC, &node_server::handle_timed_sync) HANDLE_INVOKE_T2(COMMAND_PING, &node_server::handle_ping) @@ -172,7 +300,7 @@ namespace nodetool bool make_default_peer_id(); bool make_default_config(); bool store_config(); - bool check_trust(const proof_of_trust& tr); + bool check_trust(const proof_of_trust& tr, epee::net_utils::zone zone_type); //----------------- levin_commands_handler ------------------------------------------------------------- @@ -180,8 +308,7 @@ namespace nodetool virtual void on_connection_close(p2p_connection_context& context); virtual void callback(p2p_connection_context& context); //----------------- i_p2p_endpoint ------------------------------------------------------------- - virtual bool relay_notify_to_list(int command, const epee::span<const uint8_t> data_buff, const std::list<boost::uuids::uuid> &connections); - virtual bool relay_notify_to_all(int command, const epee::span<const uint8_t> data_buff, const epee::net_utils::connection_context_base& context); + virtual bool relay_notify_to_list(int command, const epee::span<const uint8_t> data_buff, std::vector<std::pair<epee::net_utils::zone, boost::uuids::uuid>> connections); virtual bool invoke_command_to_peer(int command, const epee::span<const uint8_t> req_buff, std::string& resp_buff, const epee::net_utils::connection_context_base& context); virtual bool invoke_notify_to_peer(int command, const epee::span<const uint8_t> req_buff, const epee::net_utils::connection_context_base& context); virtual bool drop_connection(const epee::net_utils::connection_context_base& context); @@ -198,7 +325,7 @@ namespace nodetool ); bool idle_worker(); bool handle_remote_peerlist(const std::vector<peerlist_entry>& peerlist, time_t local_time, const epee::net_utils::connection_context_base& context); - bool get_local_node_data(basic_node_data& node_data); + bool get_local_node_data(basic_node_data& node_data, const network_zone& zone); //bool get_local_handshake_data(handshake_data& hshd); bool merge_peerlist_with_local(const std::vector<peerlist_entry>& bs); @@ -210,7 +337,7 @@ namespace nodetool bool do_peer_timed_sync(const epee::net_utils::connection_context_base& context, peerid_type peer_id); bool make_new_connection_from_anchor_peerlist(const std::vector<anchor_peerlist_entry>& anchor_peerlist); - bool make_new_connection_from_peerlist(bool use_white_list); + bool make_new_connection_from_peerlist(network_zone& zone, bool use_white_list); bool try_to_connect_and_handshake_with_new_peer(const epee::net_utils::network_address& na, bool just_take_peerlist = false, uint64_t last_seen_stamp = 0, PeerType peer_type = white, uint64_t first_seen_stamp = 0); size_t get_random_index_with_fixed_probability(size_t max_index); bool is_peer_used(const peerlist_entry& peer); @@ -221,7 +348,7 @@ namespace nodetool template<class t_callback> bool try_ping(basic_node_data& node_data, p2p_connection_context& context, const t_callback &cb); bool try_get_support_flags(const p2p_connection_context& context, std::function<void(p2p_connection_context&, const uint32_t&)> f); - bool make_expected_connections_count(PeerType peer_type, size_t expected_connections); + bool make_expected_connections_count(network_zone& zone, PeerType peer_type, size_t expected_connections); void cache_connect_fail_info(const epee::net_utils::network_address& addr); bool is_addr_recently_failed(const epee::net_utils::network_address& addr); bool is_priority_node(const epee::net_utils::network_address& na); @@ -234,8 +361,8 @@ namespace nodetool template <class Container> bool parse_peers_and_add_to_container(const boost::program_options::variables_map& vm, const command_line::arg_descriptor<std::vector<std::string> > & arg, Container& container); - bool set_max_out_peers(const boost::program_options::variables_map& vm, int64_t max); - bool set_max_in_peers(const boost::program_options::variables_map& vm, int64_t max); + bool set_max_out_peers(network_zone& zone, int64_t max); + bool set_max_in_peers(network_zone& zone, int64_t max); bool set_tos_flag(const boost::program_options::variables_map& vm, int limit); bool set_rate_up_limit(const boost::program_options::variables_map& vm, int64_t limit); @@ -243,6 +370,11 @@ namespace nodetool bool set_rate_limit(const boost::program_options::variables_map& vm, int64_t limit); bool has_too_many_connections(const epee::net_utils::network_address &address); + uint64_t get_connections_count(); + size_t get_incoming_connections_count(); + size_t get_incoming_connections_count(network_zone&); + size_t get_outgoing_connections_count(); + size_t get_outgoing_connections_count(network_zone&); bool check_connection_and_handshake_with_peer(const epee::net_utils::network_address& na, uint64_t last_seen_stamp); bool gray_peerlist_housekeeping(); @@ -260,25 +392,7 @@ namespace nodetool std::string print_connections_container(); - typedef epee::net_utils::boosted_tcp_server<epee::levin::async_protocol_handler<p2p_connection_context> > net_server; - - struct config - { - network_config m_net_config; - uint64_t m_peer_id; - uint32_t m_support_flags; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(m_net_config) - KV_SERIALIZE(m_peer_id) - KV_SERIALIZE(m_support_flags) - END_KV_SERIALIZE_MAP() - }; - public: - config m_config; // TODO was private, add getters? - std::atomic<unsigned int> m_current_number_of_out_peers; - std::atomic<unsigned int> m_current_number_of_in_peers; void set_save_graph(bool save_graph) { @@ -292,7 +406,6 @@ namespace nodetool bool m_first_connection_maker_call; uint32_t m_listening_port; uint32_t m_external_port; - uint32_t m_ip_address; bool m_allow_local_ip; bool m_hide_my_port; bool m_no_igd; @@ -304,7 +417,7 @@ namespace nodetool //connections_indexed_container m_connections; t_payload_net_handler& m_payload_handler; - peerlist_manager m_peerlist; + peerlist_storage m_peerlist_storage; epee::math_helper::once_a_time_seconds<P2P_DEFAULT_HANDSHAKE_INTERVAL> m_peer_handshake_idle_maker_interval; epee::math_helper::once_a_time_seconds<1> m_connections_maker_interval; @@ -312,8 +425,6 @@ namespace nodetool epee::math_helper::once_a_time_seconds<60> m_gray_peerlist_housekeeping_interval; epee::math_helper::once_a_time_seconds<3600, false> m_incoming_connections_interval; - std::string m_bind_ip; - std::string m_port; #ifdef ALLOW_DEBUG_COMMANDS uint64_t m_last_stat_request_time; #endif @@ -321,11 +432,22 @@ namespace nodetool std::vector<epee::net_utils::network_address> m_exclusive_peers; std::vector<epee::net_utils::network_address> m_seed_nodes; bool m_fallback_seed_nodes_added; - std::list<nodetool::peerlist_entry> m_command_line_peers; + std::vector<nodetool::peerlist_entry> m_command_line_peers; uint64_t m_peer_livetime; //keep connections to initiate some interactions - net_server m_net_server; - boost::uuids::uuid m_network_id; + + + static boost::optional<p2p_connection_context> public_connect(network_zone&, epee::net_utils::network_address const&, epee::net_utils::ssl_support_t); + static boost::optional<p2p_connection_context> socks_connect(network_zone&, epee::net_utils::network_address const&, epee::net_utils::ssl_support_t); + + + /* A `std::map` provides constant iterators and key/value pointers even with + inserts/erases to _other_ elements. This makes the configuration step easier + since references can safely be stored on the stack. Do not insert/erase + after configuration and before destruction, lock safety would need to be + added. `std::map::operator[]` WILL insert! */ + std::map<epee::net_utils::zone, network_zone> m_network_zones; + std::map<epee::net_utils::network_address, time_t> m_conn_fails_cache; epee::critical_section m_conn_fails_cache_lock; @@ -336,7 +458,13 @@ namespace nodetool epee::critical_section m_host_fails_score_lock; std::map<std::string, uint64_t> m_host_fails_score; + boost::mutex m_used_stripe_peers_mutex; + std::array<std::list<epee::net_utils::network_address>, 1 << CRYPTONOTE_PRUNING_LOG_STRIPES> m_used_stripe_peers; + + boost::uuids::uuid m_network_id; cryptonote::network_type m_nettype; + + epee::net_utils::ssl_support_t m_ssl_support; }; const int64_t default_limit_up = P2P_DEFAULT_LIMIT_RATE_UP; // kB/s @@ -349,6 +477,8 @@ namespace nodetool extern const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_add_priority_node; extern const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_add_exclusive_node; extern const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_seed_node; + extern const command_line::arg_descriptor<std::vector<std::string> > arg_proxy; + extern const command_line::arg_descriptor<std::vector<std::string> > arg_anonymous_inbound; extern const command_line::arg_descriptor<bool> arg_p2p_hide_my_port; extern const command_line::arg_descriptor<bool> arg_no_igd; @@ -365,3 +495,4 @@ namespace nodetool } POP_WARNINGS + diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index 25ac1ba18..e3d804086 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -31,24 +31,34 @@ // IP blocking adapted from Boolberry #include <algorithm> +#include <boost/bind.hpp> #include <boost/date_time/posix_time/posix_time.hpp> +#include <boost/filesystem/operations.hpp> +#include <boost/optional/optional.hpp> #include <boost/thread/thread.hpp> #include <boost/uuid/uuid_io.hpp> -#include <boost/bind.hpp> #include <atomic> +#include <functional> +#include <limits> +#include <memory> +#include <tuple> +#include <vector> #include "version.h" #include "string_tools.h" #include "common/util.h" #include "common/dns_utils.h" +#include "common/pruning.h" +#include "net/error.h" #include "net/net_helper.h" #include "math_helper.h" +#include "misc_log_ex.h" #include "p2p_protocol_defs.h" -#include "net_peerlist_boost_serialization.h" #include "net/local_ip.h" #include "crypto/crypto.h" #include "storages/levin_abstract_invoke2.h" #include "cryptonote_core/cryptonote_core.h" +#include "net/parse.h" #include <miniupnp/miniupnpc/miniupnpc.h> #include <miniupnp/miniupnpc/upnpcommands.h> @@ -63,6 +73,20 @@ namespace nodetool { + template<class t_payload_net_handler> + node_server<t_payload_net_handler>::~node_server() + { + // tcp server uses io_service in destructor, and every zone uses + // io_service from public zone. + for (auto current = m_network_zones.begin(); current != m_network_zones.end(); /* below */) + { + if (current->first != epee::net_utils::zone::public_) + current = m_network_zones.erase(current); + else + ++current; + } + } + //----------------------------------------------------------------------------------- inline bool append_net_address(std::vector<epee::net_utils::network_address> & seed_nodes, std::string const & addr, uint16_t default_port); //----------------------------------------------------------------------------------- template<class t_payload_net_handler> @@ -76,6 +100,8 @@ namespace nodetool command_line::add_arg(desc, arg_p2p_add_priority_node); command_line::add_arg(desc, arg_p2p_add_exclusive_node); command_line::add_arg(desc, arg_p2p_seed_node); + command_line::add_arg(desc, arg_proxy); + command_line::add_arg(desc, arg_anonymous_inbound); command_line::add_arg(desc, arg_p2p_hide_my_port); command_line::add_arg(desc, arg_no_igd); command_line::add_arg(desc, arg_out_peers); @@ -90,62 +116,14 @@ namespace nodetool template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::init_config() { - // TRY_ENTRY(); - std::string state_file_path = m_config_folder + "/" + P2P_NET_DATA_FILENAME; - std::ifstream p2p_data; - p2p_data.open( state_file_path , std::ios_base::binary | std::ios_base::in); - if(!p2p_data.fail()) - { - try - { - // first try reading in portable mode - boost::archive::portable_binary_iarchive a(p2p_data); - a >> *this; - } - catch (...) - { - // if failed, try reading in unportable mode - boost::filesystem::copy_file(state_file_path, state_file_path + ".unportable", boost::filesystem::copy_option::overwrite_if_exists); - p2p_data.close(); - p2p_data.open( state_file_path , std::ios_base::binary | std::ios_base::in); - if(!p2p_data.fail()) - { - try - { - boost::archive::binary_iarchive a(p2p_data); - a >> *this; - } - catch (const std::exception &e) - { - MWARNING("Failed to load p2p config file, falling back to default config"); - m_peerlist = peerlist_manager(); // it was probably half clobbered by the failed load - make_default_config(); - } - } - else - { - make_default_config(); - } - } - }else - { - make_default_config(); - } - - // always recreate a new peer id - make_default_peer_id(); - - //at this moment we have hardcoded config - m_config.m_net_config.handshake_interval = P2P_DEFAULT_HANDSHAKE_INTERVAL; - m_config.m_net_config.packet_max_size = P2P_DEFAULT_PACKET_MAX_SIZE; //20 MB limit - m_config.m_net_config.config_id = 0; // initial config - m_config.m_net_config.connection_timeout = P2P_DEFAULT_CONNECTION_TIMEOUT; - m_config.m_net_config.ping_connection_timeout = P2P_DEFAULT_PING_CONNECTION_TIMEOUT; - m_config.m_net_config.send_peerlist_sz = P2P_DEFAULT_PEERS_IN_HANDSHAKE; - m_config.m_support_flags = P2P_SUPPORT_FLAGS; + auto storage = peerlist_storage::open(m_config_folder + "/" + P2P_NET_DATA_FILENAME); + if (storage) + m_peerlist_storage = std::move(*storage); + m_network_zones[epee::net_utils::zone::public_].m_config.m_support_flags = P2P_SUPPORT_FLAGS; m_first_connection_maker_call = true; + CATCH_ENTRY_L0("node_server::init_config", false); return true; } @@ -153,17 +131,26 @@ namespace nodetool template<class t_payload_net_handler> void node_server<t_payload_net_handler>::for_each_connection(std::function<bool(typename t_payload_net_handler::connection_context&, peerid_type, uint32_t)> f) { - m_net_server.get_config_object().foreach_connection([&](p2p_connection_context& cntx){ - return f(cntx, cntx.peer_id, cntx.support_flags); - }); + for(auto& zone : m_network_zones) + { + zone.second.m_net_server.get_config_object().foreach_connection([&](p2p_connection_context& cntx){ + return f(cntx, cntx.peer_id, cntx.support_flags); + }); + } } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::for_connection(const boost::uuids::uuid &connection_id, std::function<bool(typename t_payload_net_handler::connection_context&, peerid_type, uint32_t)> f) { - return m_net_server.get_config_object().for_connection(connection_id, [&](p2p_connection_context& cntx){ - return f(cntx, cntx.peer_id, cntx.support_flags); - }); + for(auto& zone : m_network_zones) + { + const bool result = zone.second.m_net_server.get_config_object().for_connection(connection_id, [&](p2p_connection_context& cntx){ + return f(cntx, cntx.peer_id, cntx.support_flags); + }); + if (result) + return true; + } + return false; } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> @@ -183,36 +170,33 @@ namespace nodetool } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> - bool node_server<t_payload_net_handler>::make_default_peer_id() - { - m_config.m_peer_id = crypto::rand<uint64_t>(); - return true; - } - //----------------------------------------------------------------------------------- - template<class t_payload_net_handler> - bool node_server<t_payload_net_handler>::make_default_config() - { - return make_default_peer_id(); - } - //----------------------------------------------------------------------------------- - template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::block_host(const epee::net_utils::network_address &addr, time_t seconds) { + if(!addr.is_blockable()) + return false; + CRITICAL_REGION_LOCAL(m_blocked_hosts_lock); m_blocked_hosts[addr.host_str()] = time(nullptr) + seconds; - // drop any connection to that IP - std::list<boost::uuids::uuid> conns; - m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) + // drop any connection to that address. This should only have to look into + // the zone related to the connection, but really make sure everything is + // swept ... + std::vector<boost::uuids::uuid> conns; + for(auto& zone : m_network_zones) { - if (cntxt.m_remote_address.is_same_host(addr)) + zone.second.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) { - conns.push_back(cntxt.m_connection_id); - } - return true; - }); - for (const auto &c: conns) - m_net_server.get_config_object().close(c); + if (cntxt.m_remote_address.is_same_host(addr)) + { + conns.push_back(cntxt.m_connection_id); + } + return true; + }); + for (const auto &c: conns) + zone.second.m_net_server.get_config_object().close(c); + + conns.clear(); + } MCLOG_CYAN(el::Level::Info, "global", "Host " << addr.host_str() << " blocked."); return true; @@ -233,6 +217,9 @@ namespace nodetool template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::add_host_fail(const epee::net_utils::network_address &address) { + if(!address.is_blockable()) + return false; + CRITICAL_REGION_LOCAL(m_host_fails_score_lock); uint64_t fails = ++m_host_fails_score[address.host_str()]; MDEBUG("Host " << address.host_str() << " fail score=" << fails); @@ -247,12 +234,6 @@ namespace nodetool } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> - bool node_server<t_payload_net_handler>::parse_peer_from_string(epee::net_utils::network_address& pe, const std::string& node_addr, uint16_t default_port) - { - return epee::net_utils::create_network_address(pe, node_addr, default_port); - } - //----------------------------------------------------------------------------------- - template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::handle_command_line( const boost::program_options::variables_map& vm ) @@ -261,8 +242,11 @@ namespace nodetool bool stagenet = command_line::get_arg(vm, cryptonote::arg_stagenet_on); m_nettype = testnet ? cryptonote::TESTNET : stagenet ? cryptonote::STAGENET : cryptonote::MAINNET; - m_bind_ip = command_line::get_arg(vm, arg_p2p_bind_ip); - m_port = command_line::get_arg(vm, arg_p2p_bind_port); + network_zone& public_zone = m_network_zones[epee::net_utils::zone::public_]; + public_zone.m_connect = &public_connect; + public_zone.m_bind_ip = command_line::get_arg(vm, arg_p2p_bind_ip); + public_zone.m_port = command_line::get_arg(vm, arg_p2p_bind_port); + public_zone.m_can_pingback = true; m_external_port = command_line::get_arg(vm, arg_p2p_external_port); m_allow_local_ip = command_line::get_arg(vm, arg_p2p_allow_local_ip); m_no_igd = command_line::get_arg(vm, arg_no_igd); @@ -276,14 +260,20 @@ namespace nodetool nodetool::peerlist_entry pe = AUTO_VAL_INIT(pe); pe.id = crypto::rand<uint64_t>(); const uint16_t default_port = cryptonote::get_config(m_nettype).P2P_DEFAULT_PORT; - bool r = parse_peer_from_string(pe.adr, pr_str, default_port); - if (r) + expect<epee::net_utils::network_address> adr = net::get_network_address(pr_str, default_port); + if (adr) { - m_command_line_peers.push_back(pe); + add_zone(adr->get_zone()); + pe.adr = std::move(*adr); + m_command_line_peers.push_back(std::move(pe)); continue; } + CHECK_AND_ASSERT_MES( + adr == net::error::unsupported_address, false, "Bad address (\"" << pr_str << "\"): " << adr.error().message() + ); + std::vector<epee::net_utils::network_address> resolved_addrs; - r = append_net_address(resolved_addrs, pr_str, default_port); + bool r = append_net_address(resolved_addrs, pr_str, default_port); CHECK_AND_ASSERT_MES(r, false, "Failed to parse or resolve address from string: " << pr_str); for (const epee::net_utils::network_address& addr : resolved_addrs) { @@ -320,10 +310,13 @@ namespace nodetool if(command_line::has_arg(vm, arg_p2p_hide_my_port)) m_hide_my_port = true; - if ( !set_max_out_peers(vm, command_line::get_arg(vm, arg_out_peers) ) ) + if ( !set_max_out_peers(public_zone, command_line::get_arg(vm, arg_out_peers) ) ) return false; + else + m_payload_handler.set_max_out_peers(public_zone.m_config.m_net_config.max_out_connection_count); + - if ( !set_max_in_peers(vm, command_line::get_arg(vm, arg_in_peers) ) ) + if ( !set_max_in_peers(public_zone, command_line::get_arg(vm, arg_in_peers) ) ) return false; if ( !set_tos_flag(vm, command_line::get_arg(vm, arg_tos_flag) ) ) @@ -338,6 +331,58 @@ namespace nodetool if ( !set_rate_limit(vm, command_line::get_arg(vm, arg_limit_rate) ) ) return false; + + auto proxies = get_proxies(vm); + if (!proxies) + return false; + + for (auto& proxy : *proxies) + { + network_zone& zone = add_zone(proxy.zone); + if (zone.m_connect != nullptr) + { + MERROR("Listed --" << arg_proxy.name << " twice with " << epee::net_utils::zone_to_string(proxy.zone)); + return false; + } + zone.m_connect = &socks_connect; + zone.m_proxy_address = std::move(proxy.address); + + if (!set_max_out_peers(zone, proxy.max_connections)) + return false; + } + + for (const auto& zone : m_network_zones) + { + if (zone.second.m_connect == nullptr) + { + MERROR("Set outgoing peer for " << epee::net_utils::zone_to_string(zone.first) << " but did not set --" << arg_proxy.name); + return false; + } + } + + auto inbounds = get_anonymous_inbounds(vm); + if (!inbounds) + return false; + + for (auto& inbound : *inbounds) + { + network_zone& zone = add_zone(inbound.our_address.get_zone()); + + if (!zone.m_bind_ip.empty()) + { + MERROR("Listed --" << arg_anonymous_inbound.name << " twice with " << epee::net_utils::zone_to_string(inbound.our_address.get_zone()) << " network"); + return false; + } + + zone.m_bind_ip = std::move(inbound.local_ip); + zone.m_port = std::move(inbound.local_port); + zone.m_net_server.set_default_remote(std::move(inbound.default_remote)); + zone.m_our_address = std::move(inbound.our_address); + + if (!set_max_in_peers(zone, inbound.max_connections)) + return false; + } + return true; } //----------------------------------------------------------------------------------- @@ -419,7 +464,17 @@ namespace nodetool } return full_addrs; } + //----------------------------------------------------------------------------------- + template<class t_payload_net_handler> + typename node_server<t_payload_net_handler>::network_zone& node_server<t_payload_net_handler>::add_zone(const epee::net_utils::zone zone) + { + const auto zone_ = m_network_zones.lower_bound(zone); + if (zone_ != m_network_zones.end() && zone_->first == zone) + return zone_->second; + network_zone& public_zone = m_network_zones[epee::net_utils::zone::public_]; + return m_network_zones.emplace_hint(zone_, std::piecewise_construct, std::make_tuple(zone), std::tie(public_zone.m_net_server.get_io_service()))->second; + } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::init(const boost::program_options::variables_map& vm) @@ -536,45 +591,82 @@ namespace nodetool MDEBUG("Number of seed nodes: " << m_seed_nodes.size()); m_config_folder = command_line::get_arg(vm, cryptonote::arg_data_dir); + network_zone& public_zone = m_network_zones.at(epee::net_utils::zone::public_); - if ((m_nettype == cryptonote::MAINNET && m_port != std::to_string(::config::P2P_DEFAULT_PORT)) - || (m_nettype == cryptonote::TESTNET && m_port != std::to_string(::config::testnet::P2P_DEFAULT_PORT)) - || (m_nettype == cryptonote::STAGENET && m_port != std::to_string(::config::stagenet::P2P_DEFAULT_PORT))) { - m_config_folder = m_config_folder + "/" + m_port; + if ((m_nettype == cryptonote::MAINNET && public_zone.m_port != std::to_string(::config::P2P_DEFAULT_PORT)) + || (m_nettype == cryptonote::TESTNET && public_zone.m_port != std::to_string(::config::testnet::P2P_DEFAULT_PORT)) + || (m_nettype == cryptonote::STAGENET && public_zone.m_port != std::to_string(::config::stagenet::P2P_DEFAULT_PORT))) { + m_config_folder = m_config_folder + "/" + public_zone.m_port; } res = init_config(); CHECK_AND_ASSERT_MES(res, false, "Failed to init config."); - res = m_peerlist.init(m_allow_local_ip); - CHECK_AND_ASSERT_MES(res, false, "Failed to init peerlist."); + for (auto& zone : m_network_zones) + { + res = zone.second.m_peerlist.init(m_peerlist_storage.take_zone(zone.first), m_allow_local_ip); + CHECK_AND_ASSERT_MES(res, false, "Failed to init peerlist."); + } + for(const auto& p: m_command_line_peers) + m_network_zones.at(p.adr.get_zone()).m_peerlist.append_with_peer_white(p); - for(auto& p: m_command_line_peers) - m_peerlist.append_with_peer_white(p); +// all peers are now setup +#ifdef CRYPTONOTE_PRUNING_DEBUG_SPOOF_SEED + for (auto& zone : m_network_zones) + { + std::list<peerlist_entry> plw; + while (zone.second.m_peerlist.get_white_peers_count()) + { + plw.push_back(peerlist_entry()); + zone.second.m_peerlist.get_white_peer_by_index(plw.back(), 0); + zone.second.m_peerlist.remove_from_peer_white(plw.back()); + } + for (auto &e:plw) + zone.second.m_peerlist.append_with_peer_white(e); + + std::list<peerlist_entry> plg; + while (zone.second.m_peerlist.get_gray_peers_count()) + { + plg.push_back(peerlist_entry()); + zone.second.m_peerlist.get_gray_peer_by_index(plg.back(), 0); + zone.second.m_peerlist.remove_from_peer_gray(plg.back()); + } + for (auto &e:plg) + zone.second.m_peerlist.append_with_peer_gray(e); + } +#endif //only in case if we really sure that we have external visible ip m_have_address = true; - m_ip_address = 0; m_last_stat_request_time = 0; //configure self - m_net_server.set_threads_prefix("P2P"); - m_net_server.get_config_object().set_handler(this); - m_net_server.get_config_object().m_invoke_timeout = P2P_DEFAULT_INVOKE_TIMEOUT; - m_net_server.set_connection_filter(this); + + public_zone.m_net_server.set_threads_prefix("P2P"); // all zones use these threads/asio::io_service // from here onwards, it's online stuff if (m_offline) return res; //try to bind - MINFO("Binding on " << m_bind_ip << ":" << m_port); - res = m_net_server.init_server(m_port, m_bind_ip); - CHECK_AND_ASSERT_MES(res, false, "Failed to bind server"); + m_ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_disabled; + for (auto& zone : m_network_zones) + { + zone.second.m_net_server.get_config_object().set_handler(this); + zone.second.m_net_server.get_config_object().m_invoke_timeout = P2P_DEFAULT_INVOKE_TIMEOUT; + + if (!zone.second.m_bind_ip.empty()) + { + zone.second.m_net_server.set_connection_filter(this); + MINFO("Binding on " << zone.second.m_bind_ip << ":" << zone.second.m_port); + res = zone.second.m_net_server.init_server(zone.second.m_port, zone.second.m_bind_ip, epee::net_utils::ssl_support_t::e_ssl_support_disabled); + CHECK_AND_ASSERT_MES(res, false, "Failed to bind server"); + } + } - m_listening_port = m_net_server.get_binded_port(); - MLOG_GREEN(el::Level::Info, "Net service bound to " << m_bind_ip << ":" << m_listening_port); + m_listening_port = public_zone.m_net_server.get_binded_port(); + MLOG_GREEN(el::Level::Info, "Net service bound to " << public_zone.m_bind_ip << ":" << m_listening_port); if(m_external_port) MDEBUG("External port defined as " << m_external_port); @@ -598,44 +690,45 @@ namespace nodetool mPeersLoggerThread.reset(new boost::thread([&]() { _note("Thread monitor number of peers - start"); - while (!is_closing && !m_net_server.is_stop_signal_sent()) + const network_zone& public_zone = m_network_zones.at(epee::net_utils::zone::public_); + while (!is_closing && !public_zone.m_net_server.is_stop_signal_sent()) { // main loop of thread //number_of_peers = m_net_server.get_config_object().get_connections_count(); - unsigned int number_of_in_peers = 0; - unsigned int number_of_out_peers = 0; - m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) + for (auto& zone : m_network_zones) { - if (cntxt.m_is_income) - { - ++number_of_in_peers; - } - else + unsigned int number_of_in_peers = 0; + unsigned int number_of_out_peers = 0; + zone.second.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) { - ++number_of_out_peers; - } - return true; - }); // lambda - - m_current_number_of_in_peers = number_of_in_peers; - m_current_number_of_out_peers = number_of_out_peers; - + if (cntxt.m_is_income) + { + ++number_of_in_peers; + } + else + { + ++number_of_out_peers; + } + return true; + }); // lambda + zone.second.m_current_number_of_in_peers = number_of_in_peers; + zone.second.m_current_number_of_out_peers = number_of_out_peers; + } boost::this_thread::sleep_for(boost::chrono::seconds(1)); } // main loop of thread _note("Thread monitor number of peers - done"); })); // lambda + network_zone& public_zone = m_network_zones.at(epee::net_utils::zone::public_); + public_zone.m_net_server.add_idle_handler(boost::bind(&node_server<t_payload_net_handler>::idle_worker, this), 1000); + public_zone.m_net_server.add_idle_handler(boost::bind(&t_payload_net_handler::on_idle, &m_payload_handler), 1000); + //here you can set worker threads count int thrds_count = 10; - - m_net_server.add_idle_handler(boost::bind(&node_server<t_payload_net_handler>::idle_worker, this), 1000); - m_net_server.add_idle_handler(boost::bind(&t_payload_net_handler::on_idle, &m_payload_handler), 1000); - boost::thread::attributes attrs; attrs.set_stack_size(THREAD_STACK_SIZE); - //go to loop MINFO("Run net_service loop( " << thrds_count << " threads)..."); - if(!m_net_server.run_server(thrds_count, true, attrs)) + if(!public_zone.m_net_server.run_server(thrds_count, true, attrs)) { LOG_ERROR("Failed to run net tcp server!"); } @@ -643,23 +736,34 @@ namespace nodetool MINFO("net_service loop stopped."); return true; } - + //----------------------------------------------------------------------------------- + template<class t_payload_net_handler> + uint64_t node_server<t_payload_net_handler>::get_public_connections_count() + { + auto public_zone = m_network_zones.find(epee::net_utils::zone::public_); + if (public_zone == m_network_zones.end()) + return 0; + return public_zone->second.m_net_server.get_config_object().get_connections_count(); + } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> uint64_t node_server<t_payload_net_handler>::get_connections_count() { - return m_net_server.get_config_object().get_connections_count(); + std::uint64_t count = 0; + for (auto& zone : m_network_zones) + count += zone.second.m_net_server.get_config_object().get_connections_count(); + return count; } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::deinit() { kill(); - m_peerlist.deinit(); if (!m_offline) { - m_net_server.deinit_server(); + for(auto& zone : m_network_zones) + zone.second.m_net_server.deinit_server(); // remove UPnP port mapping if(!m_no_igd) delete_upnp_port_mapping(m_listening_port); @@ -670,28 +774,25 @@ namespace nodetool template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::store_config() { - TRY_ENTRY(); + if (!tools::create_directories_if_necessary(m_config_folder)) { - MWARNING("Failed to create data directory: " << m_config_folder); + MWARNING("Failed to create data directory \"" << m_config_folder); return false; } - std::string state_file_path = m_config_folder + "/" + P2P_NET_DATA_FILENAME; - std::ofstream p2p_data; - p2p_data.open( state_file_path , std::ios_base::binary | std::ios_base::out| std::ios::trunc); - if(p2p_data.fail()) + peerlist_types active{}; + for (auto& zone : m_network_zones) + zone.second.m_peerlist.get_peerlist(active); + + const std::string state_file_path = m_config_folder + "/" + P2P_NET_DATA_FILENAME; + if (!m_peerlist_storage.store(state_file_path, active)) { MWARNING("Failed to save config to file " << state_file_path); return false; - }; - - boost::archive::portable_binary_oarchive a(p2p_data); - a << *this; - return true; - CATCH_ENTRY_L0("blockchain_storage::save", false); - + } + CATCH_ENTRY_L0("node_server::store", false); return true; } //----------------------------------------------------------------------------------- @@ -699,37 +800,39 @@ namespace nodetool bool node_server<t_payload_net_handler>::send_stop_signal() { MDEBUG("[node] sending stop signal"); - m_net_server.send_stop_signal(); + for (auto& zone : m_network_zones) + zone.second.m_net_server.send_stop_signal(); MDEBUG("[node] Stop signal sent"); - std::list<boost::uuids::uuid> connection_ids; - m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) { - connection_ids.push_back(cntxt.m_connection_id); - return true; - }); - for (const auto &connection_id: connection_ids) - m_net_server.get_config_object().close(connection_id); - + for (auto& zone : m_network_zones) + { + std::list<boost::uuids::uuid> connection_ids; + zone.second.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) { + connection_ids.push_back(cntxt.m_connection_id); + return true; + }); + for (const auto &connection_id: connection_ids) + zone.second.m_net_server.get_config_object().close(connection_id); + } m_payload_handler.stop(); - return true; } //----------------------------------------------------------------------------------- - - template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::do_handshake_with_peer(peerid_type& pi, p2p_connection_context& context_, bool just_take_peerlist) { + network_zone& zone = m_network_zones.at(context_.m_remote_address.get_zone()); + typename COMMAND_HANDSHAKE::request arg; typename COMMAND_HANDSHAKE::response rsp; - get_local_node_data(arg.node_data); + get_local_node_data(arg.node_data, zone); m_payload_handler.get_payload_sync_data(arg.payload_data); epee::simple_event ev; std::atomic<bool> hsh_result(false); - bool r = epee::net_utils::async_invoke_remote_command2<typename COMMAND_HANDSHAKE::response>(context_.m_connection_id, COMMAND_HANDSHAKE::ID, arg, m_net_server.get_config_object(), - [this, &pi, &ev, &hsh_result, &just_take_peerlist](int code, const typename COMMAND_HANDSHAKE::response& rsp, p2p_connection_context& context) + bool r = epee::net_utils::async_invoke_remote_command2<typename COMMAND_HANDSHAKE::response>(context_.m_connection_id, COMMAND_HANDSHAKE::ID, arg, zone.m_net_server.get_config_object(), + [this, &pi, &ev, &hsh_result, &just_take_peerlist, &context_](int code, const typename COMMAND_HANDSHAKE::response& rsp, p2p_connection_context& context) { epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler([&](){ev.raise();}); @@ -762,19 +865,25 @@ namespace nodetool } pi = context.peer_id = rsp.node_data.peer_id; - m_peerlist.set_peer_just_seen(rsp.node_data.peer_id, context.m_remote_address); + m_network_zones.at(context.m_remote_address.get_zone()).m_peerlist.set_peer_just_seen(rsp.node_data.peer_id, context.m_remote_address, context.m_pruning_seed); - if(rsp.node_data.peer_id == m_config.m_peer_id) + // move + for (auto const& zone : m_network_zones) { - LOG_DEBUG_CC(context, "Connection to self detected, dropping connection"); - hsh_result = false; - return; + if(rsp.node_data.peer_id == zone.second.m_config.m_peer_id) + { + LOG_DEBUG_CC(context, "Connection to self detected, dropping connection"); + hsh_result = false; + return; + } } + LOG_INFO_CC(context, "New connection handshaked, pruning seed " << epee::string_tools::to_string_hex(context.m_pruning_seed)); LOG_DEBUG_CC(context, " COMMAND_HANDSHAKE INVOKED OK"); }else { LOG_DEBUG_CC(context, " COMMAND_HANDSHAKE(AND CLOSE) INVOKED OK"); } + context_ = context; }, P2P_DEFAULT_HANDSHAKE_INVOKE_TIMEOUT); if(r) @@ -785,7 +894,7 @@ namespace nodetool if(!hsh_result) { LOG_WARNING_CC(context_, "COMMAND_HANDSHAKE Failed"); - m_net_server.get_config_object().close(context_.m_connection_id); + m_network_zones.at(context_.m_remote_address.get_zone()).m_net_server.get_config_object().close(context_.m_connection_id); } else { @@ -804,7 +913,8 @@ namespace nodetool typename COMMAND_TIMED_SYNC::request arg = AUTO_VAL_INIT(arg); m_payload_handler.get_payload_sync_data(arg.payload_data); - bool r = epee::net_utils::async_invoke_remote_command2<typename COMMAND_TIMED_SYNC::response>(context_.m_connection_id, COMMAND_TIMED_SYNC::ID, arg, m_net_server.get_config_object(), + network_zone& zone = m_network_zones.at(context_.m_remote_address.get_zone()); + bool r = epee::net_utils::async_invoke_remote_command2<typename COMMAND_TIMED_SYNC::response>(context_.m_connection_id, COMMAND_TIMED_SYNC::ID, arg, zone.m_net_server.get_config_object(), [this](int code, const typename COMMAND_TIMED_SYNC::response& rsp, p2p_connection_context& context) { context.m_in_timedsync = false; @@ -817,11 +927,11 @@ namespace nodetool if(!handle_remote_peerlist(rsp.local_peerlist_new, rsp.local_time, context)) { LOG_WARNING_CC(context, "COMMAND_TIMED_SYNC: failed to handle_remote_peerlist(...), closing connection."); - m_net_server.get_config_object().close(context.m_connection_id ); + m_network_zones.at(context.m_remote_address.get_zone()).m_net_server.get_config_object().close(context.m_connection_id ); add_host_fail(context.m_remote_address); } if(!context.m_is_income) - m_peerlist.set_peer_just_seen(context.peer_id, context.m_remote_address); + m_network_zones.at(context.m_remote_address.get_zone()).m_peerlist.set_peer_just_seen(context.peer_id, context.m_remote_address, context.m_pruning_seed); m_payload_handler.process_payload_sync_data(rsp.payload_data, context, false); }); @@ -849,53 +959,61 @@ namespace nodetool template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::is_peer_used(const peerlist_entry& peer) { - - if(m_config.m_peer_id == peer.id) - return true;//dont make connections to ourself + for(const auto& zone : m_network_zones) + if(zone.second.m_config.m_peer_id == peer.id) + return true;//dont make connections to ourself bool used = false; - m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) + for(auto& zone : m_network_zones) { - if(cntxt.peer_id == peer.id || (!cntxt.m_is_income && peer.adr == cntxt.m_remote_address)) + zone.second.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) { - used = true; - return false;//stop enumerating - } - return true; - }); + if(cntxt.peer_id == peer.id || (!cntxt.m_is_income && peer.adr == cntxt.m_remote_address)) + { + used = true; + return false;//stop enumerating + } + return true; + }); - return used; + if(used) + return true; + } + return false; } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::is_peer_used(const anchor_peerlist_entry& peer) { - if(m_config.m_peer_id == peer.id) { - return true;//dont make connections to ourself - } - - bool used = false; - - m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) - { - if(cntxt.peer_id == peer.id || (!cntxt.m_is_income && peer.adr == cntxt.m_remote_address)) - { - used = true; - - return false;//stop enumerating + for(auto& zone : m_network_zones) { + if(zone.second.m_config.m_peer_id == peer.id) { + return true;//dont make connections to ourself } - - return true; - }); - - return used; + bool used = false; + zone.second.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) + { + if(cntxt.peer_id == peer.id || (!cntxt.m_is_income && peer.adr == cntxt.m_remote_address)) + { + used = true; + return false;//stop enumerating + } + return true; + }); + if (used) + return true; + } + return false; } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::is_addr_connected(const epee::net_utils::network_address& peer) { + const auto zone = m_network_zones.find(peer.get_zone()); + if (zone == m_network_zones.end()) + return false; + bool connected = false; - m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) + zone->second.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) { if(!cntxt.m_is_income && peer == cntxt.m_remote_address) { @@ -920,46 +1038,44 @@ namespace nodetool template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::try_to_connect_and_handshake_with_new_peer(const epee::net_utils::network_address& na, bool just_take_peerlist, uint64_t last_seen_stamp, PeerType peer_type, uint64_t first_seen_stamp) { - if (m_current_number_of_out_peers == m_config.m_net_config.max_out_connection_count) // out peers limit + network_zone& zone = m_network_zones.at(na.get_zone()); + if (zone.m_connect == nullptr) // outgoing connections in zone not possible + return false; + + if (zone.m_current_number_of_out_peers == zone.m_config.m_net_config.max_out_connection_count) // out peers limit { return false; } - else if (m_current_number_of_out_peers > m_config.m_net_config.max_out_connection_count) + else if (zone.m_current_number_of_out_peers > zone.m_config.m_net_config.max_out_connection_count) { - m_net_server.get_config_object().del_out_connections(1); - m_current_number_of_out_peers --; // atomic variable, update time = 1s + zone.m_net_server.get_config_object().del_out_connections(1); + --(zone.m_current_number_of_out_peers); // atomic variable, update time = 1s return false; } + + MDEBUG("Connecting to " << na.str() << "(peer_type=" << peer_type << ", last_seen: " << (last_seen_stamp ? epee::misc_utils::get_time_interval_string(time(NULL) - last_seen_stamp):"never") << ")..."); - CHECK_AND_ASSERT_MES(na.get_type_id() == epee::net_utils::ipv4_network_address::ID, false, - "Only IPv4 addresses are supported here"); - const epee::net_utils::ipv4_network_address &ipv4 = na.as<const epee::net_utils::ipv4_network_address>(); - - typename net_server::t_connection_context con = AUTO_VAL_INIT(con); - bool res = m_net_server.connect(epee::string_tools::get_ip_string_from_int32(ipv4.ip()), - epee::string_tools::num_to_string_fast(ipv4.port()), - m_config.m_net_config.connection_timeout, - con); - - if(!res) + auto con = zone.m_connect(zone, na, m_ssl_support); + if(!con) { bool is_priority = is_priority_node(na); - LOG_PRINT_CC_PRIORITY_NODE(is_priority, con, "Connect failed to " << na.str() + LOG_PRINT_CC_PRIORITY_NODE(is_priority, bool(con), "Connect failed to " << na.str() /*<< ", try " << try_count*/); //m_peerlist.set_peer_unreachable(pe); return false; } + con->m_anchor = peer_type == anchor; peerid_type pi = AUTO_VAL_INIT(pi); - res = do_handshake_with_peer(pi, con, just_take_peerlist); + bool res = do_handshake_with_peer(pi, *con, just_take_peerlist); if(!res) { bool is_priority = is_priority_node(na); - LOG_PRINT_CC_PRIORITY_NODE(is_priority, con, "Failed to HANDSHAKE with peer " + LOG_PRINT_CC_PRIORITY_NODE(is_priority, *con, "Failed to HANDSHAKE with peer " << na.str() /*<< ", try " << try_count*/); return false; @@ -967,8 +1083,8 @@ namespace nodetool if(just_take_peerlist) { - m_net_server.get_config_object().close(con.m_connection_id); - LOG_DEBUG_CC(con, "CONNECTION HANDSHAKED OK AND CLOSED."); + zone.m_net_server.get_config_object().close(con->m_connection_id); + LOG_DEBUG_CC(*con, "CONNECTION HANDSHAKED OK AND CLOSED."); return true; } @@ -978,7 +1094,8 @@ namespace nodetool time_t last_seen; time(&last_seen); pe_local.last_seen = static_cast<int64_t>(last_seen); - m_peerlist.append_with_peer_white(pe_local); + pe_local.pruning_seed = con->m_pruning_seed; + zone.m_peerlist.append_with_peer_white(pe_local); //update last seen and push it to peerlist manager anchor_peerlist_entry ape = AUTO_VAL_INIT(ape); @@ -986,51 +1103,46 @@ namespace nodetool ape.id = pi; ape.first_seen = first_seen_stamp ? first_seen_stamp : time(nullptr); - m_peerlist.append_with_peer_anchor(ape); + zone.m_peerlist.append_with_peer_anchor(ape); - LOG_DEBUG_CC(con, "CONNECTION HANDSHAKED OK."); + LOG_DEBUG_CC(*con, "CONNECTION HANDSHAKED OK."); return true; } template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::check_connection_and_handshake_with_peer(const epee::net_utils::network_address& na, uint64_t last_seen_stamp) { + network_zone& zone = m_network_zones.at(na.get_zone()); + if (zone.m_connect == nullptr) + return false; + LOG_PRINT_L1("Connecting to " << na.str() << "(last_seen: " << (last_seen_stamp ? epee::misc_utils::get_time_interval_string(time(NULL) - last_seen_stamp):"never") << ")..."); - CHECK_AND_ASSERT_MES(na.get_type_id() == epee::net_utils::ipv4_network_address::ID, false, - "Only IPv4 addresses are supported here"); - const epee::net_utils::ipv4_network_address &ipv4 = na.as<epee::net_utils::ipv4_network_address>(); - - typename net_server::t_connection_context con = AUTO_VAL_INIT(con); - bool res = m_net_server.connect(epee::string_tools::get_ip_string_from_int32(ipv4.ip()), - epee::string_tools::num_to_string_fast(ipv4.port()), - m_config.m_net_config.connection_timeout, - con); - - if (!res) { + auto con = zone.m_connect(zone, na, m_ssl_support); + if (!con) { bool is_priority = is_priority_node(na); - LOG_PRINT_CC_PRIORITY_NODE(is_priority, con, "Connect failed to " << na.str()); + LOG_PRINT_CC_PRIORITY_NODE(is_priority, p2p_connection_context{}, "Connect failed to " << na.str()); return false; } + con->m_anchor = false; peerid_type pi = AUTO_VAL_INIT(pi); - res = do_handshake_with_peer(pi, con, true); - + const bool res = do_handshake_with_peer(pi, *con, true); if (!res) { bool is_priority = is_priority_node(na); - LOG_PRINT_CC_PRIORITY_NODE(is_priority, con, "Failed to HANDSHAKE with peer " << na.str()); + LOG_PRINT_CC_PRIORITY_NODE(is_priority, *con, "Failed to HANDSHAKE with peer " << na.str()); return false; } - m_net_server.get_config_object().close(con.m_connection_id); + zone.m_net_server.get_config_object().close(con->m_connection_id); - LOG_DEBUG_CC(con, "CONNECTION HANDSHAKED OK AND CLOSED."); + LOG_DEBUG_CC(*con, "CONNECTION HANDSHAKED OK AND CLOSED."); return true; } @@ -1056,7 +1168,7 @@ namespace nodetool bool node_server<t_payload_net_handler>::make_new_connection_from_anchor_peerlist(const std::vector<anchor_peerlist_entry>& anchor_peerlist) { for (const auto& pe: anchor_peerlist) { - _note("Considering connecting (out) to peer: " << peerid_type(pe.id) << " " << pe.adr.str()); + _note("Considering connecting (out) to anchor peer: " << peerid_type(pe.id) << " " << pe.adr.str()); if(is_peer_used(pe)) { _note("Peer is used"); @@ -1087,49 +1199,80 @@ namespace nodetool } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> - bool node_server<t_payload_net_handler>::make_new_connection_from_peerlist(bool use_white_list) + bool node_server<t_payload_net_handler>::make_new_connection_from_peerlist(network_zone& zone, bool use_white_list) { - size_t local_peers_count = use_white_list ? m_peerlist.get_white_peers_count():m_peerlist.get_gray_peers_count(); - if(!local_peers_count) - return false;//no peers - - size_t max_random_index = std::min<uint64_t>(local_peers_count -1, 20); + size_t max_random_index = 0; std::set<size_t> tried_peers; size_t try_count = 0; size_t rand_count = 0; - while(rand_count < (max_random_index+1)*3 && try_count < 10 && !m_net_server.is_stop_signal_sent()) + while(rand_count < (max_random_index+1)*3 && try_count < 10 && !zone.m_net_server.is_stop_signal_sent()) { ++rand_count; size_t random_index; + const uint32_t next_needed_pruning_stripe = m_payload_handler.get_next_needed_pruning_stripe().second; - if (use_white_list) { - local_peers_count = m_peerlist.get_white_peers_count(); - if (!local_peers_count) - return false; - max_random_index = std::min<uint64_t>(local_peers_count -1, 20); - random_index = get_random_index_with_fixed_probability(max_random_index); - } else { - local_peers_count = m_peerlist.get_gray_peers_count(); - if (!local_peers_count) + std::deque<size_t> filtered; + const size_t limit = use_white_list ? 20 : std::numeric_limits<size_t>::max(); + size_t idx = 0; + zone.m_peerlist.foreach (use_white_list, [&filtered, &idx, limit, next_needed_pruning_stripe](const peerlist_entry &pe){ + if (filtered.size() >= limit) return false; - random_index = crypto::rand<size_t>() % local_peers_count; + if (next_needed_pruning_stripe == 0 || pe.pruning_seed == 0) + filtered.push_back(idx); + else if (next_needed_pruning_stripe == tools::get_pruning_stripe(pe.pruning_seed)) + filtered.push_front(idx); + ++idx; + return true; + }); + if (filtered.empty()) + { + MDEBUG("No available peer in " << (use_white_list ? "white" : "gray") << " list filtered by " << next_needed_pruning_stripe); + return false; + } + if (use_white_list) + { + // if using the white list, we first pick in the set of peers we've already been using earlier + random_index = get_random_index_with_fixed_probability(std::min<uint64_t>(filtered.size() - 1, 20)); + CRITICAL_REGION_LOCAL(m_used_stripe_peers_mutex); + if (next_needed_pruning_stripe > 0 && next_needed_pruning_stripe <= (1ul << CRYPTONOTE_PRUNING_LOG_STRIPES) && !m_used_stripe_peers[next_needed_pruning_stripe-1].empty()) + { + const epee::net_utils::network_address na = m_used_stripe_peers[next_needed_pruning_stripe-1].front(); + m_used_stripe_peers[next_needed_pruning_stripe-1].pop_front(); + for (size_t i = 0; i < filtered.size(); ++i) + { + peerlist_entry pe; + if (zone.m_peerlist.get_white_peer_by_index(pe, filtered[i]) && pe.adr == na) + { + MDEBUG("Reusing stripe " << next_needed_pruning_stripe << " peer " << pe.adr.str()); + random_index = i; + break; + } + } + } } + else + random_index = crypto::rand<size_t>() % filtered.size(); - CHECK_AND_ASSERT_MES(random_index < local_peers_count, false, "random_starter_index < peers_local.size() failed!!"); + CHECK_AND_ASSERT_MES(random_index < filtered.size(), false, "random_index < filtered.size() failed!!"); + random_index = filtered[random_index]; + CHECK_AND_ASSERT_MES(random_index < (use_white_list ? zone.m_peerlist.get_white_peers_count() : zone.m_peerlist.get_gray_peers_count()), + false, "random_index < peers size failed!!"); if(tried_peers.count(random_index)) continue; tried_peers.insert(random_index); peerlist_entry pe = AUTO_VAL_INIT(pe); - bool r = use_white_list ? m_peerlist.get_white_peer_by_index(pe, random_index):m_peerlist.get_gray_peer_by_index(pe, random_index); + bool r = use_white_list ? zone.m_peerlist.get_white_peer_by_index(pe, random_index):zone.m_peerlist.get_gray_peer_by_index(pe, random_index); CHECK_AND_ASSERT_MES(r, false, "Failed to get random peer from peerlist(white:" << use_white_list << ")"); ++try_count; - _note("Considering connecting (out) to peer: " << peerid_to_string(pe.id) << " " << pe.adr.str()); + _note("Considering connecting (out) to " << (use_white_list ? "white" : "gray") << " list peer: " << + peerid_to_string(pe.id) << " " << pe.adr.str() << ", pruning seed " << epee::string_tools::to_string_hex(pe.pruning_seed) << + " (stripe " << next_needed_pruning_stripe << " needed)"); if(is_peer_used(pe)) { _note("Peer is used"); @@ -1143,6 +1286,7 @@ namespace nodetool continue; MDEBUG("Selected peer: " << peerid_to_string(pe.id) << " " << pe.adr.str() + << ", pruning seed " << epee::string_tools::to_string_hex(pe.pruning_seed) << " " << "[peer_list=" << (use_white_list ? white : gray) << "] last_seen: " << (pe.last_seen ? epee::misc_utils::get_time_interval_string(time(NULL) - pe.last_seen) : "never")); @@ -1164,9 +1308,10 @@ namespace nodetool size_t try_count = 0; size_t current_index = crypto::rand<size_t>()%m_seed_nodes.size(); + const net_server& server = m_network_zones.at(epee::net_utils::zone::public_).m_net_server; while(true) { - if(m_net_server.is_stop_signal_sent()) + if(server.is_stop_signal_sent()) return false; if(try_to_connect_and_handshake_with_new_peer(m_seed_nodes[current_index], true)) @@ -1205,13 +1350,17 @@ namespace nodetool template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::connections_maker() { + using zone_type = epee::net_utils::zone; + if (m_offline) return true; if (!connect_to_peerlist(m_exclusive_peers)) return false; if (!m_exclusive_peers.empty()) return true; - size_t start_conn_count = get_outgoing_connections_count(); - if(!m_peerlist.get_white_peers_count() && m_seed_nodes.size()) + // Only have seeds in the public zone right now. + + size_t start_conn_count = get_public_outgoing_connections_count(); + if(!get_public_white_peers_count() && m_seed_nodes.size()) { if (!connect_to_seed()) return false; @@ -1219,34 +1368,41 @@ namespace nodetool if (!connect_to_peerlist(m_priority_peers)) return false; - size_t expected_white_connections = (m_config.m_net_config.max_out_connection_count*P2P_DEFAULT_WHITELIST_CONNECTIONS_PERCENT)/100; - - size_t conn_count = get_outgoing_connections_count(); - if(conn_count < m_config.m_net_config.max_out_connection_count) + for(auto& zone : m_network_zones) { - if(conn_count < expected_white_connections) - { - //start from anchor list - if(!make_expected_connections_count(anchor, P2P_DEFAULT_ANCHOR_CONNECTIONS_COUNT)) - return false; - //then do white list - if(!make_expected_connections_count(white, expected_white_connections)) - return false; - //then do grey list - if(!make_expected_connections_count(gray, m_config.m_net_config.max_out_connection_count)) - return false; - }else + size_t base_expected_white_connections = (zone.second.m_config.m_net_config.max_out_connection_count*P2P_DEFAULT_WHITELIST_CONNECTIONS_PERCENT)/100; + + size_t conn_count = get_outgoing_connections_count(zone.second); + while(conn_count < zone.second.m_config.m_net_config.max_out_connection_count) { - //start from grey list - if(!make_expected_connections_count(gray, m_config.m_net_config.max_out_connection_count)) - return false; - //and then do white list - if(!make_expected_connections_count(white, m_config.m_net_config.max_out_connection_count)) + const size_t expected_white_connections = m_payload_handler.get_next_needed_pruning_stripe().second ? zone.second.m_config.m_net_config.max_out_connection_count : base_expected_white_connections; + if(conn_count < expected_white_connections) + { + //start from anchor list + while (get_outgoing_connections_count(zone.second) < P2P_DEFAULT_ANCHOR_CONNECTIONS_COUNT + && make_expected_connections_count(zone.second, anchor, P2P_DEFAULT_ANCHOR_CONNECTIONS_COUNT)); + //then do white list + while (get_outgoing_connections_count(zone.second) < expected_white_connections + && make_expected_connections_count(zone.second, white, expected_white_connections)); + //then do grey list + while (get_outgoing_connections_count(zone.second) < zone.second.m_config.m_net_config.max_out_connection_count + && make_expected_connections_count(zone.second, gray, zone.second.m_config.m_net_config.max_out_connection_count)); + }else + { + //start from grey list + while (get_outgoing_connections_count(zone.second) < zone.second.m_config.m_net_config.max_out_connection_count + && make_expected_connections_count(zone.second, gray, zone.second.m_config.m_net_config.max_out_connection_count)); + //and then do white list + while (get_outgoing_connections_count(zone.second) < zone.second.m_config.m_net_config.max_out_connection_count + && make_expected_connections_count(zone.second, white, zone.second.m_config.m_net_config.max_out_connection_count)); + } + if(zone.second.m_net_server.is_stop_signal_sent()) return false; + conn_count = get_outgoing_connections_count(zone.second); } } - if (start_conn_count == get_outgoing_connections_count() && start_conn_count < m_config.m_net_config.max_out_connection_count) + if (start_conn_count == get_public_outgoing_connections_count() && start_conn_count < m_network_zones.at(zone_type::public_).m_config.m_net_config.max_out_connection_count) { MINFO("Failed to connect to any, trying seeds"); if (!connect_to_seed()) @@ -1257,71 +1413,128 @@ namespace nodetool } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> - bool node_server<t_payload_net_handler>::make_expected_connections_count(PeerType peer_type, size_t expected_connections) + bool node_server<t_payload_net_handler>::make_expected_connections_count(network_zone& zone, PeerType peer_type, size_t expected_connections) { if (m_offline) - return true; + return false; std::vector<anchor_peerlist_entry> apl; if (peer_type == anchor) { - m_peerlist.get_and_empty_anchor_peerlist(apl); + zone.m_peerlist.get_and_empty_anchor_peerlist(apl); } - size_t conn_count = get_outgoing_connections_count(); + size_t conn_count = get_outgoing_connections_count(zone); //add new connections from white peers - while(conn_count < expected_connections) + if(conn_count < expected_connections) { - if(m_net_server.is_stop_signal_sent()) + if(zone.m_net_server.is_stop_signal_sent()) return false; + MDEBUG("Making expected connection, type " << peer_type << ", " << conn_count << "/" << expected_connections << " connections"); + if (peer_type == anchor && !make_new_connection_from_anchor_peerlist(apl)) { - break; + return false; } - if (peer_type == white && !make_new_connection_from_peerlist(true)) { - break; + if (peer_type == white && !make_new_connection_from_peerlist(zone, true)) { + return false; } - if (peer_type == gray && !make_new_connection_from_peerlist(false)) { - break; + if (peer_type == gray && !make_new_connection_from_peerlist(zone, false)) { + return false; } - - conn_count = get_outgoing_connections_count(); } return true; } - //----------------------------------------------------------------------------------- template<class t_payload_net_handler> - size_t node_server<t_payload_net_handler>::get_outgoing_connections_count() + size_t node_server<t_payload_net_handler>::get_public_outgoing_connections_count() + { + auto public_zone = m_network_zones.find(epee::net_utils::zone::public_); + if (public_zone == m_network_zones.end()) + return 0; + return get_outgoing_connections_count(public_zone->second); + } + //----------------------------------------------------------------------------------- + template<class t_payload_net_handler> + size_t node_server<t_payload_net_handler>::get_incoming_connections_count(network_zone& zone) { size_t count = 0; - m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) + zone.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) { - if(!cntxt.m_is_income) + if(cntxt.m_is_income) ++count; return true; }); - return count; } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> - size_t node_server<t_payload_net_handler>::get_incoming_connections_count() + size_t node_server<t_payload_net_handler>::get_outgoing_connections_count(network_zone& zone) { size_t count = 0; - m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) + zone.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) { - if(cntxt.m_is_income) + if(!cntxt.m_is_income) ++count; return true; }); - return count; } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> + size_t node_server<t_payload_net_handler>::get_outgoing_connections_count() + { + size_t count = 0; + for(auto& zone : m_network_zones) + count += get_outgoing_connections_count(zone.second); + return count; + } + //----------------------------------------------------------------------------------- + template<class t_payload_net_handler> + size_t node_server<t_payload_net_handler>::get_incoming_connections_count() + { + size_t count = 0; + for (auto& zone : m_network_zones) + { + zone.second.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) + { + if(cntxt.m_is_income) + ++count; + return true; + }); + } + return count; + } + //----------------------------------------------------------------------------------- + template<class t_payload_net_handler> + size_t node_server<t_payload_net_handler>::get_public_white_peers_count() + { + auto public_zone = m_network_zones.find(epee::net_utils::zone::public_); + if (public_zone == m_network_zones.end()) + return 0; + return public_zone->second.m_peerlist.get_white_peers_count(); + } + //----------------------------------------------------------------------------------- + template<class t_payload_net_handler> + size_t node_server<t_payload_net_handler>::get_public_gray_peers_count() + { + auto public_zone = m_network_zones.find(epee::net_utils::zone::public_); + if (public_zone == m_network_zones.end()) + return 0; + return public_zone->second.m_peerlist.get_gray_peers_count(); + } + //----------------------------------------------------------------------------------- + template<class t_payload_net_handler> + void node_server<t_payload_net_handler>::get_public_peerlist(std::vector<peerlist_entry>& gray, std::vector<peerlist_entry>& white) + { + auto public_zone = m_network_zones.find(epee::net_utils::zone::public_); + if (public_zone != m_network_zones.end()) + public_zone->second.m_peerlist.get_peerlist(gray, white); + } + //----------------------------------------------------------------------------------- + template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::idle_worker() { m_peer_handshake_idle_maker_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::peer_sync_idle_maker, this)); @@ -1337,9 +1550,11 @@ namespace nodetool { if (m_offline) return true; - if (get_incoming_connections_count() == 0) + + const auto public_zone = m_network_zones.find(epee::net_utils::zone::public_); + if (public_zone != m_network_zones.end() && get_incoming_connections_count(public_zone->second) == 0) { - if (m_hide_my_port || m_config.m_net_config.max_in_connection_count == 0) + if (m_hide_my_port || public_zone->second.m_config.m_net_config.max_in_connection_count == 0) { MGINFO("Incoming connections disabled, enable them for full connectivity"); } @@ -1358,15 +1573,18 @@ namespace nodetool MDEBUG("STARTED PEERLIST IDLE HANDSHAKE"); typedef std::list<std::pair<epee::net_utils::connection_context_base, peerid_type> > local_connects_type; local_connects_type cncts; - m_net_server.get_config_object().foreach_connection([&](p2p_connection_context& cntxt) + for(auto& zone : m_network_zones) { - if(cntxt.peer_id && !cntxt.m_in_timedsync) + zone.second.m_net_server.get_config_object().foreach_connection([&](p2p_connection_context& cntxt) { - cntxt.m_in_timedsync = true; - cncts.push_back(local_connects_type::value_type(cntxt, cntxt.peer_id));//do idle sync only with handshaked connections - } - return true; - }); + if(cntxt.peer_id && !cntxt.m_in_timedsync) + { + cntxt.m_in_timedsync = true; + cncts.push_back(local_connects_type::value_type(cntxt, cntxt.peer_id));//do idle sync only with handshaked connections + } + return true; + }); + } std::for_each(cncts.begin(), cncts.end(), [&](const typename local_connects_type::value_type& vl){do_peer_timed_sync(vl.first, vl.second);}); @@ -1390,6 +1608,9 @@ namespace nodetool return false; } be.last_seen += delta; +#ifdef CRYPTONOTE_PRUNING_DEBUG_SPOOF_SEED + be.pruning_seed = tools::make_pruning_seed(1 + (be.adr.as<epee::net_utils::ipv4_network_address>().ip()) % (1ul << CRYPTONOTE_PRUNING_LOG_STRIPES), CRYPTONOTE_PRUNING_LOG_STRIPES); +#endif } return true; } @@ -1401,19 +1622,30 @@ namespace nodetool std::vector<peerlist_entry> peerlist_ = peerlist; if(!fix_time_delta(peerlist_, local_time, delta)) return false; + + const epee::net_utils::zone zone = context.m_remote_address.get_zone(); + for(const auto& peer : peerlist_) + { + if(peer.adr.get_zone() != zone) + { + MWARNING(context << " sent peerlist from another zone, dropping"); + return false; + } + } + LOG_DEBUG_CC(context, "REMOTE PEERLIST: TIME_DELTA: " << delta << ", remote peerlist size=" << peerlist_.size()); LOG_DEBUG_CC(context, "REMOTE PEERLIST: " << print_peerlist_to_string(peerlist_)); - return m_peerlist.merge_peerlist(peerlist_); + return m_network_zones.at(context.m_remote_address.get_zone()).m_peerlist.merge_peerlist(peerlist_); } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> - bool node_server<t_payload_net_handler>::get_local_node_data(basic_node_data& node_data) + bool node_server<t_payload_net_handler>::get_local_node_data(basic_node_data& node_data, const network_zone& zone) { time_t local_time; time(&local_time); - node_data.local_time = local_time; - node_data.peer_id = m_config.m_peer_id; - if(!m_hide_my_port) + node_data.local_time = local_time; // \TODO This can be an identifying value across zones (public internet to tor/i2p) ... + node_data.peer_id = zone.m_config.m_peer_id; + if(!m_hide_my_port && zone.m_can_pingback) node_data.my_port = m_external_port ? m_external_port : m_listening_port; else node_data.my_port = 0; @@ -1423,7 +1655,7 @@ namespace nodetool //----------------------------------------------------------------------------------- #ifdef ALLOW_DEBUG_COMMANDS template<class t_payload_net_handler> - bool node_server<t_payload_net_handler>::check_trust(const proof_of_trust& tr) + bool node_server<t_payload_net_handler>::check_trust(const proof_of_trust& tr, const epee::net_utils::zone zone_type) { uint64_t local_time = time(NULL); uint64_t time_delata = local_time > tr.time ? local_time - tr.time: tr.time - local_time; @@ -1437,9 +1669,11 @@ namespace nodetool MWARNING("check_trust failed to check time conditions, last_stat_request_time=" << m_last_stat_request_time << ", proof_time=" << tr.time); return false; } - if(m_config.m_peer_id != tr.peer_id) + + const network_zone& zone = m_network_zones.at(zone_type); + if(zone.m_config.m_peer_id != tr.peer_id) { - MWARNING("check_trust failed: peer_id mismatch (passed " << tr.peer_id << ", expected " << m_config.m_peer_id<< ")"); + MWARNING("check_trust failed: peer_id mismatch (passed " << tr.peer_id << ", expected " << zone.m_config.m_peer_id<< ")"); return false; } crypto::public_key pk = AUTO_VAL_INIT(pk); @@ -1458,12 +1692,12 @@ namespace nodetool template<class t_payload_net_handler> int node_server<t_payload_net_handler>::handle_get_stat_info(int command, typename COMMAND_REQUEST_STAT_INFO::request& arg, typename COMMAND_REQUEST_STAT_INFO::response& rsp, p2p_connection_context& context) { - if(!check_trust(arg.tr)) + if(!check_trust(arg.tr, context.m_remote_address.get_zone())) { drop_connection(context); return 1; } - rsp.connections_count = m_net_server.get_config_object().get_connections_count(); + rsp.connections_count = get_connections_count(); rsp.incoming_connections_count = rsp.connections_count - get_outgoing_connections_count(); rsp.version = MONERO_VERSION_FULL; rsp.os_version = tools::get_os_version_string(); @@ -1474,12 +1708,12 @@ namespace nodetool template<class t_payload_net_handler> int node_server<t_payload_net_handler>::handle_get_network_state(int command, COMMAND_REQUEST_NETWORK_STATE::request& arg, COMMAND_REQUEST_NETWORK_STATE::response& rsp, p2p_connection_context& context) { - if(!check_trust(arg.tr)) + if(!check_trust(arg.tr, context.m_remote_address.get_zone())) { drop_connection(context); return 1; } - m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) + m_network_zones.at(epee::net_utils::zone::public_).m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) { connection_entry ce; ce.adr = cntxt.m_remote_address; @@ -1489,8 +1723,9 @@ namespace nodetool return true; }); - m_peerlist.get_peerlist_full(rsp.local_peerlist_gray, rsp.local_peerlist_white); - rsp.my_id = m_config.m_peer_id; + network_zone& zone = m_network_zones.at(context.m_remote_address.get_zone()); + zone.m_peerlist.get_peerlist(rsp.local_peerlist_gray, rsp.local_peerlist_white); + rsp.my_id = zone.m_config.m_peer_id; rsp.local_time = time(NULL); return 1; } @@ -1498,7 +1733,7 @@ namespace nodetool template<class t_payload_net_handler> int node_server<t_payload_net_handler>::handle_get_peer_id(int command, COMMAND_REQUEST_PEER_ID::request& arg, COMMAND_REQUEST_PEER_ID::response& rsp, p2p_connection_context& context) { - rsp.my_id = m_config.m_peer_id; + rsp.my_id = m_network_zones.at(context.m_remote_address.get_zone()).m_config.m_peer_id; return 1; } #endif @@ -1506,40 +1741,42 @@ namespace nodetool template<class t_payload_net_handler> int node_server<t_payload_net_handler>::handle_get_support_flags(int command, COMMAND_REQUEST_SUPPORT_FLAGS::request& arg, COMMAND_REQUEST_SUPPORT_FLAGS::response& rsp, p2p_connection_context& context) { - rsp.support_flags = m_config.m_support_flags; + rsp.support_flags = m_network_zones.at(context.m_remote_address.get_zone()).m_config.m_support_flags; return 1; } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> void node_server<t_payload_net_handler>::request_callback(const epee::net_utils::connection_context_base& context) { - m_net_server.get_config_object().request_callback(context.m_connection_id); + m_network_zones.at(context.m_remote_address.get_zone()).m_net_server.get_config_object().request_callback(context.m_connection_id); } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> - bool node_server<t_payload_net_handler>::relay_notify_to_list(int command, const epee::span<const uint8_t> data_buff, const std::list<boost::uuids::uuid> &connections) + bool node_server<t_payload_net_handler>::relay_notify_to_list(int command, const epee::span<const uint8_t> data_buff, std::vector<std::pair<epee::net_utils::zone, boost::uuids::uuid>> connections) { + std::sort(connections.begin(), connections.end()); + auto zone = m_network_zones.begin(); for(const auto& c_id: connections) { - m_net_server.get_config_object().notify(command, data_buff, c_id); + for (;;) + { + if (zone == m_network_zones.end()) + { + MWARNING("Unable to relay all messages, " << epee::net_utils::zone_to_string(c_id.first) << " not available"); + return false; + } + if (c_id.first <= zone->first) + break; + + ++zone; + } + if (zone->first == c_id.first) + zone->second.m_net_server.get_config_object().notify(command, data_buff, c_id.second); } return true; } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> - bool node_server<t_payload_net_handler>::relay_notify_to_all(int command, const epee::span<const uint8_t> data_buff, const epee::net_utils::connection_context_base& context) - { - std::list<boost::uuids::uuid> connections; - m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) - { - if(cntxt.peer_id && context.m_connection_id != cntxt.m_connection_id) - connections.push_back(cntxt.m_connection_id); - return true; - }); - return relay_notify_to_list(command, data_buff, connections); - } - //----------------------------------------------------------------------------------- - template<class t_payload_net_handler> void node_server<t_payload_net_handler>::callback(p2p_connection_context& context) { m_payload_handler.on_callback(context); @@ -1548,21 +1785,29 @@ namespace nodetool template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::invoke_notify_to_peer(int command, const epee::span<const uint8_t> req_buff, const epee::net_utils::connection_context_base& context) { - int res = m_net_server.get_config_object().notify(command, req_buff, context.m_connection_id); + if(is_filtered_command(context.m_remote_address, command)) + return false; + + network_zone& zone = m_network_zones.at(context.m_remote_address.get_zone()); + int res = zone.m_net_server.get_config_object().notify(command, req_buff, context.m_connection_id); return res > 0; } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::invoke_command_to_peer(int command, const epee::span<const uint8_t> req_buff, std::string& resp_buff, const epee::net_utils::connection_context_base& context) { - int res = m_net_server.get_config_object().invoke(command, req_buff, resp_buff, context.m_connection_id); + if(is_filtered_command(context.m_remote_address, command)) + return false; + + network_zone& zone = m_network_zones.at(context.m_remote_address.get_zone()); + int res = zone.m_net_server.get_config_object().invoke(command, req_buff, resp_buff, context.m_connection_id); return res > 0; } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::drop_connection(const epee::net_utils::connection_context_base& context) { - m_net_server.get_config_object().close(context.m_connection_id); + m_network_zones.at(context.m_remote_address.get_zone()).m_net_server.get_config_object().close(context.m_connection_id); return true; } //----------------------------------------------------------------------------------- @@ -1572,18 +1817,21 @@ namespace nodetool if(!node_data.my_port) return false; - CHECK_AND_ASSERT_MES(context.m_remote_address.get_type_id() == epee::net_utils::ipv4_network_address::ID, false, + CHECK_AND_ASSERT_MES(context.m_remote_address.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id(), false, "Only IPv4 addresses are supported here"); const epee::net_utils::network_address na = context.m_remote_address; uint32_t actual_ip = na.as<const epee::net_utils::ipv4_network_address>().ip(); - if(!m_peerlist.is_host_allowed(context.m_remote_address)) + network_zone& zone = m_network_zones.at(na.get_zone()); + + if(!zone.m_peerlist.is_host_allowed(context.m_remote_address)) 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{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]( + bool r = zone.m_net_server.connect_async(ip, port, zone.m_config.m_net_config.ping_connection_timeout, [cb, /*context,*/ address, pr, this]( const typename net_server::t_connection_context& ping_context, const boost::system::error_code& ec)->bool { @@ -1603,7 +1851,9 @@ namespace nodetool // GCC 5.1.0 gives error with second use of uint64_t (peerid_type) variable. peerid_type pr_ = pr; - bool inv_call_res = epee::net_utils::async_invoke_remote_command2<COMMAND_PING::response>(ping_context.m_connection_id, COMMAND_PING::ID, req, m_net_server.get_config_object(), + network_zone& zone = m_network_zones.at(address.get_zone()); + + bool inv_call_res = epee::net_utils::async_invoke_remote_command2<COMMAND_PING::response>(ping_context.m_connection_id, COMMAND_PING::ID, req, zone.m_net_server.get_config_object(), [=](int code, const COMMAND_PING::response& rsp, p2p_connection_context& context) { if(code <= 0) @@ -1612,20 +1862,21 @@ namespace nodetool return; } + network_zone& zone = m_network_zones.at(address.get_zone()); if(rsp.status != PING_OK_RESPONSE_STATUS_TEXT || pr != rsp.peer_id) { LOG_WARNING_CC(ping_context, "back ping invoke wrong response \"" << rsp.status << "\" from" << address.str() << ", hsh_peer_id=" << pr_ << ", rsp.peer_id=" << rsp.peer_id); - m_net_server.get_config_object().close(ping_context.m_connection_id); + zone.m_net_server.get_config_object().close(ping_context.m_connection_id); return; } - m_net_server.get_config_object().close(ping_context.m_connection_id); + zone.m_net_server.get_config_object().close(ping_context.m_connection_id); cb(); }); if(!inv_call_res) { LOG_WARNING_CC(ping_context, "back ping invoke failed to " << address.str()); - m_net_server.get_config_object().close(ping_context.m_connection_id); + zone.m_net_server.get_config_object().close(ping_context.m_connection_id); return false; } return true; @@ -1640,13 +1891,16 @@ namespace nodetool template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::try_get_support_flags(const p2p_connection_context& context, std::function<void(p2p_connection_context&, const uint32_t&)> f) { + if(context.m_remote_address.get_zone() != epee::net_utils::zone::public_) + return false; + COMMAND_REQUEST_SUPPORT_FLAGS::request support_flags_request; bool r = epee::net_utils::async_invoke_remote_command2<typename COMMAND_REQUEST_SUPPORT_FLAGS::response> ( context.m_connection_id, COMMAND_REQUEST_SUPPORT_FLAGS::ID, support_flags_request, - m_net_server.get_config_object(), + m_network_zones.at(epee::net_utils::zone::public_).m_net_server.get_config_object(), [=](int code, const typename COMMAND_REQUEST_SUPPORT_FLAGS::response& rsp, p2p_connection_context& context_) { if(code < 0) @@ -1675,8 +1929,24 @@ namespace nodetool //fill response rsp.local_time = time(NULL); - m_peerlist.get_peerlist_head(rsp.local_peerlist_new); + + const epee::net_utils::zone zone_type = context.m_remote_address.get_zone(); + network_zone& zone = m_network_zones.at(zone_type); + + zone.m_peerlist.get_peerlist_head(rsp.local_peerlist_new); m_payload_handler.get_payload_sync_data(rsp.payload_data); + + /* Tor/I2P nodes receiving connections via forwarding (from tor/i2p daemon) + do not know the address of the connecting peer. This is relayed to them, + iff the node has setup an inbound hidden service. The other peer will have + to use the random peer_id value to link the two. My initial thought is that + the inbound peer should leave the other side marked as `<unknown tor host>`, + etc., because someone could give faulty addresses over Tor/I2P to get the + real peer with that identity banned/blacklisted. */ + + if(!context.m_is_income && zone.m_our_address.get_zone() == zone_type) + rsp.local_peerlist_new.push_back(peerlist_entry{zone.m_our_address, zone.m_config.m_peer_id, std::time(nullptr)}); + LOG_DEBUG_CC(context, "COMMAND_TIMED_SYNC"); return 1; } @@ -1708,7 +1978,9 @@ namespace nodetool return 1; } - if (m_current_number_of_in_peers >= m_config.m_net_config.max_in_connection_count) // in peers limit + network_zone& zone = m_network_zones.at(context.m_remote_address.get_zone()); + + if (zone.m_current_number_of_in_peers >= zone.m_config.m_net_config.max_in_connection_count) // in peers limit { LOG_WARNING_CC(context, "COMMAND_HANDSHAKE came, but already have max incoming connections, so dropping this one."); drop_connection(context); @@ -1733,14 +2005,14 @@ namespace nodetool context.peer_id = arg.node_data.peer_id; context.m_in_timedsync = false; - if(arg.node_data.peer_id != m_config.m_peer_id && arg.node_data.my_port) + if(arg.node_data.peer_id != zone.m_config.m_peer_id && arg.node_data.my_port && zone.m_can_pingback) { peerid_type peer_id_l = arg.node_data.peer_id; 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]() { - CHECK_AND_ASSERT_MES(context.m_remote_address.get_type_id() == epee::net_utils::ipv4_network_address::ID, void(), + CHECK_AND_ASSERT_MES(context.m_remote_address.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id(), void(), "Only IPv4 addresses are supported here"); //called only(!) if success pinged, update local peerlist peerlist_entry pe; @@ -1750,7 +2022,8 @@ namespace nodetool time(&last_seen); pe.last_seen = static_cast<int64_t>(last_seen); pe.id = peer_id_l; - this->m_peerlist.append_with_peer_white(pe); + pe.pruning_seed = context.m_pruning_seed; + this->m_network_zones.at(context.m_remote_address.get_zone()).m_peerlist.append_with_peer_white(pe); LOG_DEBUG_CC(context, "PING SUCCESS " << context.m_remote_address.host_str() << ":" << port_l); }); } @@ -1761,8 +2034,8 @@ namespace nodetool }); //fill response - m_peerlist.get_peerlist_head(rsp.local_peerlist_new); - get_local_node_data(rsp.node_data); + zone.m_peerlist.get_peerlist_head(rsp.local_peerlist_new); + get_local_node_data(rsp.node_data, zone); m_payload_handler.get_payload_sync_data(rsp.payload_data); LOG_DEBUG_CC(context, "COMMAND_HANDSHAKE"); return 1; @@ -1773,7 +2046,7 @@ namespace nodetool { LOG_DEBUG_CC(context, "COMMAND_PING"); rsp.status = PING_OK_RESPONSE_STATUS_TEXT; - rsp.peer_id = m_config.m_peer_id; + rsp.peer_id = m_network_zones.at(context.m_remote_address.get_zone()).m_config.m_peer_id; return 1; } //----------------------------------------------------------------------------------- @@ -1782,7 +2055,8 @@ namespace nodetool { std::vector<peerlist_entry> pl_white; std::vector<peerlist_entry> pl_gray; - m_peerlist.get_peerlist_full(pl_gray, pl_white); + for (auto& zone : m_network_zones) + zone.second.m_peerlist.get_peerlist(pl_gray, pl_white); MINFO(ENDL << "Peerlist white:" << ENDL << print_peerlist_to_string(pl_white) << ENDL << "Peerlist gray:" << ENDL << print_peerlist_to_string(pl_gray) ); return true; } @@ -1799,14 +2073,17 @@ namespace nodetool { std::stringstream ss; - m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) + for (auto& zone : m_network_zones) { - ss << cntxt.m_remote_address.str() - << " \t\tpeer_id " << cntxt.peer_id - << " \t\tconn_id " << cntxt.m_connection_id << (cntxt.m_is_income ? " INC":" OUT") - << std::endl; - return true; - }); + zone.second.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) + { + ss << cntxt.m_remote_address.str() + << " \t\tpeer_id " << cntxt.peer_id + << " \t\tconn_id " << cntxt.m_connection_id << (cntxt.m_is_income ? " INC":" OUT") + << std::endl; + return true; + }); + } std::string s = ss.str(); return s; } @@ -1820,11 +2097,12 @@ namespace nodetool template<class t_payload_net_handler> void node_server<t_payload_net_handler>::on_connection_close(p2p_connection_context& context) { - if (!m_net_server.is_stop_signal_sent() && !context.m_is_income) { + network_zone& zone = m_network_zones.at(context.m_remote_address.get_zone()); + if (!zone.m_net_server.is_stop_signal_sent() && !context.m_is_income) { epee::net_utils::network_address na = AUTO_VAL_INIT(na); na = context.m_remote_address; - m_peerlist.remove_from_peer_anchor(na); + zone.m_peerlist.remove_from_peer_anchor(na); } m_payload_handler.on_connection_close(context); @@ -1841,9 +2119,10 @@ namespace nodetool template<class t_payload_net_handler> template <class Container> bool node_server<t_payload_net_handler>::connect_to_peerlist(const Container& peers) { + const network_zone& public_zone = m_network_zones.at(epee::net_utils::zone::public_); for(const epee::net_utils::network_address& na: peers) { - if(m_net_server.is_stop_signal_sent()) + if(public_zone.m_net_server.is_stop_signal_sent()) return false; if(is_addr_connected(na)) @@ -1862,16 +2141,16 @@ namespace nodetool for(const std::string& pr_str: perrs) { - epee::net_utils::network_address na = AUTO_VAL_INIT(na); const uint16_t default_port = cryptonote::get_config(m_nettype).P2P_DEFAULT_PORT; - bool r = parse_peer_from_string(na, pr_str, default_port); - if (r) + expect<epee::net_utils::network_address> adr = net::get_network_address(pr_str, default_port); + if (adr) { - container.push_back(na); + add_zone(adr->get_zone()); + container.push_back(std::move(*adr)); continue; } std::vector<epee::net_utils::network_address> resolved_addrs; - r = append_net_address(resolved_addrs, pr_str, default_port); + bool r = append_net_address(resolved_addrs, pr_str, default_port); CHECK_AND_ASSERT_MES(r, false, "Failed to parse or resolve address from string: " << pr_str); for (const epee::net_utils::network_address& addr : resolved_addrs) { @@ -1883,37 +2162,47 @@ namespace nodetool } template<class t_payload_net_handler> - bool node_server<t_payload_net_handler>::set_max_out_peers(const boost::program_options::variables_map& vm, int64_t max) + bool node_server<t_payload_net_handler>::set_max_out_peers(network_zone& zone, int64_t max) { if(max == -1) { - m_config.m_net_config.max_out_connection_count = P2P_DEFAULT_CONNECTIONS_COUNT; + zone.m_config.m_net_config.max_out_connection_count = P2P_DEFAULT_CONNECTIONS_COUNT; return true; } - m_config.m_net_config.max_out_connection_count = max; + zone.m_config.m_net_config.max_out_connection_count = max; return true; } template<class t_payload_net_handler> - bool node_server<t_payload_net_handler>::set_max_in_peers(const boost::program_options::variables_map& vm, int64_t max) + bool node_server<t_payload_net_handler>::set_max_in_peers(network_zone& zone, int64_t max) { - if(max == -1) { - m_config.m_net_config.max_in_connection_count = -1; - return true; - } - m_config.m_net_config.max_in_connection_count = max; + zone.m_config.m_net_config.max_in_connection_count = max; return true; } template<class t_payload_net_handler> - void node_server<t_payload_net_handler>::delete_out_connections(size_t count) + void node_server<t_payload_net_handler>::change_max_out_public_peers(size_t count) { - m_net_server.get_config_object().del_out_connections(count); + auto public_zone = m_network_zones.find(epee::net_utils::zone::public_); + if (public_zone != m_network_zones.end()) + { + const auto current = public_zone->second.m_config.m_net_config.max_out_connection_count; + public_zone->second.m_config.m_net_config.max_out_connection_count = count; + if(current > count) + public_zone->second.m_net_server.get_config_object().del_out_connections(current - count); + } } template<class t_payload_net_handler> - void node_server<t_payload_net_handler>::delete_in_connections(size_t count) + void node_server<t_payload_net_handler>::change_max_in_public_peers(size_t count) { - m_net_server.get_config_object().del_in_connections(count); + auto public_zone = m_network_zones.find(epee::net_utils::zone::public_); + if (public_zone != m_network_zones.end()) + { + const auto current = public_zone->second.m_config.m_net_config.max_in_connection_count; + public_zone->second.m_config.m_net_config.max_in_connection_count = count; + if(current > count) + public_zone->second.m_net_server.get_config_object().del_in_connections(current - count); + } } template<class t_payload_net_handler> @@ -1986,10 +2275,13 @@ namespace nodetool template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::has_too_many_connections(const epee::net_utils::network_address &address) { + if (address.get_zone() != epee::net_utils::zone::public_) + return false; // Unable to determine how many connections from host + const size_t max_connections = 1; size_t count = 0; - m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) + m_network_zones.at(epee::net_utils::zone::public_).m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) { if (cntxt.m_is_income && cntxt.m_remote_address.is_same_host(address)) { count++; @@ -2010,31 +2302,68 @@ namespace nodetool { if (m_offline) return true; if (!m_exclusive_peers.empty()) return true; + if (m_payload_handler.needs_new_sync_connections()) return true; - peerlist_entry pe = AUTO_VAL_INIT(pe); - - if (m_net_server.is_stop_signal_sent()) - return false; - - if (!m_peerlist.get_random_gray_peer(pe)) { - return true; - } - - bool success = check_connection_and_handshake_with_peer(pe.adr, pe.last_seen); + for (auto& zone : m_network_zones) + { + if (zone.second.m_net_server.is_stop_signal_sent()) + return false; - if (!success) { - m_peerlist.remove_from_peer_gray(pe); + if (zone.second.m_connect == nullptr) + continue; - LOG_PRINT_L2("PEER EVICTED FROM GRAY PEER LIST IP address: " << pe.adr.host_str() << " Peer ID: " << peerid_type(pe.id)); + peerlist_entry pe{}; + if (!zone.second.m_peerlist.get_random_gray_peer(pe)) + continue; - return true; + if (!check_connection_and_handshake_with_peer(pe.adr, pe.last_seen)) + { + zone.second.m_peerlist.remove_from_peer_gray(pe); + LOG_PRINT_L2("PEER EVICTED FROM GRAY PEER LIST IP address: " << pe.adr.host_str() << " Peer ID: " << peerid_type(pe.id)); + } + else + { + zone.second.m_peerlist.set_peer_just_seen(pe.id, pe.adr, pe.pruning_seed); + LOG_PRINT_L2("PEER PROMOTED TO WHITE PEER LIST IP address: " << pe.adr.host_str() << " Peer ID: " << peerid_type(pe.id)); + } } + return true; + } - m_peerlist.set_peer_just_seen(pe.id, pe.adr); + template<class t_payload_net_handler> + void node_server<t_payload_net_handler>::add_used_stripe_peer(const typename t_payload_net_handler::connection_context &context) + { + const uint32_t stripe = tools::get_pruning_stripe(context.m_pruning_seed); + if (stripe == 0 || stripe > (1ul << CRYPTONOTE_PRUNING_LOG_STRIPES)) + return; + const uint32_t index = stripe - 1; + CRITICAL_REGION_LOCAL(m_used_stripe_peers_mutex); + MINFO("adding stripe " << stripe << " peer: " << context.m_remote_address.str()); + std::remove_if(m_used_stripe_peers[index].begin(), m_used_stripe_peers[index].end(), + [&context](const epee::net_utils::network_address &na){ return context.m_remote_address == na; }); + m_used_stripe_peers[index].push_back(context.m_remote_address); + } - LOG_PRINT_L2("PEER PROMOTED TO WHITE PEER LIST IP address: " << pe.adr.host_str() << " Peer ID: " << peerid_type(pe.id)); + template<class t_payload_net_handler> + void node_server<t_payload_net_handler>::remove_used_stripe_peer(const typename t_payload_net_handler::connection_context &context) + { + const uint32_t stripe = tools::get_pruning_stripe(context.m_pruning_seed); + if (stripe == 0 || stripe > (1ul << CRYPTONOTE_PRUNING_LOG_STRIPES)) + return; + const uint32_t index = stripe - 1; + CRITICAL_REGION_LOCAL(m_used_stripe_peers_mutex); + MINFO("removing stripe " << stripe << " peer: " << context.m_remote_address.str()); + std::remove_if(m_used_stripe_peers[index].begin(), m_used_stripe_peers[index].end(), + [&context](const epee::net_utils::network_address &na){ return context.m_remote_address == na; }); + } - return true; + template<class t_payload_net_handler> + void node_server<t_payload_net_handler>::clear_used_stripe_peers() + { + CRITICAL_REGION_LOCAL(m_used_stripe_peers_mutex); + MINFO("clearing used stripe peers"); + for (auto &e: m_used_stripe_peers) + e.clear(); } template<class t_payload_net_handler> @@ -2125,4 +2454,37 @@ namespace nodetool MINFO("No IGD was found."); } } + + template<typename t_payload_net_handler> + boost::optional<p2p_connection_context_t<typename t_payload_net_handler::connection_context>> + node_server<t_payload_net_handler>::socks_connect(network_zone& zone, const epee::net_utils::network_address& remote, epee::net_utils::ssl_support_t ssl_support) + { + auto result = socks_connect_internal(zone.m_net_server.get_stop_signal(), zone.m_net_server.get_io_service(), zone.m_proxy_address, remote); + if (result) // if no error + { + p2p_connection_context context{}; + if (zone.m_net_server.add_connection(context, std::move(*result), remote, ssl_support)) + return {std::move(context)}; + } + return boost::none; + } + + template<typename t_payload_net_handler> + boost::optional<p2p_connection_context_t<typename t_payload_net_handler::connection_context>> + node_server<t_payload_net_handler>::public_connect(network_zone& zone, epee::net_utils::network_address const& na, epee::net_utils::ssl_support_t ssl_support) + { + CHECK_AND_ASSERT_MES(na.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id(), boost::none, + "Only IPv4 addresses are supported here"); + const epee::net_utils::ipv4_network_address &ipv4 = na.as<const epee::net_utils::ipv4_network_address>(); + + typename net_server::t_connection_context con{}; + const bool res = zone.m_net_server.connect(epee::string_tools::get_ip_string_from_int32(ipv4.ip()), + epee::string_tools::num_to_string_fast(ipv4.port()), + zone.m_config.m_net_config.connection_timeout, + con, "0.0.0.0", ssl_support); + + if (res) + return {std::move(con)}; + return boost::none; + } } diff --git a/src/p2p/net_node_common.h b/src/p2p/net_node_common.h index 656c6155b..944bf48e4 100644 --- a/src/p2p/net_node_common.h +++ b/src/p2p/net_node_common.h @@ -31,6 +31,8 @@ #pragma once #include <boost/uuid/uuid.hpp> +#include <utility> +#include <vector> #include "net/net_utils_base.h" #include "p2p_protocol_defs.h" @@ -43,29 +45,28 @@ namespace nodetool template<class t_connection_context> struct i_p2p_endpoint { - virtual bool relay_notify_to_list(int command, const epee::span<const uint8_t> data_buff, const std::list<boost::uuids::uuid>& connections)=0; - virtual bool relay_notify_to_all(int command, const epee::span<const uint8_t> data_buff, const epee::net_utils::connection_context_base& context)=0; + virtual bool relay_notify_to_list(int command, const epee::span<const uint8_t> data_buff, std::vector<std::pair<epee::net_utils::zone, boost::uuids::uuid>> connections)=0; virtual bool invoke_command_to_peer(int command, const epee::span<const uint8_t> req_buff, std::string& resp_buff, const epee::net_utils::connection_context_base& context)=0; virtual bool invoke_notify_to_peer(int command, const epee::span<const uint8_t> req_buff, const epee::net_utils::connection_context_base& context)=0; virtual bool drop_connection(const epee::net_utils::connection_context_base& context)=0; virtual void request_callback(const epee::net_utils::connection_context_base& context)=0; - virtual uint64_t get_connections_count()=0; + virtual uint64_t get_public_connections_count()=0; + virtual size_t get_zone_count() const=0; virtual void for_each_connection(std::function<bool(t_connection_context&, peerid_type, uint32_t)> f)=0; virtual bool for_connection(const boost::uuids::uuid&, std::function<bool(t_connection_context&, peerid_type, uint32_t)> f)=0; virtual bool block_host(const epee::net_utils::network_address &address, time_t seconds = 0)=0; virtual bool unblock_host(const epee::net_utils::network_address &address)=0; virtual std::map<std::string, time_t> get_blocked_hosts()=0; virtual bool add_host_fail(const epee::net_utils::network_address &address)=0; + virtual void add_used_stripe_peer(const t_connection_context &context)=0; + virtual void remove_used_stripe_peer(const t_connection_context &context)=0; + virtual void clear_used_stripe_peers()=0; }; template<class t_connection_context> struct p2p_endpoint_stub: public i_p2p_endpoint<t_connection_context> { - virtual bool relay_notify_to_list(int command, const epee::span<const uint8_t> data_buff, const std::list<boost::uuids::uuid>& connections) - { - return false; - } - virtual bool relay_notify_to_all(int command, const epee::span<const uint8_t> data_buff, const epee::net_utils::connection_context_base& context) + virtual bool relay_notify_to_list(int command, const epee::span<const uint8_t> data_buff, std::vector<std::pair<epee::net_utils::zone, boost::uuids::uuid>> connections) { return false; } @@ -94,7 +95,12 @@ namespace nodetool return false; } - virtual uint64_t get_connections_count() + virtual size_t get_zone_count() const + { + return 0; + } + + virtual uint64_t get_public_connections_count() { return false; } @@ -114,5 +120,14 @@ namespace nodetool { return true; } + virtual void add_used_stripe_peer(const t_connection_context &context) + { + } + virtual void remove_used_stripe_peer(const t_connection_context &context) + { + } + virtual void clear_used_stripe_peers() + { + } }; } diff --git a/src/p2p/net_peerlist.cpp b/src/p2p/net_peerlist.cpp new file mode 100644 index 000000000..ce5c67fe5 --- /dev/null +++ b/src/p2p/net_peerlist.cpp @@ -0,0 +1,295 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "net_peerlist.h" + +#include <algorithm> +#include <functional> +#include <fstream> +#include <iterator> + +#include <boost/archive/binary_iarchive.hpp> +#include <boost/archive/portable_binary_oarchive.hpp> +#include <boost/archive/portable_binary_iarchive.hpp> +#include <boost/filesystem/operations.hpp> +#include <boost/range/join.hpp> +#include <boost/serialization/version.hpp> + +#include "net_peerlist_boost_serialization.h" + + +namespace nodetool +{ + namespace + { + constexpr unsigned CURRENT_PEERLIST_STORAGE_ARCHIVE_VER = 6; + + struct by_zone + { + using zone = epee::net_utils::zone; + + template<typename T> + bool operator()(const T& left, const zone right) const + { + return left.adr.get_zone() < right; + } + + template<typename T> + bool operator()(const zone left, const T& right) const + { + return left < right.adr.get_zone(); + } + + template<typename T, typename U> + bool operator()(const T& left, const U& right) const + { + return left.adr.get_zone() < right.adr.get_zone(); + } + }; + + template<typename Elem, typename Archive> + std::vector<Elem> load_peers(Archive& a, unsigned ver) + { + // at v6, we drop existing peerlists, because annoying change + if (ver < 6) + return {}; + + uint64_t size = 0; + a & size; + + Elem ple{}; + + std::vector<Elem> elems{}; + elems.reserve(size); + while (size--) + { + a & ple; + elems.push_back(std::move(ple)); + } + + return elems; + } + + template<typename Archive, typename Range> + void save_peers(Archive& a, const Range& elems) + { + const uint64_t size = elems.size(); + a & size; + for (const auto& elem : elems) + a & elem; + } + + template<typename T> + std::vector<T> do_take_zone(std::vector<T>& src, epee::net_utils::zone zone) + { + const auto start = std::lower_bound(src.begin(), src.end(), zone, by_zone{}); + const auto end = std::upper_bound(start, src.end(), zone, by_zone{}); + + std::vector<T> out{}; + out.assign(std::make_move_iterator(start), std::make_move_iterator(end)); + src.erase(start, end); + return out; + } + + template<typename Container, typename T> + void add_peers(Container& dest, std::vector<T>&& src) + { + dest.insert(std::make_move_iterator(src.begin()), std::make_move_iterator(src.end())); + } + + template<typename Container, typename Range> + void copy_peers(Container& dest, const Range& src) + { + std::copy(src.begin(), src.end(), std::back_inserter(dest)); + } + } // anonymous + + struct peerlist_join + { + const peerlist_types& ours; + const peerlist_types& other; + }; + + template<typename Archive> + void serialize(Archive& a, peerlist_types& elem, unsigned ver) + { + elem.white = load_peers<peerlist_entry>(a, ver); + elem.gray = load_peers<peerlist_entry>(a, ver); + elem.anchor = load_peers<anchor_peerlist_entry>(a, ver); + + if (ver == 0) + { + // from v1, we do not store the peer id anymore + peerid_type peer_id{}; + a & peer_id; + } + } + + template<typename Archive> + void serialize(Archive& a, peerlist_join elem, unsigned ver) + { + save_peers(a, boost::range::join(elem.ours.white, elem.other.white)); + save_peers(a, boost::range::join(elem.ours.gray, elem.other.gray)); + save_peers(a, boost::range::join(elem.ours.anchor, elem.other.anchor)); + } + + boost::optional<peerlist_storage> peerlist_storage::open(std::istream& src, const bool new_format) + { + try + { + peerlist_storage out{}; + if (new_format) + { + boost::archive::portable_binary_iarchive a{src}; + a >> out.m_types; + } + else + { + boost::archive::binary_iarchive a{src}; + a >> out.m_types; + } + + if (src.good()) + { + std::sort(out.m_types.white.begin(), out.m_types.white.end(), by_zone{}); + std::sort(out.m_types.gray.begin(), out.m_types.gray.end(), by_zone{}); + std::sort(out.m_types.anchor.begin(), out.m_types.anchor.end(), by_zone{}); + return {std::move(out)}; + } + } + catch (const std::exception& e) + {} + + return boost::none; + } + + boost::optional<peerlist_storage> peerlist_storage::open(const std::string& path) + { + std::ifstream src_file{}; + src_file.open( path , std::ios_base::binary | std::ios_base::in); + if(src_file.fail()) + return boost::none; + + boost::optional<peerlist_storage> out = open(src_file, true); + if (!out) + { + // if failed, try reading in unportable mode + boost::filesystem::copy_file(path, path + ".unportable", boost::filesystem::copy_option::overwrite_if_exists); + src_file.close(); + src_file.open( path , std::ios_base::binary | std::ios_base::in); + if(src_file.fail()) + return boost::none; + + out = open(src_file, false); + if (!out) + { + // This is different from the `return boost::none` cases above. Those + // cases could fail due to bad file permissions, so a shutdown is + // likely more appropriate. + MWARNING("Failed to load p2p config file, falling back to default config"); + out.emplace(); + } + } + + return out; + } + + peerlist_storage::~peerlist_storage() noexcept + {} + + bool peerlist_storage::store(std::ostream& dest, const peerlist_types& other) const + { + try + { + boost::archive::portable_binary_oarchive a{dest}; + const peerlist_join pj{std::cref(m_types), std::cref(other)}; + a << pj; + return dest.good(); + } + catch (const boost::archive::archive_exception& e) + {} + + return false; + } + + bool peerlist_storage::store(const std::string& path, const peerlist_types& other) const + { + std::ofstream dest_file{}; + dest_file.open( path , std::ios_base::binary | std::ios_base::out| std::ios::trunc); + if(dest_file.fail()) + return false; + + return store(dest_file, other); + } + + peerlist_types peerlist_storage::take_zone(epee::net_utils::zone zone) + { + peerlist_types out{}; + out.white = do_take_zone(m_types.white, zone); + out.gray = do_take_zone(m_types.gray, zone); + out.anchor = do_take_zone(m_types.anchor, zone); + return out; + } + + bool peerlist_manager::init(peerlist_types&& peers, bool allow_local_ip) + { + CRITICAL_REGION_LOCAL(m_peerlist_lock); + + if (!m_peers_white.empty() || !m_peers_gray.empty() || !m_peers_anchor.empty()) + return false; + + add_peers(m_peers_white.get<by_addr>(), std::move(peers.white)); + add_peers(m_peers_gray.get<by_addr>(), std::move(peers.gray)); + add_peers(m_peers_anchor.get<by_addr>(), std::move(peers.anchor)); + m_allow_local_ip = allow_local_ip; + return true; + } + + void peerlist_manager::get_peerlist(std::vector<peerlist_entry>& pl_gray, std::vector<peerlist_entry>& pl_white) + { + CRITICAL_REGION_LOCAL(m_peerlist_lock); + copy_peers(pl_gray, m_peers_gray.get<by_addr>()); + copy_peers(pl_white, m_peers_white.get<by_addr>()); + } + + void peerlist_manager::get_peerlist(peerlist_types& peers) + { + CRITICAL_REGION_LOCAL(m_peerlist_lock); + peers.white.reserve(peers.white.size() + m_peers_white.size()); + peers.gray.reserve(peers.gray.size() + m_peers_gray.size()); + peers.anchor.reserve(peers.anchor.size() + m_peers_anchor.size()); + + copy_peers(peers.white, m_peers_white.get<by_addr>()); + copy_peers(peers.gray, m_peers_gray.get<by_addr>()); + copy_peers(peers.anchor, m_peers_anchor.get<by_addr>()); + } +} + +BOOST_CLASS_VERSION(nodetool::peerlist_types, nodetool::CURRENT_PEERLIST_STORAGE_ARCHIVE_VER); +BOOST_CLASS_VERSION(nodetool::peerlist_join, nodetool::CURRENT_PEERLIST_STORAGE_ARCHIVE_VER); + diff --git a/src/p2p/net_peerlist.h b/src/p2p/net_peerlist.h index e7aad5abe..46726d7d8 100644 --- a/src/p2p/net_peerlist.h +++ b/src/p2p/net_peerlist.h @@ -30,33 +30,67 @@ #pragma once +#include <iosfwd> #include <list> -#include <set> -#include <map> -#include <boost/archive/binary_iarchive.hpp> -#include <boost/archive/portable_binary_oarchive.hpp> -#include <boost/archive/portable_binary_iarchive.hpp> -#include <boost/serialization/version.hpp> +#include <string> +#include <vector> #include <boost/multi_index_container.hpp> #include <boost/multi_index/ordered_index.hpp> #include <boost/multi_index/identity.hpp> #include <boost/multi_index/member.hpp> +#include <boost/optional/optional.hpp> #include <boost/range/adaptor/reversed.hpp> -#include "syncobj.h" +#include "cryptonote_config.h" +#include "net/enums.h" #include "net/local_ip.h" #include "p2p_protocol_defs.h" -#include "cryptonote_config.h" -#include "net_peerlist_boost_serialization.h" - - -#define CURRENT_PEERLIST_STORAGE_ARCHIVE_VER 6 +#include "syncobj.h" namespace nodetool { + struct peerlist_types + { + std::vector<peerlist_entry> white; + std::vector<peerlist_entry> gray; + std::vector<anchor_peerlist_entry> anchor; + }; + + class peerlist_storage + { + public: + peerlist_storage() + : m_types{} + {} + //! \return Peers stored in stream `src` in `new_format` (portable archive or older non-portable). + static boost::optional<peerlist_storage> open(std::istream& src, const bool new_format); + + //! \return Peers stored in file at `path` + static boost::optional<peerlist_storage> open(const std::string& path); + + peerlist_storage(peerlist_storage&&) = default; + peerlist_storage(const peerlist_storage&) = delete; + + ~peerlist_storage() noexcept; + + peerlist_storage& operator=(peerlist_storage&&) = default; + peerlist_storage& operator=(const peerlist_storage&) = delete; + + //! Save peers from `this` and `other` in stream `dest`. + bool store(std::ostream& dest, const peerlist_types& other) const; + + //! Save peers from `this` and `other` in one file at `path`. + bool store(const std::string& path, const peerlist_types& other) const; + + //! \return Peers in `zone` and from remove from `this`. + peerlist_types take_zone(epee::net_utils::zone zone); + + private: + peerlist_types m_types; + }; /************************************************************************/ /* */ @@ -64,25 +98,27 @@ namespace nodetool class peerlist_manager { public: - bool init(bool allow_local_ip); - bool deinit(); + bool init(peerlist_types&& peers, bool allow_local_ip); size_t get_white_peers_count(){CRITICAL_REGION_LOCAL(m_peerlist_lock); return m_peers_white.size();} size_t get_gray_peers_count(){CRITICAL_REGION_LOCAL(m_peerlist_lock); return m_peers_gray.size();} bool merge_peerlist(const std::vector<peerlist_entry>& outer_bs); bool get_peerlist_head(std::vector<peerlist_entry>& bs_head, uint32_t depth = P2P_DEFAULT_PEERS_IN_HANDSHAKE); - bool get_peerlist_full(std::vector<peerlist_entry>& pl_gray, std::vector<peerlist_entry>& pl_white); + void get_peerlist(std::vector<peerlist_entry>& pl_gray, std::vector<peerlist_entry>& pl_white); + void get_peerlist(peerlist_types& peers); bool get_white_peer_by_index(peerlist_entry& p, size_t i); bool get_gray_peer_by_index(peerlist_entry& p, size_t i); + template<typename F> bool foreach(bool white, const F &f); bool append_with_peer_white(const peerlist_entry& pr); bool append_with_peer_gray(const peerlist_entry& pr); bool append_with_peer_anchor(const anchor_peerlist_entry& ple); - bool set_peer_just_seen(peerid_type peer, const epee::net_utils::network_address& addr); + bool set_peer_just_seen(peerid_type peer, const epee::net_utils::network_address& addr, uint32_t pruning_seed); bool set_peer_unreachable(const peerlist_entry& pr); bool is_host_allowed(const epee::net_utils::network_address &address); bool get_random_gray_peer(peerlist_entry& pe); bool remove_from_peer_gray(const peerlist_entry& pe); bool get_and_empty_anchor_peerlist(std::vector<anchor_peerlist_entry>& apl); bool remove_from_peer_anchor(const epee::net_utils::network_address& addr); + bool remove_from_peer_white(const peerlist_entry& pe); private: struct by_time{}; @@ -134,18 +170,6 @@ namespace nodetool > peers_indexed; typedef boost::multi_index_container< - peerlist_entry, - boost::multi_index::indexed_by< - // access by peerlist_entry::id< - boost::multi_index::ordered_unique<boost::multi_index::tag<by_id>, boost::multi_index::member<peerlist_entry,uint64_t,&peerlist_entry::id> >, - // access by peerlist_entry::net_adress - boost::multi_index::ordered_unique<boost::multi_index::tag<by_addr>, boost::multi_index::member<peerlist_entry,epee::net_utils::network_address,&peerlist_entry::adr> >, - // sort by peerlist_entry::last_seen< - boost::multi_index::ordered_non_unique<boost::multi_index::tag<by_time>, boost::multi_index::member<peerlist_entry,int64_t,&peerlist_entry::last_seen> > - > - > peers_indexed_old; - - typedef boost::multi_index_container< anchor_peerlist_entry, boost::multi_index::indexed_by< // access by anchor_peerlist_entry::net_adress @@ -154,56 +178,8 @@ namespace nodetool boost::multi_index::ordered_non_unique<boost::multi_index::tag<by_time>, boost::multi_index::member<anchor_peerlist_entry,int64_t,&anchor_peerlist_entry::first_seen> > > > anchor_peers_indexed; - public: - - template <class Archive, class List, class Element, class t_version_type> - void serialize_peers(Archive &a, List &list, Element ple, const t_version_type ver) - { - if (typename Archive::is_saving()) - { - uint64_t size = list.size(); - a & size; - for (auto p: list) - { - a & p; - } - } - else - { - uint64_t size; - a & size; - list.clear(); - while (size--) - { - a & ple; - list.insert(ple); - } - } - } - - template <class Archive, class t_version_type> - void serialize(Archive &a, const t_version_type ver) - { - // at v6, we drop existing peerlists, because annoying change - if (ver < 6) - return; - - CRITICAL_REGION_LOCAL(m_peerlist_lock); - -#if 0 - // trouble loading more than one peer, can't find why - a & m_peers_white; - a & m_peers_gray; - a & m_peers_anchor; -#else - serialize_peers(a, m_peers_white, peerlist_entry(), ver); - serialize_peers(a, m_peers_gray, peerlist_entry(), ver); - serialize_peers(a, m_peers_anchor, anchor_peerlist_entry(), ver); -#endif - } private: - bool peers_indexed_from_old(const peers_indexed_old& pio, peers_indexed& pi); void trim_white_peerlist(); void trim_gray_peerlist(); @@ -218,34 +194,6 @@ namespace nodetool anchor_peers_indexed m_peers_anchor; }; //-------------------------------------------------------------------------------------------------- - inline - bool peerlist_manager::init(bool allow_local_ip) - { - m_allow_local_ip = allow_local_ip; - return true; - } - //-------------------------------------------------------------------------------------------------- - inline - bool peerlist_manager::deinit() - { - return true; - } - //-------------------------------------------------------------------------------------------------- - inline - bool peerlist_manager::peers_indexed_from_old(const peers_indexed_old& pio, peers_indexed& pi) - { - for(auto x: pio) - { - auto by_addr_it = pi.get<by_addr>().find(x.adr); - if(by_addr_it == pi.get<by_addr>().end()) - { - pi.insert(x); - } - } - - return true; - } - //-------------------------------------------------------------------------------------------------- inline void peerlist_manager::trim_gray_peerlist() { while(m_peers_gray.size() > P2P_LOCAL_GRAY_PEERLIST_LIMIT) @@ -335,29 +283,19 @@ namespace nodetool return true; } //-------------------------------------------------------------------------------------------------- - inline - bool peerlist_manager::get_peerlist_full(std::vector<peerlist_entry>& pl_gray, std::vector<peerlist_entry>& pl_white) - { + template<typename F> inline + bool peerlist_manager::foreach(bool white, const F &f) + { CRITICAL_REGION_LOCAL(m_peerlist_lock); - peers_indexed::index<by_time>::type& by_time_index_gr=m_peers_gray.get<by_time>(); - pl_gray.resize(pl_gray.size() + by_time_index_gr.size()); - for(const peers_indexed::value_type& vl: boost::adaptors::reverse(by_time_index_gr)) - { - pl_gray.push_back(vl); - } - - peers_indexed::index<by_time>::type& by_time_index_wt=m_peers_white.get<by_time>(); - pl_white.resize(pl_white.size() + by_time_index_wt.size()); - for(const peers_indexed::value_type& vl: boost::adaptors::reverse(by_time_index_wt)) - { - pl_white.push_back(vl); - } - + peers_indexed::index<by_time>::type& by_time_index = white ? m_peers_white.get<by_time>() : m_peers_gray.get<by_time>(); + for(const peers_indexed::value_type& vl: boost::adaptors::reverse(by_time_index)) + if (!f(vl)) + return false; return true; } //-------------------------------------------------------------------------------------------------- inline - bool peerlist_manager::set_peer_just_seen(peerid_type peer, const epee::net_utils::network_address& addr) + bool peerlist_manager::set_peer_just_seen(peerid_type peer, const epee::net_utils::network_address& addr, uint32_t pruning_seed) { TRY_ENTRY(); CRITICAL_REGION_LOCAL(m_peerlist_lock); @@ -366,6 +304,7 @@ namespace nodetool ple.adr = addr; ple.id = peer; ple.last_seen = time(NULL); + ple.pruning_seed = pruning_seed; return append_with_peer_white(ple); CATCH_ENTRY_L0("peerlist_manager::set_peer_just_seen()", false); } @@ -469,6 +408,24 @@ namespace nodetool } //-------------------------------------------------------------------------------------------------- inline + bool peerlist_manager::remove_from_peer_white(const peerlist_entry& pe) + { + TRY_ENTRY(); + + CRITICAL_REGION_LOCAL(m_peerlist_lock); + + peers_indexed::index_iterator<by_addr>::type iterator = m_peers_white.get<by_addr>().find(pe.adr); + + if (iterator != m_peers_white.get<by_addr>().end()) { + m_peers_white.erase(iterator); + } + + return true; + + CATCH_ENTRY_L0("peerlist_manager::remove_from_peer_white()", false); + } + //-------------------------------------------------------------------------------------------------- + inline bool peerlist_manager::remove_from_peer_gray(const peerlist_entry& pe) { TRY_ENTRY(); @@ -527,4 +484,3 @@ namespace nodetool //-------------------------------------------------------------------------------------------------- } -BOOST_CLASS_VERSION(nodetool::peerlist_manager, CURRENT_PEERLIST_STORAGE_ARCHIVE_VER) diff --git a/src/p2p/net_peerlist_boost_serialization.h b/src/p2p/net_peerlist_boost_serialization.h index e79207888..d2e9efa3d 100644 --- a/src/p2p/net_peerlist_boost_serialization.h +++ b/src/p2p/net_peerlist_boost_serialization.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2018, The Monero Project + // Copyright (c) 2014-2018, The Monero Project // // All rights reserved. // @@ -30,32 +30,53 @@ #pragma once +#include <cstring> + +#include "common/expect.h" #include "net/net_utils_base.h" +#include "net/tor_address.h" #include "p2p/p2p_protocol_defs.h" +#ifdef CRYPTONOTE_PRUNING_DEBUG_SPOOF_SEED +#include "common/pruning.h" +#endif + namespace boost { namespace serialization { template <class T, class Archive> - inline void do_serialize(Archive &a, epee::net_utils::network_address& na, T local) + inline void do_serialize(boost::mpl::false_, Archive &a, epee::net_utils::network_address& na) + { + T addr{}; + a & addr; + na = std::move(addr); + } + + template <class T, class Archive> + inline void do_serialize(boost::mpl::true_, Archive &a, const epee::net_utils::network_address& na) { - if (typename Archive::is_saving()) local = na.as<T>(); - a & local; - if (!typename Archive::is_saving()) na = local; + a & na.as<T>(); } + template <class Archive, class ver_type> inline void serialize(Archive &a, epee::net_utils::network_address& na, const ver_type ver) { + static constexpr const typename Archive::is_saving is_saving{}; + uint8_t type; - if (typename Archive::is_saving()) - type = na.get_type_id(); + if (is_saving) + type = uint8_t(na.get_type_id()); a & type; - switch (type) + switch (epee::net_utils::address_type(type)) { - case epee::net_utils::ipv4_network_address::ID: - do_serialize(a, na, epee::net_utils::ipv4_network_address{0, 0}); - break; + case epee::net_utils::ipv4_network_address::get_type_id(): + do_serialize<epee::net_utils::ipv4_network_address>(is_saving, a, na); + break; + case net::tor_address::get_type_id(): + do_serialize<net::tor_address>(is_saving, a, na); + break; + case epee::net_utils::address_type::invalid: default: throw std::runtime_error("Unsupported network address type"); } @@ -72,11 +93,65 @@ namespace boost } template <class Archive, class ver_type> + inline void save(Archive& a, const net::tor_address& na, const ver_type) + { + const size_t length = std::strlen(na.host_str()); + if (length > 255) + MONERO_THROW(net::error::invalid_tor_address, "Tor address too long"); + + const uint16_t port{na.port()}; + const uint8_t len = length; + a & port; + a & len; + a.save_binary(na.host_str(), length); + } + + template <class Archive, class ver_type> + inline void load(Archive& a, net::tor_address& na, const ver_type) + { + uint16_t port = 0; + uint8_t length = 0; + a & port; + a & length; + + if (length > net::tor_address::buffer_size()) + MONERO_THROW(net::error::invalid_tor_address, "Tor address too long"); + + char host[net::tor_address::buffer_size()] = {0}; + a.load_binary(host, length); + host[sizeof(host) - 1] = 0; + + if (std::strcmp(host, net::tor_address::unknown_str()) == 0) + na = net::tor_address::unknown(); + else + na = MONERO_UNWRAP(net::tor_address::make(host, port)); + } + + template <class Archive, class ver_type> + inline void serialize(Archive &a, net::tor_address& na, const ver_type ver) + { + boost::serialization::split_free(a, na, ver); + } + + template <class Archive, class ver_type> inline void serialize(Archive &a, nodetool::peerlist_entry& pl, const ver_type ver) { a & pl.adr; a & pl.id; a & pl.last_seen; + if (ver < 1) + { + if (!typename Archive::is_saving()) + pl.pruning_seed = 0; + return; + } + a & pl.pruning_seed; +#ifdef CRYPTONOTE_PRUNING_DEBUG_SPOOF_SEED + if (!typename Archive::is_saving()) + { + pl.pruning_seed = tools::make_pruning_seed(1+pl.adr.as<epee::net_utils::ipv4_network_address>().ip() % (1<<CRYPTONOTE_PRUNING_LOG_STRIPES), CRYPTONOTE_PRUNING_LOG_STRIPES); + } +#endif } template <class Archive, class ver_type> diff --git a/src/p2p/p2p_protocol_defs.h b/src/p2p/p2p_protocol_defs.h index bb9d2635c..6e5e45008 100644 --- a/src/p2p/p2p_protocol_defs.h +++ b/src/p2p/p2p_protocol_defs.h @@ -31,8 +31,10 @@ #pragma once #include <boost/uuid/uuid.hpp> +#include <boost/serialization/version.hpp> #include "serialization/keyvalue_serialization.h" #include "net/net_utils_base.h" +#include "net/tor_address.h" // needed for serialization #include "misc_language.h" #include "string_tools.h" #include "time_helper.h" @@ -72,11 +74,13 @@ namespace nodetool AddressType adr; peerid_type id; int64_t last_seen; + uint32_t pruning_seed; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(adr) KV_SERIALIZE(id) KV_SERIALIZE(last_seen) + KV_SERIALIZE_OPT(pruning_seed, (uint32_t)0) END_KV_SERIALIZE_MAP() }; typedef peerlist_entry_base<epee::net_utils::network_address> peerlist_entry; @@ -122,7 +126,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() << " \tpruning seed " << pe.pruning_seed << " \tlast_seen: " << epee::misc_utils::get_time_interval_string(now_time - pe.last_seen) << std::endl; } return ss.str(); } @@ -201,11 +205,11 @@ namespace nodetool std::vector<peerlist_entry_base<network_address_old>> local_peerlist; for (const auto &p: this_ref.local_peerlist_new) { - if (p.adr.get_type_id() == epee::net_utils::ipv4_network_address::ID) + if (p.adr.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id()) { const epee::net_utils::network_address &na = p.adr; const epee::net_utils::ipv4_network_address &ipv4 = na.as<const epee::net_utils::ipv4_network_address>(); - local_peerlist.push_back(peerlist_entry_base<network_address_old>({{ipv4.ip(), ipv4.port()}, p.id, p.last_seen})); + local_peerlist.push_back(peerlist_entry_base<network_address_old>({{ipv4.ip(), ipv4.port()}, p.id, p.last_seen, p.pruning_seed})); } else MDEBUG("Not including in legacy peer list: " << p.adr.str()); @@ -220,7 +224,7 @@ namespace nodetool std::vector<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({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, p.pruning_seed})); } } END_KV_SERIALIZE_MAP() @@ -260,7 +264,7 @@ namespace nodetool std::vector<peerlist_entry_base<network_address_old>> local_peerlist; for (const auto &p: this_ref.local_peerlist_new) { - if (p.adr.get_type_id() == epee::net_utils::ipv4_network_address::ID) + if (p.adr.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id()) { const epee::net_utils::network_address &na = p.adr; const epee::net_utils::ipv4_network_address &ipv4 = na.as<const epee::net_utils::ipv4_network_address>(); @@ -463,5 +467,6 @@ namespace nodetool } +BOOST_CLASS_VERSION(nodetool::peerlist_entry, 1) diff --git a/src/ringct/bulletproofs.cc b/src/ringct/bulletproofs.cc index d485fb748..b5fd626dc 100644 --- a/src/ringct/bulletproofs.cc +++ b/src/ringct/bulletproofs.cc @@ -202,20 +202,36 @@ static rct::keyV vector_powers(const rct::key &x, size_t n) } /* Given a scalar, return the sum of its powers from 0 to n-1 */ -static rct::key vector_power_sum(const rct::key &x, size_t n) +static rct::key vector_power_sum(rct::key x, size_t n) { if (n == 0) return rct::zero(); rct::key res = rct::identity(); if (n == 1) return res; - rct::key prev = x; - for (size_t i = 1; i < n; ++i) + + const bool is_power_of_2 = (n & (n - 1)) == 0; + if (is_power_of_2) { - if (i > 1) - sc_mul(prev.bytes, prev.bytes, x.bytes); - sc_add(res.bytes, res.bytes, prev.bytes); + sc_add(res.bytes, res.bytes, x.bytes); + while (n > 2) + { + sc_mul(x.bytes, x.bytes, x.bytes); + sc_muladd(res.bytes, x.bytes, res.bytes, res.bytes); + n /= 2; + } + } + else + { + rct::key prev = x; + for (size_t i = 1; i < n; ++i) + { + if (i > 1) + sc_mul(prev.bytes, prev.bytes, x.bytes); + sc_add(res.bytes, res.bytes, prev.bytes); + } } + return res; } diff --git a/src/ringct/rctOps.cpp b/src/ringct/rctOps.cpp index 0ec654af6..e39ba16fd 100644 --- a/src/ringct/rctOps.cpp +++ b/src/ringct/rctOps.cpp @@ -670,18 +670,58 @@ namespace rct { //Elliptic Curve Diffie Helman: encodes and decodes the amount b and mask a // where C= aG + bH - void ecdhEncode(ecdhTuple & unmasked, const key & sharedSec) { - key sharedSec1 = hash_to_scalar(sharedSec); - key sharedSec2 = hash_to_scalar(sharedSec1); + static key ecdhHash(const key &k) + { + char data[38]; + rct::key hash; + memcpy(data, "amount", 6); + memcpy(data + 6, &k, sizeof(k)); + cn_fast_hash(hash, data, sizeof(data)); + return hash; + } + static void xor8(key &v, const key &k) + { + for (int i = 0; i < 8; ++i) + v.bytes[i] ^= k.bytes[i]; + } + key genCommitmentMask(const key &sk) + { + char data[15 + sizeof(key)]; + memcpy(data, "commitment_mask", 15); + memcpy(data + 15, &sk, sizeof(sk)); + key scalar; + hash_to_scalar(scalar, data, sizeof(data)); + return scalar; + } + + void ecdhEncode(ecdhTuple & unmasked, const key & sharedSec, bool v2) { //encode - sc_add(unmasked.mask.bytes, unmasked.mask.bytes, sharedSec1.bytes); - sc_add(unmasked.amount.bytes, unmasked.amount.bytes, sharedSec2.bytes); + if (v2) + { + unmasked.mask = zero(); + xor8(unmasked.amount, ecdhHash(sharedSec)); + } + else + { + key sharedSec1 = hash_to_scalar(sharedSec); + key sharedSec2 = hash_to_scalar(sharedSec1); + sc_add(unmasked.mask.bytes, unmasked.mask.bytes, sharedSec1.bytes); + sc_add(unmasked.amount.bytes, unmasked.amount.bytes, sharedSec2.bytes); + } } - void ecdhDecode(ecdhTuple & masked, const key & sharedSec) { - key sharedSec1 = hash_to_scalar(sharedSec); - key sharedSec2 = hash_to_scalar(sharedSec1); + void ecdhDecode(ecdhTuple & masked, const key & sharedSec, bool v2) { //decode - sc_sub(masked.mask.bytes, masked.mask.bytes, sharedSec1.bytes); - sc_sub(masked.amount.bytes, masked.amount.bytes, sharedSec2.bytes); + if (v2) + { + masked.mask = genCommitmentMask(sharedSec); + xor8(masked.amount, ecdhHash(sharedSec)); + } + else + { + key sharedSec1 = hash_to_scalar(sharedSec); + key sharedSec2 = hash_to_scalar(sharedSec1); + sc_sub(masked.mask.bytes, masked.mask.bytes, sharedSec1.bytes); + sc_sub(masked.amount.bytes, masked.amount.bytes, sharedSec2.bytes); + } } } diff --git a/src/ringct/rctOps.h b/src/ringct/rctOps.h index 60e920b3a..dd6d87593 100644 --- a/src/ringct/rctOps.h +++ b/src/ringct/rctOps.h @@ -182,7 +182,8 @@ namespace rct { //Elliptic Curve Diffie Helman: encodes and decodes the amount b and mask a // where C= aG + bH - void ecdhEncode(ecdhTuple & unmasked, const key & sharedSec); - void ecdhDecode(ecdhTuple & masked, const key & sharedSec); + key genCommitmentMask(const key &sk); + void ecdhEncode(ecdhTuple & unmasked, const key & sharedSec, bool v2); + void ecdhDecode(ecdhTuple & masked, const key & sharedSec, bool v2); } #endif /* RCTOPS_H */ diff --git a/src/ringct/rctSigs.cpp b/src/ringct/rctSigs.cpp index c5c6db3c1..81bec487c 100644 --- a/src/ringct/rctSigs.cpp +++ b/src/ringct/rctSigs.cpp @@ -79,9 +79,12 @@ namespace } namespace rct { - Bulletproof proveRangeBulletproof(keyV &C, keyV &masks, const std::vector<uint64_t> &amounts) + Bulletproof proveRangeBulletproof(keyV &C, keyV &masks, const std::vector<uint64_t> &amounts, epee::span<const key> sk) { - masks = rct::skvGen(amounts.size()); + CHECK_AND_ASSERT_THROW_MES(amounts.size() == sk.size(), "Invalid amounts/sk sizes"); + masks.resize(amounts.size()); + for (size_t i = 0; i < masks.size(); ++i) + masks[i] = genCommitmentMask(sk[i]); Bulletproof proof = bulletproof_PROVE(amounts, masks); CHECK_AND_ASSERT_THROW_MES(proof.V.size() == amounts.size(), "V does not have the expected size"); C = proof.V; @@ -416,7 +419,7 @@ namespace rct { hashes.push_back(hash2rct(h)); keyV kv; - if (rv.type == RCTTypeBulletproof) + if (rv.type == RCTTypeBulletproof || rv.type == RCTTypeBulletproof2) { kv.reserve((6*2+9) * rv.p.bulletproofs.size()); for (const auto &p: rv.p.bulletproofs) @@ -686,7 +689,7 @@ namespace rct { // must know the destination private key to find the correct amount, else will return a random number // Note: For txn fees, the last index in the amounts vector should contain that // Thus the amounts vector will be "one" longer than the destinations vectort - rctSig genRct(const key &message, const ctkeyV & inSk, const keyV & destinations, const vector<xmr_amount> & amounts, const ctkeyM &mixRing, const keyV &amount_keys, const multisig_kLRki *kLRki, multisig_out *msout, unsigned int index, ctkeyV &outSk, hw::device &hwdev) { + rctSig genRct(const key &message, const ctkeyV & inSk, const keyV & destinations, const vector<xmr_amount> & amounts, const ctkeyM &mixRing, const keyV &amount_keys, const multisig_kLRki *kLRki, multisig_out *msout, unsigned int index, ctkeyV &outSk, const RCTConfig &rct_config, hw::device &hwdev) { CHECK_AND_ASSERT_THROW_MES(amounts.size() == destinations.size() || amounts.size() == destinations.size() + 1, "Different number of amounts/destinations"); CHECK_AND_ASSERT_THROW_MES(amount_keys.size() == destinations.size(), "Different number of amount_keys/destinations"); CHECK_AND_ASSERT_THROW_MES(index < mixRing.size(), "Bad index into mixRing"); @@ -716,7 +719,7 @@ namespace rct { //mask amount and mask rv.ecdhInfo[i].mask = copy(outSk[i].mask); rv.ecdhInfo[i].amount = d2h(amounts[i]); - hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i]); + hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i], rv.type == RCTTypeBulletproof2); } //set txn fee @@ -737,18 +740,18 @@ namespace rct { return rv; } - rctSig genRct(const key &message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const vector<xmr_amount> & amounts, const keyV &amount_keys, const multisig_kLRki *kLRki, multisig_out *msout, const int mixin, hw::device &hwdev) { + rctSig genRct(const key &message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const vector<xmr_amount> & amounts, const keyV &amount_keys, const multisig_kLRki *kLRki, multisig_out *msout, const int mixin, const RCTConfig &rct_config, hw::device &hwdev) { unsigned int index; ctkeyM mixRing; ctkeyV outSk; tie(mixRing, index) = populateFromBlockchain(inPk, mixin); - return genRct(message, inSk, destinations, amounts, mixRing, amount_keys, kLRki, msout, index, outSk, hwdev); + return genRct(message, inSk, destinations, amounts, mixRing, amount_keys, kLRki, msout, index, outSk, rct_config, hwdev); } //RCT simple //for post-rct only - rctSig genRctSimple(const key &message, const ctkeyV & inSk, const keyV & destinations, const vector<xmr_amount> &inamounts, const vector<xmr_amount> &outamounts, xmr_amount txnFee, const ctkeyM & mixRing, const keyV &amount_keys, const std::vector<multisig_kLRki> *kLRki, multisig_out *msout, const std::vector<unsigned int> & index, ctkeyV &outSk, RangeProofType range_proof_type, hw::device &hwdev) { - const bool bulletproof = range_proof_type != RangeProofBorromean; + rctSig genRctSimple(const key &message, const ctkeyV & inSk, const keyV & destinations, const vector<xmr_amount> &inamounts, const vector<xmr_amount> &outamounts, xmr_amount txnFee, const ctkeyM & mixRing, const keyV &amount_keys, const std::vector<multisig_kLRki> *kLRki, multisig_out *msout, const std::vector<unsigned int> & index, ctkeyV &outSk, const RCTConfig &rct_config, hw::device &hwdev) { + const bool bulletproof = rct_config.range_proof_type != RangeProofBorromean; CHECK_AND_ASSERT_THROW_MES(inamounts.size() > 0, "Empty inamounts"); CHECK_AND_ASSERT_THROW_MES(inamounts.size() == inSk.size(), "Different number of inamounts/inSk"); CHECK_AND_ASSERT_THROW_MES(outamounts.size() == destinations.size(), "Different number of amounts/destinations"); @@ -764,7 +767,7 @@ namespace rct { } rctSig rv; - rv.type = bulletproof ? RCTTypeBulletproof : RCTTypeSimple; + rv.type = bulletproof ? (rct_config.bp_version == 0 || rct_config.bp_version >= 2 ? RCTTypeBulletproof2 : RCTTypeBulletproof) : RCTTypeSimple; rv.message = message; rv.outPk.resize(destinations.size()); if (!bulletproof) @@ -793,7 +796,7 @@ namespace rct { std::vector<uint64_t> proof_amounts; size_t n_amounts = outamounts.size(); size_t amounts_proved = 0; - if (range_proof_type == RangeProofPaddedBulletproof) + if (rct_config.range_proof_type == RangeProofPaddedBulletproof) { rct::keyV C, masks; if (hwdev.get_mode() == hw::device::TRANSACTION_CREATE_FAKE) @@ -803,7 +806,8 @@ namespace rct { } else { - rv.p.bulletproofs.push_back(proveRangeBulletproof(C, masks, outamounts)); + const epee::span<const key> keys{&amount_keys[0], amount_keys.size()}; + rv.p.bulletproofs.push_back(proveRangeBulletproof(C, masks, outamounts, keys)); #ifdef DBG CHECK_AND_ASSERT_THROW_MES(verBulletproof(rv.p.bulletproofs.back()), "verBulletproof failed on newly created proof"); #endif @@ -817,7 +821,7 @@ namespace rct { else while (amounts_proved < n_amounts) { size_t batch_size = 1; - if (range_proof_type == RangeProofMultiOutputBulletproof) + if (rct_config.range_proof_type == RangeProofMultiOutputBulletproof) while (batch_size * 2 + amounts_proved <= n_amounts && batch_size * 2 <= BULLETPROOF_MAX_OUTPUTS) batch_size *= 2; rct::keyV C, masks; @@ -831,7 +835,8 @@ namespace rct { } else { - rv.p.bulletproofs.push_back(proveRangeBulletproof(C, masks, batch_amounts)); + const epee::span<const key> keys{&amount_keys[amounts_proved], batch_size}; + rv.p.bulletproofs.push_back(proveRangeBulletproof(C, masks, batch_amounts, keys)); #ifdef DBG CHECK_AND_ASSERT_THROW_MES(verBulletproof(rv.p.bulletproofs.back()), "verBulletproof failed on newly created proof"); #endif @@ -853,7 +858,7 @@ namespace rct { //mask amount and mask rv.ecdhInfo[i].mask = copy(outSk[i].mask); rv.ecdhInfo[i].amount = d2h(outamounts[i]); - hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i]); + hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i], rv.type == RCTTypeBulletproof2); } //set txn fee @@ -884,7 +889,7 @@ namespace rct { return rv; } - rctSig genRctSimple(const key &message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const vector<xmr_amount> &inamounts, const vector<xmr_amount> &outamounts, const keyV &amount_keys, const std::vector<multisig_kLRki> *kLRki, multisig_out *msout, xmr_amount txnFee, unsigned int mixin, hw::device &hwdev) { + rctSig genRctSimple(const key &message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const vector<xmr_amount> &inamounts, const vector<xmr_amount> &outamounts, const keyV &amount_keys, const std::vector<multisig_kLRki> *kLRki, multisig_out *msout, xmr_amount txnFee, unsigned int mixin, const RCTConfig &rct_config, hw::device &hwdev) { std::vector<unsigned int> index; index.resize(inPk.size()); ctkeyM mixRing; @@ -894,7 +899,7 @@ namespace rct { mixRing[i].resize(mixin+1); index[i] = populateFromBlockchainSimple(mixRing[i], inPk[i], mixin); } - return genRctSimple(message, inSk, destinations, inamounts, outamounts, txnFee, mixRing, amount_keys, kLRki, msout, index, outSk, RangeProofBorromean, hwdev); + return genRctSimple(message, inSk, destinations, inamounts, outamounts, txnFee, mixRing, amount_keys, kLRki, msout, index, outSk, rct_config, hwdev); } //RingCT protocol @@ -984,7 +989,8 @@ namespace rct { { CHECK_AND_ASSERT_MES(rvp, false, "rctSig pointer is NULL"); const rctSig &rv = *rvp; - CHECK_AND_ASSERT_MES(rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof, false, "verRctSemanticsSimple called on non simple rctSig"); + CHECK_AND_ASSERT_MES(rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof || rv.type == RCTTypeBulletproof2, + false, "verRctSemanticsSimple called on non simple rctSig"); const bool bulletproof = is_rct_bulletproof(rv.type); if (bulletproof) { @@ -1083,7 +1089,8 @@ namespace rct { { PERF_TIMER(verRctNonSemanticsSimple); - CHECK_AND_ASSERT_MES(rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof, false, "verRctNonSemanticsSimple called on non simple rctSig"); + CHECK_AND_ASSERT_MES(rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof || rv.type == RCTTypeBulletproof2, + false, "verRctNonSemanticsSimple called on non simple rctSig"); const bool bulletproof = is_rct_bulletproof(rv.type); // semantics check is early, and mixRing/MGs aren't resolved yet if (bulletproof) @@ -1149,7 +1156,7 @@ namespace rct { //mask amount and mask ecdhTuple ecdh_info = rv.ecdhInfo[i]; - hwdev.ecdhDecode(ecdh_info, sk); + hwdev.ecdhDecode(ecdh_info, sk, rv.type == RCTTypeBulletproof2); mask = ecdh_info.mask; key amount = ecdh_info.amount; key C = rv.outPk[i].mask; @@ -1173,13 +1180,13 @@ namespace rct { } xmr_amount decodeRctSimple(const rctSig & rv, const key & sk, unsigned int i, key &mask, hw::device &hwdev) { - CHECK_AND_ASSERT_MES(rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof, false, "decodeRct called on non simple rctSig"); + CHECK_AND_ASSERT_MES(rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof || rv.type == RCTTypeBulletproof2, false, "decodeRct called on non simple rctSig"); CHECK_AND_ASSERT_THROW_MES(i < rv.ecdhInfo.size(), "Bad index"); CHECK_AND_ASSERT_THROW_MES(rv.outPk.size() == rv.ecdhInfo.size(), "Mismatched sizes of rv.outPk and rv.ecdhInfo"); //mask amount and mask ecdhTuple ecdh_info = rv.ecdhInfo[i]; - hwdev.ecdhDecode(ecdh_info, sk); + hwdev.ecdhDecode(ecdh_info, sk, rv.type == RCTTypeBulletproof2); mask = ecdh_info.mask; key amount = ecdh_info.amount; key C = rv.outPk[i].mask; @@ -1203,7 +1210,7 @@ namespace rct { } bool signMultisig(rctSig &rv, const std::vector<unsigned int> &indices, const keyV &k, const multisig_out &msout, const key &secret_key) { - CHECK_AND_ASSERT_MES(rv.type == RCTTypeFull || rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof, + CHECK_AND_ASSERT_MES(rv.type == RCTTypeFull || rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof || rv.type == RCTTypeBulletproof2, false, "unsupported rct type"); CHECK_AND_ASSERT_MES(indices.size() == k.size(), false, "Mismatched k/indices sizes"); CHECK_AND_ASSERT_MES(k.size() == rv.p.MGs.size(), false, "Mismatched k/MGs size"); diff --git a/src/ringct/rctSigs.h b/src/ringct/rctSigs.h index 459edc600..9227eab1e 100644 --- a/src/ringct/rctSigs.h +++ b/src/ringct/rctSigs.h @@ -119,10 +119,10 @@ namespace rct { //decodeRct: (c.f. https://eprint.iacr.org/2015/1098 section 5.1.1) // uses the attached ecdh info to find the amounts represented by each output commitment // must know the destination private key to find the correct amount, else will return a random number - rctSig genRct(const key &message, const ctkeyV & inSk, const keyV & destinations, const std::vector<xmr_amount> & amounts, const ctkeyM &mixRing, const keyV &amount_keys, const multisig_kLRki *kLRki, multisig_out *msout, unsigned int index, ctkeyV &outSk, hw::device &hwdev); - rctSig genRct(const key &message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const std::vector<xmr_amount> & amounts, const keyV &amount_keys, const multisig_kLRki *kLRki, multisig_out *msout, const int mixin, hw::device &hwdev); - rctSig genRctSimple(const key & message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const std::vector<xmr_amount> & inamounts, const std::vector<xmr_amount> & outamounts, const keyV &amount_keys, const std::vector<multisig_kLRki> *kLRki, multisig_out *msout, xmr_amount txnFee, unsigned int mixin, hw::device &hwdev); - rctSig genRctSimple(const key & message, const ctkeyV & inSk, const keyV & destinations, const std::vector<xmr_amount> & inamounts, const std::vector<xmr_amount> & outamounts, xmr_amount txnFee, const ctkeyM & mixRing, const keyV &amount_keys, const std::vector<multisig_kLRki> *kLRki, multisig_out *msout, const std::vector<unsigned int> & index, ctkeyV &outSk, RangeProofType range_proof_type, hw::device &hwdev); + rctSig genRct(const key &message, const ctkeyV & inSk, const keyV & destinations, const std::vector<xmr_amount> & amounts, const ctkeyM &mixRing, const keyV &amount_keys, const multisig_kLRki *kLRki, multisig_out *msout, unsigned int index, ctkeyV &outSk, const RCTConfig &rct_config, hw::device &hwdev); + rctSig genRct(const key &message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const std::vector<xmr_amount> & amounts, const keyV &amount_keys, const multisig_kLRki *kLRki, multisig_out *msout, const int mixin, const RCTConfig &rct_config, hw::device &hwdev); + rctSig genRctSimple(const key & message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const std::vector<xmr_amount> & inamounts, const std::vector<xmr_amount> & outamounts, const keyV &amount_keys, const std::vector<multisig_kLRki> *kLRki, multisig_out *msout, xmr_amount txnFee, unsigned int mixin, const RCTConfig &rct_config, hw::device &hwdev); + rctSig genRctSimple(const key & message, const ctkeyV & inSk, const keyV & destinations, const std::vector<xmr_amount> & inamounts, const std::vector<xmr_amount> & outamounts, xmr_amount txnFee, const ctkeyM & mixRing, const keyV &amount_keys, const std::vector<multisig_kLRki> *kLRki, multisig_out *msout, const std::vector<unsigned int> & index, ctkeyV &outSk, const RCTConfig &rct_config, hw::device &hwdev); bool verRct(const rctSig & rv, bool semantics); static inline bool verRct(const rctSig & rv) { return verRct(rv, true) && verRct(rv, false); } bool verRctSemanticsSimple(const rctSig & rv); diff --git a/src/ringct/rctTypes.cpp b/src/ringct/rctTypes.cpp index 90ed65df0..f01e683cb 100644 --- a/src/ringct/rctTypes.cpp +++ b/src/ringct/rctTypes.cpp @@ -217,6 +217,7 @@ namespace rct { { case RCTTypeSimple: case RCTTypeBulletproof: + case RCTTypeBulletproof2: return true; default: return false; @@ -228,6 +229,7 @@ namespace rct { switch (type) { case RCTTypeBulletproof: + case RCTTypeBulletproof2: return true; default: return false; diff --git a/src/ringct/rctTypes.h b/src/ringct/rctTypes.h index 487ea6f32..50d0f4d91 100644 --- a/src/ringct/rctTypes.h +++ b/src/ringct/rctTypes.h @@ -120,17 +120,14 @@ namespace rct { // If the pedersen commitment to an amount is C = aG + bH, // "mask" contains a 32 byte key a // "amount" contains a hex representation (in 32 bytes) of a 64 bit number - // "senderPk" is not the senders actual public key, but a one-time public key generated for // the purpose of the ECDH exchange struct ecdhTuple { key mask; key amount; - key senderPk; BEGIN_SERIALIZE_OBJECT() - FIELD(mask) + FIELD(mask) // not saved from v2 BPs FIELD(amount) - // FIELD(senderPk) // not serialized, as we do not use it in monero currently END_SERIALIZE() }; @@ -231,8 +228,13 @@ namespace rct { RCTTypeFull = 1, RCTTypeSimple = 2, RCTTypeBulletproof = 3, + RCTTypeBulletproof2 = 4, }; enum RangeProofType { RangeProofBorromean, RangeProofBulletproof, RangeProofMultiOutputBulletproof, RangeProofPaddedBulletproof }; + struct RCTConfig { + RangeProofType range_proof_type; + int bp_version; + }; struct rctSigBase { uint8_t type; key message; @@ -249,7 +251,7 @@ namespace rct { FIELD(type) if (type == RCTTypeNull) return true; - if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof) + if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2) return false; VARINT_FIELD(txnFee) // inputs/outputs not saved, only here for serialization help @@ -278,7 +280,19 @@ namespace rct { return false; for (size_t i = 0; i < outputs; ++i) { - FIELDS(ecdhInfo[i]) + if (type == RCTTypeBulletproof2) + { + ar.begin_object(); + if (!typename Archive<W>::is_saving()) + memset(ecdhInfo[i].amount.bytes, 0, sizeof(ecdhInfo[i].amount.bytes)); + crypto::hash8 &amount = (crypto::hash8&)ecdhInfo[i].amount; + FIELD(amount); + ar.end_object(); + } + else + { + FIELDS(ecdhInfo[i]) + } if (outputs - i > 1) ar.delimit_array(); } @@ -310,12 +324,15 @@ namespace rct { { if (type == RCTTypeNull) return true; - if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof) + if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2) return false; - if (type == RCTTypeBulletproof) + if (type == RCTTypeBulletproof || type == RCTTypeBulletproof2) { uint32_t nbp = bulletproofs.size(); - FIELD(nbp) + if (type == RCTTypeBulletproof2) + VARINT_FIELD(nbp) + else + FIELD(nbp) ar.tag("bp"); ar.begin_array(); if (nbp > outputs) @@ -351,7 +368,7 @@ namespace rct { ar.begin_array(); // we keep a byte for size of MGs, because we don't know whether this is // a simple or full rct signature, and it's starting to annoy the hell out of me - size_t mg_elements = (type == RCTTypeSimple || type == RCTTypeBulletproof) ? inputs : 1; + size_t mg_elements = (type == RCTTypeSimple || type == RCTTypeBulletproof || type == RCTTypeBulletproof2) ? inputs : 1; PREPARE_CUSTOM_VECTOR_SERIALIZATION(mg_elements, MGs); if (MGs.size() != mg_elements) return false; @@ -369,7 +386,7 @@ namespace rct { for (size_t j = 0; j < mixin + 1; ++j) { ar.begin_array(); - size_t mg_ss2_elements = ((type == RCTTypeSimple || type == RCTTypeBulletproof) ? 1 : inputs) + 1; + size_t mg_ss2_elements = ((type == RCTTypeSimple || type == RCTTypeBulletproof || type == RCTTypeBulletproof2) ? 1 : inputs) + 1; PREPARE_CUSTOM_VECTOR_SERIALIZATION(mg_ss2_elements, MGs[i].ss[j]); if (MGs[i].ss[j].size() != mg_ss2_elements) return false; @@ -395,7 +412,7 @@ namespace rct { ar.delimit_array(); } ar.end_array(); - if (type == RCTTypeBulletproof) + if (type == RCTTypeBulletproof || type == RCTTypeBulletproof2) { ar.tag("pseudoOuts"); ar.begin_array(); @@ -419,12 +436,12 @@ namespace rct { keyV& get_pseudo_outs() { - return type == RCTTypeBulletproof ? p.pseudoOuts : pseudoOuts; + return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 ? p.pseudoOuts : pseudoOuts; } keyV const& get_pseudo_outs() const { - return type == RCTTypeBulletproof ? p.pseudoOuts : pseudoOuts; + return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 ? p.pseudoOuts : pseudoOuts; } }; diff --git a/src/rpc/CMakeLists.txt b/src/rpc/CMakeLists.txt index d2c4a33cb..60cae036c 100644 --- a/src/rpc/CMakeLists.txt +++ b/src/rpc/CMakeLists.txt @@ -112,6 +112,7 @@ target_link_libraries(rpc common cryptonote_core cryptonote_protocol + net version ${Boost_REGEX_LIBRARY} ${Boost_THREAD_LIBRARY} diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index d20000a53..d18774149 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -42,6 +42,7 @@ using namespace epee; #include "cryptonote_basic/account.h" #include "cryptonote_basic/cryptonote_basic_impl.h" #include "misc_language.h" +#include "net/parse.h" #include "storages/http_abstract_invoke.h" #include "crypto/hash.h" #include "rpc/rpc_args.h" @@ -75,6 +76,11 @@ namespace cryptonote command_line::add_arg(desc, arg_rpc_bind_port); command_line::add_arg(desc, arg_rpc_restricted_bind_port); command_line::add_arg(desc, arg_restricted_rpc); + command_line::add_arg(desc, arg_rpc_ssl); + command_line::add_arg(desc, arg_rpc_ssl_private_key); + command_line::add_arg(desc, arg_rpc_ssl_certificate); + command_line::add_arg(desc, arg_rpc_ssl_allowed_certificates); + command_line::add_arg(desc, arg_rpc_ssl_allow_any_cert); command_line::add_arg(desc, arg_bootstrap_daemon_address); command_line::add_arg(desc, arg_bootstrap_daemon_login); cryptonote::rpc_args::init_options(desc); @@ -111,11 +117,11 @@ namespace cryptonote epee::net_utils::http::login login; login.username = bootstrap_daemon_login.substr(0, loc); login.password = bootstrap_daemon_login.substr(loc + 1); - m_http_client.set_server(m_bootstrap_daemon_address, login, false); + m_http_client.set_server(m_bootstrap_daemon_address, login, epee::net_utils::ssl_support_t::e_ssl_support_autodetect); } else { - m_http_client.set_server(m_bootstrap_daemon_address, boost::none, false); + m_http_client.set_server(m_bootstrap_daemon_address, boost::none, epee::net_utils::ssl_support_t::e_ssl_support_autodetect); } m_should_use_bootstrap_daemon = true; } @@ -130,9 +136,32 @@ namespace cryptonote if (rpc_config->login) http_login.emplace(std::move(rpc_config->login->username), std::move(rpc_config->login->password).password()); + epee::net_utils::ssl_support_t ssl_support; + const std::string ssl = command_line::get_arg(vm, arg_rpc_ssl); + if (!epee::net_utils::ssl_support_from_string(ssl_support, ssl)) + { + MFATAL("Invalid RPC SSL support: " << ssl); + return false; + } + const std::string ssl_private_key = command_line::get_arg(vm, arg_rpc_ssl_private_key); + const std::string ssl_certificate = command_line::get_arg(vm, arg_rpc_ssl_certificate); + const std::vector<std::string> ssl_allowed_certificate_paths = command_line::get_arg(vm, arg_rpc_ssl_allowed_certificates); + std::list<std::string> ssl_allowed_certificates; + for (const std::string &path: ssl_allowed_certificate_paths) + { + ssl_allowed_certificates.push_back({}); + if (!epee::file_io_utils::load_file_to_string(path, ssl_allowed_certificates.back())) + { + MERROR("Failed to load certificate: " << path); + ssl_allowed_certificates.back() = std::string(); + } + } + const bool ssl_allow_any_cert = command_line::get_arg(vm, arg_rpc_ssl_allow_any_cert); + auto rng = [](size_t len, uint8_t *ptr){ return crypto::rand(len, ptr); }; return epee::http_server_impl_base<core_rpc_server, connection_context>::init( - rng, std::move(port), std::move(rpc_config->bind_ip), std::move(rpc_config->access_control_origins), std::move(http_login) + rng, std::move(port), std::move(rpc_config->bind_ip), std::move(rpc_config->access_control_origins), std::move(http_login), + ssl_support, std::make_pair(ssl_private_key, ssl_certificate), ssl_allowed_certificates, ssl_allow_any_cert ); } //------------------------------------------------------------------------------------------------------------------------------ @@ -147,7 +176,7 @@ namespace cryptonote #define CHECK_CORE_READY() do { if(!check_core_ready()){res.status = CORE_RPC_STATUS_BUSY;return true;} } while(0) //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_height(const COMMAND_RPC_GET_HEIGHT::request& req, COMMAND_RPC_GET_HEIGHT::response& res) + bool core_rpc_server::on_get_height(const COMMAND_RPC_GET_HEIGHT::request& req, COMMAND_RPC_GET_HEIGHT::response& res, const connection_context *ctx) { PERF_TIMER(on_get_height); bool r; @@ -159,7 +188,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_info(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res) + bool core_rpc_server::on_get_info(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res, const connection_context *ctx) { PERF_TIMER(on_get_info); bool r; @@ -173,6 +202,8 @@ namespace cryptonote return r; } + const bool restricted = m_restricted && ctx; + crypto::hash top_hash; m_core.get_blockchain_top(res.height, top_hash); ++res.height; // turn top block height into blockchain height @@ -182,13 +213,13 @@ namespace cryptonote res.target = m_core.get_blockchain_storage().get_difficulty_target(); res.tx_count = m_core.get_blockchain_storage().get_total_transactions() - res.height; //without coinbase res.tx_pool_size = m_core.get_pool_transactions_count(); - res.alt_blocks_count = m_restricted ? 0 : m_core.get_blockchain_storage().get_alternative_blocks_count(); - uint64_t total_conn = m_restricted ? 0 : m_p2p.get_connections_count(); - res.outgoing_connections_count = m_restricted ? 0 : m_p2p.get_outgoing_connections_count(); - res.incoming_connections_count = m_restricted ? 0 : (total_conn - res.outgoing_connections_count); - res.rpc_connections_count = m_restricted ? 0 : get_connections_count(); - res.white_peerlist_size = m_restricted ? 0 : m_p2p.get_peerlist_manager().get_white_peers_count(); - res.grey_peerlist_size = m_restricted ? 0 : m_p2p.get_peerlist_manager().get_gray_peers_count(); + res.alt_blocks_count = restricted ? 0 : m_core.get_blockchain_storage().get_alternative_blocks_count(); + uint64_t total_conn = restricted ? 0 : m_p2p.get_public_connections_count(); + res.outgoing_connections_count = restricted ? 0 : m_p2p.get_public_outgoing_connections_count(); + res.incoming_connections_count = restricted ? 0 : (total_conn - res.outgoing_connections_count); + res.rpc_connections_count = restricted ? 0 : get_connections_count(); + res.white_peerlist_size = restricted ? 0 : m_p2p.get_public_white_peers_count(); + res.grey_peerlist_size = restricted ? 0 : m_p2p.get_public_gray_peers_count(); cryptonote::network_type net_type = nettype(); res.mainnet = net_type == MAINNET; @@ -199,21 +230,21 @@ namespace cryptonote res.block_size_limit = res.block_weight_limit = m_core.get_blockchain_storage().get_current_cumulative_block_weight_limit(); res.block_size_median = res.block_weight_median = m_core.get_blockchain_storage().get_current_cumulative_block_weight_median(); res.status = CORE_RPC_STATUS_OK; - res.start_time = m_restricted ? 0 : (uint64_t)m_core.get_start_time(); - res.free_space = m_restricted ? std::numeric_limits<uint64_t>::max() : m_core.get_free_space(); + res.start_time = restricted ? 0 : (uint64_t)m_core.get_start_time(); + res.free_space = restricted ? std::numeric_limits<uint64_t>::max() : m_core.get_free_space(); res.offline = m_core.offline(); - res.bootstrap_daemon_address = m_restricted ? "" : m_bootstrap_daemon_address; - res.height_without_bootstrap = m_restricted ? 0 : res.height; - if (m_restricted) + res.bootstrap_daemon_address = restricted ? "" : m_bootstrap_daemon_address; + res.height_without_bootstrap = restricted ? 0 : res.height; + if (restricted) res.was_bootstrap_ever_used = false; else { boost::shared_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex); res.was_bootstrap_ever_used = m_was_bootstrap_ever_used; } - res.database_size = m_restricted ? 0 : m_core.get_blockchain_storage().get_db().get_database_size(); - res.update_available = m_restricted ? false : m_core.is_update_available(); - res.version = m_restricted ? "" : MONERO_VERSION; + res.database_size = restricted ? 0 : m_core.get_blockchain_storage().get_db().get_database_size(); + res.update_available = restricted ? false : m_core.is_update_available(); + res.version = restricted ? "" : MONERO_VERSION; return true; } //------------------------------------------------------------------------------------------------------------------------------ @@ -227,7 +258,7 @@ namespace cryptonote END_SERIALIZE() }; //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_blocks(const COMMAND_RPC_GET_BLOCKS_FAST::request& req, COMMAND_RPC_GET_BLOCKS_FAST::response& res) + bool core_rpc_server::on_get_blocks(const COMMAND_RPC_GET_BLOCKS_FAST::request& req, COMMAND_RPC_GET_BLOCKS_FAST::response& res, const connection_context *ctx) { PERF_TIMER(on_get_blocks); bool r; @@ -290,7 +321,7 @@ namespace cryptonote res.status = CORE_RPC_STATUS_OK; return true; } - bool core_rpc_server::on_get_alt_blocks_hashes(const COMMAND_RPC_GET_ALT_BLOCKS_HASHES::request& req, COMMAND_RPC_GET_ALT_BLOCKS_HASHES::response& res) + bool core_rpc_server::on_get_alt_blocks_hashes(const COMMAND_RPC_GET_ALT_BLOCKS_HASHES::request& req, COMMAND_RPC_GET_ALT_BLOCKS_HASHES::response& res, const connection_context *ctx) { PERF_TIMER(on_get_alt_blocks_hashes); bool r; @@ -317,7 +348,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_blocks_by_height(const COMMAND_RPC_GET_BLOCKS_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCKS_BY_HEIGHT::response& res) + bool core_rpc_server::on_get_blocks_by_height(const COMMAND_RPC_GET_BLOCKS_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCKS_BY_HEIGHT::response& res, const connection_context *ctx) { PERF_TIMER(on_get_blocks_by_height); bool r; @@ -351,7 +382,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_hashes(const COMMAND_RPC_GET_HASHES_FAST::request& req, COMMAND_RPC_GET_HASHES_FAST::response& res) + bool core_rpc_server::on_get_hashes(const COMMAND_RPC_GET_HASHES_FAST::request& req, COMMAND_RPC_GET_HASHES_FAST::response& res, const connection_context *ctx) { PERF_TIMER(on_get_hashes); bool r; @@ -374,7 +405,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_outs_bin(const COMMAND_RPC_GET_OUTPUTS_BIN::request& req, COMMAND_RPC_GET_OUTPUTS_BIN::response& res) + bool core_rpc_server::on_get_outs_bin(const COMMAND_RPC_GET_OUTPUTS_BIN::request& req, COMMAND_RPC_GET_OUTPUTS_BIN::response& res, const connection_context *ctx) { PERF_TIMER(on_get_outs_bin); bool r; @@ -383,7 +414,8 @@ namespace cryptonote res.status = "Failed"; - if (m_restricted) + const bool restricted = m_restricted && ctx; + if (restricted) { if (req.outputs.size() > MAX_RESTRICTED_GLOBAL_FAKE_OUTS_COUNT) { @@ -401,7 +433,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_outs(const COMMAND_RPC_GET_OUTPUTS::request& req, COMMAND_RPC_GET_OUTPUTS::response& res) + bool core_rpc_server::on_get_outs(const COMMAND_RPC_GET_OUTPUTS::request& req, COMMAND_RPC_GET_OUTPUTS::response& res, const connection_context *ctx) { PERF_TIMER(on_get_outs); bool r; @@ -410,7 +442,8 @@ namespace cryptonote res.status = "Failed"; - if (m_restricted) + const bool restricted = m_restricted && ctx; + if (restricted) { if (req.outputs.size() > MAX_RESTRICTED_GLOBAL_FAKE_OUTS_COUNT) { @@ -443,7 +476,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_indexes(const COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request& req, COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response& res) + bool core_rpc_server::on_get_indexes(const COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request& req, COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response& res, const connection_context *ctx) { PERF_TIMER(on_get_indexes); bool ok; @@ -461,7 +494,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_transactions(const COMMAND_RPC_GET_TRANSACTIONS::request& req, COMMAND_RPC_GET_TRANSACTIONS::response& res) + bool core_rpc_server::on_get_transactions(const COMMAND_RPC_GET_TRANSACTIONS::request& req, COMMAND_RPC_GET_TRANSACTIONS::response& res, const connection_context *ctx) { PERF_TIMER(on_get_transactions); bool ok; @@ -485,8 +518,8 @@ namespace cryptonote vh.push_back(*reinterpret_cast<const crypto::hash*>(b.data())); } std::vector<crypto::hash> missed_txs; - std::vector<transaction> txs; - bool r = m_core.get_transactions(vh, txs, missed_txs); + std::vector<std::tuple<crypto::hash, cryptonote::blobdata, crypto::hash, cryptonote::blobdata>> txs; + bool r = m_core.get_split_transactions_blobs(vh, txs, missed_txs); if(!r) { res.status = "Failed"; @@ -506,7 +539,7 @@ namespace cryptonote if(r) { // sort to match original request - std::vector<transaction> sorted_txs; + std::vector<std::tuple<crypto::hash, cryptonote::blobdata, crypto::hash, cryptonote::blobdata>> sorted_txs; std::vector<tx_info>::const_iterator i; unsigned txs_processed = 0; for (const crypto::hash &h: vh) @@ -519,7 +552,7 @@ namespace cryptonote return true; } // core returns the ones it finds in the right order - if (get_transaction_hash(txs[txs_processed]) != h) + if (std::get<0>(txs[txs_processed]) != h) { res.status = "Failed: tx hash mismatch"; return true; @@ -535,7 +568,16 @@ namespace cryptonote res.status = "Failed to parse and validate tx from blob"; return true; } - sorted_txs.push_back(tx); + std::stringstream ss; + binary_archive<true> ba(ss); + bool r = const_cast<cryptonote::transaction&>(tx).serialize_base(ba); + if (!r) + { + res.status = "Failed to serialize transaction base"; + return true; + } + const cryptonote::blobdata pruned = ss.str(); + sorted_txs.push_back(std::make_tuple(h, pruned, get_transaction_prunable_hash(tx), std::string(i->tx_blob, pruned.size()))); missed_txs.erase(std::find(missed_txs.begin(), missed_txs.end(), h)); pool_tx_hashes.insert(h); const std::string hash_string = epee::string_tools::pod_to_hex(h); @@ -564,11 +606,36 @@ namespace cryptonote crypto::hash tx_hash = *vhi++; e.tx_hash = *txhi++; - pruned_transaction pruned_tx{tx}; - blobdata blob = req.prune ? t_serializable_object_to_blob(pruned_tx) : t_serializable_object_to_blob(tx); - e.as_hex = string_tools::buff_to_hex_nodelimer(blob); - if (req.decode_as_json) - e.as_json = req.prune ? obj_to_json_str(pruned_tx) : obj_to_json_str(tx); + e.prunable_hash = epee::string_tools::pod_to_hex(std::get<2>(tx)); + if (req.split || req.prune || std::get<3>(tx).empty()) + { + e.pruned_as_hex = string_tools::buff_to_hex_nodelimer(std::get<1>(tx)); + if (!req.prune) + e.prunable_as_hex = string_tools::buff_to_hex_nodelimer(std::get<3>(tx)); + } + else + { + cryptonote::blobdata tx_data; + if (req.prune) + tx_data = std::get<1>(tx); + else + tx_data = std::get<1>(tx) + std::get<3>(tx); + e.as_hex = string_tools::buff_to_hex_nodelimer(tx_data); + if (req.decode_as_json && !tx_data.empty()) + { + cryptonote::transaction t; + if (cryptonote::parse_and_validate_tx_from_blob(tx_data, t)) + { + if (req.prune) + { + pruned_transaction pruned_tx{t}; + e.as_json = obj_to_json_str(pruned_tx); + } + else + e.as_json = obj_to_json_str(t); + } + } + } e.in_pool = pool_tx_hashes.find(tx_hash) != pool_tx_hashes.end(); if (e.in_pool) { @@ -617,13 +684,15 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_is_key_image_spent(const COMMAND_RPC_IS_KEY_IMAGE_SPENT::request& req, COMMAND_RPC_IS_KEY_IMAGE_SPENT::response& res, bool request_has_rpc_origin) + bool core_rpc_server::on_is_key_image_spent(const COMMAND_RPC_IS_KEY_IMAGE_SPENT::request& req, COMMAND_RPC_IS_KEY_IMAGE_SPENT::response& res, const connection_context *ctx) { PERF_TIMER(on_is_key_image_spent); bool ok; if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_IS_KEY_IMAGE_SPENT>(invoke_http_mode::JON, "/is_key_image_spent", req, res, ok)) return ok; + const bool restricted = m_restricted && ctx; + const bool request_has_rpc_origin = ctx != NULL; std::vector<crypto::key_image> key_images; for(const auto& ki_hex_str: req.key_images) { @@ -653,7 +722,7 @@ namespace cryptonote // check the pool too std::vector<cryptonote::tx_info> txs; std::vector<cryptonote::spent_key_image_info> ki; - r = m_core.get_pool_transactions_and_spent_keys_info(txs, ki, !request_has_rpc_origin || !m_restricted); + r = m_core.get_pool_transactions_and_spent_keys_info(txs, ki, !request_has_rpc_origin || !restricted); if(!r) { res.status = "Failed"; @@ -684,7 +753,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_send_raw_tx(const COMMAND_RPC_SEND_RAW_TX::request& req, COMMAND_RPC_SEND_RAW_TX::response& res) + bool core_rpc_server::on_send_raw_tx(const COMMAND_RPC_SEND_RAW_TX::request& req, COMMAND_RPC_SEND_RAW_TX::response& res, const connection_context *ctx) { PERF_TIMER(on_send_raw_tx); bool ok; @@ -752,7 +821,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_start_mining(const COMMAND_RPC_START_MINING::request& req, COMMAND_RPC_START_MINING::response& res) + bool core_rpc_server::on_start_mining(const COMMAND_RPC_START_MINING::request& req, COMMAND_RPC_START_MINING::response& res, const connection_context *ctx) { PERF_TIMER(on_start_mining); CHECK_CORE_READY(); @@ -806,7 +875,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_stop_mining(const COMMAND_RPC_STOP_MINING::request& req, COMMAND_RPC_STOP_MINING::response& res) + bool core_rpc_server::on_stop_mining(const COMMAND_RPC_STOP_MINING::request& req, COMMAND_RPC_STOP_MINING::response& res, const connection_context *ctx) { PERF_TIMER(on_stop_mining); cryptonote::miner &miner= m_core.get_miner(); @@ -826,7 +895,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_mining_status(const COMMAND_RPC_MINING_STATUS::request& req, COMMAND_RPC_MINING_STATUS::response& res) + bool core_rpc_server::on_mining_status(const COMMAND_RPC_MINING_STATUS::request& req, COMMAND_RPC_MINING_STATUS::response& res, const connection_context *ctx) { PERF_TIMER(on_mining_status); @@ -845,7 +914,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_save_bc(const COMMAND_RPC_SAVE_BC::request& req, COMMAND_RPC_SAVE_BC::response& res) + bool core_rpc_server::on_save_bc(const COMMAND_RPC_SAVE_BC::request& req, COMMAND_RPC_SAVE_BC::response& res, const connection_context *ctx) { PERF_TIMER(on_save_bc); if( !m_core.get_blockchain_storage().store_blockchain() ) @@ -857,38 +926,38 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_peer_list(const COMMAND_RPC_GET_PEER_LIST::request& req, COMMAND_RPC_GET_PEER_LIST::response& res) + bool core_rpc_server::on_get_peer_list(const COMMAND_RPC_GET_PEER_LIST::request& req, COMMAND_RPC_GET_PEER_LIST::response& res, const connection_context *ctx) { PERF_TIMER(on_get_peer_list); std::vector<nodetool::peerlist_entry> white_list; std::vector<nodetool::peerlist_entry> gray_list; - m_p2p.get_peerlist_manager().get_peerlist_full(gray_list, white_list); + m_p2p.get_public_peerlist(gray_list, white_list); res.white_list.reserve(white_list.size()); for (auto & entry : white_list) { - if (entry.adr.get_type_id() == epee::net_utils::ipv4_network_address::ID) + if (entry.adr.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id()) res.white_list.emplace_back(entry.id, entry.adr.as<epee::net_utils::ipv4_network_address>().ip(), - entry.adr.as<epee::net_utils::ipv4_network_address>().port(), entry.last_seen); + entry.adr.as<epee::net_utils::ipv4_network_address>().port(), entry.last_seen, entry.pruning_seed); else - res.white_list.emplace_back(entry.id, entry.adr.str(), entry.last_seen); + res.white_list.emplace_back(entry.id, entry.adr.str(), entry.last_seen, entry.pruning_seed); } res.gray_list.reserve(gray_list.size()); for (auto & entry : gray_list) { - if (entry.adr.get_type_id() == epee::net_utils::ipv4_network_address::ID) + if (entry.adr.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id()) res.gray_list.emplace_back(entry.id, entry.adr.as<epee::net_utils::ipv4_network_address>().ip(), - entry.adr.as<epee::net_utils::ipv4_network_address>().port(), entry.last_seen); + entry.adr.as<epee::net_utils::ipv4_network_address>().port(), entry.last_seen, entry.pruning_seed); else - res.gray_list.emplace_back(entry.id, entry.adr.str(), entry.last_seen); + res.gray_list.emplace_back(entry.id, entry.adr.str(), entry.last_seen, entry.pruning_seed); } res.status = CORE_RPC_STATUS_OK; return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_set_log_hash_rate(const COMMAND_RPC_SET_LOG_HASH_RATE::request& req, COMMAND_RPC_SET_LOG_HASH_RATE::response& res) + bool core_rpc_server::on_set_log_hash_rate(const COMMAND_RPC_SET_LOG_HASH_RATE::request& req, COMMAND_RPC_SET_LOG_HASH_RATE::response& res, const connection_context *ctx) { PERF_TIMER(on_set_log_hash_rate); if(m_core.get_miner().is_mining()) @@ -903,7 +972,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_set_log_level(const COMMAND_RPC_SET_LOG_LEVEL::request& req, COMMAND_RPC_SET_LOG_LEVEL::response& res) + bool core_rpc_server::on_set_log_level(const COMMAND_RPC_SET_LOG_LEVEL::request& req, COMMAND_RPC_SET_LOG_LEVEL::response& res, const connection_context *ctx) { PERF_TIMER(on_set_log_level); if (req.level < 0 || req.level > 4) @@ -916,7 +985,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_set_log_categories(const COMMAND_RPC_SET_LOG_CATEGORIES::request& req, COMMAND_RPC_SET_LOG_CATEGORIES::response& res) + bool core_rpc_server::on_set_log_categories(const COMMAND_RPC_SET_LOG_CATEGORIES::request& req, COMMAND_RPC_SET_LOG_CATEGORIES::response& res, const connection_context *ctx) { PERF_TIMER(on_set_log_categories); mlog_set_log(req.categories.c_str()); @@ -925,41 +994,47 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_transaction_pool(const COMMAND_RPC_GET_TRANSACTION_POOL::request& req, COMMAND_RPC_GET_TRANSACTION_POOL::response& res, bool request_has_rpc_origin) + bool core_rpc_server::on_get_transaction_pool(const COMMAND_RPC_GET_TRANSACTION_POOL::request& req, COMMAND_RPC_GET_TRANSACTION_POOL::response& res, const connection_context *ctx) { PERF_TIMER(on_get_transaction_pool); bool r; if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_TRANSACTION_POOL>(invoke_http_mode::JON, "/get_transaction_pool", req, res, r)) return r; - m_core.get_pool_transactions_and_spent_keys_info(res.transactions, res.spent_key_images, !request_has_rpc_origin || !m_restricted); + const bool restricted = m_restricted && ctx; + const bool request_has_rpc_origin = ctx != NULL; + m_core.get_pool_transactions_and_spent_keys_info(res.transactions, res.spent_key_images, !request_has_rpc_origin || !restricted); for (tx_info& txi : res.transactions) txi.tx_blob = epee::string_tools::buff_to_hex_nodelimer(txi.tx_blob); res.status = CORE_RPC_STATUS_OK; return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_transaction_pool_hashes_bin(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::response& res, bool request_has_rpc_origin) + bool core_rpc_server::on_get_transaction_pool_hashes_bin(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::response& res, const connection_context *ctx) { PERF_TIMER(on_get_transaction_pool_hashes); bool r; if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN>(invoke_http_mode::JON, "/get_transaction_pool_hashes.bin", req, res, r)) return r; - m_core.get_pool_transaction_hashes(res.tx_hashes, !request_has_rpc_origin || !m_restricted); + const bool restricted = m_restricted && ctx; + const bool request_has_rpc_origin = ctx != NULL; + m_core.get_pool_transaction_hashes(res.tx_hashes, !request_has_rpc_origin || !restricted); res.status = CORE_RPC_STATUS_OK; return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_transaction_pool_hashes(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::response& res, bool request_has_rpc_origin) + bool core_rpc_server::on_get_transaction_pool_hashes(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::response& res, const connection_context *ctx) { PERF_TIMER(on_get_transaction_pool_hashes); bool r; if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_TRANSACTION_POOL_HASHES>(invoke_http_mode::JON, "/get_transaction_pool_hashes", req, res, r)) return r; + const bool restricted = m_restricted && ctx; + const bool request_has_rpc_origin = ctx != NULL; std::vector<crypto::hash> tx_hashes; - m_core.get_pool_transaction_hashes(tx_hashes, !request_has_rpc_origin || !m_restricted); + m_core.get_pool_transaction_hashes(tx_hashes, !request_has_rpc_origin || !restricted); res.tx_hashes.reserve(tx_hashes.size()); for (const crypto::hash &tx_hash: tx_hashes) res.tx_hashes.push_back(epee::string_tools::pod_to_hex(tx_hash)); @@ -967,19 +1042,21 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_transaction_pool_stats(const COMMAND_RPC_GET_TRANSACTION_POOL_STATS::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_STATS::response& res, bool request_has_rpc_origin) + bool core_rpc_server::on_get_transaction_pool_stats(const COMMAND_RPC_GET_TRANSACTION_POOL_STATS::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_STATS::response& res, const connection_context *ctx) { PERF_TIMER(on_get_transaction_pool_stats); bool r; if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_TRANSACTION_POOL_STATS>(invoke_http_mode::JON, "/get_transaction_pool_stats", req, res, r)) return r; - m_core.get_pool_transaction_stats(res.pool_stats, !request_has_rpc_origin || !m_restricted); + const bool restricted = m_restricted && ctx; + const bool request_has_rpc_origin = ctx != NULL; + m_core.get_pool_transaction_stats(res.pool_stats, !request_has_rpc_origin || !restricted); res.status = CORE_RPC_STATUS_OK; return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_stop_daemon(const COMMAND_RPC_STOP_DAEMON::request& req, COMMAND_RPC_STOP_DAEMON::response& res) + bool core_rpc_server::on_stop_daemon(const COMMAND_RPC_STOP_DAEMON::request& req, COMMAND_RPC_STOP_DAEMON::response& res, const connection_context *ctx) { PERF_TIMER(on_stop_daemon); // FIXME: replace back to original m_p2p.send_stop_signal() after @@ -989,7 +1066,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request& req, COMMAND_RPC_GETBLOCKCOUNT::response& res) + bool core_rpc_server::on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request& req, COMMAND_RPC_GETBLOCKCOUNT::response& res, const connection_context *ctx) { PERF_TIMER(on_getblockcount); { @@ -1005,7 +1082,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_getblockhash(const COMMAND_RPC_GETBLOCKHASH::request& req, COMMAND_RPC_GETBLOCKHASH::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_getblockhash(const COMMAND_RPC_GETBLOCKHASH::request& req, COMMAND_RPC_GETBLOCKHASH::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { PERF_TIMER(on_getblockhash); { @@ -1049,7 +1126,7 @@ namespace cryptonote return 0; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_getblocktemplate(const COMMAND_RPC_GETBLOCKTEMPLATE::request& req, COMMAND_RPC_GETBLOCKTEMPLATE::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_getblocktemplate(const COMMAND_RPC_GETBLOCKTEMPLATE::request& req, COMMAND_RPC_GETBLOCKTEMPLATE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { PERF_TIMER(on_getblocktemplate); bool r; @@ -1128,7 +1205,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_submitblock(const COMMAND_RPC_SUBMITBLOCK::request& req, COMMAND_RPC_SUBMITBLOCK::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_submitblock(const COMMAND_RPC_SUBMITBLOCK::request& req, COMMAND_RPC_SUBMITBLOCK::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { PERF_TIMER(on_submitblock); { @@ -1183,7 +1260,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_generateblocks(const COMMAND_RPC_GENERATEBLOCKS::request& req, COMMAND_RPC_GENERATEBLOCKS::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_generateblocks(const COMMAND_RPC_GENERATEBLOCKS::request& req, COMMAND_RPC_GENERATEBLOCKS::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { PERF_TIMER(on_generateblocks); @@ -1212,7 +1289,7 @@ namespace cryptonote for(size_t i = 0; i < req.amount_of_blocks; i++) { - r = on_getblocktemplate(template_req, template_res, error_resp); + r = on_getblocktemplate(template_req, template_res, error_resp, ctx); res.status = template_res.status; if (!r) return false; @@ -1234,7 +1311,7 @@ namespace cryptonote miner::find_nonce_for_given_block(b, template_res.difficulty, template_res.height); submit_req.front() = string_tools::buff_to_hex_nodelimer(block_to_blob(b)); - r = on_submitblock(submit_req, submit_res, error_resp); + r = on_submitblock(submit_req, submit_res, error_resp, ctx); res.status = submit_res.status; if (!r) return false; @@ -1273,6 +1350,7 @@ namespace cryptonote response.block_size = response.block_weight = m_core.get_blockchain_storage().get_db().get_block_weight(height); response.num_txes = blk.tx_hashes.size(); response.pow_hash = fill_pow_hash ? string_tools::pod_to_hex(get_block_longhash(blk, height)) : ""; + response.long_term_weight = m_core.get_blockchain_storage().get_db().get_block_long_term_weight(height); return true; } //------------------------------------------------------------------------------------------------------------------------------ @@ -1343,7 +1421,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_last_block_header(const COMMAND_RPC_GET_LAST_BLOCK_HEADER::request& req, COMMAND_RPC_GET_LAST_BLOCK_HEADER::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_get_last_block_header(const COMMAND_RPC_GET_LAST_BLOCK_HEADER::request& req, COMMAND_RPC_GET_LAST_BLOCK_HEADER::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { PERF_TIMER(on_get_last_block_header); bool r; @@ -1373,7 +1451,8 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_block_header_by_hash(const COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::request& req, COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::response& res, epee::json_rpc::error& error_resp){ + bool core_rpc_server::on_get_block_header_by_hash(const COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::request& req, COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) + { PERF_TIMER(on_get_block_header_by_hash); bool r; if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH>(invoke_http_mode::JON_RPC, "getblockheaderbyhash", req, res, r)) @@ -1414,7 +1493,8 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_block_headers_range(const COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::request& req, COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::response& res, epee::json_rpc::error& error_resp){ + bool core_rpc_server::on_get_block_headers_range(const COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::request& req, COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) + { PERF_TIMER(on_get_block_headers_range); bool r; if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_BLOCK_HEADERS_RANGE>(invoke_http_mode::JON_RPC, "getblockheadersrange", req, res, r)) @@ -1464,7 +1544,8 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_block_header_by_height(const COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::response& res, epee::json_rpc::error& error_resp){ + bool core_rpc_server::on_get_block_header_by_height(const COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) + { PERF_TIMER(on_get_block_header_by_height); bool r; if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT>(invoke_http_mode::JON_RPC, "getblockheaderbyheight", req, res, r)) @@ -1496,7 +1577,8 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_block(const COMMAND_RPC_GET_BLOCK::request& req, COMMAND_RPC_GET_BLOCK::response& res, epee::json_rpc::error& error_resp){ + bool core_rpc_server::on_get_block(const COMMAND_RPC_GET_BLOCK::request& req, COMMAND_RPC_GET_BLOCK::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) + { PERF_TIMER(on_get_block); bool r; if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_BLOCK>(invoke_http_mode::JON_RPC, "getblock", req, res, r)) @@ -1557,7 +1639,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_connections(const COMMAND_RPC_GET_CONNECTIONS::request& req, COMMAND_RPC_GET_CONNECTIONS::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_get_connections(const COMMAND_RPC_GET_CONNECTIONS::request& req, COMMAND_RPC_GET_CONNECTIONS::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { PERF_TIMER(on_get_connections); @@ -1568,7 +1650,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_info_json(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_get_info_json(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { PERF_TIMER(on_get_info_json); bool r; @@ -1582,6 +1664,8 @@ namespace cryptonote return r; } + const bool restricted = m_restricted && ctx; + crypto::hash top_hash; m_core.get_blockchain_top(res.height, top_hash); ++res.height; // turn top block height into blockchain height @@ -1591,13 +1675,13 @@ namespace cryptonote res.target = m_core.get_blockchain_storage().get_current_hard_fork_version() < 2 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2; res.tx_count = m_core.get_blockchain_storage().get_total_transactions() - res.height; //without coinbase res.tx_pool_size = m_core.get_pool_transactions_count(); - res.alt_blocks_count = m_restricted ? 0 : m_core.get_blockchain_storage().get_alternative_blocks_count(); - uint64_t total_conn = m_restricted ? 0 : m_p2p.get_connections_count(); - res.outgoing_connections_count = m_restricted ? 0 : m_p2p.get_outgoing_connections_count(); - res.incoming_connections_count = m_restricted ? 0 : (total_conn - res.outgoing_connections_count); - res.rpc_connections_count = m_restricted ? 0 : get_connections_count(); - res.white_peerlist_size = m_restricted ? 0 : m_p2p.get_peerlist_manager().get_white_peers_count(); - res.grey_peerlist_size = m_restricted ? 0 : m_p2p.get_peerlist_manager().get_gray_peers_count(); + res.alt_blocks_count = restricted ? 0 : m_core.get_blockchain_storage().get_alternative_blocks_count(); + uint64_t total_conn = restricted ? 0 : m_p2p.get_public_connections_count(); + res.outgoing_connections_count = restricted ? 0 : m_p2p.get_public_outgoing_connections_count(); + res.incoming_connections_count = restricted ? 0 : (total_conn - res.outgoing_connections_count); + res.rpc_connections_count = restricted ? 0 : get_connections_count(); + res.white_peerlist_size = restricted ? 0 : m_p2p.get_public_white_peers_count(); + res.grey_peerlist_size = restricted ? 0 : m_p2p.get_public_gray_peers_count(); cryptonote::network_type net_type = nettype(); res.mainnet = net_type == MAINNET; @@ -1609,25 +1693,25 @@ namespace cryptonote res.block_size_limit = res.block_weight_limit = m_core.get_blockchain_storage().get_current_cumulative_block_weight_limit(); res.block_size_median = res.block_weight_median = m_core.get_blockchain_storage().get_current_cumulative_block_weight_median(); res.status = CORE_RPC_STATUS_OK; - res.start_time = m_restricted ? 0 : (uint64_t)m_core.get_start_time(); - res.free_space = m_restricted ? std::numeric_limits<uint64_t>::max() : m_core.get_free_space(); + res.start_time = restricted ? 0 : (uint64_t)m_core.get_start_time(); + res.free_space = restricted ? std::numeric_limits<uint64_t>::max() : m_core.get_free_space(); res.offline = m_core.offline(); - res.bootstrap_daemon_address = m_restricted ? "" : m_bootstrap_daemon_address; - res.height_without_bootstrap = m_restricted ? 0 : res.height; - if (m_restricted) + res.bootstrap_daemon_address = restricted ? "" : m_bootstrap_daemon_address; + res.height_without_bootstrap = restricted ? 0 : res.height; + if (restricted) res.was_bootstrap_ever_used = false; else { boost::shared_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex); res.was_bootstrap_ever_used = m_was_bootstrap_ever_used; } - res.database_size = m_restricted ? 0 : m_core.get_blockchain_storage().get_db().get_database_size(); - res.update_available = m_restricted ? false : m_core.is_update_available(); - res.version = m_restricted ? "" : MONERO_VERSION; + res.database_size = restricted ? 0 : m_core.get_blockchain_storage().get_db().get_database_size(); + res.update_available = restricted ? false : m_core.is_update_available(); + res.version = restricted ? "" : MONERO_VERSION; return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_hard_fork_info(const COMMAND_RPC_HARD_FORK_INFO::request& req, COMMAND_RPC_HARD_FORK_INFO::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_hard_fork_info(const COMMAND_RPC_HARD_FORK_INFO::request& req, COMMAND_RPC_HARD_FORK_INFO::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { PERF_TIMER(on_hard_fork_info); bool r; @@ -1643,7 +1727,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_bans(const COMMAND_RPC_GETBANS::request& req, COMMAND_RPC_GETBANS::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_get_bans(const COMMAND_RPC_GETBANS::request& req, COMMAND_RPC_GETBANS::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { PERF_TIMER(on_get_bans); @@ -1667,7 +1751,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_set_bans(const COMMAND_RPC_SETBANS::request& req, COMMAND_RPC_SETBANS::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_set_bans(const COMMAND_RPC_SETBANS::request& req, COMMAND_RPC_SETBANS::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { PERF_TIMER(on_set_bans); @@ -1676,12 +1760,14 @@ namespace cryptonote epee::net_utils::network_address na; if (!i->host.empty()) { - if (!epee::net_utils::create_network_address(na, i->host)) + auto na_parsed = net::get_network_address(i->host, 0); + if (!na_parsed) { error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM; error_resp.message = "Unsupported host type"; return false; } + na = std::move(*na_parsed); } else { @@ -1697,7 +1783,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_flush_txpool(const COMMAND_RPC_FLUSH_TRANSACTION_POOL::request& req, COMMAND_RPC_FLUSH_TRANSACTION_POOL::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_flush_txpool(const COMMAND_RPC_FLUSH_TRANSACTION_POOL::request& req, COMMAND_RPC_FLUSH_TRANSACTION_POOL::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { PERF_TIMER(on_flush_txpool); @@ -1752,7 +1838,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_output_histogram(const COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request& req, COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_get_output_histogram(const COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request& req, COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { PERF_TIMER(on_get_output_histogram); bool r; @@ -1782,7 +1868,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_version(const COMMAND_RPC_GET_VERSION::request& req, COMMAND_RPC_GET_VERSION::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_get_version(const COMMAND_RPC_GET_VERSION::request& req, COMMAND_RPC_GET_VERSION::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { PERF_TIMER(on_get_version); bool r; @@ -1794,7 +1880,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_coinbase_tx_sum(const COMMAND_RPC_GET_COINBASE_TX_SUM::request& req, COMMAND_RPC_GET_COINBASE_TX_SUM::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_get_coinbase_tx_sum(const COMMAND_RPC_GET_COINBASE_TX_SUM::request& req, COMMAND_RPC_GET_COINBASE_TX_SUM::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { PERF_TIMER(on_get_coinbase_tx_sum); std::pair<uint64_t, uint64_t> amounts = m_core.get_coinbase_tx_sum(req.height, req.count); @@ -1804,7 +1890,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_base_fee_estimate(const COMMAND_RPC_GET_BASE_FEE_ESTIMATE::request& req, COMMAND_RPC_GET_BASE_FEE_ESTIMATE::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_get_base_fee_estimate(const COMMAND_RPC_GET_BASE_FEE_ESTIMATE::request& req, COMMAND_RPC_GET_BASE_FEE_ESTIMATE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { PERF_TIMER(on_get_base_fee_estimate); bool r; @@ -1817,7 +1903,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_alternate_chains(const COMMAND_RPC_GET_ALTERNATE_CHAINS::request& req, COMMAND_RPC_GET_ALTERNATE_CHAINS::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_get_alternate_chains(const COMMAND_RPC_GET_ALTERNATE_CHAINS::request& req, COMMAND_RPC_GET_ALTERNATE_CHAINS::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { PERF_TIMER(on_get_alternate_chains); try @@ -1848,7 +1934,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_limit(const COMMAND_RPC_GET_LIMIT::request& req, COMMAND_RPC_GET_LIMIT::response& res) + bool core_rpc_server::on_get_limit(const COMMAND_RPC_GET_LIMIT::request& req, COMMAND_RPC_GET_LIMIT::response& res, const connection_context *ctx) { PERF_TIMER(on_get_limit); bool r; @@ -1861,7 +1947,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_set_limit(const COMMAND_RPC_SET_LIMIT::request& req, COMMAND_RPC_SET_LIMIT::response& res) + bool core_rpc_server::on_set_limit(const COMMAND_RPC_SET_LIMIT::request& req, COMMAND_RPC_SET_LIMIT::response& res, const connection_context *ctx) { PERF_TIMER(on_set_limit); // -1 = reset to default @@ -1901,31 +1987,23 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_out_peers(const COMMAND_RPC_OUT_PEERS::request& req, COMMAND_RPC_OUT_PEERS::response& res) + bool core_rpc_server::on_out_peers(const COMMAND_RPC_OUT_PEERS::request& req, COMMAND_RPC_OUT_PEERS::response& res, const connection_context *ctx) { PERF_TIMER(on_out_peers); - size_t n_connections = m_p2p.get_outgoing_connections_count(); - size_t n_delete = (n_connections > req.out_peers) ? n_connections - req.out_peers : 0; - m_p2p.m_config.m_net_config.max_out_connection_count = req.out_peers; - if (n_delete) - m_p2p.delete_out_connections(n_delete); + m_p2p.change_max_out_public_peers(req.out_peers); res.status = CORE_RPC_STATUS_OK; return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_in_peers(const COMMAND_RPC_IN_PEERS::request& req, COMMAND_RPC_IN_PEERS::response& res) + bool core_rpc_server::on_in_peers(const COMMAND_RPC_IN_PEERS::request& req, COMMAND_RPC_IN_PEERS::response& res, const connection_context *ctx) { PERF_TIMER(on_in_peers); - size_t n_connections = m_p2p.get_incoming_connections_count(); - size_t n_delete = (n_connections > req.in_peers) ? n_connections - req.in_peers : 0; - m_p2p.m_config.m_net_config.max_in_connection_count = req.in_peers; - if (n_delete) - m_p2p.delete_in_connections(n_delete); + m_p2p.change_max_in_public_peers(req.in_peers); res.status = CORE_RPC_STATUS_OK; return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_start_save_graph(const COMMAND_RPC_START_SAVE_GRAPH::request& req, COMMAND_RPC_START_SAVE_GRAPH::response& res) + bool core_rpc_server::on_start_save_graph(const COMMAND_RPC_START_SAVE_GRAPH::request& req, COMMAND_RPC_START_SAVE_GRAPH::response& res, const connection_context *ctx) { PERF_TIMER(on_start_save_graph); m_p2p.set_save_graph(true); @@ -1933,7 +2011,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_stop_save_graph(const COMMAND_RPC_STOP_SAVE_GRAPH::request& req, COMMAND_RPC_STOP_SAVE_GRAPH::response& res) + bool core_rpc_server::on_stop_save_graph(const COMMAND_RPC_STOP_SAVE_GRAPH::request& req, COMMAND_RPC_STOP_SAVE_GRAPH::response& res, const connection_context *ctx) { PERF_TIMER(on_stop_save_graph); m_p2p.set_save_graph(false); @@ -1941,7 +2019,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_update(const COMMAND_RPC_UPDATE::request& req, COMMAND_RPC_UPDATE::response& res) + bool core_rpc_server::on_update(const COMMAND_RPC_UPDATE::request& req, COMMAND_RPC_UPDATE::response& res, const connection_context *ctx) { PERF_TIMER(on_update); static const char software[] = "monero"; @@ -2036,7 +2114,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_pop_blocks(const COMMAND_RPC_POP_BLOCKS::request& req, COMMAND_RPC_POP_BLOCKS::response& res) + bool core_rpc_server::on_pop_blocks(const COMMAND_RPC_POP_BLOCKS::request& req, COMMAND_RPC_POP_BLOCKS::response& res, const connection_context *ctx) { PERF_TIMER(on_pop_blocks); @@ -2048,7 +2126,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_relay_tx(const COMMAND_RPC_RELAY_TX::request& req, COMMAND_RPC_RELAY_TX::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_relay_tx(const COMMAND_RPC_RELAY_TX::request& req, COMMAND_RPC_RELAY_TX::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { PERF_TIMER(on_relay_tx); @@ -2094,7 +2172,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_sync_info(const COMMAND_RPC_SYNC_INFO::request& req, COMMAND_RPC_SYNC_INFO::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_sync_info(const COMMAND_RPC_SYNC_INFO::request& req, COMMAND_RPC_SYNC_INFO::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { PERF_TIMER(on_sync_info); @@ -2102,6 +2180,7 @@ namespace cryptonote m_core.get_blockchain_top(res.height, top_hash); ++res.height; // turn top block height into blockchain height res.target_height = m_core.get_target_blockchain_height(); + res.next_needed_pruning_seed = m_p2p.get_payload_object().get_next_needed_pruning_stripe().second; for (const auto &c: m_p2p.get_payload_object().get_connections()) res.peers.push_back({c}); @@ -2116,12 +2195,13 @@ namespace cryptonote res.spans.push_back({span.start_block_height, span.nblocks, span_connection_id, (uint32_t)(span.rate + 0.5f), speed, span.size, address}); return true; }); + res.overview = block_queue.get_overview(res.height); res.status = CORE_RPC_STATUS_OK; return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_txpool_backlog(const COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_get_txpool_backlog(const COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { PERF_TIMER(on_get_txpool_backlog); bool r; @@ -2139,7 +2219,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_output_distribution(const COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::request& req, COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_get_output_distribution(const COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::request& req, COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { PERF_TIMER(on_get_output_distribution); bool r; @@ -2174,7 +2254,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_output_distribution_bin(const COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::request& req, COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::response& res) + bool core_rpc_server::on_get_output_distribution_bin(const COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::request& req, COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::response& res, const connection_context *ctx) { PERF_TIMER(on_get_output_distribution_bin); @@ -2215,6 +2295,29 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool core_rpc_server::on_prune_blockchain(const COMMAND_RPC_PRUNE_BLOCKCHAIN::request& req, COMMAND_RPC_PRUNE_BLOCKCHAIN::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) + { + try + { + if (!(req.check ? m_core.check_blockchain_pruning() : m_core.prune_blockchain())) + { + error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; + error_resp.message = req.check ? "Failed to check blockchain pruning" : "Failed to prune blockchain"; + return false; + } + res.pruning_seed = m_core.get_blockchain_pruning_seed(); + } + catch (const std::exception &e) + { + error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; + error_resp.message = "Failed to prune blockchain"; + return false; + } + + res.status = CORE_RPC_STATUS_OK; + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ const command_line::arg_descriptor<std::string, false, true, 2> core_rpc_server::arg_rpc_bind_port = { @@ -2243,6 +2346,35 @@ namespace cryptonote , false }; + const command_line::arg_descriptor<std::string> core_rpc_server::arg_rpc_ssl = { + "rpc-ssl" + , "Enable SSL on RPC connections: enabled|disabled|autodetect" + , "autodetect" + }; + + const command_line::arg_descriptor<std::string> core_rpc_server::arg_rpc_ssl_private_key = { + "rpc-ssl-private-key" + , "Path to a PEM format private key" + , "" + }; + + const command_line::arg_descriptor<std::string> core_rpc_server::arg_rpc_ssl_certificate = { + "rpc-ssl-certificate" + , "Path to a PEM format certificate" + , "" + }; + + const command_line::arg_descriptor<std::vector<std::string>> core_rpc_server::arg_rpc_ssl_allowed_certificates = { + "rpc-ssl-allowed-certificates" + , "List of paths to PEM format certificates of allowed peers (all allowed if empty)" + }; + + const command_line::arg_descriptor<bool> core_rpc_server::arg_rpc_ssl_allow_any_cert = { + "rpc-ssl-allow-any-cert" + , "Allow any peer certificate, rather than just those on the allowed list" + , false + }; + const command_line::arg_descriptor<std::string> core_rpc_server::arg_bootstrap_daemon_address = { "bootstrap-daemon-address" , "URL of a 'bootstrap' remote daemon that the connected wallets can use while this daemon is still not fully synced" diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index 081ccc25d..da1907af2 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -56,6 +56,11 @@ namespace cryptonote static const command_line::arg_descriptor<std::string, false, true, 2> arg_rpc_bind_port; static const command_line::arg_descriptor<std::string> arg_rpc_restricted_bind_port; static const command_line::arg_descriptor<bool> arg_restricted_rpc; + static const command_line::arg_descriptor<std::string> arg_rpc_ssl; + static const command_line::arg_descriptor<std::string> arg_rpc_ssl_private_key; + static const command_line::arg_descriptor<std::string> arg_rpc_ssl_certificate; + static const command_line::arg_descriptor<std::vector<std::string>> arg_rpc_ssl_allowed_certificates; + static const command_line::arg_descriptor<bool> arg_rpc_ssl_allow_any_cert; static const command_line::arg_descriptor<std::string> arg_bootstrap_daemon_address; static const command_line::arg_descriptor<std::string> arg_bootstrap_daemon_login; @@ -153,70 +158,72 @@ namespace cryptonote MAP_JON_RPC_WE_IF("sync_info", on_sync_info, COMMAND_RPC_SYNC_INFO, !m_restricted) MAP_JON_RPC_WE("get_txpool_backlog", on_get_txpool_backlog, COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG) MAP_JON_RPC_WE("get_output_distribution", on_get_output_distribution, COMMAND_RPC_GET_OUTPUT_DISTRIBUTION) + MAP_JON_RPC_WE_IF("prune_blockchain", on_prune_blockchain, COMMAND_RPC_PRUNE_BLOCKCHAIN, !m_restricted) END_JSON_RPC_MAP() END_URI_MAP2() - bool on_get_height(const COMMAND_RPC_GET_HEIGHT::request& req, COMMAND_RPC_GET_HEIGHT::response& res); - bool on_get_blocks(const COMMAND_RPC_GET_BLOCKS_FAST::request& req, COMMAND_RPC_GET_BLOCKS_FAST::response& res); - bool on_get_alt_blocks_hashes(const COMMAND_RPC_GET_ALT_BLOCKS_HASHES::request& req, COMMAND_RPC_GET_ALT_BLOCKS_HASHES::response& res); - bool on_get_blocks_by_height(const COMMAND_RPC_GET_BLOCKS_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCKS_BY_HEIGHT::response& res); - bool on_get_hashes(const COMMAND_RPC_GET_HASHES_FAST::request& req, COMMAND_RPC_GET_HASHES_FAST::response& res); - bool on_get_transactions(const COMMAND_RPC_GET_TRANSACTIONS::request& req, COMMAND_RPC_GET_TRANSACTIONS::response& res); - bool on_is_key_image_spent(const COMMAND_RPC_IS_KEY_IMAGE_SPENT::request& req, COMMAND_RPC_IS_KEY_IMAGE_SPENT::response& res, bool request_has_rpc_origin = true); - bool on_get_indexes(const COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request& req, COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response& res); - bool on_send_raw_tx(const COMMAND_RPC_SEND_RAW_TX::request& req, COMMAND_RPC_SEND_RAW_TX::response& res); - bool on_start_mining(const COMMAND_RPC_START_MINING::request& req, COMMAND_RPC_START_MINING::response& res); - bool on_stop_mining(const COMMAND_RPC_STOP_MINING::request& req, COMMAND_RPC_STOP_MINING::response& res); - bool on_mining_status(const COMMAND_RPC_MINING_STATUS::request& req, COMMAND_RPC_MINING_STATUS::response& res); - bool on_get_outs_bin(const COMMAND_RPC_GET_OUTPUTS_BIN::request& req, COMMAND_RPC_GET_OUTPUTS_BIN::response& res); - bool on_get_outs(const COMMAND_RPC_GET_OUTPUTS::request& req, COMMAND_RPC_GET_OUTPUTS::response& res); - bool on_get_info(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res); - bool on_save_bc(const COMMAND_RPC_SAVE_BC::request& req, COMMAND_RPC_SAVE_BC::response& res); - bool on_get_peer_list(const COMMAND_RPC_GET_PEER_LIST::request& req, COMMAND_RPC_GET_PEER_LIST::response& res); - bool on_set_log_hash_rate(const COMMAND_RPC_SET_LOG_HASH_RATE::request& req, COMMAND_RPC_SET_LOG_HASH_RATE::response& res); - bool on_set_log_level(const COMMAND_RPC_SET_LOG_LEVEL::request& req, COMMAND_RPC_SET_LOG_LEVEL::response& res); - bool on_set_log_categories(const COMMAND_RPC_SET_LOG_CATEGORIES::request& req, COMMAND_RPC_SET_LOG_CATEGORIES::response& res); - bool on_get_transaction_pool(const COMMAND_RPC_GET_TRANSACTION_POOL::request& req, COMMAND_RPC_GET_TRANSACTION_POOL::response& res, bool request_has_rpc_origin = true); - bool on_get_transaction_pool_hashes_bin(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::response& res, bool request_has_rpc_origin = true); - bool on_get_transaction_pool_hashes(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::response& res, bool request_has_rpc_origin = true); - bool on_get_transaction_pool_stats(const COMMAND_RPC_GET_TRANSACTION_POOL_STATS::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_STATS::response& res, bool request_has_rpc_origin = true); - 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_in_peers(const COMMAND_RPC_IN_PEERS::request& req, COMMAND_RPC_IN_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); - bool on_update(const COMMAND_RPC_UPDATE::request& req, COMMAND_RPC_UPDATE::response& res); - bool on_get_output_distribution_bin(const COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::request& req, COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::response& res); - bool on_pop_blocks(const COMMAND_RPC_POP_BLOCKS::request& req, COMMAND_RPC_POP_BLOCKS::response& res); + bool on_get_height(const COMMAND_RPC_GET_HEIGHT::request& req, COMMAND_RPC_GET_HEIGHT::response& res, const connection_context *ctx = NULL); + bool on_get_blocks(const COMMAND_RPC_GET_BLOCKS_FAST::request& req, COMMAND_RPC_GET_BLOCKS_FAST::response& res, const connection_context *ctx = NULL); + bool on_get_alt_blocks_hashes(const COMMAND_RPC_GET_ALT_BLOCKS_HASHES::request& req, COMMAND_RPC_GET_ALT_BLOCKS_HASHES::response& res, const connection_context *ctx = NULL); + bool on_get_blocks_by_height(const COMMAND_RPC_GET_BLOCKS_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCKS_BY_HEIGHT::response& res, const connection_context *ctx = NULL); + bool on_get_hashes(const COMMAND_RPC_GET_HASHES_FAST::request& req, COMMAND_RPC_GET_HASHES_FAST::response& res, const connection_context *ctx = NULL); + bool on_get_transactions(const COMMAND_RPC_GET_TRANSACTIONS::request& req, COMMAND_RPC_GET_TRANSACTIONS::response& res, const connection_context *ctx = NULL); + bool on_is_key_image_spent(const COMMAND_RPC_IS_KEY_IMAGE_SPENT::request& req, COMMAND_RPC_IS_KEY_IMAGE_SPENT::response& res, const connection_context *ctx = NULL); + bool on_get_indexes(const COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request& req, COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response& res, const connection_context *ctx = NULL); + bool on_send_raw_tx(const COMMAND_RPC_SEND_RAW_TX::request& req, COMMAND_RPC_SEND_RAW_TX::response& res, const connection_context *ctx = NULL); + bool on_start_mining(const COMMAND_RPC_START_MINING::request& req, COMMAND_RPC_START_MINING::response& res, const connection_context *ctx = NULL); + bool on_stop_mining(const COMMAND_RPC_STOP_MINING::request& req, COMMAND_RPC_STOP_MINING::response& res, const connection_context *ctx = NULL); + bool on_mining_status(const COMMAND_RPC_MINING_STATUS::request& req, COMMAND_RPC_MINING_STATUS::response& res, const connection_context *ctx = NULL); + bool on_get_outs_bin(const COMMAND_RPC_GET_OUTPUTS_BIN::request& req, COMMAND_RPC_GET_OUTPUTS_BIN::response& res, const connection_context *ctx = NULL); + bool on_get_outs(const COMMAND_RPC_GET_OUTPUTS::request& req, COMMAND_RPC_GET_OUTPUTS::response& res, const connection_context *ctx = NULL); + bool on_get_info(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res, const connection_context *ctx = NULL); + bool on_save_bc(const COMMAND_RPC_SAVE_BC::request& req, COMMAND_RPC_SAVE_BC::response& res, const connection_context *ctx = NULL); + bool on_get_peer_list(const COMMAND_RPC_GET_PEER_LIST::request& req, COMMAND_RPC_GET_PEER_LIST::response& res, const connection_context *ctx = NULL); + bool on_set_log_hash_rate(const COMMAND_RPC_SET_LOG_HASH_RATE::request& req, COMMAND_RPC_SET_LOG_HASH_RATE::response& res, const connection_context *ctx = NULL); + bool on_set_log_level(const COMMAND_RPC_SET_LOG_LEVEL::request& req, COMMAND_RPC_SET_LOG_LEVEL::response& res, const connection_context *ctx = NULL); + bool on_set_log_categories(const COMMAND_RPC_SET_LOG_CATEGORIES::request& req, COMMAND_RPC_SET_LOG_CATEGORIES::response& res, const connection_context *ctx = NULL); + bool on_get_transaction_pool(const COMMAND_RPC_GET_TRANSACTION_POOL::request& req, COMMAND_RPC_GET_TRANSACTION_POOL::response& res, const connection_context *ctx = NULL); + bool on_get_transaction_pool_hashes_bin(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::response& res, const connection_context *ctx = NULL); + bool on_get_transaction_pool_hashes(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::response& res, const connection_context *ctx = NULL); + bool on_get_transaction_pool_stats(const COMMAND_RPC_GET_TRANSACTION_POOL_STATS::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_STATS::response& res, const connection_context *ctx = NULL); + bool on_stop_daemon(const COMMAND_RPC_STOP_DAEMON::request& req, COMMAND_RPC_STOP_DAEMON::response& res, const connection_context *ctx = NULL); + bool on_get_limit(const COMMAND_RPC_GET_LIMIT::request& req, COMMAND_RPC_GET_LIMIT::response& res, const connection_context *ctx = NULL); + bool on_set_limit(const COMMAND_RPC_SET_LIMIT::request& req, COMMAND_RPC_SET_LIMIT::response& res, const connection_context *ctx = NULL); + bool on_out_peers(const COMMAND_RPC_OUT_PEERS::request& req, COMMAND_RPC_OUT_PEERS::response& res, const connection_context *ctx = NULL); + bool on_in_peers(const COMMAND_RPC_IN_PEERS::request& req, COMMAND_RPC_IN_PEERS::response& res, const connection_context *ctx = NULL); + bool on_start_save_graph(const COMMAND_RPC_START_SAVE_GRAPH::request& req, COMMAND_RPC_START_SAVE_GRAPH::response& res, const connection_context *ctx = NULL); + bool on_stop_save_graph(const COMMAND_RPC_STOP_SAVE_GRAPH::request& req, COMMAND_RPC_STOP_SAVE_GRAPH::response& res, const connection_context *ctx = NULL); + bool on_update(const COMMAND_RPC_UPDATE::request& req, COMMAND_RPC_UPDATE::response& res, const connection_context *ctx = NULL); + bool on_get_output_distribution_bin(const COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::request& req, COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::response& res, const connection_context *ctx = NULL); + bool on_pop_blocks(const COMMAND_RPC_POP_BLOCKS::request& req, COMMAND_RPC_POP_BLOCKS::response& res, const connection_context *ctx = NULL); //json_rpc - bool on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request& req, COMMAND_RPC_GETBLOCKCOUNT::response& res); - bool on_getblockhash(const COMMAND_RPC_GETBLOCKHASH::request& req, COMMAND_RPC_GETBLOCKHASH::response& res, epee::json_rpc::error& error_resp); - bool on_getblocktemplate(const COMMAND_RPC_GETBLOCKTEMPLATE::request& req, COMMAND_RPC_GETBLOCKTEMPLATE::response& res, epee::json_rpc::error& error_resp); - bool on_submitblock(const COMMAND_RPC_SUBMITBLOCK::request& req, COMMAND_RPC_SUBMITBLOCK::response& res, epee::json_rpc::error& error_resp); - bool on_generateblocks(const COMMAND_RPC_GENERATEBLOCKS::request& req, COMMAND_RPC_GENERATEBLOCKS::response& res, epee::json_rpc::error& error_resp); - bool on_get_last_block_header(const COMMAND_RPC_GET_LAST_BLOCK_HEADER::request& req, COMMAND_RPC_GET_LAST_BLOCK_HEADER::response& res, epee::json_rpc::error& error_resp); - bool on_get_block_header_by_hash(const COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::request& req, COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::response& res, epee::json_rpc::error& error_resp); - bool on_get_block_header_by_height(const COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::response& res, epee::json_rpc::error& error_resp); - bool on_get_block_headers_range(const COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::request& req, COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::response& res, epee::json_rpc::error& error_resp); - bool on_get_block(const COMMAND_RPC_GET_BLOCK::request& req, COMMAND_RPC_GET_BLOCK::response& res, epee::json_rpc::error& error_resp); - bool on_get_connections(const COMMAND_RPC_GET_CONNECTIONS::request& req, COMMAND_RPC_GET_CONNECTIONS::response& res, epee::json_rpc::error& error_resp); - bool on_get_info_json(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res, epee::json_rpc::error& error_resp); - bool on_hard_fork_info(const COMMAND_RPC_HARD_FORK_INFO::request& req, COMMAND_RPC_HARD_FORK_INFO::response& res, epee::json_rpc::error& error_resp); - bool on_set_bans(const COMMAND_RPC_SETBANS::request& req, COMMAND_RPC_SETBANS::response& res, epee::json_rpc::error& error_resp); - bool on_get_bans(const COMMAND_RPC_GETBANS::request& req, COMMAND_RPC_GETBANS::response& res, epee::json_rpc::error& error_resp); - bool on_flush_txpool(const COMMAND_RPC_FLUSH_TRANSACTION_POOL::request& req, COMMAND_RPC_FLUSH_TRANSACTION_POOL::response& res, epee::json_rpc::error& error_resp); - bool on_get_output_histogram(const COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request& req, COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response& res, epee::json_rpc::error& error_resp); - bool on_get_version(const COMMAND_RPC_GET_VERSION::request& req, COMMAND_RPC_GET_VERSION::response& res, epee::json_rpc::error& error_resp); - bool on_get_coinbase_tx_sum(const COMMAND_RPC_GET_COINBASE_TX_SUM::request& req, COMMAND_RPC_GET_COINBASE_TX_SUM::response& res, epee::json_rpc::error& error_resp); - bool on_get_base_fee_estimate(const COMMAND_RPC_GET_BASE_FEE_ESTIMATE::request& req, COMMAND_RPC_GET_BASE_FEE_ESTIMATE::response& res, epee::json_rpc::error& error_resp); - bool on_get_alternate_chains(const COMMAND_RPC_GET_ALTERNATE_CHAINS::request& req, COMMAND_RPC_GET_ALTERNATE_CHAINS::response& res, epee::json_rpc::error& error_resp); - bool on_relay_tx(const COMMAND_RPC_RELAY_TX::request& req, COMMAND_RPC_RELAY_TX::response& res, epee::json_rpc::error& error_resp); - bool on_sync_info(const COMMAND_RPC_SYNC_INFO::request& req, COMMAND_RPC_SYNC_INFO::response& res, epee::json_rpc::error& error_resp); - bool on_get_txpool_backlog(const COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::response& res, epee::json_rpc::error& error_resp); - bool on_get_output_distribution(const COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::request& req, COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::response& res, epee::json_rpc::error& error_resp); + bool on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request& req, COMMAND_RPC_GETBLOCKCOUNT::response& res, const connection_context *ctx = NULL); + bool on_getblockhash(const COMMAND_RPC_GETBLOCKHASH::request& req, COMMAND_RPC_GETBLOCKHASH::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_getblocktemplate(const COMMAND_RPC_GETBLOCKTEMPLATE::request& req, COMMAND_RPC_GETBLOCKTEMPLATE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_submitblock(const COMMAND_RPC_SUBMITBLOCK::request& req, COMMAND_RPC_SUBMITBLOCK::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_generateblocks(const COMMAND_RPC_GENERATEBLOCKS::request& req, COMMAND_RPC_GENERATEBLOCKS::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_get_last_block_header(const COMMAND_RPC_GET_LAST_BLOCK_HEADER::request& req, COMMAND_RPC_GET_LAST_BLOCK_HEADER::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_get_block_header_by_hash(const COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::request& req, COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_get_block_header_by_height(const COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_get_block_headers_range(const COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::request& req, COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_get_block(const COMMAND_RPC_GET_BLOCK::request& req, COMMAND_RPC_GET_BLOCK::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_get_connections(const COMMAND_RPC_GET_CONNECTIONS::request& req, COMMAND_RPC_GET_CONNECTIONS::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_get_info_json(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_hard_fork_info(const COMMAND_RPC_HARD_FORK_INFO::request& req, COMMAND_RPC_HARD_FORK_INFO::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_set_bans(const COMMAND_RPC_SETBANS::request& req, COMMAND_RPC_SETBANS::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_get_bans(const COMMAND_RPC_GETBANS::request& req, COMMAND_RPC_GETBANS::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_flush_txpool(const COMMAND_RPC_FLUSH_TRANSACTION_POOL::request& req, COMMAND_RPC_FLUSH_TRANSACTION_POOL::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_get_output_histogram(const COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request& req, COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_get_version(const COMMAND_RPC_GET_VERSION::request& req, COMMAND_RPC_GET_VERSION::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_get_coinbase_tx_sum(const COMMAND_RPC_GET_COINBASE_TX_SUM::request& req, COMMAND_RPC_GET_COINBASE_TX_SUM::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_get_base_fee_estimate(const COMMAND_RPC_GET_BASE_FEE_ESTIMATE::request& req, COMMAND_RPC_GET_BASE_FEE_ESTIMATE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_get_alternate_chains(const COMMAND_RPC_GET_ALTERNATE_CHAINS::request& req, COMMAND_RPC_GET_ALTERNATE_CHAINS::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_relay_tx(const COMMAND_RPC_RELAY_TX::request& req, COMMAND_RPC_RELAY_TX::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_sync_info(const COMMAND_RPC_SYNC_INFO::request& req, COMMAND_RPC_SYNC_INFO::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_get_txpool_backlog(const COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_get_output_distribution(const COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::request& req, COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); + bool on_prune_blockchain(const COMMAND_RPC_PRUNE_BLOCKCHAIN::request& req, COMMAND_RPC_PRUNE_BLOCKCHAIN::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); //----------------------- private: diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 0a07930ec..e52e4fc67 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -84,7 +84,7 @@ namespace cryptonote // advance which version they will stop working with // Don't go over 32767 for any of these #define CORE_RPC_VERSION_MAJOR 2 -#define CORE_RPC_VERSION_MINOR 2 +#define CORE_RPC_VERSION_MINOR 3 #define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor)) #define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR) @@ -601,11 +601,13 @@ namespace cryptonote std::vector<std::string> txs_hashes; bool decode_as_json; bool prune; + bool split; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(txs_hashes) KV_SERIALIZE(decode_as_json) KV_SERIALIZE_OPT(prune, false) + KV_SERIALIZE_OPT(split, false) END_KV_SERIALIZE_MAP() }; @@ -613,6 +615,9 @@ namespace cryptonote { std::string tx_hash; std::string as_hex; + std::string pruned_as_hex; + std::string prunable_as_hex; + std::string prunable_hash; std::string as_json; bool in_pool; bool double_spend_seen; @@ -623,6 +628,9 @@ namespace cryptonote BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(tx_hash) KV_SERIALIZE(as_hex) + KV_SERIALIZE(pruned_as_hex) + KV_SERIALIZE(prunable_as_hex) + KV_SERIALIZE(prunable_hash) KV_SERIALIZE(as_json) KV_SERIALIZE(in_pool) KV_SERIALIZE(double_spend_seen) @@ -1164,6 +1172,7 @@ namespace cryptonote uint64_t block_weight; uint64_t num_txes; std::string pow_hash; + uint64_t long_term_weight; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(major_version) @@ -1182,6 +1191,7 @@ namespace cryptonote KV_SERIALIZE_OPT(block_weight, (uint64_t)0) KV_SERIALIZE(num_txes) KV_SERIALIZE(pow_hash) + KV_SERIALIZE_OPT(long_term_weight, (uint64_t)0) END_KV_SERIALIZE_MAP() }; @@ -1311,14 +1321,15 @@ namespace cryptonote uint32_t ip; uint16_t port; uint64_t last_seen; + uint32_t pruning_seed; peer() = default; - peer(uint64_t id, const std::string &host, uint64_t last_seen) - : id(id), host(host), ip(0), port(0), last_seen(last_seen) + peer(uint64_t id, const std::string &host, uint64_t last_seen, uint32_t pruning_seed) + : id(id), host(host), ip(0), port(0), last_seen(last_seen), pruning_seed(pruning_seed) {} - peer(uint64_t id, uint32_t ip, uint16_t port, uint64_t last_seen) - : id(id), host(std::to_string(ip)), ip(ip), port(port), last_seen(last_seen) + peer(uint64_t id, uint32_t ip, uint16_t port, uint64_t last_seen, uint32_t pruning_seed) + : id(id), host(std::to_string(ip)), ip(ip), port(port), last_seen(last_seen), pruning_seed(pruning_seed) {} BEGIN_KV_SERIALIZE_MAP() @@ -1327,6 +1338,7 @@ namespace cryptonote KV_SERIALIZE(ip) KV_SERIALIZE(port) KV_SERIALIZE(last_seen) + KV_SERIALIZE_OPT(pruning_seed, (uint32_t)0) END_KV_SERIALIZE_MAP() }; @@ -2238,15 +2250,19 @@ namespace cryptonote std::string status; uint64_t height; uint64_t target_height; + uint32_t next_needed_pruning_seed; std::list<peer> peers; std::list<span> spans; + std::string overview; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(status) KV_SERIALIZE(height) KV_SERIALIZE(target_height) + KV_SERIALIZE(next_needed_pruning_seed) KV_SERIALIZE(peers) KV_SERIALIZE(spans) + KV_SERIALIZE(overview) END_KV_SERIALIZE_MAP() }; }; @@ -2351,4 +2367,27 @@ namespace cryptonote }; }; + struct COMMAND_RPC_PRUNE_BLOCKCHAIN + { + struct request + { + bool check; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_OPT(check, false) + END_KV_SERIALIZE_MAP() + }; + + struct response + { + uint32_t pruning_seed; + std::string status; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(status) + KV_SERIALIZE(pruning_seed) + END_KV_SERIALIZE_MAP() + }; + }; + } diff --git a/src/rpc/daemon_handler.cpp b/src/rpc/daemon_handler.cpp index e2885dbb5..871f7d368 100644 --- a/src/rpc/daemon_handler.cpp +++ b/src/rpc/daemon_handler.cpp @@ -423,13 +423,13 @@ namespace rpc res.info.alt_blocks_count = chain.get_alternative_blocks_count(); - uint64_t total_conn = m_p2p.get_connections_count(); - res.info.outgoing_connections_count = m_p2p.get_outgoing_connections_count(); + uint64_t total_conn = m_p2p.get_public_connections_count(); + res.info.outgoing_connections_count = m_p2p.get_public_outgoing_connections_count(); res.info.incoming_connections_count = total_conn - res.info.outgoing_connections_count; - res.info.white_peerlist_size = m_p2p.get_peerlist_manager().get_white_peers_count(); + res.info.white_peerlist_size = m_p2p.get_public_white_peers_count(); - res.info.grey_peerlist_size = m_p2p.get_peerlist_manager().get_gray_peers_count(); + res.info.grey_peerlist_size = m_p2p.get_public_gray_peers_count(); res.info.mainnet = m_core.get_nettype() == MAINNET; res.info.testnet = m_core.get_nettype() == TESTNET; diff --git a/src/rpc/message_data_structs.h b/src/rpc/message_data_structs.h index e09b6749e..73cf28cec 100644 --- a/src/rpc/message_data_structs.h +++ b/src/rpc/message_data_structs.h @@ -79,6 +79,7 @@ namespace rpc uint32_t ip; uint16_t port; uint64_t last_seen; + uint32_t pruning_seed; }; struct tx_in_pool diff --git a/src/serialization/binary_archive.h b/src/serialization/binary_archive.h index f47a4494d..242b8fd68 100644 --- a/src/serialization/binary_archive.h +++ b/src/serialization/binary_archive.h @@ -99,7 +99,7 @@ struct binary_archive<false> : public binary_archive_base<std::istream, false> { explicit binary_archive(stream_type &s) : base_type(s) { - stream_type::streampos pos = stream_.tellg(); + stream_type::pos_type pos = stream_.tellg(); stream_.seekg(0, std::ios_base::end); eof_pos_ = stream_.tellg(); stream_.seekg(pos); diff --git a/src/serialization/json_object.cpp b/src/serialization/json_object.cpp index 8b1af9c12..ee4fa4a19 100644 --- a/src/serialization/json_object.cpp +++ b/src/serialization/json_object.cpp @@ -734,6 +734,7 @@ void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::peer& peer, ra INSERT_INTO_JSON_OBJECT(val, doc, ip, peer.ip); INSERT_INTO_JSON_OBJECT(val, doc, port, peer.port); INSERT_INTO_JSON_OBJECT(val, doc, last_seen, peer.last_seen); + INSERT_INTO_JSON_OBJECT(val, doc, pruning_seed, peer.pruning_seed); } @@ -748,6 +749,7 @@ void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::peer& peer) GET_FROM_JSON_OBJECT(val, peer.ip, ip); GET_FROM_JSON_OBJECT(val, peer.port, port); GET_FROM_JSON_OBJECT(val, peer.last_seen, last_seen); + GET_FROM_JSON_OBJECT(val, peer.pruning_seed, pruning_seed); } void toJsonValue(rapidjson::Document& doc, const cryptonote::rpc::tx_in_pool& tx, rapidjson::Value& val) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 4856405b5..ceb844fbf 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -116,7 +116,7 @@ typedef cryptonote::simple_wallet sw; #define LONG_PAYMENT_ID_SUPPORT_CHECK() \ do { \ if (!m_long_payment_id_support) { \ - fail_msg_writer() << tr("Long payment IDs are obsolete. Use --long-payment-id-support if you really must use one."); \ + fail_msg_writer() << tr("Long payment IDs are obsolete. Use --long-payment-id-support if you really must use one, and warn the recipient they are using an obsolete feature that will disappear in the future."); \ return true; \ } \ } while(0) @@ -7827,8 +7827,9 @@ void simple_wallet::wallet_idle_thread() try { uint64_t fetched_blocks; + bool received_money; if (try_connect_to_daemon(true)) - m_wallet->refresh(m_wallet->is_trusted_daemon(), 0, fetched_blocks); + m_wallet->refresh(m_wallet->is_trusted_daemon(), 0, fetched_blocks, received_money, false); // don't check the pool in background mode } catch(...) {} m_auto_refresh_refreshing = false; @@ -8401,7 +8402,8 @@ bool simple_wallet::status(const std::vector<std::string> &args) { uint64_t local_height = m_wallet->get_blockchain_current_height(); uint32_t version = 0; - if (!m_wallet->check_connection(&version)) + bool ssl = false; + if (!m_wallet->check_connection(&version, &ssl)) { success_msg_writer() << "Refreshed " << local_height << "/?, no daemon connected"; return true; @@ -8413,7 +8415,7 @@ bool simple_wallet::status(const std::vector<std::string> &args) { bool synced = local_height == bc_height; success_msg_writer() << "Refreshed " << local_height << "/" << bc_height << ", " << (synced ? "synced" : "syncing") - << ", daemon RPC v" << get_version_string(version); + << ", daemon RPC v" << get_version_string(version) << ", " << (ssl ? "SSL" : "no SSL"); } else { diff --git a/src/wallet/api/subaddress_account.cpp b/src/wallet/api/subaddress_account.cpp index 19ed8fb38..4765465c3 100644 --- a/src/wallet/api/subaddress_account.cpp +++ b/src/wallet/api/subaddress_account.cpp @@ -62,7 +62,7 @@ void SubaddressAccountImpl::refresh() { m_rows.push_back(new SubaddressAccountRow( i, - m_wallet->m_wallet->get_subaddress_as_str({i,0}).substr(0,6), + m_wallet->m_wallet->get_subaddress_as_str({i,0}), m_wallet->m_wallet->get_subaddress_label({i,0}), cryptonote::print_money(m_wallet->m_wallet->balance(i)), cryptonote::print_money(m_wallet->m_wallet->unlocked_balance(i)) diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 935a8d51c..2b7853330 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -1924,7 +1924,7 @@ bool WalletImpl::verifyMessageWithPublicKey(const std::string &message, const st bool WalletImpl::connectToDaemon() { - bool result = m_wallet->check_connection(NULL, DEFAULT_CONNECTION_TIMEOUT_MILLIS); + bool result = m_wallet->check_connection(NULL, NULL, DEFAULT_CONNECTION_TIMEOUT_MILLIS); if (!result) { setStatusError("Error connecting to daemon at " + m_wallet->get_daemon_address()); } else { @@ -1937,7 +1937,7 @@ bool WalletImpl::connectToDaemon() Wallet::ConnectionStatus WalletImpl::connected() const { uint32_t version = 0; - m_is_connected = m_wallet->check_connection(&version, DEFAULT_CONNECTION_TIMEOUT_MILLIS); + m_is_connected = m_wallet->check_connection(&version, NULL, DEFAULT_CONNECTION_TIMEOUT_MILLIS); if (!m_is_connected) return Wallet::ConnectionStatus_Disconnected; // Version check is not implemented in light wallets nodes/wallets diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index a86d681d3..6b2c27d5e 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -237,6 +237,11 @@ struct options { const command_line::arg_descriptor<std::string> password_file = {"password-file", tools::wallet2::tr("Wallet password file"), "", true}; const command_line::arg_descriptor<int> daemon_port = {"daemon-port", tools::wallet2::tr("Use daemon instance at port <arg> instead of 18081"), 0}; const command_line::arg_descriptor<std::string> daemon_login = {"daemon-login", tools::wallet2::tr("Specify username[:password] for daemon RPC client"), "", true}; + const command_line::arg_descriptor<std::string> daemon_ssl = {"daemon-ssl", tools::wallet2::tr("Enable SSL on daemon RPC connections: enabled|disabled|autodetect"), "autodetect"}; + const command_line::arg_descriptor<std::string> daemon_ssl_private_key = {"daemon-ssl-private-key", tools::wallet2::tr("Path to a PEM format private key"), ""}; + const command_line::arg_descriptor<std::string> daemon_ssl_certificate = {"daemon-ssl-certificate", tools::wallet2::tr("Path to a PEM format certificate"), ""}; + const command_line::arg_descriptor<std::vector<std::string>> daemon_ssl_allowed_certificates = {"daemon-ssl-allowed-certificates", tools::wallet2::tr("List of paths to PEM format certificates of allowed RPC servers")}; + const command_line::arg_descriptor<bool> daemon_ssl_allow_any_cert = {"daemon-ssl-allow-any-cert", tools::wallet2::tr("Allow any SSL certificate from the daemon"), false}; const command_line::arg_descriptor<bool> testnet = {"testnet", tools::wallet2::tr("For testnet. Daemon must also be launched with --testnet flag"), false}; const command_line::arg_descriptor<bool> stagenet = {"stagenet", tools::wallet2::tr("For stagenet. Daemon must also be launched with --stagenet flag"), false}; const command_line::arg_descriptor<std::string, false, true, 2> shared_ringdb_dir = { @@ -308,6 +313,14 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl auto daemon_port = command_line::get_arg(vm, opts.daemon_port); auto device_name = command_line::get_arg(vm, opts.hw_device); auto device_derivation_path = command_line::get_arg(vm, opts.hw_device_derivation_path); + auto daemon_ssl_private_key = command_line::get_arg(vm, opts.daemon_ssl_private_key); + auto daemon_ssl_certificate = command_line::get_arg(vm, opts.daemon_ssl_certificate); + auto daemon_ssl_allowed_certificates = command_line::get_arg(vm, opts.daemon_ssl_allowed_certificates); + auto daemon_ssl_allow_any_cert = command_line::get_arg(vm, opts.daemon_ssl_allow_any_cert); + auto daemon_ssl = command_line::get_arg(vm, opts.daemon_ssl); + epee::net_utils::ssl_support_t ssl_support; + THROW_WALLET_EXCEPTION_IF(!epee::net_utils::ssl_support_from_string(ssl_support, daemon_ssl), tools::error::wallet_internal_error, + tools::wallet2::tr("Invalid argument for ") + std::string(opts.daemon_ssl.name)); THROW_WALLET_EXCEPTION_IF(!daemon_address.empty() && !daemon_host.empty() && 0 != daemon_port, tools::error::wallet_internal_error, tools::wallet2::tr("can't specify daemon host or port more than once")); @@ -358,8 +371,20 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl catch (const std::exception &e) { } } + std::list<std::string> ssl_allowed_certificates; + for (const std::string &path: daemon_ssl_allowed_certificates) + { + ssl_allowed_certificates.push_back({}); + if (!epee::file_io_utils::load_file_to_string(path, ssl_allowed_certificates.back())) + { + MERROR("Failed to load certificate: " << path); + ssl_allowed_certificates.back() = std::string(); + } + } + std::unique_ptr<tools::wallet2> wallet(new tools::wallet2(nettype, kdf_rounds, unattended)); - wallet->init(std::move(daemon_address), std::move(login), 0, false, *trusted_daemon); + wallet->init(std::move(daemon_address), std::move(login), 0, *trusted_daemon, ssl_support, std::make_pair(daemon_ssl_private_key, daemon_ssl_certificate), ssl_allowed_certificates, daemon_ssl_allow_any_cert); + boost::filesystem::path ringdb_path = command_line::get_arg(vm, opts.shared_ringdb_dir); wallet->set_ring_database(ringdb_path.string()); wallet->get_message_store().set_options(vm); @@ -373,7 +398,7 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl } catch (const std::exception &e) { - MERROR("Failed to parse tx notify spec"); + MERROR("Failed to parse tx notify spec: " << e.what()); } return wallet; @@ -628,7 +653,7 @@ std::string strjoin(const std::vector<size_t> &V, const char *sep) return ss.str(); } -static void emplace_or_replace(std::unordered_multimap<crypto::hash, tools::wallet2::pool_payment_details> &container, +static bool emplace_or_replace(std::unordered_multimap<crypto::hash, tools::wallet2::pool_payment_details> &container, const crypto::hash &key, const tools::wallet2::pool_payment_details &pd) { auto range = container.equal_range(key); @@ -637,10 +662,11 @@ static void emplace_or_replace(std::unordered_multimap<crypto::hash, tools::wall if (i->second.m_pd.m_tx_hash == pd.m_pd.m_tx_hash && i->second.m_pd.m_subaddr_index == pd.m_pd.m_subaddr_index) { i->second = pd; - return; + return false; } } container.emplace(key, pd); + return true; } void drop_from_short_history(std::list<crypto::hash> &short_chain_history, size_t N) @@ -814,6 +840,43 @@ static void setup_shim(hw::wallet_shim * shim, tools::wallet2 * wallet) shim->get_tx_pub_key_from_received_outs = boost::bind(&tools::wallet2::get_tx_pub_key_from_received_outs, wallet, _1); } +bool get_pruned_tx(const cryptonote::COMMAND_RPC_GET_TRANSACTIONS::entry &entry, cryptonote::transaction &tx, crypto::hash &tx_hash) +{ + cryptonote::blobdata bd; + + // easy case if we have the whole tx + if (!entry.as_hex.empty() || (!entry.prunable_as_hex.empty() && !entry.pruned_as_hex.empty())) + { + CHECK_AND_ASSERT_MES(epee::string_tools::parse_hexstr_to_binbuff(entry.as_hex.empty() ? entry.pruned_as_hex + entry.prunable_as_hex : entry.as_hex, bd), false, "Failed to parse tx data"); + CHECK_AND_ASSERT_MES(cryptonote::parse_and_validate_tx_from_blob(bd, tx), false, "Invalid tx data"); + tx_hash = cryptonote::get_transaction_hash(tx); + // if the hash was given, check it matches + CHECK_AND_ASSERT_MES(entry.tx_hash.empty() || epee::string_tools::pod_to_hex(tx_hash) == entry.tx_hash, false, + "Response claims a different hash than the data yields"); + return true; + } + // case of a pruned tx with its prunable data hash + if (!entry.pruned_as_hex.empty() && !entry.prunable_hash.empty()) + { + crypto::hash ph; + CHECK_AND_ASSERT_MES(epee::string_tools::hex_to_pod(entry.prunable_hash, ph), false, "Failed to parse prunable hash"); + CHECK_AND_ASSERT_MES(epee::string_tools::parse_hexstr_to_binbuff(entry.pruned_as_hex, bd), false, "Failed to parse pruned data"); + CHECK_AND_ASSERT_MES(parse_and_validate_tx_base_from_blob(bd, tx), false, "Invalid base tx data"); + // only v2 txes can calculate their txid after pruned + if (bd[0] > 1) + { + tx_hash = cryptonote::get_pruned_transaction_hash(tx, ph); + } + else + { + // for v1, we trust the dameon + CHECK_AND_ASSERT_MES(epee::string_tools::hex_to_pod(entry.tx_hash, tx_hash), false, "Failed to parse tx hash"); + } + return true; + } + return false; +} + //----------------------------------------------------------------- } //namespace @@ -977,6 +1040,11 @@ void wallet2::init_options(boost::program_options::options_description& desc_par command_line::add_arg(desc_params, opts.password_file); command_line::add_arg(desc_params, opts.daemon_port); command_line::add_arg(desc_params, opts.daemon_login); + command_line::add_arg(desc_params, opts.daemon_ssl); + command_line::add_arg(desc_params, opts.daemon_ssl_private_key); + command_line::add_arg(desc_params, opts.daemon_ssl_certificate); + command_line::add_arg(desc_params, opts.daemon_ssl_allowed_certificates); + command_line::add_arg(desc_params, opts.daemon_ssl_allow_any_cert); command_line::add_arg(desc_params, opts.testnet); command_line::add_arg(desc_params, opts.stagenet); command_line::add_arg(desc_params, opts.shared_ringdb_dir); @@ -1028,7 +1096,7 @@ std::unique_ptr<wallet2> wallet2::make_dummy(const boost::program_options::varia } //---------------------------------------------------------------------------------------------------- -bool wallet2::init(std::string daemon_address, boost::optional<epee::net_utils::http::login> daemon_login, uint64_t upper_transaction_weight_limit, bool ssl, bool trusted_daemon) +bool wallet2::init(std::string daemon_address, boost::optional<epee::net_utils::http::login> daemon_login, uint64_t upper_transaction_weight_limit, bool trusted_daemon, epee::net_utils::ssl_support_t ssl_support, const std::pair<std::string, std::string> &private_key_and_certificate_path, const std::list<std::string> &allowed_certificates, bool allow_any_cert) { m_checkpoints.init_default_checkpoints(m_nettype); if(m_http_client.is_connected()) @@ -1038,8 +1106,7 @@ bool wallet2::init(std::string daemon_address, boost::optional<epee::net_utils:: m_daemon_address = std::move(daemon_address); m_daemon_login = std::move(daemon_login); m_trusted_daemon = trusted_daemon; - // When switching from light wallet to full wallet, we need to reset the height we got from lw node. - return m_http_client.set_server(get_daemon_address(), get_daemon_login(), ssl); + return m_http_client.set_server(get_daemon_address(), get_daemon_login(), ssl_support, private_key_and_certificate_path, allowed_certificates, allow_any_cert); } //---------------------------------------------------------------------------------------------------- bool wallet2::is_deterministic() const @@ -1372,6 +1439,7 @@ static uint64_t decodeRct(const rct::rctSig & rv, const crypto::key_derivation & { case rct::RCTTypeSimple: case rct::RCTTypeBulletproof: + case rct::RCTTypeBulletproof2: return rct::decodeRctSimple(rv, rct::sk2rct(scalar1), i, mask, hwdev); case rct::RCTTypeFull: return rct::decodeRct(rv, rct::sk2rct(scalar1), i, mask, hwdev); @@ -1387,7 +1455,7 @@ static uint64_t decodeRct(const rct::rctSig & rv, const crypto::key_derivation & } } //---------------------------------------------------------------------------------------------------- -void wallet2::scan_output(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, std::unordered_map<cryptonote::subaddress_index, uint64_t> &tx_money_got_in_outs, std::vector<size_t> &outs) +void wallet2::scan_output(const cryptonote::transaction &tx, bool miner_tx, const crypto::public_key &tx_pub_key, size_t i, tx_scan_info_t &tx_scan_info, int &num_vouts_received, std::unordered_map<cryptonote::subaddress_index, uint64_t> &tx_money_got_in_outs, std::vector<size_t> &outs, bool pool) { THROW_WALLET_EXCEPTION_IF(i >= tx.vout.size(), error::wallet_internal_error, "Invalid vout index"); @@ -1398,7 +1466,7 @@ void wallet2::scan_output(const cryptonote::transaction &tx, const crypto::publi CRITICAL_REGION_LOCAL(password_lock); if (!m_encrypt_keys_after_refresh) { - boost::optional<epee::wipeable_string> pwd = m_callback->on_get_password("output received"); + boost::optional<epee::wipeable_string> pwd = m_callback->on_get_password(pool ? "output found in pool" : "output received"); THROW_WALLET_EXCEPTION_IF(!pwd, error::password_needed, tr("Password is needed to compute key image for incoming monero")); THROW_WALLET_EXCEPTION_IF(!verify_password(*pwd), error::password_needed, tr("Invalid password: password is needed to compute key image for incoming monero")); decrypt_keys(*pwd); @@ -1420,11 +1488,14 @@ void wallet2::scan_output(const cryptonote::transaction &tx, const crypto::publi error::wallet_internal_error, "key_image generated ephemeral public key not matched with output_key"); } + THROW_WALLET_EXCEPTION_IF(std::find(outs.begin(), outs.end(), i) != outs.end(), error::wallet_internal_error, "Same output cannot be added twice"); outs.push_back(i); - if (tx_scan_info.money_transfered == 0) + if (tx_scan_info.money_transfered == 0 && !miner_tx) { tx_scan_info.money_transfered = tools::decodeRct(tx.rct_signatures, tx_scan_info.received->derivation, i, tx_scan_info.mask, m_account.get_device()); } + THROW_WALLET_EXCEPTION_IF(tx_money_got_in_outs[tx_scan_info.received->index] >= std::numeric_limits<uint64_t>::max() - tx_scan_info.money_transfered, + error::wallet_internal_error, "Overflow in received amounts"); tx_money_got_in_outs[tx_scan_info.received->index] += tx_scan_info.money_transfered; tx_scan_info.amount = tx_scan_info.money_transfered; ++num_vouts_received; @@ -1602,7 +1673,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote if (tx_scan_info[i].received) { hwdev.conceal_derivation(tx_scan_info[i].received->derivation, tx_pub_key, additional_tx_pub_keys.data, derivation, additional_derivations); - scan_output(tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs); + scan_output(tx, miner_tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs, pool); } } } @@ -1625,7 +1696,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote if (tx_scan_info[i].received) { hwdev.conceal_derivation(tx_scan_info[i].received->derivation, tx_pub_key, additional_tx_pub_keys.data, derivation, additional_derivations); - scan_output(tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs); + scan_output(tx, miner_tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs, pool); } } } @@ -1641,7 +1712,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote boost::unique_lock<hw::device> hwdev_lock (hwdev); hwdev.set_mode(hw::device::NONE); hwdev.conceal_derivation(tx_scan_info[i].received->derivation, tx_pub_key, additional_tx_pub_keys.data, derivation, additional_derivations); - scan_output(tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs); + scan_output(tx, miner_tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs, pool); } } } @@ -1977,6 +2048,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote return; } + bool all_same = true; for (const auto& i : tx_money_got_in_outs) { payment_details payment; @@ -1989,7 +2061,8 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote payment.m_coinbase = miner_tx; payment.m_subaddr_index = i.first; if (pool) { - emplace_or_replace(m_unconfirmed_payments, payment_id, pool_payment_details{payment, double_spend_seen}); + if (emplace_or_replace(m_unconfirmed_payments, payment_id, pool_payment_details{payment, double_spend_seen})) + all_same = false; if (0 != m_callback) m_callback->on_unconfirmed_money_received(height, txid, tx, payment.m_amount, payment.m_subaddr_index); } @@ -1997,13 +2070,17 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote m_payments.emplace(payment_id, payment); LOG_PRINT_L2("Payment found in " << (pool ? "pool" : "block") << ": " << payment_id << " / " << payment.m_tx_hash << " / " << payment.m_amount); } + + // if it's a pool tx and we already had it, don't notify again + if (pool && all_same) + notify = false; } if (notify) { std::shared_ptr<tools::Notify> tx_notify = m_tx_notify; if (tx_notify) - tx_notify->notify(epee::string_tools::pod_to_hex(txid).c_str()); + tx_notify->notify("%s", epee::string_tools::pod_to_hex(txid).c_str(), NULL); } } //---------------------------------------------------------------------------------------------------- @@ -2588,7 +2665,7 @@ void wallet2::update_pool_state(bool refreshed) req.txs_hashes.push_back(epee::string_tools::pod_to_hex(p.first)); MDEBUG("asking for " << txids.size() << " transactions"); req.decode_as_json = false; - req.prune = false; + req.prune = true; m_daemon_rpc_mutex.lock(); bool r = epee::net_utils::invoke_http_json("/gettransactions", req, res, m_http_client, rpc_timeout); m_daemon_rpc_mutex.unlock(); @@ -2603,11 +2680,10 @@ void wallet2::update_pool_state(bool refreshed) { cryptonote::transaction tx; cryptonote::blobdata bd; - crypto::hash tx_hash, tx_prefix_hash; - if (epee::string_tools::parse_hexstr_to_binbuff(tx_entry.as_hex, bd)) + crypto::hash tx_hash; + + if (get_pruned_tx(tx_entry, tx, tx_hash)) { - if (cryptonote::parse_and_validate_tx_from_blob(bd, tx, tx_hash, tx_prefix_hash)) - { const std::vector<std::pair<crypto::hash, bool>>::const_iterator i = std::find_if(txids.begin(), txids.end(), [tx_hash](const std::pair<crypto::hash, bool> &e) { return e.first == tx_hash; }); if (i != txids.end()) @@ -2624,11 +2700,6 @@ void wallet2::update_pool_state(bool refreshed) { MERROR("Got txid " << tx_hash << " which we did not ask for"); } - } - else - { - LOG_PRINT_L0("failed to validate transaction from daemon"); - } } else { @@ -2755,7 +2826,7 @@ std::shared_ptr<std::map<std::pair<uint64_t, uint64_t>, size_t>> wallet2::create return cache; } //---------------------------------------------------------------------------------------------------- -void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blocks_fetched, bool& received_money) +void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blocks_fetched, bool& received_money, bool check_pool) { if(m_light_wallet) { @@ -2950,7 +3021,7 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo try { // If stop() is called we don't need to check pending transactions - if(m_run.load(std::memory_order_relaxed)) + if (check_pool && m_run.load(std::memory_order_relaxed)) update_pool_state(refreshed); } catch (...) @@ -4814,7 +4885,7 @@ bool wallet2::prepare_file_names(const std::string& file_path) return true; } //---------------------------------------------------------------------------------------------------- -bool wallet2::check_connection(uint32_t *version, uint32_t timeout) +bool wallet2::check_connection(uint32_t *version, bool *ssl, uint32_t timeout) { THROW_WALLET_EXCEPTION_IF(!m_is_initialized, error::wallet_not_initialized); @@ -4822,15 +4893,20 @@ bool wallet2::check_connection(uint32_t *version, uint32_t timeout) // TODO: Add light wallet version check. if(m_light_wallet) { - version = 0; + if (version) + *version = 0; + if (ssl) + *ssl = m_light_wallet_connected; // light wallet is always SSL return m_light_wallet_connected; } - if(!m_http_client.is_connected()) + if(!m_http_client.is_connected(ssl)) { m_node_rpc_proxy.invalidate(); if (!m_http_client.connect(std::chrono::milliseconds(timeout))) return false; + if(!m_http_client.is_connected(ssl)) + return false; } if (version) @@ -5894,15 +5970,16 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector<wallet2::pendin 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(); - rct::RangeProofType range_proof_type = rct::RangeProofBorromean; + rct::RCTConfig rct_config = { rct::RangeProofBorromean, 0 }; if (sd.use_bulletproofs) { - range_proof_type = rct::RangeProofPaddedBulletproof; + rct_config.range_proof_type = rct::RangeProofPaddedBulletproof; + rct_config.bp_version = use_fork_rules(HF_VERSION_SMALLER_BP, -10) ? 2 : 1; } crypto::secret_key tx_key; std::vector<crypto::secret_key> additional_tx_keys; rct::multisig_out msout; - bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sd.sources, sd.splitted_dsts, sd.change_dts.addr, sd.extra, ptx.tx, sd.unlock_time, tx_key, additional_tx_keys, sd.use_rct, range_proof_type, m_multisig ? &msout : NULL); + bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sd.sources, sd.splitted_dsts, sd.change_dts.addr, sd.extra, ptx.tx, sd.unlock_time, tx_key, additional_tx_keys, sd.use_rct, rct_config, m_multisig ? &msout : NULL); THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sd.sources, sd.splitted_dsts, sd.unlock_time, m_nettype); // we don't test tx size, because we don't know the current limit, due to not having a blockchain, // and it's a bit pointless to fail there anyway, since it'd be a (good) guess only. We sign anyway, @@ -6364,12 +6441,13 @@ bool wallet2::sign_multisig_tx(multisig_tx_set &exported_txs, std::vector<crypto cryptonote::transaction tx; rct::multisig_out msout = ptx.multisig_sigs.front().msout; auto sources = sd.sources; - rct::RangeProofType range_proof_type = rct::RangeProofBorromean; + rct::RCTConfig rct_config = { rct::RangeProofBorromean, 0 }; if (sd.use_bulletproofs) { - range_proof_type = rct::RangeProofPaddedBulletproof; + rct_config.range_proof_type = rct::RangeProofPaddedBulletproof; + rct_config.bp_version = use_fork_rules(HF_VERSION_SMALLER_BP, -10) ? 2 : 1; } - bool r = cryptonote::construct_tx_with_tx_key(m_account.get_keys(), m_subaddresses, sources, sd.splitted_dsts, ptx.change_dts.addr, sd.extra, tx, sd.unlock_time, ptx.tx_key, ptx.additional_tx_keys, sd.use_rct, range_proof_type, &msout, false); + bool r = cryptonote::construct_tx_with_tx_key(m_account.get_keys(), m_subaddresses, sources, sd.splitted_dsts, ptx.change_dts.addr, sd.extra, tx, sd.unlock_time, ptx.tx_key, ptx.additional_tx_keys, sd.use_rct, rct_config, &msout, false); THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sd.sources, sd.splitted_dsts, sd.unlock_time, m_nettype); THROW_WALLET_EXCEPTION_IF(get_transaction_prefix_hash (tx) != get_transaction_prefix_hash(ptx.tx), @@ -6819,11 +6897,12 @@ bool wallet2::find_and_save_rings(bool force) MDEBUG("Found " << std::to_string(txs_hashes.size()) << " transactions"); // get those transactions from the daemon + auto it = txs_hashes.begin(); static const size_t SLICE_SIZE = 200; for (size_t slice = 0; slice < txs_hashes.size(); slice += SLICE_SIZE) { req.decode_as_json = false; - req.prune = false; + req.prune = true; req.txs_hashes.clear(); size_t ntxes = slice + SLICE_SIZE > txs_hashes.size() ? txs_hashes.size() - slice : SLICE_SIZE; for (size_t s = slice; s < slice + ntxes; ++s) @@ -6842,19 +6921,15 @@ bool wallet2::find_and_save_rings(bool force) MDEBUG("Scanning " << res.txs.size() << " transactions"); THROW_WALLET_EXCEPTION_IF(slice + res.txs.size() > txs_hashes.size(), error::wallet_internal_error, "Unexpected tx array size"); - auto it = req.txs_hashes.begin(); for (size_t i = 0; i < res.txs.size(); ++i, ++it) { const auto &tx_info = res.txs[i]; - THROW_WALLET_EXCEPTION_IF(tx_info.tx_hash != epee::string_tools::pod_to_hex(txs_hashes[slice + i]), error::wallet_internal_error, "Wrong txid received"); - THROW_WALLET_EXCEPTION_IF(tx_info.tx_hash != *it, error::wallet_internal_error, "Wrong txid received"); - cryptonote::blobdata bd; - THROW_WALLET_EXCEPTION_IF(!epee::string_tools::parse_hexstr_to_binbuff(tx_info.as_hex, bd), error::wallet_internal_error, "failed to parse tx from hexstr"); - cryptonote::transaction tx; - crypto::hash tx_hash, tx_prefix_hash; - THROW_WALLET_EXCEPTION_IF(!cryptonote::parse_and_validate_tx_from_blob(bd, tx, tx_hash, tx_prefix_hash), error::wallet_internal_error, "failed to parse tx from blob"); - THROW_WALLET_EXCEPTION_IF(epee::string_tools::pod_to_hex(tx_hash) != tx_info.tx_hash, error::wallet_internal_error, "txid mismatch"); - THROW_WALLET_EXCEPTION_IF(!add_rings(get_ringdb_key(), tx), error::wallet_internal_error, "Failed to save ring"); + cryptonote::transaction tx; + crypto::hash tx_hash; + THROW_WALLET_EXCEPTION_IF(!get_pruned_tx(tx_info, tx, tx_hash), error::wallet_internal_error, + "Failed to get transaction from daemon"); + THROW_WALLET_EXCEPTION_IF(!(tx_hash == *it), error::wallet_internal_error, "Wrong txid received"); + THROW_WALLET_EXCEPTION_IF(!add_rings(get_ringdb_key(), tx), error::wallet_internal_error, "Failed to save ring"); } } @@ -7784,7 +7859,7 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent std::vector<crypto::secret_key> additional_tx_keys; rct::multisig_out msout; LOG_PRINT_L2("constructing tx"); - bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sources, splitted_dsts, change_dts.addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, rct::RangeProofBulletproof, m_multisig ? &msout : NULL); + bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sources, splitted_dsts, change_dts.addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, {}, m_multisig ? &msout : NULL); LOG_PRINT_L2("constructed tx, r="<<r); THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, splitted_dsts, unlock_time, m_nettype); THROW_WALLET_EXCEPTION_IF(upper_transaction_weight_limit <= get_transaction_weight(tx), error::tx_too_big, tx, upper_transaction_weight_limit); @@ -7833,7 +7908,7 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry> dsts, const std::vector<size_t>& selected_transfers, size_t fake_outputs_count, std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs, - uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx, rct::RangeProofType range_proof_type) + uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx, const rct::RCTConfig &rct_config) { using namespace cryptonote; // throw if attempting a transaction with no destinations @@ -8015,7 +8090,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry rct::multisig_out msout; LOG_PRINT_L2("constructing tx"); auto sources_copy = sources; - bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sources, splitted_dsts, change_dts.addr, extra, tx, unlock_time, tx_key, additional_tx_keys, true, range_proof_type, m_multisig ? &msout : NULL); + bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sources, splitted_dsts, change_dts.addr, extra, tx, unlock_time, tx_key, additional_tx_keys, true, rct_config, m_multisig ? &msout : NULL); LOG_PRINT_L2("constructed tx, r="<<r); THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, dsts, unlock_time, m_nettype); THROW_WALLET_EXCEPTION_IF(upper_transaction_weight_limit <= get_transaction_weight(tx), error::tx_too_big, tx, upper_transaction_weight_limit); @@ -8060,7 +8135,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry LOG_PRINT_L2("Creating supplementary multisig transaction"); cryptonote::transaction ms_tx; auto sources_copy_copy = sources_copy; - bool r = cryptonote::construct_tx_with_tx_key(m_account.get_keys(), m_subaddresses, sources_copy_copy, splitted_dsts, change_dts.addr, extra, ms_tx, unlock_time,tx_key, additional_tx_keys, true, range_proof_type, &msout, false); + bool r = cryptonote::construct_tx_with_tx_key(m_account.get_keys(), m_subaddresses, sources_copy_copy, splitted_dsts, change_dts.addr, extra, ms_tx, unlock_time,tx_key, additional_tx_keys, true, rct_config, &msout, false); LOG_PRINT_L2("constructed tx, r="<<r); THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, splitted_dsts, unlock_time, m_nettype); THROW_WALLET_EXCEPTION_IF(upper_transaction_weight_limit <= get_transaction_weight(tx), error::tx_too_big, tx, upper_transaction_weight_limit); @@ -8771,7 +8846,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp const bool use_per_byte_fee = use_fork_rules(HF_VERSION_PER_BYTE_FEE, 0); const bool use_rct = use_fork_rules(4, 0); const bool bulletproof = use_fork_rules(get_bulletproof_fork(), 0); - const rct::RangeProofType range_proof_type = bulletproof ? rct::RangeProofPaddedBulletproof : rct::RangeProofBorromean; + const rct::RCTConfig rct_config { + bulletproof ? rct::RangeProofPaddedBulletproof : rct::RangeProofBorromean, + bulletproof ? (use_fork_rules(HF_VERSION_SMALLER_BP, -10) ? 2 : 1) : 0 + }; const uint64_t base_fee = get_base_fee(); const uint64_t fee_multiplier = get_fee_multiplier(priority, get_fee_algorithm()); @@ -9084,7 +9162,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp tx.selected_transfers.size() << " inputs"); if (use_rct) transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra, - test_tx, test_ptx, range_proof_type); + test_tx, test_ptx, rct_config); else transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra, detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx); @@ -9127,7 +9205,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp while (needed_fee > test_ptx.fee) { if (use_rct) transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra, - test_tx, test_ptx, range_proof_type); + test_tx, test_ptx, rct_config); else transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra, detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx); @@ -9200,7 +9278,7 @@ skip_tx: extra, /* const std::vector<uint8_t>& extra, */ test_tx, /* OUT cryptonote::transaction& tx, */ test_ptx, /* OUT cryptonote::transaction& tx, */ - range_proof_type); + rct_config); } else { transfer_selected(tx.dsts, tx.selected_transfers, @@ -9340,7 +9418,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton const bool use_per_byte_fee = use_fork_rules(HF_VERSION_PER_BYTE_FEE); const bool use_rct = fake_outs_count > 0 && use_fork_rules(4, 0); const bool bulletproof = use_fork_rules(get_bulletproof_fork(), 0); - const rct::RangeProofType range_proof_type = bulletproof ? rct::RangeProofPaddedBulletproof : rct::RangeProofBorromean; + const rct::RCTConfig rct_config { + bulletproof ? rct::RangeProofPaddedBulletproof : rct::RangeProofBorromean, + bulletproof ? (use_fork_rules(HF_VERSION_SMALLER_BP, -10) ? 2 : 1) : 0, + }; const uint64_t base_fee = get_base_fee(); const uint64_t fee_multiplier = get_fee_multiplier(priority, get_fee_algorithm()); const uint64_t fee_quantization_mask = get_fee_quantization_mask(); @@ -9416,7 +9497,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton tx.selected_transfers.size() << " outputs"); if (use_rct) transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra, - test_tx, test_ptx, range_proof_type); + test_tx, test_ptx, rct_config); else transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra, detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx); @@ -9453,7 +9534,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton } if (use_rct) transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra, - test_tx, test_ptx, range_proof_type); + test_tx, test_ptx, rct_config); else transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra, detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx); @@ -9492,7 +9573,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton pending_tx test_ptx; if (use_rct) { transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, tx.outs, unlock_time, tx.needed_fee, extra, - test_tx, test_ptx, range_proof_type); + test_tx, test_ptx, rct_config); } else { transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, tx.outs, unlock_time, tx.needed_fee, extra, detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx); @@ -9596,7 +9677,7 @@ bool wallet2::use_fork_rules(uint8_t version, int64_t early_blocks) const result = m_node_rpc_proxy.get_earliest_height(version, earliest_height); throw_on_rpc_response_error(result, "get_hard_fork_info"); - bool close_enough = height >= earliest_height - early_blocks; // start using the rules that many blocks beforehand + bool close_enough = height >= earliest_height - early_blocks && earliest_height != std::numeric_limits<uint64_t>::max(); // start using the rules that many blocks beforehand if (close_enough) LOG_PRINT_L2("Using v" << (unsigned)version << " rules"); else @@ -9787,7 +9868,7 @@ void wallet2::set_tx_key(const crypto::hash &txid, const crypto::secret_key &tx_ COMMAND_RPC_GET_TRANSACTIONS::request req = AUTO_VAL_INIT(req); req.txs_hashes.push_back(epee::string_tools::pod_to_hex(txid)); req.decode_as_json = false; - req.prune = false; + req.prune = true; COMMAND_RPC_GET_TRANSACTIONS::response res = AUTO_VAL_INIT(res); bool r; { @@ -9800,11 +9881,10 @@ void wallet2::set_tx_key(const crypto::hash &txid, const crypto::secret_key &tx_ THROW_WALLET_EXCEPTION_IF(res.txs.size() != 1, error::wallet_internal_error, "daemon returned wrong response for gettransactions, wrong txs count = " + std::to_string(res.txs.size()) + ", expected 1"); - cryptonote::blobdata bd; - THROW_WALLET_EXCEPTION_IF(!epee::string_tools::parse_hexstr_to_binbuff(res.txs[0].as_hex, bd), error::wallet_internal_error, "failed to parse tx from hexstr"); cryptonote::transaction tx; - crypto::hash tx_hash, tx_prefix_hash; - THROW_WALLET_EXCEPTION_IF(!cryptonote::parse_and_validate_tx_from_blob(bd, tx, tx_hash, tx_prefix_hash), error::wallet_internal_error, "failed to parse tx from blob"); + crypto::hash tx_hash; + THROW_WALLET_EXCEPTION_IF(!get_pruned_tx(res.txs[0], tx, tx_hash), error::wallet_internal_error, + "Failed to get transaction from daemon"); THROW_WALLET_EXCEPTION_IF(tx_hash != txid, error::wallet_internal_error, "txid mismatch"); std::vector<tx_extra_field> tx_extra_fields; THROW_WALLET_EXCEPTION_IF(!parse_tx_extra(tx.extra, tx_extra_fields), error::wallet_internal_error, "Transaction extra has unsupported format"); @@ -9838,7 +9918,7 @@ std::string wallet2::get_spend_proof(const crypto::hash &txid, const std::string COMMAND_RPC_GET_TRANSACTIONS::request req = AUTO_VAL_INIT(req); req.txs_hashes.push_back(epee::string_tools::pod_to_hex(txid)); req.decode_as_json = false; - req.prune = false; + req.prune = true; COMMAND_RPC_GET_TRANSACTIONS::response res = AUTO_VAL_INIT(res); bool r; { @@ -9851,12 +9931,10 @@ std::string wallet2::get_spend_proof(const crypto::hash &txid, const std::string THROW_WALLET_EXCEPTION_IF(res.txs.size() != 1, error::wallet_internal_error, "daemon returned wrong response for gettransactions, wrong txs count = " + std::to_string(res.txs.size()) + ", expected 1"); - cryptonote::blobdata bd; - THROW_WALLET_EXCEPTION_IF(!epee::string_tools::parse_hexstr_to_binbuff(res.txs[0].as_hex, bd), error::wallet_internal_error, "failed to parse tx from hexstr"); + cryptonote::transaction tx; - crypto::hash tx_hash, tx_prefix_hash; - THROW_WALLET_EXCEPTION_IF(!cryptonote::parse_and_validate_tx_from_blob(bd, tx, tx_hash, tx_prefix_hash), error::wallet_internal_error, "failed to parse tx from blob"); - THROW_WALLET_EXCEPTION_IF(tx_hash != txid, error::wallet_internal_error, "txid mismatch"); + crypto::hash tx_hash; + THROW_WALLET_EXCEPTION_IF(!get_pruned_tx(res.txs[0], tx, tx_hash), error::wallet_internal_error, "Failed to get tx from daemon"); std::vector<std::vector<crypto::signature>> signatures; @@ -9958,7 +10036,7 @@ bool wallet2::check_spend_proof(const crypto::hash &txid, const std::string &mes COMMAND_RPC_GET_TRANSACTIONS::request req = AUTO_VAL_INIT(req); req.txs_hashes.push_back(epee::string_tools::pod_to_hex(txid)); req.decode_as_json = false; - req.prune = false; + req.prune = true; COMMAND_RPC_GET_TRANSACTIONS::response res = AUTO_VAL_INIT(res); bool r; { @@ -9971,12 +10049,10 @@ bool wallet2::check_spend_proof(const crypto::hash &txid, const std::string &mes THROW_WALLET_EXCEPTION_IF(res.txs.size() != 1, error::wallet_internal_error, "daemon returned wrong response for gettransactions, wrong txs count = " + std::to_string(res.txs.size()) + ", expected 1"); - cryptonote::blobdata bd; - THROW_WALLET_EXCEPTION_IF(!epee::string_tools::parse_hexstr_to_binbuff(res.txs[0].as_hex, bd), error::wallet_internal_error, "failed to parse tx from hexstr"); + cryptonote::transaction tx; - crypto::hash tx_hash, tx_prefix_hash; - THROW_WALLET_EXCEPTION_IF(!cryptonote::parse_and_validate_tx_from_blob(bd, tx, tx_hash, tx_prefix_hash), error::wallet_internal_error, "failed to parse tx from blob"); - THROW_WALLET_EXCEPTION_IF(tx_hash != txid, error::wallet_internal_error, "txid mismatch"); + crypto::hash tx_hash; + THROW_WALLET_EXCEPTION_IF(!get_pruned_tx(res.txs[0], tx, tx_hash), error::wallet_internal_error, "failed to get tx from daemon"); // check signature size size_t num_sigs = 0; @@ -10083,24 +10159,30 @@ void wallet2::check_tx_key_helper(const crypto::hash &txid, const crypto::key_de COMMAND_RPC_GET_TRANSACTIONS::response res; req.txs_hashes.push_back(epee::string_tools::pod_to_hex(txid)); req.decode_as_json = false; - req.prune = false; + req.prune = true; m_daemon_rpc_mutex.lock(); bool ok = epee::net_utils::invoke_http_json("/gettransactions", req, res, m_http_client); m_daemon_rpc_mutex.unlock(); THROW_WALLET_EXCEPTION_IF(!ok || (res.txs.size() != 1 && res.txs_as_hex.size() != 1), error::wallet_internal_error, "Failed to get transaction from daemon"); - cryptonote::blobdata tx_data; + cryptonote::transaction tx; + crypto::hash tx_hash; if (res.txs.size() == 1) - ok = string_tools::parse_hexstr_to_binbuff(res.txs.front().as_hex, tx_data); + { + ok = get_pruned_tx(res.txs.front(), tx, tx_hash); + THROW_WALLET_EXCEPTION_IF(!ok, error::wallet_internal_error, "Failed to parse transaction from daemon"); + } else + { + cryptonote::blobdata tx_data; + crypto::hash tx_prefix_hash; ok = string_tools::parse_hexstr_to_binbuff(res.txs_as_hex.front(), tx_data); - THROW_WALLET_EXCEPTION_IF(!ok, error::wallet_internal_error, "Failed to parse transaction from daemon"); + THROW_WALLET_EXCEPTION_IF(!ok, error::wallet_internal_error, "Failed to parse transaction from daemon"); + THROW_WALLET_EXCEPTION_IF(!cryptonote::parse_and_validate_tx_from_blob(tx_data, tx, tx_hash, tx_prefix_hash), + error::wallet_internal_error, "Failed to validate transaction from daemon"); + } - crypto::hash tx_hash, tx_prefix_hash; - cryptonote::transaction tx; - THROW_WALLET_EXCEPTION_IF(!cryptonote::parse_and_validate_tx_from_blob(tx_data, tx, tx_hash, tx_prefix_hash), error::wallet_internal_error, - "Failed to validate transaction from daemon"); THROW_WALLET_EXCEPTION_IF(tx_hash != txid, error::wallet_internal_error, "Failed to get the right transaction from daemon"); THROW_WALLET_EXCEPTION_IF(!additional_derivations.empty() && additional_derivations.size() != tx.vout.size(), error::wallet_internal_error, @@ -10139,7 +10221,7 @@ void wallet2::check_tx_key_helper(const crypto::hash &txid, const crypto::key_de crypto::secret_key scalar1; hwdev.derivation_to_scalar(found_derivation, n, scalar1); rct::ecdhTuple ecdh_info = tx.rct_signatures.ecdhInfo[n]; - hwdev.ecdhDecode(ecdh_info, rct::sk2rct(scalar1)); + hwdev.ecdhDecode(ecdh_info, rct::sk2rct(scalar1), tx.rct_signatures.type == rct::RCTTypeBulletproof2); const rct::key C = tx.rct_signatures.outPk[n].mask; rct::key Ctmp; THROW_WALLET_EXCEPTION_IF(sc_check(ecdh_info.mask.bytes) != 0, error::wallet_internal_error, "Bad ECDH input mask"); @@ -10223,24 +10305,30 @@ std::string wallet2::get_tx_proof(const crypto::hash &txid, const cryptonote::ac COMMAND_RPC_GET_TRANSACTIONS::response res; req.txs_hashes.push_back(epee::string_tools::pod_to_hex(txid)); req.decode_as_json = false; - req.prune = false; + req.prune = true; m_daemon_rpc_mutex.lock(); bool ok = net_utils::invoke_http_json("/gettransactions", req, res, m_http_client); m_daemon_rpc_mutex.unlock(); THROW_WALLET_EXCEPTION_IF(!ok || (res.txs.size() != 1 && res.txs_as_hex.size() != 1), error::wallet_internal_error, "Failed to get transaction from daemon"); - cryptonote::blobdata tx_data; + cryptonote::transaction tx; + crypto::hash tx_hash; if (res.txs.size() == 1) - ok = string_tools::parse_hexstr_to_binbuff(res.txs.front().as_hex, tx_data); + { + ok = get_pruned_tx(res.txs.front(), tx, tx_hash); + THROW_WALLET_EXCEPTION_IF(!ok, error::wallet_internal_error, "Failed to parse transaction from daemon"); + } else + { + cryptonote::blobdata tx_data; + crypto::hash tx_prefix_hash; ok = string_tools::parse_hexstr_to_binbuff(res.txs_as_hex.front(), tx_data); - THROW_WALLET_EXCEPTION_IF(!ok, error::wallet_internal_error, "Failed to parse transaction from daemon"); + THROW_WALLET_EXCEPTION_IF(!ok, error::wallet_internal_error, "Failed to parse transaction from daemon"); + THROW_WALLET_EXCEPTION_IF(!cryptonote::parse_and_validate_tx_from_blob(tx_data, tx, tx_hash, tx_prefix_hash), + error::wallet_internal_error, "Failed to validate transaction from daemon"); + } - crypto::hash tx_hash, tx_prefix_hash; - cryptonote::transaction tx; - THROW_WALLET_EXCEPTION_IF(!cryptonote::parse_and_validate_tx_from_blob(tx_data, tx, tx_hash, tx_prefix_hash), error::wallet_internal_error, - "Failed to validate transaction from daemon"); THROW_WALLET_EXCEPTION_IF(tx_hash != txid, error::wallet_internal_error, "Failed to get the right transaction from daemon"); crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(tx); @@ -10335,24 +10423,30 @@ bool wallet2::check_tx_proof(const crypto::hash &txid, const cryptonote::account COMMAND_RPC_GET_TRANSACTIONS::response res; req.txs_hashes.push_back(epee::string_tools::pod_to_hex(txid)); req.decode_as_json = false; - req.prune = false; + req.prune = true; m_daemon_rpc_mutex.lock(); bool ok = net_utils::invoke_http_json("/gettransactions", req, res, m_http_client); m_daemon_rpc_mutex.unlock(); THROW_WALLET_EXCEPTION_IF(!ok || (res.txs.size() != 1 && res.txs_as_hex.size() != 1), error::wallet_internal_error, "Failed to get transaction from daemon"); - cryptonote::blobdata tx_data; + cryptonote::transaction tx; + crypto::hash tx_hash; if (res.txs.size() == 1) - ok = string_tools::parse_hexstr_to_binbuff(res.txs.front().as_hex, tx_data); + { + ok = get_pruned_tx(res.txs.front(), tx, tx_hash); + THROW_WALLET_EXCEPTION_IF(!ok, error::wallet_internal_error, "Failed to parse transaction from daemon"); + } else + { + cryptonote::blobdata tx_data; + crypto::hash tx_prefix_hash; ok = string_tools::parse_hexstr_to_binbuff(res.txs_as_hex.front(), tx_data); - THROW_WALLET_EXCEPTION_IF(!ok, error::wallet_internal_error, "Failed to parse transaction from daemon"); + THROW_WALLET_EXCEPTION_IF(!ok, error::wallet_internal_error, "Failed to parse transaction from daemon"); + THROW_WALLET_EXCEPTION_IF(!cryptonote::parse_and_validate_tx_from_blob(tx_data, tx, tx_hash, tx_prefix_hash), + error::wallet_internal_error, "Failed to validate transaction from daemon"); + } - crypto::hash tx_hash, tx_prefix_hash; - cryptonote::transaction tx; - THROW_WALLET_EXCEPTION_IF(!cryptonote::parse_and_validate_tx_from_blob(tx_data, tx, tx_hash, tx_prefix_hash), error::wallet_internal_error, - "Failed to validate transaction from daemon"); THROW_WALLET_EXCEPTION_IF(tx_hash != txid, error::wallet_internal_error, "Failed to get the right transaction from daemon"); crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(tx); @@ -10571,7 +10665,7 @@ bool wallet2::check_reserve_proof(const cryptonote::account_public_address &addr for (size_t i = 0; i < proofs.size(); ++i) gettx_req.txs_hashes.push_back(epee::string_tools::pod_to_hex(proofs[i].txid)); gettx_req.decode_as_json = false; - gettx_req.prune = false; + gettx_req.prune = true; m_daemon_rpc_mutex.lock(); bool ok = net_utils::invoke_http_json("/gettransactions", gettx_req, gettx_res, m_http_client); m_daemon_rpc_mutex.unlock(); @@ -10595,14 +10689,11 @@ bool wallet2::check_reserve_proof(const cryptonote::account_public_address &addr const reserve_proof_entry& proof = proofs[i]; THROW_WALLET_EXCEPTION_IF(gettx_res.txs[i].in_pool, error::wallet_internal_error, "Tx is unconfirmed"); - cryptonote::blobdata tx_data; - ok = string_tools::parse_hexstr_to_binbuff(gettx_res.txs[i].as_hex, tx_data); + cryptonote::transaction tx; + crypto::hash tx_hash; + ok = get_pruned_tx(gettx_res.txs[i], tx, tx_hash); THROW_WALLET_EXCEPTION_IF(!ok, error::wallet_internal_error, "Failed to parse transaction from daemon"); - crypto::hash tx_hash, tx_prefix_hash; - cryptonote::transaction tx; - THROW_WALLET_EXCEPTION_IF(!cryptonote::parse_and_validate_tx_from_blob(tx_data, tx, tx_hash, tx_prefix_hash), error::wallet_internal_error, - "Failed to validate transaction from daemon"); THROW_WALLET_EXCEPTION_IF(tx_hash != proof.txid, error::wallet_internal_error, "Failed to get the right transaction from daemon"); THROW_WALLET_EXCEPTION_IF(proof.index_in_tx >= tx.vout.size(), error::wallet_internal_error, "index_in_tx is out of bound"); @@ -10644,7 +10735,7 @@ bool wallet2::check_reserve_proof(const cryptonote::account_public_address &addr crypto::secret_key shared_secret; crypto::derivation_to_scalar(derivation, proof.index_in_tx, shared_secret); rct::ecdhTuple ecdh_info = tx.rct_signatures.ecdhInfo[proof.index_in_tx]; - rct::ecdhDecode(ecdh_info, rct::sk2rct(shared_secret)); + rct::ecdhDecode(ecdh_info, rct::sk2rct(shared_secret), tx.rct_signatures.type == rct::RCTTypeBulletproof2); amount = rct::h2d(ecdh_info.amount); } total += amount; @@ -11212,7 +11303,7 @@ uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_imag COMMAND_RPC_GET_TRANSACTIONS::request gettxs_req; COMMAND_RPC_GET_TRANSACTIONS::response gettxs_res; gettxs_req.decode_as_json = false; - gettxs_req.prune = false; + gettxs_req.prune = true; gettxs_req.txs_hashes.reserve(spent_txids.size()); for (const crypto::hash& spent_txid : spent_txids) gettxs_req.txs_hashes.push_back(epee::string_tools::pod_to_hex(spent_txid)); @@ -11232,17 +11323,16 @@ uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_imag PERF_TIMER_START(import_key_images_F); auto spent_txid = spent_txids.begin(); hw::device &hwdev = m_account.get_device(); + auto it = spent_txids.begin(); for (const COMMAND_RPC_GET_TRANSACTIONS::entry& e : gettxs_res.txs) { THROW_WALLET_EXCEPTION_IF(e.in_pool, error::wallet_internal_error, "spent tx isn't supposed to be in txpool"); - // parse tx - cryptonote::blobdata bd; - THROW_WALLET_EXCEPTION_IF(!epee::string_tools::parse_hexstr_to_binbuff(e.as_hex, bd), error::wallet_internal_error, "parse_hexstr_to_binbuff failed"); cryptonote::transaction spent_tx; - crypto::hash spnet_txid_parsed, spent_txid_prefix; - THROW_WALLET_EXCEPTION_IF(!cryptonote::parse_and_validate_tx_from_blob(bd, spent_tx, spnet_txid_parsed, spent_txid_prefix), error::wallet_internal_error, "parse_and_validate_tx_from_blob failed"); - THROW_WALLET_EXCEPTION_IF(*spent_txid != spnet_txid_parsed, error::wallet_internal_error, "parsed txid mismatch"); + crypto::hash spnet_txid_parsed; + THROW_WALLET_EXCEPTION_IF(!get_pruned_tx(e, spent_tx, spnet_txid_parsed), error::wallet_internal_error, "Failed to get tx from daemon"); + THROW_WALLET_EXCEPTION_IF(!(spnet_txid_parsed == *it), error::wallet_internal_error, "parsed txid mismatch"); + ++it; // get received (change) amount uint64_t tx_money_got_in_outs = 0; @@ -11260,6 +11350,7 @@ uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_imag THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to generate key derivation"); } size_t output_index = 0; + bool miner_tx = cryptonote::is_coinbase(spent_tx); for (const cryptonote::tx_out& out : spent_tx.vout) { tx_scan_info_t tx_scan_info; @@ -11267,11 +11358,13 @@ uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_imag THROW_WALLET_EXCEPTION_IF(tx_scan_info.error, error::wallet_internal_error, "check_acc_out_precomp failed"); if (tx_scan_info.received) { - if (tx_scan_info.money_transfered == 0) + if (tx_scan_info.money_transfered == 0 && !miner_tx) { rct::key mask; tx_scan_info.money_transfered = tools::decodeRct(spent_tx.rct_signatures, tx_scan_info.received->derivation, output_index, mask, hwdev); } + THROW_WALLET_EXCEPTION_IF(tx_money_got_in_outs >= std::numeric_limits<uint64_t>::max() - tx_scan_info.money_transfered, + error::wallet_internal_error, "Overflow in received amounts"); tx_money_got_in_outs += tx_scan_info.money_transfered; } ++output_index; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index ed92aec19..ea1172f40 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -676,7 +676,11 @@ namespace tools bool deinit(); bool init(std::string daemon_address = "http://localhost:8080", - boost::optional<epee::net_utils::http::login> daemon_login = boost::none, uint64_t upper_transaction_weight_limit = 0, bool ssl = false, bool trusted_daemon = false); + boost::optional<epee::net_utils::http::login> daemon_login = boost::none, uint64_t upper_transaction_weight_limit = 0, + bool trusted_daemon = true, + epee::net_utils::ssl_support_t ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_autodetect, + const std::pair<std::string, std::string> &private_key_and_certificate_path = {}, + const std::list<std::string> &allowed_certificates = {}, bool allow_any_cert = false); void stop() { m_run.store(false, std::memory_order_relaxed); m_message_store.stop(); } @@ -733,7 +737,7 @@ namespace tools bool is_deprecated() const; void refresh(bool trusted_daemon); void refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blocks_fetched); - void refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blocks_fetched, bool& received_money); + void refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blocks_fetched, bool& received_money, bool check_pool = true); bool refresh(bool trusted_daemon, uint64_t & blocks_fetched, bool& received_money, bool& ok); void set_refresh_type(RefreshType refresh_type) { m_refresh_type = refresh_type; } @@ -764,7 +768,7 @@ namespace tools uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx &ptx); void transfer_selected_rct(std::vector<cryptonote::tx_destination_entry> dsts, const std::vector<size_t>& selected_transfers, size_t fake_outputs_count, std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs, - uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx, rct::RangeProofType range_proof_type); + uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx, const rct::RCTConfig &rct_config); void commit_tx(pending_tx& ptx_vector); void commit_tx(std::vector<pending_tx>& ptx_vector); @@ -800,7 +804,7 @@ namespace tools bool sign_multisig_tx_to_file(multisig_tx_set &exported_txs, const std::string &filename, std::vector<crypto::hash> &txids); std::vector<pending_tx> create_unmixable_sweep_transactions(); void discard_unmixable_outputs(); - bool check_connection(uint32_t *version = NULL, uint32_t timeout = 200000); + bool check_connection(uint32_t *version = NULL, bool *ssl = NULL, uint32_t timeout = 200000); void get_transfers(wallet2::transfer_container& incoming_transfers) const; void get_payments(const crypto::hash& payment_id, std::list<wallet2::payment_details>& payments, uint64_t min_height = 0, const boost::optional<uint32_t>& subaddr_account = boost::none, const std::set<uint32_t>& subaddr_indices = {}) const; void get_payments(std::list<std::pair<crypto::hash,wallet2::payment_details>>& payments, uint64_t min_height, uint64_t max_height = (uint64_t)-1, const boost::optional<uint32_t>& subaddr_account = boost::none, const std::set<uint32_t>& subaddr_indices = {}) const; @@ -1292,7 +1296,7 @@ namespace tools bool tx_add_fake_output(std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs, uint64_t global_index, const crypto::public_key& tx_public_key, const rct::key& mask, uint64_t real_index, bool unlocked) 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; - void scan_output(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, std::unordered_map<cryptonote::subaddress_index, uint64_t> &tx_money_got_in_outs, std::vector<size_t> &outs); + void scan_output(const cryptonote::transaction &tx, bool miner_tx, const crypto::public_key &tx_pub_key, size_t i, tx_scan_info_t &tx_scan_info, int &num_vouts_received, std::unordered_map<cryptonote::subaddress_index, uint64_t> &tx_money_got_in_outs, std::vector<size_t> &outs, bool pool); void trim_hashchain(); crypto::key_image get_multisig_composite_key_image(size_t n) const; rct::multisig_kLRki get_multisig_composite_kLRki(size_t n, const std::unordered_set<crypto::public_key> &ignore_set, std::unordered_set<rct::key> &used_L, std::unordered_set<rct::key> &new_used_L) const; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 5dc6ac0e8..385e23818 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -63,6 +63,10 @@ namespace const command_line::arg_descriptor<bool> arg_restricted = {"restricted-rpc", "Restricts to view-only commands", false}; const command_line::arg_descriptor<std::string> arg_wallet_dir = {"wallet-dir", "Directory for newly created wallets"}; const command_line::arg_descriptor<bool> arg_prompt_for_password = {"prompt-for-password", "Prompts for password when not provided", false}; + const command_line::arg_descriptor<std::string> arg_rpc_ssl = {"rpc-ssl", tools::wallet2::tr("Enable SSL on wallet RPC connections: enabled|disabled|autodetect"), "autodetect"}; + const command_line::arg_descriptor<std::string> arg_rpc_ssl_private_key = {"rpc-ssl-private-key", tools::wallet2::tr("Path to a PEM format private key"), ""}; + const command_line::arg_descriptor<std::string> arg_rpc_ssl_certificate = {"rpc-ssl-certificate", tools::wallet2::tr("Path to a PEM format certificate"), ""}; + const command_line::arg_descriptor<std::vector<std::string>> arg_rpc_ssl_allowed_certificates = {"rpc-ssl-allowed-certificates", tools::wallet2::tr("List of paths to PEM format certificates of allowed RPC servers (all allowed if empty)")}; constexpr const char default_rpc_username[] = "monero"; @@ -233,10 +237,32 @@ namespace tools assert(bool(http_login)); } // end auth enabled + auto rpc_ssl_private_key = command_line::get_arg(vm, arg_rpc_ssl_private_key); + auto rpc_ssl_certificate = command_line::get_arg(vm, arg_rpc_ssl_certificate); + auto rpc_ssl_allowed_certificates = command_line::get_arg(vm, arg_rpc_ssl_allowed_certificates); + auto rpc_ssl = command_line::get_arg(vm, arg_rpc_ssl); + epee::net_utils::ssl_support_t rpc_ssl_support; + if (!epee::net_utils::ssl_support_from_string(rpc_ssl_support, rpc_ssl)) + { + MERROR("Invalid argument for " << std::string(arg_rpc_ssl.name)); + return false; + } + std::list<std::string> allowed_certificates; + for (const std::string &path: rpc_ssl_allowed_certificates) + { + allowed_certificates.push_back({}); + if (!epee::file_io_utils::load_file_to_string(path, allowed_certificates.back())) + { + MERROR("Failed to load certificate: " << path); + allowed_certificates.back() = std::string(); + } + } + m_net_server.set_threads_prefix("RPC"); auto rng = [](size_t len, uint8_t *ptr) { return crypto::rand(len, ptr); }; return epee::http_server_impl_base<wallet_rpc_server, connection_context>::init( - rng, std::move(bind_port), std::move(rpc_config->bind_ip), std::move(rpc_config->access_control_origins), std::move(http_login) + rng, std::move(bind_port), std::move(rpc_config->bind_ip), std::move(rpc_config->access_control_origins), std::move(http_login), + rpc_ssl_support, std::make_pair(rpc_ssl_private_key, rpc_ssl_certificate), allowed_certificates ); } //------------------------------------------------------------------------------------------------------------------------------ @@ -332,7 +358,7 @@ namespace tools set_confirmations(entry, m_wallet->get_blockchain_current_height(), m_wallet->get_last_block_reward()); } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_getbalance(const wallet_rpc::COMMAND_RPC_GET_BALANCE::request& req, wallet_rpc::COMMAND_RPC_GET_BALANCE::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_getbalance(const wallet_rpc::COMMAND_RPC_GET_BALANCE::request& req, wallet_rpc::COMMAND_RPC_GET_BALANCE::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); try @@ -371,7 +397,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_getaddress(const wallet_rpc::COMMAND_RPC_GET_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_GET_ADDRESS::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_getaddress(const wallet_rpc::COMMAND_RPC_GET_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_GET_ADDRESS::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); try @@ -411,7 +437,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_getaddress_index(const wallet_rpc::COMMAND_RPC_GET_ADDRESS_INDEX::request& req, wallet_rpc::COMMAND_RPC_GET_ADDRESS_INDEX::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_getaddress_index(const wallet_rpc::COMMAND_RPC_GET_ADDRESS_INDEX::request& req, wallet_rpc::COMMAND_RPC_GET_ADDRESS_INDEX::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); cryptonote::address_parse_info info; @@ -432,7 +458,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_create_address(const wallet_rpc::COMMAND_RPC_CREATE_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_CREATE_ADDRESS::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_create_address(const wallet_rpc::COMMAND_RPC_CREATE_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_CREATE_ADDRESS::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); try @@ -449,7 +475,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_label_address(const wallet_rpc::COMMAND_RPC_LABEL_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_LABEL_ADDRESS::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_label_address(const wallet_rpc::COMMAND_RPC_LABEL_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_LABEL_ADDRESS::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); try @@ -464,7 +490,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_get_accounts(const wallet_rpc::COMMAND_RPC_GET_ACCOUNTS::request& req, wallet_rpc::COMMAND_RPC_GET_ACCOUNTS::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_get_accounts(const wallet_rpc::COMMAND_RPC_GET_ACCOUNTS::request& req, wallet_rpc::COMMAND_RPC_GET_ACCOUNTS::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); try @@ -503,7 +529,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_create_account(const wallet_rpc::COMMAND_RPC_CREATE_ACCOUNT::request& req, wallet_rpc::COMMAND_RPC_CREATE_ACCOUNT::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_create_account(const wallet_rpc::COMMAND_RPC_CREATE_ACCOUNT::request& req, wallet_rpc::COMMAND_RPC_CREATE_ACCOUNT::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); try @@ -520,7 +546,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_label_account(const wallet_rpc::COMMAND_RPC_LABEL_ACCOUNT::request& req, wallet_rpc::COMMAND_RPC_LABEL_ACCOUNT::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_label_account(const wallet_rpc::COMMAND_RPC_LABEL_ACCOUNT::request& req, wallet_rpc::COMMAND_RPC_LABEL_ACCOUNT::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); try @@ -535,7 +561,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_get_account_tags(const wallet_rpc::COMMAND_RPC_GET_ACCOUNT_TAGS::request& req, wallet_rpc::COMMAND_RPC_GET_ACCOUNT_TAGS::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_get_account_tags(const wallet_rpc::COMMAND_RPC_GET_ACCOUNT_TAGS::request& req, wallet_rpc::COMMAND_RPC_GET_ACCOUNT_TAGS::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); const std::pair<std::map<std::string, std::string>, std::vector<std::string>> account_tags = m_wallet->get_account_tags(); @@ -554,7 +580,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_tag_accounts(const wallet_rpc::COMMAND_RPC_TAG_ACCOUNTS::request& req, wallet_rpc::COMMAND_RPC_TAG_ACCOUNTS::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_tag_accounts(const wallet_rpc::COMMAND_RPC_TAG_ACCOUNTS::request& req, wallet_rpc::COMMAND_RPC_TAG_ACCOUNTS::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); try @@ -569,7 +595,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_untag_accounts(const wallet_rpc::COMMAND_RPC_UNTAG_ACCOUNTS::request& req, wallet_rpc::COMMAND_RPC_UNTAG_ACCOUNTS::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_untag_accounts(const wallet_rpc::COMMAND_RPC_UNTAG_ACCOUNTS::request& req, wallet_rpc::COMMAND_RPC_UNTAG_ACCOUNTS::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); try @@ -584,7 +610,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_set_account_tag_description(const wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION::request& req, wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_set_account_tag_description(const wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION::request& req, wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); try @@ -599,7 +625,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_getheight(const wallet_rpc::COMMAND_RPC_GET_HEIGHT::request& req, wallet_rpc::COMMAND_RPC_GET_HEIGHT::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_getheight(const wallet_rpc::COMMAND_RPC_GET_HEIGHT::request& req, wallet_rpc::COMMAND_RPC_GET_HEIGHT::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); try @@ -691,13 +717,9 @@ namespace tools if (wallet2::parse_long_payment_id(payment_id_str, long_payment_id)) { cryptonote::set_payment_id_to_tx_extra_nonce(extra_nonce, long_payment_id); } - /* or short payment ID */ - else if (wallet2::parse_short_payment_id(payment_id_str, short_payment_id)) { - cryptonote::set_encrypted_payment_id_to_tx_extra_nonce(extra_nonce, short_payment_id); - } else { er.code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID; - er.message = "Payment id has invalid format: \"" + payment_id_str + "\", expected 16 or 64 character string"; + er.message = "Payment id has invalid format: \"" + payment_id_str + "\", expected 64 character string"; return false; } @@ -813,7 +835,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_transfer(const wallet_rpc::COMMAND_RPC_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_TRANSFER::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_transfer(const wallet_rpc::COMMAND_RPC_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_TRANSFER::response& res, epee::json_rpc::error& er, const connection_context *ctx) { std::vector<cryptonote::tx_destination_entry> dsts; @@ -874,7 +896,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_transfer_split(const wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT::request& req, wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_transfer_split(const wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT::request& req, wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT::response& res, epee::json_rpc::error& er, const connection_context *ctx) { std::vector<cryptonote::tx_destination_entry> dsts; @@ -921,7 +943,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_sign_transfer(const wallet_rpc::COMMAND_RPC_SIGN_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_SIGN_TRANSFER::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_sign_transfer(const wallet_rpc::COMMAND_RPC_SIGN_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_SIGN_TRANSFER::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -1002,7 +1024,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_describe_transfer(const wallet_rpc::COMMAND_RPC_DESCRIBE_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_DESCRIBE_TRANSFER::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_describe_transfer(const wallet_rpc::COMMAND_RPC_DESCRIBE_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_DESCRIBE_TRANSFER::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -1167,7 +1189,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_submit_transfer(const wallet_rpc::COMMAND_RPC_SUBMIT_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_SUBMIT_TRANSFER::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_submit_transfer(const wallet_rpc::COMMAND_RPC_SUBMIT_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_SUBMIT_TRANSFER::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -1227,7 +1249,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_sweep_dust(const wallet_rpc::COMMAND_RPC_SWEEP_DUST::request& req, wallet_rpc::COMMAND_RPC_SWEEP_DUST::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_sweep_dust(const wallet_rpc::COMMAND_RPC_SWEEP_DUST::request& req, wallet_rpc::COMMAND_RPC_SWEEP_DUST::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -1252,7 +1274,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_sweep_all(const wallet_rpc::COMMAND_RPC_SWEEP_ALL::request& req, wallet_rpc::COMMAND_RPC_SWEEP_ALL::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_sweep_all(const wallet_rpc::COMMAND_RPC_SWEEP_ALL::request& req, wallet_rpc::COMMAND_RPC_SWEEP_ALL::response& res, epee::json_rpc::error& er, const connection_context *ctx) { std::vector<cryptonote::tx_destination_entry> dsts; std::vector<uint8_t> extra; @@ -1307,7 +1329,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_sweep_single(const wallet_rpc::COMMAND_RPC_SWEEP_SINGLE::request& req, wallet_rpc::COMMAND_RPC_SWEEP_SINGLE::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_sweep_single(const wallet_rpc::COMMAND_RPC_SWEEP_SINGLE::request& req, wallet_rpc::COMMAND_RPC_SWEEP_SINGLE::response& res, epee::json_rpc::error& er, const connection_context *ctx) { std::vector<cryptonote::tx_destination_entry> dsts; std::vector<uint8_t> extra; @@ -1396,7 +1418,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_relay_tx(const wallet_rpc::COMMAND_RPC_RELAY_TX::request& req, wallet_rpc::COMMAND_RPC_RELAY_TX::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_relay_tx(const wallet_rpc::COMMAND_RPC_RELAY_TX::request& req, wallet_rpc::COMMAND_RPC_RELAY_TX::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); @@ -1438,7 +1460,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_make_integrated_address(const wallet_rpc::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_make_integrated_address(const wallet_rpc::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); try @@ -1502,7 +1524,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_split_integrated_address(const wallet_rpc::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_split_integrated_address(const wallet_rpc::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); try @@ -1533,7 +1555,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_store(const wallet_rpc::COMMAND_RPC_STORE::request& req, wallet_rpc::COMMAND_RPC_STORE::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_store(const wallet_rpc::COMMAND_RPC_STORE::request& req, wallet_rpc::COMMAND_RPC_STORE::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -1555,7 +1577,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_get_payments(const wallet_rpc::COMMAND_RPC_GET_PAYMENTS::request& req, wallet_rpc::COMMAND_RPC_GET_PAYMENTS::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_get_payments(const wallet_rpc::COMMAND_RPC_GET_PAYMENTS::request& req, wallet_rpc::COMMAND_RPC_GET_PAYMENTS::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); crypto::hash payment_id; @@ -1604,7 +1626,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_get_bulk_payments(const wallet_rpc::COMMAND_RPC_GET_BULK_PAYMENTS::request& req, wallet_rpc::COMMAND_RPC_GET_BULK_PAYMENTS::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_get_bulk_payments(const wallet_rpc::COMMAND_RPC_GET_BULK_PAYMENTS::request& req, wallet_rpc::COMMAND_RPC_GET_BULK_PAYMENTS::response& res, epee::json_rpc::error& er, const connection_context *ctx) { res.payments.clear(); if (!m_wallet) return not_open(er); @@ -1683,7 +1705,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_incoming_transfers(const wallet_rpc::COMMAND_RPC_INCOMING_TRANSFERS::request& req, wallet_rpc::COMMAND_RPC_INCOMING_TRANSFERS::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_incoming_transfers(const wallet_rpc::COMMAND_RPC_INCOMING_TRANSFERS::request& req, wallet_rpc::COMMAND_RPC_INCOMING_TRANSFERS::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if(req.transfer_type.compare("all") != 0 && req.transfer_type.compare("available") != 0 && req.transfer_type.compare("unavailable") != 0) @@ -1735,7 +1757,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_query_key(const wallet_rpc::COMMAND_RPC_QUERY_KEY::request& req, wallet_rpc::COMMAND_RPC_QUERY_KEY::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_query_key(const wallet_rpc::COMMAND_RPC_QUERY_KEY::request& req, wallet_rpc::COMMAND_RPC_QUERY_KEY::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -1806,7 +1828,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_rescan_blockchain(const wallet_rpc::COMMAND_RPC_RESCAN_BLOCKCHAIN::request& req, wallet_rpc::COMMAND_RPC_RESCAN_BLOCKCHAIN::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_rescan_blockchain(const wallet_rpc::COMMAND_RPC_RESCAN_BLOCKCHAIN::request& req, wallet_rpc::COMMAND_RPC_RESCAN_BLOCKCHAIN::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -1828,7 +1850,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_sign(const wallet_rpc::COMMAND_RPC_SIGN::request& req, wallet_rpc::COMMAND_RPC_SIGN::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_sign(const wallet_rpc::COMMAND_RPC_SIGN::request& req, wallet_rpc::COMMAND_RPC_SIGN::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -1842,7 +1864,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_verify(const wallet_rpc::COMMAND_RPC_VERIFY::request& req, wallet_rpc::COMMAND_RPC_VERIFY::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_verify(const wallet_rpc::COMMAND_RPC_VERIFY::request& req, wallet_rpc::COMMAND_RPC_VERIFY::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -1877,7 +1899,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_stop_wallet(const wallet_rpc::COMMAND_RPC_STOP_WALLET::request& req, wallet_rpc::COMMAND_RPC_STOP_WALLET::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_stop_wallet(const wallet_rpc::COMMAND_RPC_STOP_WALLET::request& req, wallet_rpc::COMMAND_RPC_STOP_WALLET::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -1900,7 +1922,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_set_tx_notes(const wallet_rpc::COMMAND_RPC_SET_TX_NOTES::request& req, wallet_rpc::COMMAND_RPC_SET_TX_NOTES::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_set_tx_notes(const wallet_rpc::COMMAND_RPC_SET_TX_NOTES::request& req, wallet_rpc::COMMAND_RPC_SET_TX_NOTES::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -1943,7 +1965,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_get_tx_notes(const wallet_rpc::COMMAND_RPC_GET_TX_NOTES::request& req, wallet_rpc::COMMAND_RPC_GET_TX_NOTES::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_get_tx_notes(const wallet_rpc::COMMAND_RPC_GET_TX_NOTES::request& req, wallet_rpc::COMMAND_RPC_GET_TX_NOTES::response& res, epee::json_rpc::error& er, const connection_context *ctx) { res.notes.clear(); if (!m_wallet) return not_open(er); @@ -1972,7 +1994,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_set_attribute(const wallet_rpc::COMMAND_RPC_SET_ATTRIBUTE::request& req, wallet_rpc::COMMAND_RPC_SET_ATTRIBUTE::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_set_attribute(const wallet_rpc::COMMAND_RPC_SET_ATTRIBUTE::request& req, wallet_rpc::COMMAND_RPC_SET_ATTRIBUTE::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -1987,7 +2009,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_get_attribute(const wallet_rpc::COMMAND_RPC_GET_ATTRIBUTE::request& req, wallet_rpc::COMMAND_RPC_GET_ATTRIBUTE::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_get_attribute(const wallet_rpc::COMMAND_RPC_GET_ATTRIBUTE::request& req, wallet_rpc::COMMAND_RPC_GET_ATTRIBUTE::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -2000,7 +2022,7 @@ namespace tools res.value = m_wallet->get_attribute(req.key); return true; } - bool wallet_rpc_server::on_get_tx_key(const wallet_rpc::COMMAND_RPC_GET_TX_KEY::request& req, wallet_rpc::COMMAND_RPC_GET_TX_KEY::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_get_tx_key(const wallet_rpc::COMMAND_RPC_GET_TX_KEY::request& req, wallet_rpc::COMMAND_RPC_GET_TX_KEY::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); @@ -2029,7 +2051,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_check_tx_key(const wallet_rpc::COMMAND_RPC_CHECK_TX_KEY::request& req, wallet_rpc::COMMAND_RPC_CHECK_TX_KEY::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_check_tx_key(const wallet_rpc::COMMAND_RPC_CHECK_TX_KEY::request& req, wallet_rpc::COMMAND_RPC_CHECK_TX_KEY::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); @@ -2091,7 +2113,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_get_tx_proof(const wallet_rpc::COMMAND_RPC_GET_TX_PROOF::request& req, wallet_rpc::COMMAND_RPC_GET_TX_PROOF::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_get_tx_proof(const wallet_rpc::COMMAND_RPC_GET_TX_PROOF::request& req, wallet_rpc::COMMAND_RPC_GET_TX_PROOF::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); @@ -2124,7 +2146,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_check_tx_proof(const wallet_rpc::COMMAND_RPC_CHECK_TX_PROOF::request& req, wallet_rpc::COMMAND_RPC_CHECK_TX_PROOF::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_check_tx_proof(const wallet_rpc::COMMAND_RPC_CHECK_TX_PROOF::request& req, wallet_rpc::COMMAND_RPC_CHECK_TX_PROOF::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); @@ -2160,7 +2182,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_get_spend_proof(const wallet_rpc::COMMAND_RPC_GET_SPEND_PROOF::request& req, wallet_rpc::COMMAND_RPC_GET_SPEND_PROOF::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_get_spend_proof(const wallet_rpc::COMMAND_RPC_GET_SPEND_PROOF::request& req, wallet_rpc::COMMAND_RPC_GET_SPEND_PROOF::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); @@ -2185,7 +2207,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_check_spend_proof(const wallet_rpc::COMMAND_RPC_CHECK_SPEND_PROOF::request& req, wallet_rpc::COMMAND_RPC_CHECK_SPEND_PROOF::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_check_spend_proof(const wallet_rpc::COMMAND_RPC_CHECK_SPEND_PROOF::request& req, wallet_rpc::COMMAND_RPC_CHECK_SPEND_PROOF::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); @@ -2210,7 +2232,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_get_reserve_proof(const wallet_rpc::COMMAND_RPC_GET_RESERVE_PROOF::request& req, wallet_rpc::COMMAND_RPC_GET_RESERVE_PROOF::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_get_reserve_proof(const wallet_rpc::COMMAND_RPC_GET_RESERVE_PROOF::request& req, wallet_rpc::COMMAND_RPC_GET_RESERVE_PROOF::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); @@ -2239,7 +2261,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_check_reserve_proof(const wallet_rpc::COMMAND_RPC_CHECK_RESERVE_PROOF::request& req, wallet_rpc::COMMAND_RPC_CHECK_RESERVE_PROOF::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_check_reserve_proof(const wallet_rpc::COMMAND_RPC_CHECK_RESERVE_PROOF::request& req, wallet_rpc::COMMAND_RPC_CHECK_RESERVE_PROOF::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); @@ -2270,7 +2292,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_get_transfers(const wallet_rpc::COMMAND_RPC_GET_TRANSFERS::request& req, wallet_rpc::COMMAND_RPC_GET_TRANSFERS::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_get_transfers(const wallet_rpc::COMMAND_RPC_GET_TRANSFERS::request& req, wallet_rpc::COMMAND_RPC_GET_TRANSFERS::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -2336,7 +2358,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_get_transfer_by_txid(const wallet_rpc::COMMAND_RPC_GET_TRANSFER_BY_TXID::request& req, wallet_rpc::COMMAND_RPC_GET_TRANSFER_BY_TXID::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_get_transfer_by_txid(const wallet_rpc::COMMAND_RPC_GET_TRANSFER_BY_TXID::request& req, wallet_rpc::COMMAND_RPC_GET_TRANSFER_BY_TXID::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -2426,7 +2448,7 @@ namespace tools return false; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_export_outputs(const wallet_rpc::COMMAND_RPC_EXPORT_OUTPUTS::request& req, wallet_rpc::COMMAND_RPC_EXPORT_OUTPUTS::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_export_outputs(const wallet_rpc::COMMAND_RPC_EXPORT_OUTPUTS::request& req, wallet_rpc::COMMAND_RPC_EXPORT_OUTPUTS::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -2455,7 +2477,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_import_outputs(const wallet_rpc::COMMAND_RPC_IMPORT_OUTPUTS::request& req, wallet_rpc::COMMAND_RPC_IMPORT_OUTPUTS::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_import_outputs(const wallet_rpc::COMMAND_RPC_IMPORT_OUTPUTS::request& req, wallet_rpc::COMMAND_RPC_IMPORT_OUTPUTS::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -2492,7 +2514,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_export_key_images(const wallet_rpc::COMMAND_RPC_EXPORT_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_EXPORT_KEY_IMAGES::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_export_key_images(const wallet_rpc::COMMAND_RPC_EXPORT_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_EXPORT_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); try @@ -2516,7 +2538,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_import_key_images(const wallet_rpc::COMMAND_RPC_IMPORT_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_IMPORT_KEY_IMAGES::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_import_key_images(const wallet_rpc::COMMAND_RPC_IMPORT_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_IMPORT_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -2571,7 +2593,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_make_uri(const wallet_rpc::COMMAND_RPC_MAKE_URI::request& req, wallet_rpc::COMMAND_RPC_MAKE_URI::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_make_uri(const wallet_rpc::COMMAND_RPC_MAKE_URI::request& req, wallet_rpc::COMMAND_RPC_MAKE_URI::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); std::string error; @@ -2587,7 +2609,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_parse_uri(const wallet_rpc::COMMAND_RPC_PARSE_URI::request& req, wallet_rpc::COMMAND_RPC_PARSE_URI::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_parse_uri(const wallet_rpc::COMMAND_RPC_PARSE_URI::request& req, wallet_rpc::COMMAND_RPC_PARSE_URI::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); std::string error; @@ -2600,7 +2622,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_get_address_book(const wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_get_address_book(const wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); const auto ab = m_wallet->get_address_book(); @@ -2627,7 +2649,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_add_address_book(const wallet_rpc::COMMAND_RPC_ADD_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_ADD_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_add_address_book(const wallet_rpc::COMMAND_RPC_ADD_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_ADD_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -2702,7 +2724,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_delete_address_book(const wallet_rpc::COMMAND_RPC_DELETE_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_DELETE_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_delete_address_book(const wallet_rpc::COMMAND_RPC_DELETE_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_DELETE_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -2728,7 +2750,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_refresh(const wallet_rpc::COMMAND_RPC_REFRESH::request& req, wallet_rpc::COMMAND_RPC_REFRESH::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_refresh(const wallet_rpc::COMMAND_RPC_REFRESH::request& req, wallet_rpc::COMMAND_RPC_REFRESH::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -2750,7 +2772,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_rescan_spent(const wallet_rpc::COMMAND_RPC_RESCAN_SPENT::request& req, wallet_rpc::COMMAND_RPC_RESCAN_SPENT::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_rescan_spent(const wallet_rpc::COMMAND_RPC_RESCAN_SPENT::request& req, wallet_rpc::COMMAND_RPC_RESCAN_SPENT::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -2772,7 +2794,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_start_mining(const wallet_rpc::COMMAND_RPC_START_MINING::request& req, wallet_rpc::COMMAND_RPC_START_MINING::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_start_mining(const wallet_rpc::COMMAND_RPC_START_MINING::request& req, wallet_rpc::COMMAND_RPC_START_MINING::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (!m_wallet->is_trusted_daemon()) @@ -2807,7 +2829,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_stop_mining(const wallet_rpc::COMMAND_RPC_STOP_MINING::request& req, wallet_rpc::COMMAND_RPC_STOP_MINING::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_stop_mining(const wallet_rpc::COMMAND_RPC_STOP_MINING::request& req, wallet_rpc::COMMAND_RPC_STOP_MINING::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); cryptonote::COMMAND_RPC_STOP_MINING::request daemon_req; @@ -2822,13 +2844,13 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_get_languages(const wallet_rpc::COMMAND_RPC_GET_LANGUAGES::request& req, wallet_rpc::COMMAND_RPC_GET_LANGUAGES::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_get_languages(const wallet_rpc::COMMAND_RPC_GET_LANGUAGES::request& req, wallet_rpc::COMMAND_RPC_GET_LANGUAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx) { crypto::ElectrumWords::get_language_list(res.languages); return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_create_wallet(const wallet_rpc::COMMAND_RPC_CREATE_WALLET::request& req, wallet_rpc::COMMAND_RPC_CREATE_WALLET::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_create_wallet(const wallet_rpc::COMMAND_RPC_CREATE_WALLET::request& req, wallet_rpc::COMMAND_RPC_CREATE_WALLET::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (m_wallet_dir.empty()) { @@ -2928,7 +2950,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_open_wallet(const wallet_rpc::COMMAND_RPC_OPEN_WALLET::request& req, wallet_rpc::COMMAND_RPC_OPEN_WALLET::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_open_wallet(const wallet_rpc::COMMAND_RPC_OPEN_WALLET::request& req, wallet_rpc::COMMAND_RPC_OPEN_WALLET::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (m_wallet_dir.empty()) { @@ -2998,7 +3020,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_close_wallet(const wallet_rpc::COMMAND_RPC_CLOSE_WALLET::request& req, wallet_rpc::COMMAND_RPC_CLOSE_WALLET::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_close_wallet(const wallet_rpc::COMMAND_RPC_CLOSE_WALLET::request& req, wallet_rpc::COMMAND_RPC_CLOSE_WALLET::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); @@ -3016,7 +3038,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_change_wallet_password(const wallet_rpc::COMMAND_RPC_CHANGE_WALLET_PASSWORD::request& req, wallet_rpc::COMMAND_RPC_CHANGE_WALLET_PASSWORD::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_change_wallet_password(const wallet_rpc::COMMAND_RPC_CHANGE_WALLET_PASSWORD::request& req, wallet_rpc::COMMAND_RPC_CHANGE_WALLET_PASSWORD::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -3129,7 +3151,7 @@ namespace tools } } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_restore_deterministic_wallet(const wallet_rpc::COMMAND_RPC_RESTORE_DETERMINISTIC_WALLET::request &req, wallet_rpc::COMMAND_RPC_RESTORE_DETERMINISTIC_WALLET::response &res, epee::json_rpc::error &er) + bool wallet_rpc_server::on_restore_deterministic_wallet(const wallet_rpc::COMMAND_RPC_RESTORE_DETERMINISTIC_WALLET::request &req, wallet_rpc::COMMAND_RPC_RESTORE_DETERMINISTIC_WALLET::response &res, epee::json_rpc::error &er, const connection_context *ctx) { if (m_wallet_dir.empty()) { @@ -3323,14 +3345,14 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_is_multisig(const wallet_rpc::COMMAND_RPC_IS_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_IS_MULTISIG::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_is_multisig(const wallet_rpc::COMMAND_RPC_IS_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_IS_MULTISIG::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); res.multisig = m_wallet->multisig(&res.ready, &res.threshold, &res.total); return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_prepare_multisig(const wallet_rpc::COMMAND_RPC_PREPARE_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_PREPARE_MULTISIG::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_prepare_multisig(const wallet_rpc::COMMAND_RPC_PREPARE_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_PREPARE_MULTISIG::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -3356,7 +3378,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_make_multisig(const wallet_rpc::COMMAND_RPC_MAKE_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_MAKE_MULTISIG::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_make_multisig(const wallet_rpc::COMMAND_RPC_MAKE_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_MAKE_MULTISIG::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -3393,7 +3415,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_export_multisig(const wallet_rpc::COMMAND_RPC_EXPORT_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_EXPORT_MULTISIG::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_export_multisig(const wallet_rpc::COMMAND_RPC_EXPORT_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_EXPORT_MULTISIG::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -3433,7 +3455,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_import_multisig(const wallet_rpc::COMMAND_RPC_IMPORT_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_IMPORT_MULTISIG::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_import_multisig(const wallet_rpc::COMMAND_RPC_IMPORT_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_IMPORT_MULTISIG::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -3506,7 +3528,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_finalize_multisig(const wallet_rpc::COMMAND_RPC_FINALIZE_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_FINALIZE_MULTISIG::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_finalize_multisig(const wallet_rpc::COMMAND_RPC_FINALIZE_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_FINALIZE_MULTISIG::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -3557,7 +3579,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_exchange_multisig_keys(const wallet_rpc::COMMAND_RPC_EXCHANGE_MULTISIG_KEYS::request& req, wallet_rpc::COMMAND_RPC_EXCHANGE_MULTISIG_KEYS::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_exchange_multisig_keys(const wallet_rpc::COMMAND_RPC_EXCHANGE_MULTISIG_KEYS::request& req, wallet_rpc::COMMAND_RPC_EXCHANGE_MULTISIG_KEYS::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -3606,7 +3628,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_sign_multisig(const wallet_rpc::COMMAND_RPC_SIGN_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_SIGN_MULTISIG::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_sign_multisig(const wallet_rpc::COMMAND_RPC_SIGN_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_SIGN_MULTISIG::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -3675,7 +3697,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_submit_multisig(const wallet_rpc::COMMAND_RPC_SUBMIT_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_SUBMIT_MULTISIG::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_submit_multisig(const wallet_rpc::COMMAND_RPC_SUBMIT_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_SUBMIT_MULTISIG::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -3741,7 +3763,7 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_get_version(const wallet_rpc::COMMAND_RPC_GET_VERSION::request& req, wallet_rpc::COMMAND_RPC_GET_VERSION::response& res, epee::json_rpc::error& er) + bool wallet_rpc_server::on_get_version(const wallet_rpc::COMMAND_RPC_GET_VERSION::request& req, wallet_rpc::COMMAND_RPC_GET_VERSION::response& res, epee::json_rpc::error& er, const connection_context *ctx) { res.version = WALLET_RPC_VERSION; return true; @@ -3937,6 +3959,10 @@ int main(int argc, char** argv) { command_line::add_arg(desc_params, arg_from_json); command_line::add_arg(desc_params, arg_wallet_dir); command_line::add_arg(desc_params, arg_prompt_for_password); + command_line::add_arg(desc_params, arg_rpc_ssl); + command_line::add_arg(desc_params, arg_rpc_ssl_private_key); + command_line::add_arg(desc_params, arg_rpc_ssl_certificate); + command_line::add_arg(desc_params, arg_rpc_ssl_allowed_certificates); daemonizer::init_options(hidden_options, desc_params); desc_params.add(hidden_options); diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index abbbe82c5..1a54e4c79 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -152,85 +152,84 @@ namespace tools END_URI_MAP2() //json_rpc - bool on_getbalance(const wallet_rpc::COMMAND_RPC_GET_BALANCE::request& req, wallet_rpc::COMMAND_RPC_GET_BALANCE::response& res, epee::json_rpc::error& er); - bool on_getaddress(const wallet_rpc::COMMAND_RPC_GET_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_GET_ADDRESS::response& res, epee::json_rpc::error& er); - bool on_getaddress_index(const wallet_rpc::COMMAND_RPC_GET_ADDRESS_INDEX::request& req, wallet_rpc::COMMAND_RPC_GET_ADDRESS_INDEX::response& res, epee::json_rpc::error& er); - bool on_create_address(const wallet_rpc::COMMAND_RPC_CREATE_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_CREATE_ADDRESS::response& res, epee::json_rpc::error& er); - bool on_label_address(const wallet_rpc::COMMAND_RPC_LABEL_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_LABEL_ADDRESS::response& res, epee::json_rpc::error& er); - bool on_get_accounts(const wallet_rpc::COMMAND_RPC_GET_ACCOUNTS::request& req, wallet_rpc::COMMAND_RPC_GET_ACCOUNTS::response& res, epee::json_rpc::error& er); - bool on_create_account(const wallet_rpc::COMMAND_RPC_CREATE_ACCOUNT::request& req, wallet_rpc::COMMAND_RPC_CREATE_ACCOUNT::response& res, epee::json_rpc::error& er); - bool on_label_account(const wallet_rpc::COMMAND_RPC_LABEL_ACCOUNT::request& req, wallet_rpc::COMMAND_RPC_LABEL_ACCOUNT::response& res, epee::json_rpc::error& er); - bool on_get_account_tags(const wallet_rpc::COMMAND_RPC_GET_ACCOUNT_TAGS::request& req, wallet_rpc::COMMAND_RPC_GET_ACCOUNT_TAGS::response& res, epee::json_rpc::error& er); - bool on_tag_accounts(const wallet_rpc::COMMAND_RPC_TAG_ACCOUNTS::request& req, wallet_rpc::COMMAND_RPC_TAG_ACCOUNTS::response& res, epee::json_rpc::error& er); - bool on_untag_accounts(const wallet_rpc::COMMAND_RPC_UNTAG_ACCOUNTS::request& req, wallet_rpc::COMMAND_RPC_UNTAG_ACCOUNTS::response& res, epee::json_rpc::error& er); - bool on_set_account_tag_description(const wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION::request& req, wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION::response& res, epee::json_rpc::error& er); - bool on_getheight(const wallet_rpc::COMMAND_RPC_GET_HEIGHT::request& req, wallet_rpc::COMMAND_RPC_GET_HEIGHT::response& res, epee::json_rpc::error& er); - bool validate_transfer(const std::list<wallet_rpc::transfer_destination>& destinations, const std::string& payment_id, std::vector<cryptonote::tx_destination_entry>& dsts, std::vector<uint8_t>& extra, bool at_least_one_destination, epee::json_rpc::error& er); - bool on_transfer(const wallet_rpc::COMMAND_RPC_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_TRANSFER::response& res, epee::json_rpc::error& er); - bool on_transfer_split(const wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT::request& req, wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT::response& res, epee::json_rpc::error& er); - bool on_sign_transfer(const wallet_rpc::COMMAND_RPC_SIGN_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_SIGN_TRANSFER::response& res, epee::json_rpc::error& er); - bool on_describe_transfer(const wallet_rpc::COMMAND_RPC_DESCRIBE_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_DESCRIBE_TRANSFER::response& res, epee::json_rpc::error& er); - bool on_submit_transfer(const wallet_rpc::COMMAND_RPC_SUBMIT_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_SUBMIT_TRANSFER::response& res, epee::json_rpc::error& er); - bool on_sweep_dust(const wallet_rpc::COMMAND_RPC_SWEEP_DUST::request& req, wallet_rpc::COMMAND_RPC_SWEEP_DUST::response& res, epee::json_rpc::error& er); - bool on_sweep_all(const wallet_rpc::COMMAND_RPC_SWEEP_ALL::request& req, wallet_rpc::COMMAND_RPC_SWEEP_ALL::response& res, epee::json_rpc::error& er); - bool on_sweep_single(const wallet_rpc::COMMAND_RPC_SWEEP_SINGLE::request& req, wallet_rpc::COMMAND_RPC_SWEEP_SINGLE::response& res, epee::json_rpc::error& er); - bool on_relay_tx(const wallet_rpc::COMMAND_RPC_RELAY_TX::request& req, wallet_rpc::COMMAND_RPC_RELAY_TX::response& res, epee::json_rpc::error& er); - bool on_make_integrated_address(const wallet_rpc::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS::response& res, epee::json_rpc::error& er); - bool on_split_integrated_address(const wallet_rpc::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS::response& res, epee::json_rpc::error& er); - bool on_store(const wallet_rpc::COMMAND_RPC_STORE::request& req, wallet_rpc::COMMAND_RPC_STORE::response& res, epee::json_rpc::error& er); - bool on_get_payments(const wallet_rpc::COMMAND_RPC_GET_PAYMENTS::request& req, wallet_rpc::COMMAND_RPC_GET_PAYMENTS::response& res, epee::json_rpc::error& er); - bool on_get_bulk_payments(const wallet_rpc::COMMAND_RPC_GET_BULK_PAYMENTS::request& req, wallet_rpc::COMMAND_RPC_GET_BULK_PAYMENTS::response& res, epee::json_rpc::error& er); - bool on_incoming_transfers(const wallet_rpc::COMMAND_RPC_INCOMING_TRANSFERS::request& req, wallet_rpc::COMMAND_RPC_INCOMING_TRANSFERS::response& res, epee::json_rpc::error& er); - bool on_stop_wallet(const wallet_rpc::COMMAND_RPC_STOP_WALLET::request& req, wallet_rpc::COMMAND_RPC_STOP_WALLET::response& res, epee::json_rpc::error& er); - bool on_rescan_blockchain(const wallet_rpc::COMMAND_RPC_RESCAN_BLOCKCHAIN::request& req, wallet_rpc::COMMAND_RPC_RESCAN_BLOCKCHAIN::response& res, epee::json_rpc::error& er); - bool on_set_tx_notes(const wallet_rpc::COMMAND_RPC_SET_TX_NOTES::request& req, wallet_rpc::COMMAND_RPC_SET_TX_NOTES::response& res, epee::json_rpc::error& er); - bool on_get_tx_notes(const wallet_rpc::COMMAND_RPC_GET_TX_NOTES::request& req, wallet_rpc::COMMAND_RPC_GET_TX_NOTES::response& res, epee::json_rpc::error& er); - bool on_set_attribute(const wallet_rpc::COMMAND_RPC_SET_ATTRIBUTE::request& req, wallet_rpc::COMMAND_RPC_SET_ATTRIBUTE::response& res, epee::json_rpc::error& er); - bool on_get_attribute(const wallet_rpc::COMMAND_RPC_GET_ATTRIBUTE::request& req, wallet_rpc::COMMAND_RPC_GET_ATTRIBUTE::response& res, epee::json_rpc::error& er); - bool on_get_tx_key(const wallet_rpc::COMMAND_RPC_GET_TX_KEY::request& req, wallet_rpc::COMMAND_RPC_GET_TX_KEY::response& res, epee::json_rpc::error& er); - bool on_check_tx_key(const wallet_rpc::COMMAND_RPC_CHECK_TX_KEY::request& req, wallet_rpc::COMMAND_RPC_CHECK_TX_KEY::response& res, epee::json_rpc::error& er); - bool on_get_tx_proof(const wallet_rpc::COMMAND_RPC_GET_TX_PROOF::request& req, wallet_rpc::COMMAND_RPC_GET_TX_PROOF::response& res, epee::json_rpc::error& er); - bool on_check_tx_proof(const wallet_rpc::COMMAND_RPC_CHECK_TX_PROOF::request& req, wallet_rpc::COMMAND_RPC_CHECK_TX_PROOF::response& res, epee::json_rpc::error& er); - bool on_get_spend_proof(const wallet_rpc::COMMAND_RPC_GET_SPEND_PROOF::request& req, wallet_rpc::COMMAND_RPC_GET_SPEND_PROOF::response& res, epee::json_rpc::error& er); - bool on_check_spend_proof(const wallet_rpc::COMMAND_RPC_CHECK_SPEND_PROOF::request& req, wallet_rpc::COMMAND_RPC_CHECK_SPEND_PROOF::response& res, epee::json_rpc::error& er); - bool on_get_reserve_proof(const wallet_rpc::COMMAND_RPC_GET_RESERVE_PROOF::request& req, wallet_rpc::COMMAND_RPC_GET_RESERVE_PROOF::response& res, epee::json_rpc::error& er); - bool on_check_reserve_proof(const wallet_rpc::COMMAND_RPC_CHECK_RESERVE_PROOF::request& req, wallet_rpc::COMMAND_RPC_CHECK_RESERVE_PROOF::response& res, epee::json_rpc::error& er); - bool on_get_transfers(const wallet_rpc::COMMAND_RPC_GET_TRANSFERS::request& req, wallet_rpc::COMMAND_RPC_GET_TRANSFERS::response& res, epee::json_rpc::error& er); - bool on_get_transfer_by_txid(const wallet_rpc::COMMAND_RPC_GET_TRANSFER_BY_TXID::request& req, wallet_rpc::COMMAND_RPC_GET_TRANSFER_BY_TXID::response& res, epee::json_rpc::error& er); - bool on_sign(const wallet_rpc::COMMAND_RPC_SIGN::request& req, wallet_rpc::COMMAND_RPC_SIGN::response& res, epee::json_rpc::error& er); - bool on_verify(const wallet_rpc::COMMAND_RPC_VERIFY::request& req, wallet_rpc::COMMAND_RPC_VERIFY::response& res, epee::json_rpc::error& er); - bool on_export_outputs(const wallet_rpc::COMMAND_RPC_EXPORT_OUTPUTS::request& req, wallet_rpc::COMMAND_RPC_EXPORT_OUTPUTS::response& res, epee::json_rpc::error& er); - bool on_import_outputs(const wallet_rpc::COMMAND_RPC_IMPORT_OUTPUTS::request& req, wallet_rpc::COMMAND_RPC_IMPORT_OUTPUTS::response& res, epee::json_rpc::error& er); - bool on_export_key_images(const wallet_rpc::COMMAND_RPC_EXPORT_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_EXPORT_KEY_IMAGES::response& res, epee::json_rpc::error& er); - bool on_import_key_images(const wallet_rpc::COMMAND_RPC_IMPORT_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_IMPORT_KEY_IMAGES::response& res, epee::json_rpc::error& er); - bool on_make_uri(const wallet_rpc::COMMAND_RPC_MAKE_URI::request& req, wallet_rpc::COMMAND_RPC_MAKE_URI::response& res, epee::json_rpc::error& er); - bool on_parse_uri(const wallet_rpc::COMMAND_RPC_PARSE_URI::request& req, wallet_rpc::COMMAND_RPC_PARSE_URI::response& res, epee::json_rpc::error& er); - bool on_get_address_book(const wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er); - bool on_add_address_book(const wallet_rpc::COMMAND_RPC_ADD_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_ADD_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er); - bool on_delete_address_book(const wallet_rpc::COMMAND_RPC_DELETE_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_DELETE_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er); - bool on_refresh(const wallet_rpc::COMMAND_RPC_REFRESH::request& req, wallet_rpc::COMMAND_RPC_REFRESH::response& res, epee::json_rpc::error& er); - bool on_rescan_spent(const wallet_rpc::COMMAND_RPC_RESCAN_SPENT::request& req, wallet_rpc::COMMAND_RPC_RESCAN_SPENT::response& res, epee::json_rpc::error& er); - bool on_start_mining(const wallet_rpc::COMMAND_RPC_START_MINING::request& req, wallet_rpc::COMMAND_RPC_START_MINING::response& res, epee::json_rpc::error& er); - bool on_stop_mining(const wallet_rpc::COMMAND_RPC_STOP_MINING::request& req, wallet_rpc::COMMAND_RPC_STOP_MINING::response& res, epee::json_rpc::error& er); - bool on_get_languages(const wallet_rpc::COMMAND_RPC_GET_LANGUAGES::request& req, wallet_rpc::COMMAND_RPC_GET_LANGUAGES::response& res, epee::json_rpc::error& er); - bool on_create_wallet(const wallet_rpc::COMMAND_RPC_CREATE_WALLET::request& req, wallet_rpc::COMMAND_RPC_CREATE_WALLET::response& res, epee::json_rpc::error& er); - bool on_open_wallet(const wallet_rpc::COMMAND_RPC_OPEN_WALLET::request& req, wallet_rpc::COMMAND_RPC_OPEN_WALLET::response& res, epee::json_rpc::error& er); - bool on_close_wallet(const wallet_rpc::COMMAND_RPC_CLOSE_WALLET::request& req, wallet_rpc::COMMAND_RPC_CLOSE_WALLET::response& res, epee::json_rpc::error& er); - bool on_change_wallet_password(const wallet_rpc::COMMAND_RPC_CHANGE_WALLET_PASSWORD::request& req, wallet_rpc::COMMAND_RPC_CHANGE_WALLET_PASSWORD::response& res, epee::json_rpc::error& er); - bool on_restore_deterministic_wallet(const wallet_rpc::COMMAND_RPC_RESTORE_DETERMINISTIC_WALLET::request& req, wallet_rpc::COMMAND_RPC_RESTORE_DETERMINISTIC_WALLET::response& res, epee::json_rpc::error& er); - bool on_is_multisig(const wallet_rpc::COMMAND_RPC_IS_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_IS_MULTISIG::response& res, epee::json_rpc::error& er); - bool on_prepare_multisig(const wallet_rpc::COMMAND_RPC_PREPARE_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_PREPARE_MULTISIG::response& res, epee::json_rpc::error& er); - bool on_make_multisig(const wallet_rpc::COMMAND_RPC_MAKE_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_MAKE_MULTISIG::response& res, epee::json_rpc::error& er); - bool on_export_multisig(const wallet_rpc::COMMAND_RPC_EXPORT_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_EXPORT_MULTISIG::response& res, epee::json_rpc::error& er); - bool on_import_multisig(const wallet_rpc::COMMAND_RPC_IMPORT_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_IMPORT_MULTISIG::response& res, epee::json_rpc::error& er); - bool on_finalize_multisig(const wallet_rpc::COMMAND_RPC_FINALIZE_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_FINALIZE_MULTISIG::response& res, epee::json_rpc::error& er); - bool on_exchange_multisig_keys(const wallet_rpc::COMMAND_RPC_EXCHANGE_MULTISIG_KEYS::request& req, wallet_rpc::COMMAND_RPC_EXCHANGE_MULTISIG_KEYS::response& res, epee::json_rpc::error& er); - bool on_sign_multisig(const wallet_rpc::COMMAND_RPC_SIGN_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_SIGN_MULTISIG::response& res, epee::json_rpc::error& er); - bool on_submit_multisig(const wallet_rpc::COMMAND_RPC_SUBMIT_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_SUBMIT_MULTISIG::response& res, epee::json_rpc::error& er); - bool on_get_version(const wallet_rpc::COMMAND_RPC_GET_VERSION::request& req, wallet_rpc::COMMAND_RPC_GET_VERSION::response& res, epee::json_rpc::error& er); + bool on_getbalance(const wallet_rpc::COMMAND_RPC_GET_BALANCE::request& req, wallet_rpc::COMMAND_RPC_GET_BALANCE::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_getaddress(const wallet_rpc::COMMAND_RPC_GET_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_GET_ADDRESS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_getaddress_index(const wallet_rpc::COMMAND_RPC_GET_ADDRESS_INDEX::request& req, wallet_rpc::COMMAND_RPC_GET_ADDRESS_INDEX::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_create_address(const wallet_rpc::COMMAND_RPC_CREATE_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_CREATE_ADDRESS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_label_address(const wallet_rpc::COMMAND_RPC_LABEL_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_LABEL_ADDRESS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_get_accounts(const wallet_rpc::COMMAND_RPC_GET_ACCOUNTS::request& req, wallet_rpc::COMMAND_RPC_GET_ACCOUNTS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_create_account(const wallet_rpc::COMMAND_RPC_CREATE_ACCOUNT::request& req, wallet_rpc::COMMAND_RPC_CREATE_ACCOUNT::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_label_account(const wallet_rpc::COMMAND_RPC_LABEL_ACCOUNT::request& req, wallet_rpc::COMMAND_RPC_LABEL_ACCOUNT::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_get_account_tags(const wallet_rpc::COMMAND_RPC_GET_ACCOUNT_TAGS::request& req, wallet_rpc::COMMAND_RPC_GET_ACCOUNT_TAGS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_tag_accounts(const wallet_rpc::COMMAND_RPC_TAG_ACCOUNTS::request& req, wallet_rpc::COMMAND_RPC_TAG_ACCOUNTS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_untag_accounts(const wallet_rpc::COMMAND_RPC_UNTAG_ACCOUNTS::request& req, wallet_rpc::COMMAND_RPC_UNTAG_ACCOUNTS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_set_account_tag_description(const wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION::request& req, wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_getheight(const wallet_rpc::COMMAND_RPC_GET_HEIGHT::request& req, wallet_rpc::COMMAND_RPC_GET_HEIGHT::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_transfer(const wallet_rpc::COMMAND_RPC_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_TRANSFER::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_transfer_split(const wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT::request& req, wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_sign_transfer(const wallet_rpc::COMMAND_RPC_SIGN_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_SIGN_TRANSFER::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_describe_transfer(const wallet_rpc::COMMAND_RPC_DESCRIBE_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_DESCRIBE_TRANSFER::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_submit_transfer(const wallet_rpc::COMMAND_RPC_SUBMIT_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_SUBMIT_TRANSFER::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_sweep_dust(const wallet_rpc::COMMAND_RPC_SWEEP_DUST::request& req, wallet_rpc::COMMAND_RPC_SWEEP_DUST::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_sweep_all(const wallet_rpc::COMMAND_RPC_SWEEP_ALL::request& req, wallet_rpc::COMMAND_RPC_SWEEP_ALL::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_sweep_single(const wallet_rpc::COMMAND_RPC_SWEEP_SINGLE::request& req, wallet_rpc::COMMAND_RPC_SWEEP_SINGLE::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_relay_tx(const wallet_rpc::COMMAND_RPC_RELAY_TX::request& req, wallet_rpc::COMMAND_RPC_RELAY_TX::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_make_integrated_address(const wallet_rpc::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_split_integrated_address(const wallet_rpc::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_store(const wallet_rpc::COMMAND_RPC_STORE::request& req, wallet_rpc::COMMAND_RPC_STORE::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_get_payments(const wallet_rpc::COMMAND_RPC_GET_PAYMENTS::request& req, wallet_rpc::COMMAND_RPC_GET_PAYMENTS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_get_bulk_payments(const wallet_rpc::COMMAND_RPC_GET_BULK_PAYMENTS::request& req, wallet_rpc::COMMAND_RPC_GET_BULK_PAYMENTS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_incoming_transfers(const wallet_rpc::COMMAND_RPC_INCOMING_TRANSFERS::request& req, wallet_rpc::COMMAND_RPC_INCOMING_TRANSFERS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_stop_wallet(const wallet_rpc::COMMAND_RPC_STOP_WALLET::request& req, wallet_rpc::COMMAND_RPC_STOP_WALLET::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_rescan_blockchain(const wallet_rpc::COMMAND_RPC_RESCAN_BLOCKCHAIN::request& req, wallet_rpc::COMMAND_RPC_RESCAN_BLOCKCHAIN::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_set_tx_notes(const wallet_rpc::COMMAND_RPC_SET_TX_NOTES::request& req, wallet_rpc::COMMAND_RPC_SET_TX_NOTES::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_get_tx_notes(const wallet_rpc::COMMAND_RPC_GET_TX_NOTES::request& req, wallet_rpc::COMMAND_RPC_GET_TX_NOTES::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_set_attribute(const wallet_rpc::COMMAND_RPC_SET_ATTRIBUTE::request& req, wallet_rpc::COMMAND_RPC_SET_ATTRIBUTE::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_get_attribute(const wallet_rpc::COMMAND_RPC_GET_ATTRIBUTE::request& req, wallet_rpc::COMMAND_RPC_GET_ATTRIBUTE::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_get_tx_key(const wallet_rpc::COMMAND_RPC_GET_TX_KEY::request& req, wallet_rpc::COMMAND_RPC_GET_TX_KEY::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_check_tx_key(const wallet_rpc::COMMAND_RPC_CHECK_TX_KEY::request& req, wallet_rpc::COMMAND_RPC_CHECK_TX_KEY::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_get_tx_proof(const wallet_rpc::COMMAND_RPC_GET_TX_PROOF::request& req, wallet_rpc::COMMAND_RPC_GET_TX_PROOF::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_check_tx_proof(const wallet_rpc::COMMAND_RPC_CHECK_TX_PROOF::request& req, wallet_rpc::COMMAND_RPC_CHECK_TX_PROOF::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_get_spend_proof(const wallet_rpc::COMMAND_RPC_GET_SPEND_PROOF::request& req, wallet_rpc::COMMAND_RPC_GET_SPEND_PROOF::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_check_spend_proof(const wallet_rpc::COMMAND_RPC_CHECK_SPEND_PROOF::request& req, wallet_rpc::COMMAND_RPC_CHECK_SPEND_PROOF::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_get_reserve_proof(const wallet_rpc::COMMAND_RPC_GET_RESERVE_PROOF::request& req, wallet_rpc::COMMAND_RPC_GET_RESERVE_PROOF::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_check_reserve_proof(const wallet_rpc::COMMAND_RPC_CHECK_RESERVE_PROOF::request& req, wallet_rpc::COMMAND_RPC_CHECK_RESERVE_PROOF::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_get_transfers(const wallet_rpc::COMMAND_RPC_GET_TRANSFERS::request& req, wallet_rpc::COMMAND_RPC_GET_TRANSFERS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_get_transfer_by_txid(const wallet_rpc::COMMAND_RPC_GET_TRANSFER_BY_TXID::request& req, wallet_rpc::COMMAND_RPC_GET_TRANSFER_BY_TXID::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_sign(const wallet_rpc::COMMAND_RPC_SIGN::request& req, wallet_rpc::COMMAND_RPC_SIGN::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_verify(const wallet_rpc::COMMAND_RPC_VERIFY::request& req, wallet_rpc::COMMAND_RPC_VERIFY::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_export_outputs(const wallet_rpc::COMMAND_RPC_EXPORT_OUTPUTS::request& req, wallet_rpc::COMMAND_RPC_EXPORT_OUTPUTS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_import_outputs(const wallet_rpc::COMMAND_RPC_IMPORT_OUTPUTS::request& req, wallet_rpc::COMMAND_RPC_IMPORT_OUTPUTS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_export_key_images(const wallet_rpc::COMMAND_RPC_EXPORT_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_EXPORT_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_import_key_images(const wallet_rpc::COMMAND_RPC_IMPORT_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_IMPORT_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_make_uri(const wallet_rpc::COMMAND_RPC_MAKE_URI::request& req, wallet_rpc::COMMAND_RPC_MAKE_URI::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_parse_uri(const wallet_rpc::COMMAND_RPC_PARSE_URI::request& req, wallet_rpc::COMMAND_RPC_PARSE_URI::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_get_address_book(const wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_add_address_book(const wallet_rpc::COMMAND_RPC_ADD_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_ADD_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_delete_address_book(const wallet_rpc::COMMAND_RPC_DELETE_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_DELETE_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_refresh(const wallet_rpc::COMMAND_RPC_REFRESH::request& req, wallet_rpc::COMMAND_RPC_REFRESH::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_rescan_spent(const wallet_rpc::COMMAND_RPC_RESCAN_SPENT::request& req, wallet_rpc::COMMAND_RPC_RESCAN_SPENT::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_start_mining(const wallet_rpc::COMMAND_RPC_START_MINING::request& req, wallet_rpc::COMMAND_RPC_START_MINING::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_stop_mining(const wallet_rpc::COMMAND_RPC_STOP_MINING::request& req, wallet_rpc::COMMAND_RPC_STOP_MINING::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_get_languages(const wallet_rpc::COMMAND_RPC_GET_LANGUAGES::request& req, wallet_rpc::COMMAND_RPC_GET_LANGUAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_create_wallet(const wallet_rpc::COMMAND_RPC_CREATE_WALLET::request& req, wallet_rpc::COMMAND_RPC_CREATE_WALLET::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_open_wallet(const wallet_rpc::COMMAND_RPC_OPEN_WALLET::request& req, wallet_rpc::COMMAND_RPC_OPEN_WALLET::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_close_wallet(const wallet_rpc::COMMAND_RPC_CLOSE_WALLET::request& req, wallet_rpc::COMMAND_RPC_CLOSE_WALLET::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_change_wallet_password(const wallet_rpc::COMMAND_RPC_CHANGE_WALLET_PASSWORD::request& req, wallet_rpc::COMMAND_RPC_CHANGE_WALLET_PASSWORD::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_restore_deterministic_wallet(const wallet_rpc::COMMAND_RPC_RESTORE_DETERMINISTIC_WALLET::request& req, wallet_rpc::COMMAND_RPC_RESTORE_DETERMINISTIC_WALLET::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_is_multisig(const wallet_rpc::COMMAND_RPC_IS_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_IS_MULTISIG::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_prepare_multisig(const wallet_rpc::COMMAND_RPC_PREPARE_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_PREPARE_MULTISIG::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_make_multisig(const wallet_rpc::COMMAND_RPC_MAKE_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_MAKE_MULTISIG::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_export_multisig(const wallet_rpc::COMMAND_RPC_EXPORT_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_EXPORT_MULTISIG::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_import_multisig(const wallet_rpc::COMMAND_RPC_IMPORT_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_IMPORT_MULTISIG::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_finalize_multisig(const wallet_rpc::COMMAND_RPC_FINALIZE_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_FINALIZE_MULTISIG::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_exchange_multisig_keys(const wallet_rpc::COMMAND_RPC_EXCHANGE_MULTISIG_KEYS::request& req, wallet_rpc::COMMAND_RPC_EXCHANGE_MULTISIG_KEYS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_sign_multisig(const wallet_rpc::COMMAND_RPC_SIGN_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_SIGN_MULTISIG::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_submit_multisig(const wallet_rpc::COMMAND_RPC_SUBMIT_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_SUBMIT_MULTISIG::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_get_version(const wallet_rpc::COMMAND_RPC_GET_VERSION::request& req, wallet_rpc::COMMAND_RPC_GET_VERSION::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); //json rpc v2 - bool on_query_key(const wallet_rpc::COMMAND_RPC_QUERY_KEY::request& req, wallet_rpc::COMMAND_RPC_QUERY_KEY::response& res, epee::json_rpc::error& er); + bool on_query_key(const wallet_rpc::COMMAND_RPC_QUERY_KEY::request& req, wallet_rpc::COMMAND_RPC_QUERY_KEY::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); // helpers void fill_transfer_entry(tools::wallet_rpc::transfer_entry &entry, const crypto::hash &txid, const crypto::hash &payment_id, const tools::wallet2::payment_details &pd); @@ -245,6 +244,8 @@ namespace tools bool get_tx_key, Ts& tx_key, Tu &amount, Tu &fee, std::string &multisig_txset, std::string &unsigned_txset, bool do_not_relay, Ts &tx_hash, bool get_tx_hex, Ts &tx_blob, bool get_tx_metadata, Ts &tx_metadata, epee::json_rpc::error &er); + bool validate_transfer(const std::list<wallet_rpc::transfer_destination>& destinations, const std::string& payment_id, std::vector<cryptonote::tx_destination_entry>& dsts, std::vector<uint8_t>& extra, bool at_least_one_destination, epee::json_rpc::error& er); + wallet2 *m_wallet; std::string m_wallet_dir; tools::private_file rpc_login_file; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 20afd4203..89d77cf32 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -85,6 +85,7 @@ add_subdirectory(performance_tests) add_subdirectory(core_proxy) add_subdirectory(unit_tests) add_subdirectory(difficulty) +add_subdirectory(block_weight) add_subdirectory(hash) add_subdirectory(net_load_tests) if (BUILD_GUI_DEPS) @@ -115,6 +116,7 @@ add_test( set(enabled_tests core_tests difficulty + block_weight hash performance_tests core_proxy diff --git a/tests/block_weight/CMakeLists.txt b/tests/block_weight/CMakeLists.txt new file mode 100644 index 000000000..b0d716ea0 --- /dev/null +++ b/tests/block_weight/CMakeLists.txt @@ -0,0 +1,45 @@ +# Copyright (c) 2014-2018, The Monero Project +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other +# materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be +# used to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set(block_weight_sources + block_weight.cpp) + +set(block_weight_headers) + +add_executable(block_weight + ${block_weight_sources} + ${block_weight_headers}) +target_link_libraries(block_weight + PRIVATE + cryptonote_core + blockchain_db + ${EXTRA_LIBRARIES}) + +add_test( + NAME block_weight + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/compare.py ${CMAKE_CURRENT_SOURCE_DIR}/block_weight.py ${CMAKE_CURRENT_BINARY_DIR}/block_weight) diff --git a/tests/block_weight/block_weight.cpp b/tests/block_weight/block_weight.cpp new file mode 100644 index 000000000..a67f40f0f --- /dev/null +++ b/tests/block_weight/block_weight.cpp @@ -0,0 +1,183 @@ +// Copyright (c) 2019, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#define IN_UNIT_TESTS + +#include <stdio.h> +#include <math.h> +#include "cryptonote_core/blockchain.h" +#include "cryptonote_core/tx_pool.h" +#include "cryptonote_core/cryptonote_core.h" +#include "blockchain_db/testdb.h" + +#define LONG_TERM_BLOCK_WEIGHT_WINDOW 5000 + +enum test_t +{ + test_max = 0, + test_lcg = 1, + test_min = 2, +}; + +namespace +{ + +class TestDB: public cryptonote::BaseTestDB +{ +private: + struct block_t + { + size_t weight; + uint64_t long_term_weight; + }; + +public: + TestDB() { m_open = true; } + + virtual void add_block( const cryptonote::block& blk + , size_t block_weight + , uint64_t long_term_block_weight + , const cryptonote::difficulty_type& cumulative_difficulty + , const uint64_t& coins_generated + , uint64_t num_rct_outs + , const crypto::hash& blk_hash + ) override { + blocks.push_back({block_weight, long_term_block_weight}); + } + virtual uint64_t height() const override { return blocks.size(); } + virtual size_t get_block_weight(const uint64_t &h) const override { return blocks[h].weight; } + virtual uint64_t get_block_long_term_weight(const uint64_t &h) const override { return blocks[h].long_term_weight; } + virtual crypto::hash top_block_hash() const override { + uint64_t h = height(); + crypto::hash top = crypto::null_hash; + if (h) + *(uint64_t*)&top = h - 1; + return top; + } + virtual void pop_block(cryptonote::block &blk, std::vector<cryptonote::transaction> &txs) override { blocks.pop_back(); } + virtual void set_hard_fork_version(uint64_t height, uint8_t version) override { if (height >= hf.size()) hf.resize(height + 1); hf[height] = version; } + virtual uint8_t get_hard_fork_version(uint64_t height) const override { if (height >= hf.size()) return 255; return hf[height]; } + +private: + std::vector<block_t> blocks; + std::vector<uint8_t> hf; +}; + +} + +#define PREFIX_WINDOW(hf_version,window) \ + std::unique_ptr<cryptonote::Blockchain> bc; \ + cryptonote::tx_memory_pool txpool(*bc); \ + bc.reset(new cryptonote::Blockchain(txpool)); \ + struct get_test_options { \ + const std::pair<uint8_t, uint64_t> hard_forks[3]; \ + const cryptonote::test_options test_options = { \ + hard_forks, \ + window, \ + }; \ + get_test_options(): hard_forks{std::make_pair(1, (uint64_t)0), std::make_pair((uint8_t)hf_version, (uint64_t)LONG_TERM_BLOCK_WEIGHT_WINDOW), std::make_pair((uint8_t)0, (uint64_t)0)} {} \ + } opts; \ + cryptonote::Blockchain *blockchain = bc.get(); \ + bool r = blockchain->init(new TestDB(), cryptonote::FAKECHAIN, true, &opts.test_options, 0, NULL); \ + if (!r) \ + { \ + fprintf(stderr, "Failed to init blockchain\n"); \ + exit(1); \ + } + +#define PREFIX(hf_version) PREFIX_WINDOW(hf_version, LONG_TERM_BLOCK_WEIGHT_WINDOW) + +static uint32_t lcg_seed = 0; + +static uint32_t lcg() +{ + lcg_seed = (lcg_seed * 0x100000001b3 + 0xcbf29ce484222325) & 0xffffffff; + return lcg_seed; +} + +static void test(test_t t, uint64_t blocks) +{ + PREFIX(10); + + for (uint64_t h = 0; h < LONG_TERM_BLOCK_WEIGHT_WINDOW; ++h) + { + cryptonote::block b; + b.major_version = 1; + b.minor_version = 1; + bc->get_db().add_block(b, 300000, 300000, bc->get_db().height(), bc->get_db().height(), {}); + if (!bc->update_next_cumulative_weight_limit()) + { + fprintf(stderr, "Failed to update cumulative weight limit 1\n"); + exit(1); + } + } + + for (uint64_t h = 0; h < blocks; ++h) + { + uint64_t w; + uint64_t effective_block_weight_median = bc->get_current_cumulative_block_weight_median(); + switch (t) + { + case test_lcg: + { + uint32_t r = lcg(); + int64_t wi = 90 + r % 500000 + 250000 + sin(h / 200.) * 350000; + w = wi < 90 ? 90 : wi; + break; + } + case test_max: + w = bc->get_current_cumulative_block_weight_limit(); + break; + case test_min: + w = 90; + break; + default: + exit(1); + } + uint64_t ltw = bc->get_next_long_term_block_weight(w); + cryptonote::block b; + b.major_version = 10; + b.minor_version = 10; + bc->get_db().add_block(std::move(b), w, ltw, bc->get_db().height(), bc->get_db().height(), {}); + + if (!bc->update_next_cumulative_weight_limit()) + { + fprintf(stderr, "Failed to update cumulative weight limit\n"); + exit(1); + } + std::cout << "H " << h << ", BW " << w << ", EMBW " << effective_block_weight_median << ", LTBW " << ltw << std::endl; + } +} + +int main() +{ + test(test_max, 2 * LONG_TERM_BLOCK_WEIGHT_WINDOW); + test(test_lcg, 9 * LONG_TERM_BLOCK_WEIGHT_WINDOW); + test(test_min, 1 * LONG_TERM_BLOCK_WEIGHT_WINDOW); + return 0; +} diff --git a/tests/block_weight/block_weight.py b/tests/block_weight/block_weight.py new file mode 100755 index 000000000..06aaabb02 --- /dev/null +++ b/tests/block_weight/block_weight.py @@ -0,0 +1,74 @@ +#!/usr/bin/python +# Simulate a maximal block attack on the Monero network +# This uses the scheme proposed by ArticMine +# Written by Sarang Nother +# Copyright (c) 2019 The Monero Project +import sys +import math + +MEDIAN_WINDOW_SMALL = 100 # number of recent blocks for median computation +MEDIAN_WINDOW_BIG = 5000 +MULTIPLIER_SMALL = 1.4 # multipliers for determining weights +MULTIPLIER_BIG = 50.0 +MEDIAN_THRESHOLD = 300*1000 # initial value for median (scaled kB -> B) +lcg_seed = 0 +embw = MEDIAN_THRESHOLD +ltembw = MEDIAN_THRESHOLD + +weights = [MEDIAN_THRESHOLD]*MEDIAN_WINDOW_SMALL # weights of recent blocks (B), with index -1 most recent +lt_weights = [MEDIAN_THRESHOLD]*MEDIAN_WINDOW_BIG # long-term weights + +# Compute the median of a list +def get_median(vec): + #temp = vec + temp = sorted(vec) + if len(temp) % 2 == 1: + return temp[len(temp)/2] + else: + return int((temp[len(temp)/2]+temp[len(temp)/2-1])/2) + +def LCG(): + global lcg_seed + lcg_seed = (lcg_seed * 0x100000001b3 + 0xcbf29ce484222325) & 0xffffffff + return lcg_seed + +def run(t, blocks): + global embw + global ltembw + + weights = [MEDIAN_THRESHOLD]*MEDIAN_WINDOW_SMALL # weights of recent blocks (B), with index -1 most recent + lt_weights = [MEDIAN_THRESHOLD]*MEDIAN_WINDOW_BIG # long-term weights + + for block in range(blocks): + # determine the long-term effective weight + ltmedian = get_median(lt_weights[-MEDIAN_WINDOW_BIG:]) + ltembw = max(MEDIAN_THRESHOLD,ltmedian) + + # determine the effective weight + stmedian = get_median(weights[-MEDIAN_WINDOW_SMALL:]) + embw = min(max(MEDIAN_THRESHOLD,stmedian),int(MULTIPLIER_BIG*ltembw)) + + # drop the lowest values + weights = weights[1:] + lt_weights = lt_weights[1:] + + # add a block of max weight + if t == 0: + max_weight = 2 * embw + elif t == 1: + r = LCG() + max_weight = int(90 + r % 500000 + 250000 + math.sin(block / 200.) * 350000) + if max_weight < 90: max_weight = 90 + elif t == 2: + max_weight = 90 + else: + sys.exit(1) + weights.append(max_weight) + lt_weights.append(min(max_weight,int(ltembw + int(ltembw * 2 / 5)))) + + #print "H %u, r %u, BW %u, EMBW %u, LTBW %u, LTEMBW %u, ltmedian %u" % (block, r, max_weight, embw, lt_weights[-1], ltembw, ltmedian) + print "H %u, BW %u, EMBW %u, LTBW %u" % (block, max_weight, embw, lt_weights[-1]) + +run(0, 2 * MEDIAN_WINDOW_BIG) +run(1, 9 * MEDIAN_WINDOW_BIG) +run(2, 1 * MEDIAN_WINDOW_BIG) diff --git a/tests/block_weight/compare.py b/tests/block_weight/compare.py new file mode 100755 index 000000000..c6be05206 --- /dev/null +++ b/tests/block_weight/compare.py @@ -0,0 +1,13 @@ +#!/usr/bin/python + +import sys +import subprocess + +print 'running: ', sys.argv[1] +S0 = subprocess.check_output(sys.argv[1], stderr=subprocess.STDOUT) +print 'running: ', sys.argv[2] +S1 = subprocess.check_output(sys.argv[2], stderr=subprocess.STDOUT) +print 'comparing' +if S0 != S1: + sys.exit(1) +sys.exit(0) diff --git a/tests/core_proxy/core_proxy.h b/tests/core_proxy/core_proxy.h index 023c220ae..7888540cc 100644 --- a/tests/core_proxy/core_proxy.h +++ b/tests/core_proxy/core_proxy.h @@ -105,5 +105,7 @@ namespace tests bool fluffy_blocks_enabled() const { return false; } uint64_t prevalidate_block_hashes(uint64_t height, const std::vector<crypto::hash> &hashes) { return 0; } bool pad_transactions() const { return false; } + uint32_t get_blockchain_pruning_seed() const { return 0; } + bool prune_blockchain(uint32_t pruning_seed) const { return true; } }; } diff --git a/tests/core_tests/bulletproofs.cpp b/tests/core_tests/bulletproofs.cpp index db875d2a2..3e2db2e29 100644 --- a/tests/core_tests/bulletproofs.cpp +++ b/tests/core_tests/bulletproofs.cpp @@ -42,7 +42,7 @@ using namespace cryptonote; // Tests bool gen_bp_tx_validation_base::generate_with(std::vector<test_event_entry>& events, - size_t mixin, size_t n_txes, const uint64_t *amounts_paid, bool valid, const rct::RangeProofType *range_proof_type, + size_t mixin, size_t n_txes, const uint64_t *amounts_paid, bool valid, const rct::RCTConfig *rct_config, const std::function<bool(std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations, size_t tx_idx)> &pre_tx, const std::function<bool(transaction &tx, size_t tx_idx)> &post_tx) const { @@ -136,7 +136,7 @@ bool gen_bp_tx_validation_base::generate_with(std::vector<test_event_entry>& eve std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses; subaddresses[miner_accounts[n].get_keys().m_account_address.m_spend_public_key] = {0,0}; rct_txes.resize(rct_txes.size() + 1); - bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes.back(), 0, tx_key, additional_tx_keys, true, range_proof_type[n]); + bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes.back(), 0, tx_key, additional_tx_keys, true, rct_config[n]); CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction"); if (post_tx && !post_tx(rct_txes.back(), n)) @@ -157,7 +157,8 @@ bool gen_bp_tx_validation_base::generate_with(std::vector<test_event_entry>& eve crypto::secret_key amount_key; crypto::derivation_to_scalar(derivation, o, amount_key); rct::key rct_tx_mask; - if (rct_txes.back().rct_signatures.type == rct::RCTTypeSimple || rct_txes.back().rct_signatures.type == rct::RCTTypeBulletproof) + const uint8_t type = rct_txes.back().rct_signatures.type; + if (type == rct::RCTTypeSimple || type == rct::RCTTypeBulletproof || type == rct::RCTTypeBulletproof2) rct::decodeRctSimple(rct_txes.back().rct_signatures, rct::sk2rct(amount_key), o, rct_tx_mask, hw::get_device("default")); else rct::decodeRct(rct_txes.back().rct_signatures, rct::sk2rct(amount_key), o, rct_tx_mask, hw::get_device("default")); @@ -173,8 +174,8 @@ bool gen_bp_tx_validation_base::generate_with(std::vector<test_event_entry>& eve CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk_txes, blk_last, miner_account, test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_tx_hashes | test_generator::bf_hf_version | test_generator::bf_max_outs, - 8, 8, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long - crypto::hash(), 0, transaction(), starting_rct_tx_hashes, 0, 6, 8), + 10, 10, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long + crypto::hash(), 0, transaction(), starting_rct_tx_hashes, 0, 6, 10), false, "Failed to generate block"); if (!valid) DO_CALLBACK(events, "mark_invalid_block"); @@ -210,16 +211,16 @@ bool gen_bp_tx_valid_1::generate(std::vector<test_event_entry>& events) const const size_t mixin = 10; const uint64_t amounts_paid[] = {10000, (uint64_t)-1}; const size_t bp_sizes[] = {1, (size_t)-1}; - const rct::RangeProofType range_proof_type[] = {rct::RangeProofPaddedBulletproof}; - return generate_with(events, mixin, 1, amounts_paid, true, range_proof_type, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_1"); }); + const rct::RCTConfig rct_config[] = { { rct::RangeProofPaddedBulletproof, 0 } }; + return generate_with(events, mixin, 1, amounts_paid, true, rct_config, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_1"); }); } bool gen_bp_tx_invalid_1_1::generate(std::vector<test_event_entry>& events) const { const size_t mixin = 10; const uint64_t amounts_paid[] = {5000, 5000, (uint64_t)-1}; - const rct::RangeProofType range_proof_type[] = { rct::RangeProofBulletproof }; - return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, NULL); + const rct::RCTConfig rct_config[] = { { rct::RangeProofBulletproof , 0 } }; + return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, NULL); } bool gen_bp_tx_valid_2::generate(std::vector<test_event_entry>& events) const @@ -227,8 +228,8 @@ bool gen_bp_tx_valid_2::generate(std::vector<test_event_entry>& events) const const size_t mixin = 10; const uint64_t amounts_paid[] = {5000, 5000, (uint64_t)-1}; const size_t bp_sizes[] = {2, (size_t)-1}; - const rct::RangeProofType range_proof_type[] = {rct::RangeProofPaddedBulletproof}; - return generate_with(events, mixin, 1, amounts_paid, true, range_proof_type, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_2"); }); + const rct::RCTConfig rct_config[] = { { rct::RangeProofPaddedBulletproof, 0 } }; + return generate_with(events, mixin, 1, amounts_paid, true, rct_config, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_2"); }); } bool gen_bp_tx_valid_3::generate(std::vector<test_event_entry>& events) const @@ -236,8 +237,8 @@ bool gen_bp_tx_valid_3::generate(std::vector<test_event_entry>& events) const const size_t mixin = 10; const uint64_t amounts_paid[] = {5000, 5000, 5000, (uint64_t)-1}; const size_t bp_sizes[] = {4, (size_t)-1}; - const rct::RangeProofType range_proof_type[] = { rct::RangeProofPaddedBulletproof }; - return generate_with(events, mixin, 1, amounts_paid, true, range_proof_type, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_3"); }); + const rct::RCTConfig rct_config[] = { { rct::RangeProofPaddedBulletproof , 0 } }; + return generate_with(events, mixin, 1, amounts_paid, true, rct_config, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_3"); }); } bool gen_bp_tx_valid_16::generate(std::vector<test_event_entry>& events) const @@ -245,24 +246,24 @@ bool gen_bp_tx_valid_16::generate(std::vector<test_event_entry>& events) const const size_t mixin = 10; const uint64_t amounts_paid[] = {500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, (uint64_t)-1}; const size_t bp_sizes[] = {16, (size_t)-1}; - const rct::RangeProofType range_proof_type[] = { rct::RangeProofPaddedBulletproof }; - return generate_with(events, mixin, 1, amounts_paid, true, range_proof_type, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_16"); }); + const rct::RCTConfig rct_config[] = { { rct::RangeProofPaddedBulletproof , 0 } }; + return generate_with(events, mixin, 1, amounts_paid, true, rct_config, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_16"); }); } bool gen_bp_tx_invalid_4_2_1::generate(std::vector<test_event_entry>& events) const { const size_t mixin = 10; const uint64_t amounts_paid[] = {1000, 1000, 1000, 1000, 1000, 1000, 1000, (uint64_t)-1}; - const rct::RangeProofType range_proof_type[] = { rct::RangeProofMultiOutputBulletproof }; - return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, NULL); + const rct::RCTConfig rct_config[] = { { rct::RangeProofMultiOutputBulletproof , 0 } }; + return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, NULL); } bool gen_bp_tx_invalid_16_16::generate(std::vector<test_event_entry>& events) const { const size_t mixin = 10; const uint64_t amounts_paid[] = {1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, (uint64_t)-1}; - const rct::RangeProofType range_proof_type[] = { rct::RangeProofMultiOutputBulletproof }; - return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, NULL); + const rct::RCTConfig rct_config[] = { { rct::RangeProofMultiOutputBulletproof , 0 } }; + return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, NULL); } bool gen_bp_txs_valid_2_and_2::generate(std::vector<test_event_entry>& events) const @@ -270,25 +271,25 @@ bool gen_bp_txs_valid_2_and_2::generate(std::vector<test_event_entry>& events) c const size_t mixin = 10; const uint64_t amounts_paid[] = {1000, 1000, (size_t)-1, 1000, 1000, (uint64_t)-1}; const size_t bp_sizes[] = {2, (size_t)-1, 2, (size_t)-1}; - const rct::RangeProofType range_proof_type[] = { rct::RangeProofPaddedBulletproof, rct::RangeProofPaddedBulletproof}; - return generate_with(events, mixin, 2, amounts_paid, true, range_proof_type, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_txs_valid_2_and_2"); }); + const rct::RCTConfig rct_config[] = { { rct::RangeProofPaddedBulletproof, 0 }, {rct::RangeProofPaddedBulletproof, 0 } }; + return generate_with(events, mixin, 2, amounts_paid, true, rct_config, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_txs_valid_2_and_2"); }); } bool gen_bp_txs_invalid_2_and_8_2_and_16_16_1::generate(std::vector<test_event_entry>& events) const { const size_t mixin = 10; const uint64_t amounts_paid[] = {1000, 1000, (uint64_t)-1, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, (uint64_t)-1, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, (uint64_t)-1}; - const rct::RangeProofType range_proof_type[] = {rct::RangeProofMultiOutputBulletproof, rct::RangeProofMultiOutputBulletproof, rct::RangeProofMultiOutputBulletproof}; - return generate_with(events, mixin, 3, amounts_paid, false, range_proof_type, NULL, NULL); + const rct::RCTConfig rct_config[] = {{rct::RangeProofMultiOutputBulletproof, 0}, {rct::RangeProofMultiOutputBulletproof, 0}, {rct::RangeProofMultiOutputBulletproof, 0}}; + return generate_with(events, mixin, 3, amounts_paid, false, rct_config, NULL, NULL); } bool gen_bp_txs_valid_2_and_3_and_2_and_4::generate(std::vector<test_event_entry>& events) const { const size_t mixin = 10; const uint64_t amounts_paid[] = {11111115000, 11111115000, (uint64_t)-1, 11111115000, 11111115000, 11111115001, (uint64_t)-1, 11111115000, 11111115002, (uint64_t)-1, 11111115000, 11111115000, 11111115000, 11111115003, (uint64_t)-1}; - const rct::RangeProofType range_proof_type[] = {rct::RangeProofPaddedBulletproof, rct::RangeProofPaddedBulletproof, rct::RangeProofPaddedBulletproof, rct::RangeProofPaddedBulletproof}; + const rct::RCTConfig rct_config[] = {{rct::RangeProofPaddedBulletproof, 0}, {rct::RangeProofPaddedBulletproof, 0}, {rct::RangeProofPaddedBulletproof, 0}, {rct::RangeProofPaddedBulletproof, 0}}; const size_t bp_sizes[] = {2, (size_t)-1, 4, (size_t)-1, 2, (size_t)-1, 4, (size_t)-1}; - return generate_with(events, mixin, 4, amounts_paid, true, range_proof_type, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx) { return check_bp(tx, tx_idx, bp_sizes, "gen_bp_txs_valid_2_and_3_and_2_and_4"); }); + return generate_with(events, mixin, 4, amounts_paid, true, rct_config, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx) { return check_bp(tx, tx_idx, bp_sizes, "gen_bp_txs_valid_2_and_3_and_2_and_4"); }); } bool gen_bp_tx_invalid_not_enough_proofs::generate(std::vector<test_event_entry>& events) const @@ -296,9 +297,9 @@ bool gen_bp_tx_invalid_not_enough_proofs::generate(std::vector<test_event_entry> DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_not_enough_proofs"); const size_t mixin = 10; const uint64_t amounts_paid[] = {5000, 5000, (uint64_t)-1}; - const rct::RangeProofType range_proof_type[] = { rct::RangeProofBulletproof }; - return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, [&](cryptonote::transaction &tx, size_t idx){ - CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof); + const rct::RCTConfig rct_config[] = { { rct::RangeProofBulletproof, 0 } }; + return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, [&](cryptonote::transaction &tx, size_t idx){ + CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof || tx.rct_signatures.type == rct::RCTTypeBulletproof2); CHECK_TEST_CONDITION(!tx.rct_signatures.p.bulletproofs.empty()); tx.rct_signatures.p.bulletproofs.pop_back(); CHECK_TEST_CONDITION(!tx.rct_signatures.p.bulletproofs.empty()); @@ -311,9 +312,9 @@ bool gen_bp_tx_invalid_empty_proofs::generate(std::vector<test_event_entry>& eve DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_empty_proofs"); const size_t mixin = 10; const uint64_t amounts_paid[] = {50000, 50000, (uint64_t)-1}; - const rct::RangeProofType range_proof_type[] = { rct::RangeProofBulletproof }; - return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, [&](cryptonote::transaction &tx, size_t idx){ - CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof); + const rct::RCTConfig rct_config[] = { { rct::RangeProofBulletproof, 0 } }; + return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, [&](cryptonote::transaction &tx, size_t idx){ + CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof || tx.rct_signatures.type == rct::RCTTypeBulletproof2); tx.rct_signatures.p.bulletproofs.clear(); return true; }); @@ -324,9 +325,9 @@ bool gen_bp_tx_invalid_too_many_proofs::generate(std::vector<test_event_entry>& DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_too_many_proofs"); const size_t mixin = 10; const uint64_t amounts_paid[] = {10000, (uint64_t)-1}; - const rct::RangeProofType range_proof_type[] = { rct::RangeProofBulletproof }; - return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, [&](cryptonote::transaction &tx, size_t idx){ - CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof); + const rct::RCTConfig rct_config[] = { { rct::RangeProofBulletproof, 0 } }; + return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, [&](cryptonote::transaction &tx, size_t idx){ + CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof || tx.rct_signatures.type == rct::RCTTypeBulletproof2); CHECK_TEST_CONDITION(!tx.rct_signatures.p.bulletproofs.empty()); tx.rct_signatures.p.bulletproofs.push_back(tx.rct_signatures.p.bulletproofs.back()); return true; @@ -338,9 +339,9 @@ bool gen_bp_tx_invalid_wrong_amount::generate(std::vector<test_event_entry>& eve DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_wrong_amount"); const size_t mixin = 10; const uint64_t amounts_paid[] = {10000, (uint64_t)-1}; - const rct::RangeProofType range_proof_type[] = { rct::RangeProofBulletproof }; - return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, [&](cryptonote::transaction &tx, size_t idx){ - CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof); + const rct::RCTConfig rct_config[] = { { rct::RangeProofBulletproof, 0 } }; + return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, [&](cryptonote::transaction &tx, size_t idx){ + CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof || tx.rct_signatures.type == rct::RCTTypeBulletproof2); CHECK_TEST_CONDITION(!tx.rct_signatures.p.bulletproofs.empty()); tx.rct_signatures.p.bulletproofs.back() = rct::bulletproof_PROVE(1000, rct::skGen()); return true; @@ -352,10 +353,8 @@ bool gen_bp_tx_invalid_borromean_type::generate(std::vector<test_event_entry>& e DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_borromean_type"); const size_t mixin = 10; const uint64_t amounts_paid[] = {5000, 5000, (uint64_t)-1}; - const rct::RangeProofType range_proof_type[] = {rct::RangeProofPaddedBulletproof}; - return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, [&](cryptonote::transaction &tx, size_t tx_idx){ - CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof); - tx.rct_signatures.type = rct::RCTTypeSimple; + const rct::RCTConfig rct_config[] = { { rct::RangeProofBorromean, 0 } }; + return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, [&](cryptonote::transaction &tx, size_t tx_idx){ return true; }); } diff --git a/tests/core_tests/bulletproofs.h b/tests/core_tests/bulletproofs.h index e29b34690..b0289f355 100644 --- a/tests/core_tests/bulletproofs.h +++ b/tests/core_tests/bulletproofs.h @@ -82,7 +82,7 @@ struct gen_bp_tx_validation_base : public test_chain_unit_base } bool generate_with(std::vector<test_event_entry>& events, size_t mixin, - size_t n_txes, const uint64_t *amounts_paid, bool valid, const rct::RangeProofType *range_proof_type, + size_t n_txes, const uint64_t *amounts_paid, bool valid, const rct::RCTConfig *rct_config, const std::function<bool(std::vector<cryptonote::tx_source_entry> &sources, std::vector<cryptonote::tx_destination_entry> &destinations, size_t)> &pre_tx, const std::function<bool(cryptonote::transaction &tx, size_t)> &post_tx) const; @@ -95,7 +95,7 @@ private: template<> struct get_test_options<gen_bp_tx_validation_base> { - const std::pair<uint8_t, uint64_t> hard_forks[4] = {std::make_pair(1, 0), std::make_pair(2, 1), std::make_pair(8, 73), std::make_pair(0, 0)}; + const std::pair<uint8_t, uint64_t> hard_forks[4] = {std::make_pair(1, 0), std::make_pair(2, 1), std::make_pair(10, 73), std::make_pair(0, 0)}; const cryptonote::test_options test_options = { hard_forks }; diff --git a/tests/core_tests/multisig.cpp b/tests/core_tests/multisig.cpp index 46ba997be..37fda6643 100644 --- a/tests/core_tests/multisig.cpp +++ b/tests/core_tests/multisig.cpp @@ -365,7 +365,7 @@ bool gen_multisig_tx_validation_base::generate_with(std::vector<test_event_entry #endif std::vector<crypto::secret_key> additional_tx_secret_keys; auto sources_copy = sources; - r = construct_tx_and_get_tx_key(miner_account[creator].get_keys(), subaddresses, sources, destinations, boost::none, std::vector<uint8_t>(), tx, 0, tx_key, additional_tx_secret_keys, true, rct::RangeProofBorromean, msoutp); + r = construct_tx_and_get_tx_key(miner_account[creator].get_keys(), subaddresses, sources, destinations, boost::none, std::vector<uint8_t>(), tx, 0, tx_key, additional_tx_secret_keys, true, { rct::RangeProofBorromean, 0 }, msoutp); CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction"); #ifndef NO_MULTISIG @@ -455,7 +455,7 @@ bool gen_multisig_tx_validation_base::generate_with(std::vector<test_event_entry crypto::secret_key scalar1; crypto::derivation_to_scalar(derivation, n, scalar1); rct::ecdhTuple ecdh_info = tx.rct_signatures.ecdhInfo[n]; - rct::ecdhDecode(ecdh_info, rct::sk2rct(scalar1)); + rct::ecdhDecode(ecdh_info, rct::sk2rct(scalar1), tx.rct_signatures.type == rct::RCTTypeBulletproof2); rct::key C = tx.rct_signatures.outPk[n].mask; rct::addKeys2(Ctmp, ecdh_info.mask, ecdh_info.amount, rct::H); CHECK_AND_ASSERT_MES(rct::equalKeys(C, Ctmp), false, "Failed to decode amount"); diff --git a/tests/core_tests/rct.cpp b/tests/core_tests/rct.cpp index 342c3f1ee..bb7dd013b 100644 --- a/tests/core_tests/rct.cpp +++ b/tests/core_tests/rct.cpp @@ -133,7 +133,8 @@ bool gen_rct_tx_validation_base::generate_with(std::vector<test_event_entry>& ev CHECK_AND_ASSERT_MES(r, false, "Failed to generate key derivation"); crypto::secret_key amount_key; crypto::derivation_to_scalar(derivation, o, amount_key); - if (rct_txes[n].rct_signatures.type == rct::RCTTypeSimple || rct_txes[n].rct_signatures.type == rct::RCTTypeBulletproof) + const uint8_t type = rct_txes[n].rct_signatures.type; + if (type == rct::RCTTypeSimple || type == rct::RCTTypeBulletproof || type == rct::RCTTypeBulletproof2) rct::decodeRctSimple(rct_txes[n].rct_signatures, rct::sk2rct(amount_key), o, rct_tx_masks[o+n*4], hw::get_device("default")); else rct::decodeRct(rct_txes[n].rct_signatures, rct::sk2rct(amount_key), o, rct_tx_masks[o+n*4], hw::get_device("default")); diff --git a/tests/core_tests/v2_tests.h b/tests/core_tests/v2_tests.h index ecb23818c..cd2bcb839 100644 --- a/tests/core_tests/v2_tests.h +++ b/tests/core_tests/v2_tests.h @@ -81,7 +81,7 @@ template<> struct get_test_options<gen_v2_tx_validation_base> { const std::pair<uint8_t, uint64_t> hard_forks[3] = {std::make_pair(1, 0), std::make_pair(2, 1), std::make_pair(0, 0)}; const cryptonote::test_options test_options = { - hard_forks + hard_forks, 0 }; }; diff --git a/tests/crypto/CMakeLists.txt b/tests/crypto/CMakeLists.txt index df96c57cc..8789cb552 100644 --- a/tests/crypto/CMakeLists.txt +++ b/tests/crypto/CMakeLists.txt @@ -52,3 +52,17 @@ set_property(TARGET cncrypto-tests add_test( NAME cncrypto COMMAND cncrypto-tests "${CMAKE_CURRENT_SOURCE_DIR}/tests.txt") + +add_executable(cnv4-jit-tests cnv4-jit.c) +target_link_libraries(cnv4-jit-tests + PRIVATE + crypto + common + ${EXTRA_LIBRARIES}) +set_property(TARGET cnv4-jit-tests + PROPERTY + FOLDER "tests") + +add_test( + NAME cnv4-jit + COMMAND cnv4-jit-tests 1788000 1789000) diff --git a/tests/crypto/cnv4-jit.c b/tests/crypto/cnv4-jit.c new file mode 100644 index 000000000..0f11e4393 --- /dev/null +++ b/tests/crypto/cnv4-jit.c @@ -0,0 +1,119 @@ +// Copyright (c) 2019, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <stdint.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include "crypto/hash-ops.h" + +extern volatile int use_v4_jit_flag; + +static int test(const uint8_t *data, size_t len, uint64_t height) +{ + char hash0[32], hash1[32]; + use_v4_jit_flag = 0; + cn_slow_hash(data, len, hash0, 4, 0, height); + use_v4_jit_flag = 1; + cn_slow_hash(data, len, hash1, 4, 0, height); + return memcmp(hash0, hash1, 32); +} + +int main(int argc, char **argv) +{ + uint8_t data[64]; + uint64_t start_height = 1788000; + uint64_t end_height = 1788001; + + if (argc != 1 && argc != 2 && argc != 3) + { + fprintf(stderr, "usage: %s [<start_height> [<end_height>]]\n", argv[0]); + return 1; + } + if (argc > 1) + { + errno = 0; + start_height = strtoull(argv[1], NULL, 10); + if ((start_height == 0 && errno) || start_height == ULLONG_MAX) + { + fprintf(stderr, "invalid start_height\n"); + return 1; + } + end_height = start_height; + if (argc > 2) + { + errno = 0; + end_height = strtoull(argv[2], NULL, 10); + if ((end_height == 0 && errno) || end_height == ULLONG_MAX) + { + fprintf(stderr, "invalid end_height\n"); + return 1; + } + } + } + + if (start_height == end_height) + { + uint64_t counter = 0; + while (1) + { + printf("\r%llu", (unsigned long long)counter); + fflush(stdout); + size_t offset = 0; + while (offset + 8 < sizeof(data)) + { + memcpy(data + offset, &counter, sizeof(counter)); + offset += 8; + } + if (test(data, sizeof(data), start_height)) + { + fprintf(stderr, "\nFailure at height %llu, counter %llu\n", (unsigned long long)start_height, (unsigned long long)counter); + return 0; + } + ++counter; + } + } + + memset(data, 0x42, sizeof(data)); + for (uint64_t h = start_height; h < end_height; ++h) + { + printf("\r%llu/%llu", (unsigned long long)(h-start_height), (unsigned long long)(end_height-start_height)); + fflush(stdout); + if (test(data, sizeof(data), h)) + { + fprintf(stderr, "\nFailure at height %llu\n", (unsigned long long)h); + return 0; + } + } + + printf("\r"); + + return 0; +} diff --git a/tests/hash/CMakeLists.txt b/tests/hash/CMakeLists.txt index 433cf94e9..105cf2c13 100644 --- a/tests/hash/CMakeLists.txt +++ b/tests/hash/CMakeLists.txt @@ -43,7 +43,7 @@ set_property(TARGET hash-tests PROPERTY FOLDER "tests") -foreach (hash IN ITEMS fast slow slow-1 slow-2 tree extra-blake extra-groestl extra-jh extra-skein) +foreach (hash IN ITEMS fast slow slow-1 slow-2 slow-4 tree extra-blake extra-groestl extra-jh extra-skein) add_test( NAME "hash-${hash}" COMMAND hash-tests "${hash}" "${CMAKE_CURRENT_SOURCE_DIR}/tests-${hash}.txt") diff --git a/tests/hash/main.cpp b/tests/hash/main.cpp index 7767d0d3b..acfd99e96 100644 --- a/tests/hash/main.cpp +++ b/tests/hash/main.cpp @@ -44,6 +44,13 @@ using namespace std; using namespace crypto; typedef crypto::hash chash; +struct V4_Data +{ + const void* data; + size_t length; + uint64_t height; +}; + PUSH_WARNINGS DISABLE_VS_WARNINGS(4297) extern "C" { @@ -54,13 +61,17 @@ extern "C" { tree_hash((const char (*)[crypto::HASH_SIZE]) data, length >> 5, hash); } static void cn_slow_hash_0(const void *data, size_t length, char *hash) { - return cn_slow_hash(data, length, hash, 0/*variant*/, 0/*prehashed*/); + return cn_slow_hash(data, length, hash, 0/*variant*/, 0/*prehashed*/, 0/*height*/); } static void cn_slow_hash_1(const void *data, size_t length, char *hash) { - return cn_slow_hash(data, length, hash, 1/*variant*/, 0/*prehashed*/); + return cn_slow_hash(data, length, hash, 1/*variant*/, 0/*prehashed*/, 0/*height*/); } static void cn_slow_hash_2(const void *data, size_t length, char *hash) { - return cn_slow_hash(data, length, hash, 2/*variant*/, 0/*prehashed*/); + return cn_slow_hash(data, length, hash, 2/*variant*/, 0/*prehashed*/, 0/*height*/); + } + static void cn_slow_hash_4(const void *data, size_t, char *hash) { + const V4_Data* p = reinterpret_cast<const V4_Data*>(data); + return cn_slow_hash(p->data, p->length, hash, 4/*variant*/, 0/*prehashed*/, p->height); } } POP_WARNINGS @@ -72,7 +83,7 @@ struct hash_func { } hashes[] = {{"fast", cn_fast_hash}, {"slow", cn_slow_hash_0}, {"tree", hash_tree}, {"extra-blake", hash_extra_blake}, {"extra-groestl", hash_extra_groestl}, {"extra-jh", hash_extra_jh}, {"extra-skein", hash_extra_skein}, - {"slow-1", cn_slow_hash_1}, {"slow-2", cn_slow_hash_2}}; + {"slow-1", cn_slow_hash_1}, {"slow-2", cn_slow_hash_2}, {"slow-4", cn_slow_hash_4}}; int test_variant2_int_sqrt(); int test_variant2_int_sqrt_ref(); @@ -140,7 +151,15 @@ int main(int argc, char *argv[]) { input.exceptions(ios_base::badbit | ios_base::failbit | ios_base::eofbit); input.clear(input.rdstate()); get(input, data); - f(data.data(), data.size(), (char *) &actual); + if (f == cn_slow_hash_4) { + V4_Data d; + d.data = data.data(); + d.length = data.size(); + get(input, d.height); + f(&d, 0, (char *) &actual); + } else { + f(data.data(), data.size(), (char *) &actual); + } if (expected != actual) { size_t i; cerr << "Hash mismatch on test " << test << endl << "Input: "; diff --git a/tests/hash/tests-slow-4.txt b/tests/hash/tests-slow-4.txt new file mode 100644 index 000000000..06ab52cff --- /dev/null +++ b/tests/hash/tests-slow-4.txt @@ -0,0 +1,10 @@ +f759588ad57e758467295443a9bd71490abff8e9dad1b95b6bf2f5d0d78387bc 5468697320697320612074657374205468697320697320612074657374205468697320697320612074657374 1806260 +5bb833deca2bdd7252a9ccd7b4ce0b6a4854515794b56c207262f7a5b9bdb566 4c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73656374657475722061646970697363696e67 1806261 +1ee6728da60fbd8d7d55b2b1ade487a3cf52a2c3ac6f520db12c27d8921f6cab 656c69742c2073656420646f20656975736d6f642074656d706f7220696e6369646964756e74207574206c61626f7265 1806262 +6969fe2ddfb758438d48049f302fc2108a4fcc93e37669170e6db4b0b9b4c4cb 657420646f6c6f7265206d61676e6120616c697175612e20557420656e696d206164206d696e696d2076656e69616d2c 1806263 +7f3048b4e90d0cbe7a57c0394f37338a01fae3adfdc0e5126d863a895eb04e02 71756973206e6f737472756420657865726369746174696f6e20756c6c616d636f206c61626f726973206e697369 1806264 +1d290443a4b542af04a82f6b2494a6ee7f20f2754c58e0849032483a56e8e2ef 757420616c697175697020657820656120636f6d6d6f646f20636f6e7365717561742e20447569732061757465 1806265 +c43cc6567436a86afbd6aa9eaa7c276e9806830334b614b2bee23cc76634f6fd 697275726520646f6c6f7220696e20726570726568656e646572697420696e20766f6c7570746174652076656c6974 1806266 +87be2479c0c4e8edfdfaa5603e93f4265b3f8224c1c5946feb424819d18990a4 657373652063696c6c756d20646f6c6f726520657520667567696174206e756c6c612070617269617475722e 1806267 +dd9d6a6d8e47465cceac0877ef889b93e7eba979557e3935d7f86dce11b070f3 4578636570746575722073696e74206f6363616563617420637570696461746174206e6f6e2070726f6964656e742c 1806268 +75c6f2ae49a20521de97285b431e717125847fb8935ed84a61e7f8d36a2c3d8e 73756e7420696e2063756c706120717569206f666669636961206465736572756e74206d6f6c6c697420616e696d20696420657374206c61626f72756d2e 1806269 diff --git a/tests/performance_tests/check_tx_signature.h b/tests/performance_tests/check_tx_signature.h index ee382d9ad..755d8f941 100644 --- a/tests/performance_tests/check_tx_signature.h +++ b/tests/performance_tests/check_tx_signature.h @@ -40,7 +40,7 @@ #include "multi_tx_test_base.h" -template<size_t a_ring_size, size_t a_outputs, bool a_rct, rct::RangeProofType range_proof_type = rct::RangeProofBorromean> +template<size_t a_ring_size, size_t a_outputs, bool a_rct, rct::RangeProofType range_proof_type = rct::RangeProofBorromean, int bp_version = 2> class test_check_tx_signature : private multi_tx_test_base<a_ring_size> { static_assert(0 < a_ring_size, "ring_size must be greater than 0"); @@ -71,7 +71,8 @@ public: std::vector<crypto::secret_key> additional_tx_keys; std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses; subaddresses[this->m_miners[this->real_source_idx].get_keys().m_account_address.m_spend_public_key] = {0,0}; - if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, 0, tx_key, additional_tx_keys, rct, range_proof_type)) + rct::RCTConfig rct_config{range_proof_type, bp_version}; + if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, 0, tx_key, additional_tx_keys, rct, rct_config)) return false; get_transaction_prefix_hash(m_tx, m_tx_prefix_hash); @@ -135,7 +136,7 @@ public: m_txes.resize(a_num_txes + (extra_outs > 0 ? 1 : 0)); for (size_t n = 0; n < a_num_txes; ++n) { - if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes[n], 0, tx_key, additional_tx_keys, true, rct::RangeProofPaddedBulletproof)) + if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes[n], 0, tx_key, additional_tx_keys, true, {rct::RangeProofPaddedBulletproof, 2})) return false; } @@ -146,7 +147,7 @@ public: for (size_t n = 1; n < extra_outs; ++n) destinations.push_back(tx_destination_entry(1, m_alice.get_keys().m_account_address, false)); - if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes.back(), 0, tx_key, additional_tx_keys, true, rct::RangeProofMultiOutputBulletproof)) + if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes.back(), 0, tx_key, additional_tx_keys, true, {rct::RangeProofMultiOutputBulletproof, 2})) return false; } diff --git a/tests/performance_tests/cn_slow_hash.h b/tests/performance_tests/cn_slow_hash.h index b484afa41..79ebb8778 100644 --- a/tests/performance_tests/cn_slow_hash.h +++ b/tests/performance_tests/cn_slow_hash.h @@ -34,6 +34,7 @@ #include "crypto/crypto.h" #include "cryptonote_basic/cryptonote_basic.h" +template<unsigned int variant> class test_cn_slow_hash { public: @@ -42,18 +43,15 @@ public: #pragma pack(push, 1) struct data_t { - char data[13]; + char data[43]; }; #pragma pack(pop) - static_assert(13 == sizeof(data_t), "Invalid structure size"); + static_assert(43 == sizeof(data_t), "Invalid structure size"); bool init() { - if (!epee::string_tools::hex_to_pod("63617665617420656d70746f72", m_data)) - return false; - - if (!epee::string_tools::hex_to_pod("bbec2cacf69866a8e740380fe7b818fc78f8571221742d729d9d02d7f8989b87", m_expected_hash)) + if (!epee::string_tools::hex_to_pod("63617665617420656d70746f763617665617420656d70746f72263617665617420656d70746f7201020304", m_data)) return false; return true; @@ -62,11 +60,10 @@ public: bool test() { crypto::hash hash; - crypto::cn_slow_hash(&m_data, sizeof(m_data), hash); - return hash == m_expected_hash; + crypto::cn_slow_hash(&m_data, sizeof(m_data), hash, variant); + return true; } private: data_t m_data; - crypto::hash m_expected_hash; }; diff --git a/tests/performance_tests/construct_tx.h b/tests/performance_tests/construct_tx.h index 378065ddd..71d42073d 100644 --- a/tests/performance_tests/construct_tx.h +++ b/tests/performance_tests/construct_tx.h @@ -36,7 +36,7 @@ #include "multi_tx_test_base.h" -template<size_t a_in_count, size_t a_out_count, bool a_rct, rct::RangeProofType range_proof_type = rct::RangeProofBorromean> +template<size_t a_in_count, size_t a_out_count, bool a_rct, rct::RangeProofType range_proof_type = rct::RangeProofBorromean, int bp_version = 2> class test_construct_tx : private multi_tx_test_base<a_in_count> { static_assert(0 < a_in_count, "in_count must be greater than 0"); @@ -73,7 +73,8 @@ public: std::vector<crypto::secret_key> additional_tx_keys; std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses; subaddresses[this->m_miners[this->real_source_idx].get_keys().m_account_address.m_spend_public_key] = {0,0}; - return cryptonote::construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, m_destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, 0, tx_key, additional_tx_keys, rct, range_proof_type); + rct::RCTConfig rct_config{range_proof_type, bp_version}; + return cryptonote::construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, m_destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, 0, tx_key, additional_tx_keys, rct, rct_config); } private: diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp index 6749b71e4..86450760c 100644 --- a/tests/performance_tests/main.cpp +++ b/tests/performance_tests/main.cpp @@ -134,17 +134,17 @@ int main(int argc, char** argv) TEST_PERFORMANCE3(filter, p, test_construct_tx, 100, 2, true); TEST_PERFORMANCE3(filter, p, test_construct_tx, 100, 10, true); - TEST_PERFORMANCE4(filter, p, test_construct_tx, 2, 1, true, rct::RangeProofPaddedBulletproof); - TEST_PERFORMANCE4(filter, p, test_construct_tx, 2, 2, true, rct::RangeProofPaddedBulletproof); - TEST_PERFORMANCE4(filter, p, test_construct_tx, 2, 10, true, rct::RangeProofPaddedBulletproof); + TEST_PERFORMANCE5(filter, p, test_construct_tx, 2, 1, true, rct::RangeProofPaddedBulletproof, 2); + TEST_PERFORMANCE5(filter, p, test_construct_tx, 2, 2, true, rct::RangeProofPaddedBulletproof, 2); + TEST_PERFORMANCE5(filter, p, test_construct_tx, 2, 10, true, rct::RangeProofPaddedBulletproof, 2); - TEST_PERFORMANCE4(filter, p, test_construct_tx, 10, 1, true, rct::RangeProofPaddedBulletproof); - TEST_PERFORMANCE4(filter, p, test_construct_tx, 10, 2, true, rct::RangeProofPaddedBulletproof); - TEST_PERFORMANCE4(filter, p, test_construct_tx, 10, 10, true, rct::RangeProofPaddedBulletproof); + TEST_PERFORMANCE5(filter, p, test_construct_tx, 10, 1, true, rct::RangeProofPaddedBulletproof, 2); + TEST_PERFORMANCE5(filter, p, test_construct_tx, 10, 2, true, rct::RangeProofPaddedBulletproof, 2); + TEST_PERFORMANCE5(filter, p, test_construct_tx, 10, 10, true, rct::RangeProofPaddedBulletproof, 2); - TEST_PERFORMANCE4(filter, p, test_construct_tx, 100, 1, true, rct::RangeProofPaddedBulletproof); - TEST_PERFORMANCE4(filter, p, test_construct_tx, 100, 2, true, rct::RangeProofPaddedBulletproof); - TEST_PERFORMANCE4(filter, p, test_construct_tx, 100, 10, true, rct::RangeProofPaddedBulletproof); + TEST_PERFORMANCE5(filter, p, test_construct_tx, 100, 1, true, rct::RangeProofPaddedBulletproof, 2); + TEST_PERFORMANCE5(filter, p, test_construct_tx, 100, 2, true, rct::RangeProofPaddedBulletproof, 2); + TEST_PERFORMANCE5(filter, p, test_construct_tx, 100, 10, true, rct::RangeProofPaddedBulletproof, 2); TEST_PERFORMANCE3(filter, p, test_check_tx_signature, 1, 2, false); TEST_PERFORMANCE3(filter, p, test_check_tx_signature, 2, 2, false); @@ -157,14 +157,14 @@ int main(int argc, char** argv) TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 100, 2, true, rct::RangeProofBorromean); TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 10, true, rct::RangeProofBorromean); - TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 2, true, rct::RangeProofPaddedBulletproof); - TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 2, true, rct::RangeProofMultiOutputBulletproof); - TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 10, 2, true, rct::RangeProofPaddedBulletproof); - TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 10, 2, true, rct::RangeProofMultiOutputBulletproof); - TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 100, 2, true, rct::RangeProofPaddedBulletproof); - TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 100, 2, true, rct::RangeProofMultiOutputBulletproof); - TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 10, true, rct::RangeProofPaddedBulletproof); - TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 10, true, rct::RangeProofMultiOutputBulletproof); + TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 2, 2, true, rct::RangeProofPaddedBulletproof, 2); + TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 2, 2, true, rct::RangeProofMultiOutputBulletproof, 2); + TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 10, 2, true, rct::RangeProofPaddedBulletproof, 2); + TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 10, 2, true, rct::RangeProofMultiOutputBulletproof, 2); + TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 100, 2, true, rct::RangeProofPaddedBulletproof, 2); + TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 100, 2, true, rct::RangeProofMultiOutputBulletproof, 2); + TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 2, 10, true, rct::RangeProofPaddedBulletproof, 2); + TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 2, 10, true, rct::RangeProofMultiOutputBulletproof, 2); TEST_PERFORMANCE3(filter, p, test_check_tx_signature_aggregated_bulletproofs, 2, 2, 64); TEST_PERFORMANCE3(filter, p, test_check_tx_signature_aggregated_bulletproofs, 10, 2, 64); @@ -193,7 +193,10 @@ int main(int argc, char** argv) TEST_PERFORMANCE2(filter, p, test_wallet2_expand_subaddresses, 50, 200); - TEST_PERFORMANCE0(filter, p, test_cn_slow_hash); + TEST_PERFORMANCE1(filter, p, test_cn_slow_hash, 0); + TEST_PERFORMANCE1(filter, p, test_cn_slow_hash, 1); + TEST_PERFORMANCE1(filter, p, test_cn_slow_hash, 2); + TEST_PERFORMANCE1(filter, p, test_cn_slow_hash, 4); TEST_PERFORMANCE1(filter, p, test_cn_fast_hash, 32); TEST_PERFORMANCE1(filter, p, test_cn_fast_hash, 16384); diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt index f7012746d..aea82ede2 100644 --- a/tests/unit_tests/CMakeLists.txt +++ b/tests/unit_tests/CMakeLists.txt @@ -55,6 +55,7 @@ set(unit_tests_sources http.cpp keccak.cpp logging.cpp + long_term_block_weight.cpp main.cpp memwipe.cpp mlocker.cpp @@ -62,9 +63,11 @@ set(unit_tests_sources mul_div.cpp multiexp.cpp multisig.cpp + net.cpp notify.cpp output_distribution.cpp parse_amount.cpp + pruning.cpp random.cpp serialization.cpp sha256.cpp @@ -99,6 +102,7 @@ target_link_libraries(unit_tests cryptonote_core blockchain_db rpc + net serialization wallet p2p diff --git a/tests/unit_tests/ban.cpp b/tests/unit_tests/ban.cpp index 12625a949..1e764c83e 100644 --- a/tests/unit_tests/ban.cpp +++ b/tests/unit_tests/ban.cpp @@ -84,6 +84,8 @@ public: bool fluffy_blocks_enabled() const { return false; } uint64_t prevalidate_block_hashes(uint64_t height, const std::vector<crypto::hash> &hashes) { return 0; } bool pad_transactions() { return false; } + uint32_t get_blockchain_pruning_seed() const { return 0; } + bool prune_blockchain(uint32_t pruning_seed = 0) { return true; } void stop() {} }; diff --git a/tests/unit_tests/blockchain_db.cpp b/tests/unit_tests/blockchain_db.cpp index 7e7ce9bf7..9cf8c5fbe 100644 --- a/tests/unit_tests/blockchain_db.cpp +++ b/tests/unit_tests/blockchain_db.cpp @@ -277,10 +277,10 @@ TYPED_TEST(BlockchainDBTest, AddBlock) // TODO: need at least one more block to make this reasonable, as the // BlockchainDB implementation should not check for parent if // no blocks have been added yet (because genesis has no parent). - //ASSERT_THROW(this->m_db->add_block(this->m_blocks[1], t_sizes[1], t_diffs[1], t_coins[1], this->m_txs[1]), BLOCK_PARENT_DNE); + //ASSERT_THROW(this->m_db->add_block(this->m_blocks[1], t_sizes[1], t_sizes[1], t_diffs[1], t_coins[1], this->m_txs[1]), BLOCK_PARENT_DNE); - ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[0], t_sizes[0], t_diffs[0], t_coins[0], this->m_txs[0])); - ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[1], t_sizes[1], t_diffs[1], t_coins[1], this->m_txs[1])); + ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[0], t_sizes[0], t_sizes[0], t_diffs[0], t_coins[0], this->m_txs[0])); + ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[1], t_sizes[1], t_sizes[1], t_diffs[1], t_coins[1], this->m_txs[1])); block b; ASSERT_TRUE(this->m_db->block_exists(get_block_hash(this->m_blocks[0]))); @@ -293,7 +293,7 @@ TYPED_TEST(BlockchainDBTest, AddBlock) ASSERT_TRUE(compare_blocks(this->m_blocks[0], b)); // assert that we can't add the same block twice - ASSERT_THROW(this->m_db->add_block(this->m_blocks[0], t_sizes[0], t_diffs[0], t_coins[0], this->m_txs[0]), TX_EXISTS); + ASSERT_THROW(this->m_db->add_block(this->m_blocks[0], t_sizes[0], t_sizes[0], t_diffs[0], t_coins[0], this->m_txs[0]), TX_EXISTS); for (auto& h : this->m_blocks[0].tx_hashes) { @@ -317,14 +317,14 @@ TYPED_TEST(BlockchainDBTest, RetrieveBlockData) this->get_filenames(); this->init_hard_fork(); - ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[0], t_sizes[0], t_diffs[0], t_coins[0], this->m_txs[0])); + ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[0], t_sizes[0], t_sizes[0], t_diffs[0], t_coins[0], this->m_txs[0])); ASSERT_EQ(t_sizes[0], this->m_db->get_block_weight(0)); ASSERT_EQ(t_diffs[0], this->m_db->get_block_cumulative_difficulty(0)); ASSERT_EQ(t_diffs[0], this->m_db->get_block_difficulty(0)); ASSERT_EQ(t_coins[0], this->m_db->get_block_already_generated_coins(0)); - ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[1], t_sizes[1], t_diffs[1], t_coins[1], this->m_txs[1])); + ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[1], t_sizes[1], t_sizes[1], t_diffs[1], t_coins[1], this->m_txs[1])); ASSERT_EQ(t_diffs[1] - t_diffs[0], this->m_db->get_block_difficulty(1)); ASSERT_HASH_EQ(get_block_hash(this->m_blocks[0]), this->m_db->get_block_hash_from_height(0)); diff --git a/tests/unit_tests/bulletproofs.cpp b/tests/unit_tests/bulletproofs.cpp index ac6eaca0b..4f07415b0 100644 --- a/tests/unit_tests/bulletproofs.cpp +++ b/tests/unit_tests/bulletproofs.cpp @@ -131,7 +131,8 @@ TEST(bulletproofs, multi_splitting) } rct::ctkeyV outSk; - rct::rctSig s = rct::genRctSimple(rct::zero(), sc, destinations, inamounts, outamounts, available, mixRing, amount_keys, NULL, NULL, index, outSk, rct::RangeProofPaddedBulletproof, hw::get_device("default")); + rct::RCTConfig rct_config { rct::RangeProofPaddedBulletproof, 0 }; + rct::rctSig s = rct::genRctSimple(rct::zero(), sc, destinations, inamounts, outamounts, available, mixRing, amount_keys, NULL, NULL, index, outSk, rct_config, hw::get_device("default")); ASSERT_TRUE(rct::verRctSimple(s)); for (size_t i = 0; i < n_outputs; ++i) { diff --git a/tests/unit_tests/device.cpp b/tests/unit_tests/device.cpp index 50ccec9fa..c0e8fecc1 100644 --- a/tests/unit_tests/device.cpp +++ b/tests/unit_tests/device.cpp @@ -114,18 +114,17 @@ TEST(device, ops) ASSERT_EQ(ki0, ki1); } -TEST(device, ecdh) +TEST(device, ecdh32) { hw::core::device_default dev; rct::ecdhTuple tuple, tuple2; rct::key key = rct::skGen(); tuple.mask = rct::skGen(); tuple.amount = rct::skGen(); - tuple.senderPk = rct::pkGen(); tuple2 = tuple; - dev.ecdhEncode(tuple, key); - dev.ecdhDecode(tuple, key); + dev.ecdhEncode(tuple, key, false); + dev.ecdhDecode(tuple, key, false); ASSERT_EQ(tuple2.mask, tuple.mask); ASSERT_EQ(tuple2.amount, tuple.amount); - ASSERT_EQ(tuple2.senderPk, tuple.senderPk); } + diff --git a/tests/unit_tests/epee_utils.cpp b/tests/unit_tests/epee_utils.cpp index 3d5882d7d..18fb262c2 100644 --- a/tests/unit_tests/epee_utils.cpp +++ b/tests/unit_tests/epee_utils.cpp @@ -545,6 +545,8 @@ TEST(StringTools, GetIpInt32) TEST(NetUtils, IPv4NetworkAddress) { + static_assert(epee::net_utils::ipv4_network_address::get_type_id() == epee::net_utils::address_type::ipv4, "bad ipv4 type id"); + 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); @@ -555,7 +557,7 @@ TEST(NetUtils, IPv4NetworkAddress) 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(epee::net_utils::ipv4_network_address::get_type_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); @@ -568,7 +570,7 @@ TEST(NetUtils, IPv4NetworkAddress) 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(epee::net_utils::ipv4_network_address::get_type_id(), address1.get_type_id()); EXPECT_EQ(ip_loopback, loopback.ip()); EXPECT_EQ(0, loopback.port()); @@ -624,7 +626,9 @@ TEST(NetUtils, NetworkAddress) 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); } + constexpr static epee::net_utils::address_type get_type_id() noexcept { return epee::net_utils::address_type(-1); } + constexpr static epee::net_utils::zone get_zone() noexcept { return epee::net_utils::zone::invalid; } + constexpr static bool is_blockable() noexcept { return false; } }; const epee::net_utils::network_address empty; @@ -634,7 +638,9 @@ TEST(NetUtils, NetworkAddress) 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_EQ(epee::net_utils::address_type::invalid, empty.get_type_id()); + EXPECT_EQ(epee::net_utils::zone::invalid, empty.get_zone()); + EXPECT_FALSE(empty.is_blockable()); EXPECT_THROW(empty.as<custom_address>(), std::bad_cast); epee::net_utils::network_address address1{ @@ -650,7 +656,9 @@ TEST(NetUtils, NetworkAddress) 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(epee::net_utils::ipv4_network_address::get_type_id(), address1.get_type_id()); + EXPECT_EQ(epee::net_utils::zone::public_, address1.get_zone()); + EXPECT_TRUE(address1.is_blockable()); EXPECT_NO_THROW(address1.as<epee::net_utils::ipv4_network_address>()); EXPECT_THROW(address1.as<custom_address>(), std::bad_cast); @@ -667,7 +675,9 @@ TEST(NetUtils, NetworkAddress) 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(epee::net_utils::ipv4_network_address::get_type_id(), address1.get_type_id()); + EXPECT_EQ(epee::net_utils::zone::public_, address1.get_zone()); + EXPECT_EQ(epee::net_utils::ipv4_network_address::get_type_id(), address1.get_type_id()); const epee::net_utils::network_address local{ epee::net_utils::ipv4_network_address{ip_local, 8080} diff --git a/tests/unit_tests/hardfork.cpp b/tests/unit_tests/hardfork.cpp index ec8d1d202..12dfde1bc 100644 --- a/tests/unit_tests/hardfork.cpp +++ b/tests/unit_tests/hardfork.cpp @@ -34,7 +34,7 @@ #include "blockchain_db/blockchain_db.h" #include "cryptonote_basic/cryptonote_format_utils.h" #include "cryptonote_basic/hardfork.h" -#include "testdb.h" +#include "blockchain_db/testdb.h" using namespace cryptonote; @@ -44,11 +44,12 @@ using namespace cryptonote; namespace { -class TestDB: public BaseTestDB { +class TestDB: public cryptonote::BaseTestDB { public: virtual uint64_t height() const { return blocks.size(); } virtual void add_block( const block& blk , size_t block_weight + , uint64_t long_term_block_weight , const difficulty_type& cumulative_difficulty , const uint64_t& coins_generated , uint64_t num_rct_outs @@ -106,20 +107,20 @@ TEST(major, Only) ASSERT_FALSE(hf.add(mkblock(0, 2), 0)); ASSERT_FALSE(hf.add(mkblock(2, 2), 0)); ASSERT_TRUE(hf.add(mkblock(1, 2), 0)); - db.add_block(mkblock(1, 1), 0, 0, 0, 0, crypto::hash()); + db.add_block(mkblock(1, 1), 0, 0, 0, 0, 0, crypto::hash()); // block height 1, only version 1 is accepted ASSERT_FALSE(hf.add(mkblock(0, 2), 1)); ASSERT_FALSE(hf.add(mkblock(2, 2), 1)); ASSERT_TRUE(hf.add(mkblock(1, 2), 1)); - db.add_block(mkblock(1, 1), 0, 0, 0, 0, crypto::hash()); + db.add_block(mkblock(1, 1), 0, 0, 0, 0, 0, crypto::hash()); // block height 2, only version 2 is accepted ASSERT_FALSE(hf.add(mkblock(0, 2), 2)); ASSERT_FALSE(hf.add(mkblock(1, 2), 2)); ASSERT_FALSE(hf.add(mkblock(3, 2), 2)); ASSERT_TRUE(hf.add(mkblock(2, 2), 2)); - db.add_block(mkblock(2, 1), 0, 0, 0, 0, crypto::hash()); + db.add_block(mkblock(2, 1), 0, 0, 0, 0, 0, crypto::hash()); } TEST(empty_hardforks, Success) @@ -133,7 +134,7 @@ TEST(empty_hardforks, Success) ASSERT_TRUE(hf.get_state(time(NULL) + 3600*24*400) == HardFork::Ready); for (uint64_t h = 0; h <= 10; ++h) { - db.add_block(mkblock(hf, h, 1), 0, 0, 0, 0, crypto::hash()); + db.add_block(mkblock(hf, h, 1), 0, 0, 0, 0, 0, crypto::hash()); ASSERT_TRUE(hf.add(db.get_block_from_height(h), h)); } ASSERT_EQ(hf.get(0), 1); @@ -167,14 +168,14 @@ TEST(check_for_height, Success) for (uint64_t h = 0; h <= 4; ++h) { ASSERT_TRUE(hf.check_for_height(mkblock(1, 1), h)); ASSERT_FALSE(hf.check_for_height(mkblock(2, 2), h)); // block version is too high - db.add_block(mkblock(hf, h, 1), 0, 0, 0, 0, crypto::hash()); + db.add_block(mkblock(hf, h, 1), 0, 0, 0, 0, 0, crypto::hash()); ASSERT_TRUE(hf.add(db.get_block_from_height(h), h)); } for (uint64_t h = 5; h <= 10; ++h) { ASSERT_FALSE(hf.check_for_height(mkblock(1, 1), h)); // block version is too low ASSERT_TRUE(hf.check_for_height(mkblock(2, 2), h)); - db.add_block(mkblock(hf, h, 2), 0, 0, 0, 0, crypto::hash()); + db.add_block(mkblock(hf, h, 2), 0, 0, 0, 0, 0, crypto::hash()); ASSERT_TRUE(hf.add(db.get_block_from_height(h), h)); } } @@ -191,19 +192,19 @@ TEST(get, next_version) for (uint64_t h = 0; h <= 4; ++h) { ASSERT_EQ(2, hf.get_next_version()); - db.add_block(mkblock(hf, h, 1), 0, 0, 0, 0, crypto::hash()); + db.add_block(mkblock(hf, h, 1), 0, 0, 0, 0, 0, crypto::hash()); ASSERT_TRUE(hf.add(db.get_block_from_height(h), h)); } for (uint64_t h = 5; h <= 9; ++h) { ASSERT_EQ(4, hf.get_next_version()); - db.add_block(mkblock(hf, h, 2), 0, 0, 0, 0, crypto::hash()); + db.add_block(mkblock(hf, h, 2), 0, 0, 0, 0, 0, crypto::hash()); ASSERT_TRUE(hf.add(db.get_block_from_height(h), h)); } for (uint64_t h = 10; h <= 15; ++h) { ASSERT_EQ(4, hf.get_next_version()); - db.add_block(mkblock(hf, h, 4), 0, 0, 0, 0, crypto::hash()); + db.add_block(mkblock(hf, h, 4), 0, 0, 0, 0, 0, crypto::hash()); ASSERT_TRUE(hf.add(db.get_block_from_height(h), h)); } } @@ -244,7 +245,7 @@ TEST(steps_asap, Success) hf.init(); for (uint64_t h = 0; h < 10; ++h) { - db.add_block(mkblock(hf, h, 9), 0, 0, 0, 0, crypto::hash()); + db.add_block(mkblock(hf, h, 9), 0, 0, 0, 0, 0, crypto::hash()); ASSERT_TRUE(hf.add(db.get_block_from_height(h), h)); } @@ -271,7 +272,7 @@ TEST(steps_1, Success) hf.init(); for (uint64_t h = 0 ; h < 10; ++h) { - db.add_block(mkblock(hf, h, h+1), 0, 0, 0, 0, crypto::hash()); + db.add_block(mkblock(hf, h, h+1), 0, 0, 0, 0, 0, crypto::hash()); ASSERT_TRUE(hf.add(db.get_block_from_height(h), h)); } @@ -296,7 +297,7 @@ TEST(reorganize, Same) // index 0 1 2 3 4 5 6 7 8 9 static const uint8_t block_versions[] = { 1, 1, 4, 4, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 }; for (uint64_t h = 0; h < 20; ++h) { - db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, crypto::hash()); + db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, 0, crypto::hash()); ASSERT_TRUE(hf.add(db.get_block_from_height(h), h)); } @@ -327,7 +328,7 @@ TEST(reorganize, Changed) static const uint8_t block_versions[] = { 1, 1, 4, 4, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 }; static const uint8_t expected_versions[] = { 1, 1, 1, 1, 1, 1, 4, 4, 7, 7, 9, 9, 9, 9, 9, 9 }; for (uint64_t h = 0; h < 16; ++h) { - db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, crypto::hash()); + db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, 0, crypto::hash()); ASSERT_TRUE (hf.add(db.get_block_from_height(h), h)); } @@ -347,7 +348,7 @@ TEST(reorganize, Changed) ASSERT_EQ(db.height(), 3); hf.reorganize_from_block_height(2); for (uint64_t h = 3; h < 16; ++h) { - db.add_block(mkblock(hf, h, block_versions_new[h]), 0, 0, 0, 0, crypto::hash()); + db.add_block(mkblock(hf, h, block_versions_new[h]), 0, 0, 0, 0, 0, crypto::hash()); bool ret = hf.add(db.get_block_from_height(h), h); ASSERT_EQ (ret, h < 15); } @@ -371,7 +372,7 @@ TEST(voting, threshold) for (uint64_t h = 0; h <= 8; ++h) { uint8_t v = 1 + !!(h % 8); - db.add_block(mkblock(hf, h, v), 0, 0, 0, 0, crypto::hash()); + db.add_block(mkblock(hf, h, v), 0, 0, 0, 0, 0, crypto::hash()); bool ret = hf.add(db.get_block_from_height(h), h); if (h >= 8 && threshold == 87) { // for threshold 87, we reach the treshold at height 7, so from height 8, hard fork to version 2, but 8 tries to add 1 @@ -405,7 +406,7 @@ TEST(voting, different_thresholds) static const uint8_t expected_versions[] = { 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4 }; for (uint64_t h = 0; h < sizeof(block_versions) / sizeof(block_versions[0]); ++h) { - db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, crypto::hash()); + db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, 0, crypto::hash()); bool ret = hf.add(db.get_block_from_height(h), h); ASSERT_EQ(ret, true); } @@ -459,7 +460,7 @@ TEST(voting, info) ASSERT_EQ(expected_thresholds[h], threshold); ASSERT_EQ(4, voting); - db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, crypto::hash()); + db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, 0, crypto::hash()); ASSERT_TRUE(hf.add(db.get_block_from_height(h), h)); } } @@ -522,7 +523,7 @@ TEST(reorganize, changed) #define ADD(v, h, a) \ do { \ cryptonote::block b = mkblock(hf, h, v); \ - db.add_block(b, 0, 0, 0, 0, crypto::hash()); \ + db.add_block(b, 0, 0, 0, 0, 0, crypto::hash()); \ ASSERT_##a(hf.add(b, h)); \ } while(0) #define ADD_TRUE(v, h) ADD(v, h, TRUE) diff --git a/tests/unit_tests/json_serialization.cpp b/tests/unit_tests/json_serialization.cpp index 234cb2c33..53d9f84c7 100644 --- a/tests/unit_tests/json_serialization.cpp +++ b/tests/unit_tests/json_serialization.cpp @@ -75,7 +75,7 @@ namespace std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses; subaddresses[from.m_account_address.m_spend_public_key] = {0,0}; - if (!cryptonote::construct_tx_and_get_tx_key(from, subaddresses, actual_sources, to, boost::none, {}, tx, 0, tx_key, extra_keys, rct, bulletproof ? rct::RangeProofBulletproof : rct::RangeProofBorromean)) + if (!cryptonote::construct_tx_and_get_tx_key(from, subaddresses, actual_sources, to, boost::none, {}, tx, 0, tx_key, extra_keys, rct, { bulletproof ? rct::RangeProofBulletproof : rct::RangeProofBorromean, bulletproof ? 2 : 0 })) throw std::runtime_error{"transaction construction error"}; return tx; diff --git a/tests/unit_tests/long_term_block_weight.cpp b/tests/unit_tests/long_term_block_weight.cpp new file mode 100644 index 000000000..0ee6c5c2b --- /dev/null +++ b/tests/unit_tests/long_term_block_weight.cpp @@ -0,0 +1,384 @@ +// Copyright (c) 2019, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#define IN_UNIT_TESTS + +#include "gtest/gtest.h" +#include "cryptonote_core/blockchain.h" +#include "cryptonote_core/tx_pool.h" +#include "cryptonote_core/cryptonote_core.h" +#include "blockchain_db/testdb.h" + +#define TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW 5000 + +namespace +{ + +class TestDB: public cryptonote::BaseTestDB +{ +private: + struct block_t + { + size_t weight; + uint64_t long_term_weight; + }; + +public: + TestDB() { m_open = true; } + + virtual void add_block( const cryptonote::block& blk + , size_t block_weight + , uint64_t long_term_block_weight + , const cryptonote::difficulty_type& cumulative_difficulty + , const uint64_t& coins_generated + , uint64_t num_rct_outs + , const crypto::hash& blk_hash + ) override { + blocks.push_back({block_weight, long_term_block_weight}); + } + virtual uint64_t height() const override { return blocks.size(); } + virtual size_t get_block_weight(const uint64_t &h) const override { return blocks[h].weight; } + virtual uint64_t get_block_long_term_weight(const uint64_t &h) const override { return blocks[h].long_term_weight; } + virtual crypto::hash top_block_hash() const override { + uint64_t h = height(); + crypto::hash top = crypto::null_hash; + if (h) + *(uint64_t*)&top = h - 1; + return top; + } + virtual void pop_block(cryptonote::block &blk, std::vector<cryptonote::transaction> &txs) override { blocks.pop_back(); } + +private: + std::vector<block_t> blocks; +}; + +static uint32_t lcg_seed = 0; + +static uint32_t lcg() +{ + lcg_seed = (lcg_seed * 0x100000001b3 + 0xcbf29ce484222325) & 0xffffffff; + return lcg_seed; +} + +} + +#define PREFIX_WINDOW(hf_version,window) \ + std::unique_ptr<cryptonote::Blockchain> bc; \ + cryptonote::tx_memory_pool txpool(*bc); \ + bc.reset(new cryptonote::Blockchain(txpool)); \ + struct get_test_options { \ + const std::pair<uint8_t, uint64_t> hard_forks[3]; \ + const cryptonote::test_options test_options = { \ + hard_forks, \ + window, \ + }; \ + get_test_options(): hard_forks{std::make_pair(1, (uint64_t)0), std::make_pair((uint8_t)hf_version, (uint64_t)1), std::make_pair((uint8_t)0, (uint64_t)0)} {} \ + } opts; \ + cryptonote::Blockchain *blockchain = bc.get(); \ + bool r = blockchain->init(new TestDB(), cryptonote::FAKECHAIN, true, &opts.test_options, 0, NULL); \ + ASSERT_TRUE(r) + +#define PREFIX(hf_version) PREFIX_WINDOW(hf_version, TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW) + +TEST(long_term_block_weight, empty_short) +{ + PREFIX(9); + + ASSERT_TRUE(bc->update_next_cumulative_weight_limit()); + + ASSERT_EQ(bc->get_current_cumulative_block_weight_median(), CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5); + ASSERT_EQ(bc->get_current_cumulative_block_weight_limit(), CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 * 2); +} + +TEST(long_term_block_weight, identical_before_fork) +{ + PREFIX(9); + + for (uint64_t h = 1; h < 10 * TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW; ++h) + { + size_t w = h < CRYPTONOTE_REWARD_BLOCKS_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit(); + uint64_t ltw = bc->get_next_long_term_block_weight(w); + bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {}); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit()); + } + for (uint64_t h = 0; h < 10 * TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW; ++h) + { + ASSERT_EQ(bc->get_db().get_block_long_term_weight(h), bc->get_db().get_block_weight(h)); + } +} + +TEST(long_term_block_weight, identical_after_fork_before_long_term_window) +{ + PREFIX(10); + + for (uint64_t h = 1; h <= TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW; ++h) + { + size_t w = h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit(); + uint64_t ltw = bc->get_next_long_term_block_weight(w); + bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {}); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit()); + } + for (uint64_t h = 0; h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW; ++h) + { + ASSERT_EQ(bc->get_db().get_block_long_term_weight(h), bc->get_db().get_block_weight(h)); + } +} + +TEST(long_term_block_weight, ceiling_at_30000000) +{ + PREFIX(10); + + for (uint64_t h = 0; h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW + TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW / 2 - 1; ++h) + { + size_t w = h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit(); + uint64_t ltw = bc->get_next_long_term_block_weight(w); + bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {}); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit()); + } + ASSERT_EQ(bc->get_current_cumulative_block_weight_median(), 15000000); + ASSERT_EQ(bc->get_current_cumulative_block_weight_limit(), 30000000); +} + +TEST(long_term_block_weight, multi_pop) +{ + PREFIX(10); + + for (uint64_t h = 1; h <= TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW + 20; ++h) + { + size_t w = h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit(); + uint64_t ltw = bc->get_next_long_term_block_weight(w); + bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {}); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit()); + } + + const uint64_t effective_median = bc->get_current_cumulative_block_weight_median(); + const uint64_t effective_limit = bc->get_current_cumulative_block_weight_limit(); + + for (uint64_t h = 0; h < 4; ++h) + { + size_t w = h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit(); + uint64_t ltw = bc->get_next_long_term_block_weight(w); + bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {}); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit()); + } + + cryptonote::block b; + std::vector<cryptonote::transaction> txs; + bc->get_db().pop_block(b, txs); + bc->get_db().pop_block(b, txs); + bc->get_db().pop_block(b, txs); + bc->get_db().pop_block(b, txs); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit()); + + ASSERT_EQ(effective_median, bc->get_current_cumulative_block_weight_median()); + ASSERT_EQ(effective_limit, bc->get_current_cumulative_block_weight_limit()); +} + +TEST(long_term_block_weight, multiple_updates) +{ + PREFIX(10); + + for (uint64_t h = 1; h <= 3 * TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW; ++h) + { + size_t w = h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit(); + uint64_t ltw = bc->get_next_long_term_block_weight(w); + bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {}); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit()); + const uint64_t effective_median = bc->get_current_cumulative_block_weight_median(); + const uint64_t effective_limit = bc->get_current_cumulative_block_weight_limit(); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit()); + ASSERT_EQ(effective_median, bc->get_current_cumulative_block_weight_median()); + ASSERT_EQ(effective_limit, bc->get_current_cumulative_block_weight_limit()); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit()); + ASSERT_EQ(effective_median, bc->get_current_cumulative_block_weight_median()); + ASSERT_EQ(effective_limit, bc->get_current_cumulative_block_weight_limit()); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit()); + ASSERT_EQ(effective_median, bc->get_current_cumulative_block_weight_median()); + ASSERT_EQ(effective_limit, bc->get_current_cumulative_block_weight_limit()); + } +} + +TEST(long_term_block_weight, pop_invariant_max) +{ + PREFIX(10); + + for (uint64_t h = 1; h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW - 10; ++h) + { + size_t w = bc->get_db().height() < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit(); + uint64_t ltw = bc->get_next_long_term_block_weight(w); + bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {}); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit()); + } + + for (int n = 0; n < 1000; ++n) + { + // pop some blocks, then add some more + int remove = 1 + (n * 17) % 8; + int add = (n * 23) % 12; + + // save long term block weights we're about to remove + uint64_t old_ltbw[16], h0 = bc->get_db().height() - remove - 1; + for (int i = -2; i < remove; ++i) + { + old_ltbw[i + 2] = bc->get_db().get_block_long_term_weight(h0 + i); + } + + for (int i = 0; i < remove; ++i) + { + cryptonote::block b; + std::vector<cryptonote::transaction> txs; + bc->get_db().pop_block(b, txs); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit()); + } + for (int i = 0; i < add; ++i) + { + size_t w = bc->get_db().height() < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit(); + uint64_t ltw = bc->get_next_long_term_block_weight(w); + bc->get_db().add_block(cryptonote::block(), w, ltw, bc->get_db().height(), bc->get_db().height(), {}); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit()); + } + + // check the new values are the same as the old ones + for (int i = -2; i < std::min(add, remove); ++i) + { + ASSERT_EQ(bc->get_db().get_block_long_term_weight(h0 + i), old_ltbw[i + 2]); + } + } +} + +TEST(long_term_block_weight, pop_invariant_random) +{ + PREFIX(10); + + for (uint64_t h = 1; h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW - 10; ++h) + { + size_t w = bc->get_db().height() < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit(); + uint64_t ltw = bc->get_next_long_term_block_weight(w); + bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {}); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit()); + } + + for (int n = 0; n < 1000; ++n) + { + // pop some blocks, then add some more + int remove = 1 + (n * 17) % 8; + int add = (n * 23) % 123; + + // save long term block weights we're about to remove + uint64_t old_ltbw[16], h0 = bc->get_db().height() - remove - 1; + for (int i = -2; i < remove; ++i) + { + old_ltbw[i + 2] = bc->get_db().get_block_long_term_weight(h0 + i); + } + + for (int i = 0; i < remove; ++i) + { + cryptonote::block b; + std::vector<cryptonote::transaction> txs; + bc->get_db().pop_block(b, txs); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit()); + const uint64_t effective_median = bc->get_current_cumulative_block_weight_median(); + const uint64_t effective_limit = bc->get_current_cumulative_block_weight_limit(); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit()); + ASSERT_EQ(effective_median, bc->get_current_cumulative_block_weight_median()); + ASSERT_EQ(effective_limit, bc->get_current_cumulative_block_weight_limit()); + } + for (int i = 0; i < add; ++i) + { + lcg_seed = bc->get_db().height(); + uint32_t r = lcg(); + size_t w = bc->get_db().height() < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : (r % bc->get_current_cumulative_block_weight_limit()); + uint64_t ltw = bc->get_next_long_term_block_weight(w); + bc->get_db().add_block(cryptonote::block(), w, ltw, bc->get_db().height(), bc->get_db().height(), {}); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit()); + const uint64_t effective_median = bc->get_current_cumulative_block_weight_median(); + const uint64_t effective_limit = bc->get_current_cumulative_block_weight_limit(); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit()); + ASSERT_EQ(effective_median, bc->get_current_cumulative_block_weight_median()); + ASSERT_EQ(effective_limit, bc->get_current_cumulative_block_weight_limit()); + } + + // check the new values are the same as the old ones + for (int i = -2; i < std::min(add, remove); ++i) + { + ASSERT_EQ(bc->get_db().get_block_long_term_weight(h0 + i), old_ltbw[i + 2]); + } + } +} + +TEST(long_term_block_weight, long_growth_spike_and_drop) +{ + PREFIX(10); + + uint64_t long_term_effective_median_block_weight; + + // constant init + for (uint64_t h = 0; h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW; ++h) + { + size_t w = CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5; + uint64_t ltw = bc->get_next_long_term_block_weight(w); + bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {}); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit(&long_term_effective_median_block_weight)); + } + ASSERT_EQ(long_term_effective_median_block_weight, 300000); + + // slow 10% yearly for a year (scaled down by 100000 / TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW) -> 8% change + for (uint64_t h = 0; h < 365 * 720 * TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW / 100000; ++h) + { + //size_t w = bc->get_current_cumulative_block_weight_median() * rate; + float t = h / float(365 * 720 * TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW / 100000); + size_t w = 300000 + t * 30000; + uint64_t ltw = bc->get_next_long_term_block_weight(w); + bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {}); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit(&long_term_effective_median_block_weight)); + } + ASSERT_GT(long_term_effective_median_block_weight, 300000 * 1.07); + ASSERT_LT(long_term_effective_median_block_weight, 300000 * 1.09); + + // spike over three weeks - does not move much + for (uint64_t h = 0; h < 21 * 720 * TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW / 100000; ++h) + { + size_t w = bc->get_current_cumulative_block_weight_limit(); + uint64_t ltw = bc->get_next_long_term_block_weight(w); + bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {}); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit(&long_term_effective_median_block_weight)); + } + ASSERT_GT(long_term_effective_median_block_weight, 300000 * 1.07); + ASSERT_LT(long_term_effective_median_block_weight, 300000 * 1.09); + + // drop - does not move much + for (uint64_t h = 0; h < 21 * 720 * TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW / 100000; ++h) + { + size_t w = bc->get_current_cumulative_block_weight_median() * .25; + uint64_t ltw = bc->get_next_long_term_block_weight(w); + bc->get_db().add_block(cryptonote::block(), w, ltw, h, h, {}); + ASSERT_TRUE(bc->update_next_cumulative_weight_limit(&long_term_effective_median_block_weight)); + } + ASSERT_GT(long_term_effective_median_block_weight, 300000 * 1.07); + ASSERT_LT(long_term_effective_median_block_weight, 300000 * 1.09); +} diff --git a/tests/unit_tests/mnemonics.cpp b/tests/unit_tests/mnemonics.cpp index 4dc2d931e..59642828d 100644 --- a/tests/unit_tests/mnemonics.cpp +++ b/tests/unit_tests/mnemonics.cpp @@ -51,6 +51,7 @@ #include "mnemonics/english_old.h" #include "mnemonics/language_base.h" #include "mnemonics/singleton.h" +#include <boost/algorithm/string.hpp> namespace { @@ -221,3 +222,38 @@ TEST(mnemonics, utf8prefix) ASSERT_TRUE(Language::utf8prefix(epee::wipeable_string("æon"), 3) == "æon"); ASSERT_TRUE(Language::utf8prefix(epee::wipeable_string("æon"), 4) == "æon"); } + +TEST(mnemonics, case_tolerance) +{ + bool res; + // + crypto::secret_key key_1; + std::string language_name_1; + const std::string seed_1 = "Neubau umarmen Abart umarmen Turban feilen Brett Bargeld Episode Milchkuh Substanz Jahr Armband Maibaum Tand Grünalge Tabak erziehen Federboa Lobrede Tenor Leuchter Curry Diskurs Tenor"; + res = crypto::ElectrumWords::words_to_bytes(seed_1, key_1, language_name_1); + ASSERT_EQ(true, res); + ASSERT_STREQ(language_name_1.c_str(), "Deutsch"); + // + crypto::secret_key key_2; + std::string language_name_2; + // neubau is capitalized in the word list, but the language detection code should be able to detect it as Deutsch + std::string seed_2 = "neubau umarmen Abart umarmen Turban feilen Brett Bargeld Episode Milchkuh Substanz Jahr Armband Maibaum Tand Grünalge Tabak erziehen Federboa Lobrede Tenor Leuchter Curry Diskurs tenor"; + boost::algorithm::to_lower(seed_2); + res = crypto::ElectrumWords::words_to_bytes(seed_2, key_2, language_name_2); + ASSERT_EQ(true, res); + ASSERT_STREQ(language_name_2.c_str(), "Deutsch"); + // + ASSERT_TRUE(key_1 == key_2); +} + +TEST(mnemonics, partial_word_tolerance) +{ + bool res; + // + crypto::secret_key key_1; + std::string language_name_1; + const std::string seed_1 = "crim bam scamp gna limi woma wron tuit birth mundane donuts square cohesive dolphin titans narrate fue saved wrap aloof magic mirr toget upda wra"; + res = crypto::ElectrumWords::words_to_bytes(seed_1, key_1, language_name_1); + ASSERT_EQ(true, res); + ASSERT_STREQ(language_name_1.c_str(), "English"); +}
\ No newline at end of file diff --git a/tests/unit_tests/net.cpp b/tests/unit_tests/net.cpp new file mode 100644 index 000000000..a38ecfe81 --- /dev/null +++ b/tests/unit_tests/net.cpp @@ -0,0 +1,745 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <atomic> +#include <boost/archive/portable_binary_oarchive.hpp> +#include <boost/archive/portable_binary_iarchive.hpp> +#include <boost/asio/buffer.hpp> +#include <boost/asio/io_service.hpp> +#include <boost/asio/ip/tcp.hpp> +#include <boost/asio/read.hpp> +#include <boost/asio/write.hpp> +#include <boost/endian/conversion.hpp> +#include <boost/system/error_code.hpp> +#include <boost/thread/thread.hpp> +#include <cstring> +#include <functional> +#include <gtest/gtest.h> +#include <memory> + +#include "net/error.h" +#include "net/net_utils_base.h" +#include "net/socks.h" +#include "net/parse.h" +#include "net/tor_address.h" +#include "p2p/net_peerlist_boost_serialization.h" +#include "serialization/keyvalue_serialization.h" +#include "storages/portable_storage.h" + +namespace +{ + static constexpr const char v2_onion[] = + "xmrto2bturnore26.onion"; + static constexpr const char v3_onion[] = + "vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd.onion"; +} + +TEST(tor_address, constants) +{ + static_assert(!net::tor_address::is_local(), "bad is_local() response"); + static_assert(!net::tor_address::is_loopback(), "bad is_loopback() response"); + static_assert(net::tor_address::get_type_id() == epee::net_utils::address_type::tor, "bad get_type_id() response"); + + EXPECT_FALSE(net::tor_address::is_local()); + EXPECT_FALSE(net::tor_address::is_loopback()); + EXPECT_EQ(epee::net_utils::address_type::tor, net::tor_address::get_type_id()); + EXPECT_EQ(epee::net_utils::address_type::tor, net::tor_address::get_type_id()); +} + +TEST(tor_address, invalid) +{ + EXPECT_TRUE(net::tor_address::make("").has_error()); + EXPECT_TRUE(net::tor_address::make(":").has_error()); + EXPECT_TRUE(net::tor_address::make(".onion").has_error()); + EXPECT_TRUE(net::tor_address::make(".onion:").has_error()); + EXPECT_TRUE(net::tor_address::make(v2_onion + 1).has_error()); + EXPECT_TRUE(net::tor_address::make(v3_onion + 1).has_error()); + EXPECT_TRUE(net::tor_address::make(boost::string_ref{v2_onion, sizeof(v2_onion) - 2}).has_error()); + EXPECT_TRUE(net::tor_address::make(boost::string_ref{v3_onion, sizeof(v3_onion) - 2}).has_error()); + EXPECT_TRUE(net::tor_address::make(std::string{v2_onion} + ":-").has_error()); + EXPECT_TRUE(net::tor_address::make(std::string{v2_onion} + ":900a").has_error()); + EXPECT_TRUE(net::tor_address::make(std::string{v3_onion} + ":65536").has_error()); + EXPECT_TRUE(net::tor_address::make(std::string{v3_onion} + ":-1").has_error()); + + std::string onion{v3_onion}; + onion.at(10) = 1; + EXPECT_TRUE(net::tor_address::make(onion).has_error()); +} + +TEST(tor_address, unblockable_types) +{ + net::tor_address tor{}; + + ASSERT_NE(nullptr, tor.host_str()); + EXPECT_STREQ("<unknown tor host>", tor.host_str()); + EXPECT_STREQ("<unknown tor host>", tor.str().c_str()); + EXPECT_EQ(0u, tor.port()); + EXPECT_TRUE(tor.is_unknown()); + EXPECT_FALSE(tor.is_local()); + EXPECT_FALSE(tor.is_loopback()); + EXPECT_EQ(epee::net_utils::address_type::tor, tor.get_type_id()); + EXPECT_EQ(epee::net_utils::zone::tor, tor.get_zone()); + + tor = net::tor_address::unknown(); + ASSERT_NE(nullptr, tor.host_str()); + EXPECT_STREQ("<unknown tor host>", tor.host_str()); + EXPECT_STREQ("<unknown tor host>", tor.str().c_str()); + EXPECT_EQ(0u, tor.port()); + EXPECT_TRUE(tor.is_unknown()); + EXPECT_FALSE(tor.is_local()); + EXPECT_FALSE(tor.is_loopback()); + EXPECT_EQ(epee::net_utils::address_type::tor, tor.get_type_id()); + EXPECT_EQ(epee::net_utils::zone::tor, tor.get_zone()); + + EXPECT_EQ(net::tor_address{}, net::tor_address::unknown()); +} + +TEST(tor_address, valid) +{ + const auto address1 = net::tor_address::make(v3_onion); + + ASSERT_TRUE(address1.has_value()); + EXPECT_EQ(0u, address1->port()); + EXPECT_STREQ(v3_onion, address1->host_str()); + EXPECT_STREQ(v3_onion, address1->str().c_str()); + EXPECT_TRUE(address1->is_blockable()); + + net::tor_address address2{*address1}; + + EXPECT_EQ(0u, address2.port()); + EXPECT_STREQ(v3_onion, address2.host_str()); + EXPECT_STREQ(v3_onion, address2.str().c_str()); + EXPECT_TRUE(address2.is_blockable()); + EXPECT_TRUE(address2.equal(*address1)); + EXPECT_TRUE(address1->equal(address2)); + EXPECT_TRUE(address2 == *address1); + EXPECT_TRUE(*address1 == address2); + EXPECT_FALSE(address2 != *address1); + EXPECT_FALSE(*address1 != address2); + EXPECT_TRUE(address2.is_same_host(*address1)); + EXPECT_TRUE(address1->is_same_host(address2)); + EXPECT_FALSE(address2.less(*address1)); + EXPECT_FALSE(address1->less(address2)); + + address2 = MONERO_UNWRAP(net::tor_address::make(std::string{v2_onion} + ":6545")); + + EXPECT_EQ(6545, address2.port()); + EXPECT_STREQ(v2_onion, address2.host_str()); + EXPECT_EQ(std::string{v2_onion} + ":6545", address2.str().c_str()); + EXPECT_TRUE(address2.is_blockable()); + EXPECT_FALSE(address2.equal(*address1)); + EXPECT_FALSE(address1->equal(address2)); + EXPECT_FALSE(address2 == *address1); + EXPECT_FALSE(*address1 == address2); + EXPECT_TRUE(address2 != *address1); + EXPECT_TRUE(*address1 != address2); + EXPECT_FALSE(address2.is_same_host(*address1)); + EXPECT_FALSE(address1->is_same_host(address2)); + EXPECT_FALSE(address2.less(*address1)); + EXPECT_TRUE(address1->less(address2)); + + address2 = MONERO_UNWRAP(net::tor_address::make(std::string{v3_onion} + ":", 65535)); + + EXPECT_EQ(65535, address2.port()); + EXPECT_STREQ(v3_onion, address2.host_str()); + EXPECT_EQ(std::string{v3_onion} + ":65535", address2.str().c_str()); + EXPECT_TRUE(address2.is_blockable()); + EXPECT_FALSE(address2.equal(*address1)); + EXPECT_FALSE(address1->equal(address2)); + EXPECT_FALSE(address2 == *address1); + EXPECT_FALSE(*address1 == address2); + EXPECT_TRUE(address2 != *address1); + EXPECT_TRUE(*address1 != address2); + EXPECT_TRUE(address2.is_same_host(*address1)); + EXPECT_TRUE(address1->is_same_host(address2)); + EXPECT_FALSE(address2.less(*address1)); + EXPECT_TRUE(address1->less(address2)); +} + +TEST(tor_address, generic_network_address) +{ + const epee::net_utils::network_address tor1{MONERO_UNWRAP(net::tor_address::make(v3_onion, 8080))}; + const epee::net_utils::network_address tor2{MONERO_UNWRAP(net::tor_address::make(v3_onion, 8080))}; + const epee::net_utils::network_address ip{epee::net_utils::ipv4_network_address{100, 200}}; + + EXPECT_EQ(tor1, tor2); + EXPECT_NE(ip, tor1); + EXPECT_LT(ip, tor1); + + EXPECT_STREQ(v3_onion, tor1.host_str().c_str()); + EXPECT_EQ(std::string{v3_onion} + ":8080", tor1.str()); + EXPECT_EQ(epee::net_utils::address_type::tor, tor1.get_type_id()); + EXPECT_EQ(epee::net_utils::address_type::tor, tor2.get_type_id()); + EXPECT_EQ(epee::net_utils::address_type::ipv4, ip.get_type_id()); + EXPECT_EQ(epee::net_utils::zone::tor, tor1.get_zone()); + EXPECT_EQ(epee::net_utils::zone::tor, tor2.get_zone()); + EXPECT_EQ(epee::net_utils::zone::public_, ip.get_zone()); + EXPECT_TRUE(tor1.is_blockable()); + EXPECT_TRUE(tor2.is_blockable()); + EXPECT_TRUE(ip.is_blockable()); +} + +namespace +{ + struct test_command + { + net::tor_address tor; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(tor); + END_KV_SERIALIZE_MAP() + }; +} + +TEST(tor_address, epee_serializev_v2) +{ + std::string buffer{}; + { + test_command command{MONERO_UNWRAP(net::tor_address::make(v2_onion, 10))}; + EXPECT_FALSE(command.tor.is_unknown()); + EXPECT_NE(net::tor_address{}, command.tor); + EXPECT_STREQ(v2_onion, command.tor.host_str()); + EXPECT_EQ(10u, command.tor.port()); + + epee::serialization::portable_storage stg{}; + EXPECT_TRUE(command.store(stg)); + EXPECT_TRUE(stg.store_to_binary(buffer)); + } + + test_command command{}; + { + EXPECT_TRUE(command.tor.is_unknown()); + EXPECT_EQ(net::tor_address{}, command.tor); + EXPECT_STREQ(net::tor_address::unknown_str(), command.tor.host_str()); + EXPECT_EQ(0u, command.tor.port()); + + epee::serialization::portable_storage stg{}; + EXPECT_TRUE(stg.load_from_binary(buffer)); + EXPECT_TRUE(command.load(stg)); + } + EXPECT_FALSE(command.tor.is_unknown()); + EXPECT_NE(net::tor_address{}, command.tor); + EXPECT_STREQ(v2_onion, command.tor.host_str()); + EXPECT_EQ(10u, command.tor.port()); + + // make sure that exceeding max buffer doesn't destroy tor_address::_load + { + epee::serialization::portable_storage stg{}; + stg.load_from_binary(buffer); + + std::string host{}; + ASSERT_TRUE(stg.get_value("host", host, stg.open_section("tor", nullptr, false))); + EXPECT_EQ(std::strlen(v2_onion), host.size()); + + host.push_back('k'); + EXPECT_TRUE(stg.set_value("host", host, stg.open_section("tor", nullptr, false))); + EXPECT_TRUE(command.load(stg)); // poor error reporting from `KV_SERIALIZE` + } + + EXPECT_TRUE(command.tor.is_unknown()); + EXPECT_EQ(net::tor_address{}, command.tor); + EXPECT_STREQ(net::tor_address::unknown_str(), command.tor.host_str()); + EXPECT_EQ(0u, command.tor.port()); +} + +TEST(tor_address, epee_serializev_v3) +{ + std::string buffer{}; + { + test_command command{MONERO_UNWRAP(net::tor_address::make(v3_onion, 10))}; + EXPECT_FALSE(command.tor.is_unknown()); + EXPECT_NE(net::tor_address{}, command.tor); + EXPECT_STREQ(v3_onion, command.tor.host_str()); + EXPECT_EQ(10u, command.tor.port()); + + epee::serialization::portable_storage stg{}; + EXPECT_TRUE(command.store(stg)); + EXPECT_TRUE(stg.store_to_binary(buffer)); + } + + test_command command{}; + { + EXPECT_TRUE(command.tor.is_unknown()); + EXPECT_EQ(net::tor_address{}, command.tor); + EXPECT_STREQ(net::tor_address::unknown_str(), command.tor.host_str()); + EXPECT_EQ(0u, command.tor.port()); + + epee::serialization::portable_storage stg{}; + EXPECT_TRUE(stg.load_from_binary(buffer)); + EXPECT_TRUE(command.load(stg)); + } + EXPECT_FALSE(command.tor.is_unknown()); + EXPECT_NE(net::tor_address{}, command.tor); + EXPECT_STREQ(v3_onion, command.tor.host_str()); + EXPECT_EQ(10u, command.tor.port()); + + // make sure that exceeding max buffer doesn't destroy tor_address::_load + { + epee::serialization::portable_storage stg{}; + stg.load_from_binary(buffer); + + std::string host{}; + ASSERT_TRUE(stg.get_value("host", host, stg.open_section("tor", nullptr, false))); + EXPECT_EQ(std::strlen(v3_onion), host.size()); + + host.push_back('k'); + EXPECT_TRUE(stg.set_value("host", host, stg.open_section("tor", nullptr, false))); + EXPECT_TRUE(command.load(stg)); // poor error reporting from `KV_SERIALIZE` + } + + EXPECT_TRUE(command.tor.is_unknown()); + EXPECT_EQ(net::tor_address{}, command.tor); + EXPECT_STRNE(v3_onion, command.tor.host_str()); + EXPECT_EQ(0u, command.tor.port()); +} + +TEST(tor_address, epee_serialize_unknown) +{ + std::string buffer{}; + { + test_command command{net::tor_address::unknown()}; + EXPECT_TRUE(command.tor.is_unknown()); + EXPECT_EQ(net::tor_address{}, command.tor); + EXPECT_STREQ(net::tor_address::unknown_str(), command.tor.host_str()); + EXPECT_EQ(0u, command.tor.port()); + + epee::serialization::portable_storage stg{}; + EXPECT_TRUE(command.store(stg)); + EXPECT_TRUE(stg.store_to_binary(buffer)); + } + + test_command command{}; + { + EXPECT_TRUE(command.tor.is_unknown()); + EXPECT_EQ(net::tor_address{}, command.tor); + EXPECT_STRNE(v3_onion, command.tor.host_str()); + EXPECT_EQ(0u, command.tor.port()); + + epee::serialization::portable_storage stg{}; + EXPECT_TRUE(stg.load_from_binary(buffer)); + EXPECT_TRUE(command.load(stg)); + } + EXPECT_TRUE(command.tor.is_unknown()); + EXPECT_EQ(net::tor_address{}, command.tor); + EXPECT_STREQ(net::tor_address::unknown_str(), command.tor.host_str()); + EXPECT_EQ(0u, command.tor.port()); + + // make sure that exceeding max buffer doesn't destroy tor_address::_load + { + epee::serialization::portable_storage stg{}; + stg.load_from_binary(buffer); + + std::string host{}; + ASSERT_TRUE(stg.get_value("host", host, stg.open_section("tor", nullptr, false))); + EXPECT_EQ(std::strlen(net::tor_address::unknown_str()), host.size()); + + host.push_back('k'); + EXPECT_TRUE(stg.set_value("host", host, stg.open_section("tor", nullptr, false))); + EXPECT_TRUE(command.load(stg)); // poor error reporting from `KV_SERIALIZE` + } + + EXPECT_TRUE(command.tor.is_unknown()); + EXPECT_EQ(net::tor_address{}, command.tor); + EXPECT_STRNE(v3_onion, command.tor.host_str()); + EXPECT_EQ(0u, command.tor.port()); +} + +TEST(tor_address, boost_serialize_v2) +{ + std::string buffer{}; + { + const net::tor_address tor = MONERO_UNWRAP(net::tor_address::make(v2_onion, 10)); + EXPECT_FALSE(tor.is_unknown()); + EXPECT_NE(net::tor_address{}, tor); + EXPECT_STREQ(v2_onion, tor.host_str()); + EXPECT_EQ(10u, tor.port()); + + std::ostringstream stream{}; + { + boost::archive::portable_binary_oarchive archive{stream}; + archive << tor; + } + buffer = stream.str(); + } + + net::tor_address tor{}; + { + EXPECT_TRUE(tor.is_unknown()); + EXPECT_EQ(net::tor_address{}, tor); + EXPECT_STREQ(net::tor_address::unknown_str(), tor.host_str()); + EXPECT_EQ(0u, tor.port()); + + std::istringstream stream{buffer}; + boost::archive::portable_binary_iarchive archive{stream}; + archive >> tor; + } + EXPECT_FALSE(tor.is_unknown()); + EXPECT_NE(net::tor_address{}, tor); + EXPECT_STREQ(v2_onion, tor.host_str()); + EXPECT_EQ(10u, tor.port()); +} + +TEST(tor_address, boost_serialize_v3) +{ + std::string buffer{}; + { + const net::tor_address tor = MONERO_UNWRAP(net::tor_address::make(v3_onion, 10)); + EXPECT_FALSE(tor.is_unknown()); + EXPECT_NE(net::tor_address{}, tor); + EXPECT_STREQ(v3_onion, tor.host_str()); + EXPECT_EQ(10u, tor.port()); + + std::ostringstream stream{}; + { + boost::archive::portable_binary_oarchive archive{stream}; + archive << tor; + } + buffer = stream.str(); + } + + net::tor_address tor{}; + { + EXPECT_TRUE(tor.is_unknown()); + EXPECT_EQ(net::tor_address{}, tor); + EXPECT_STREQ(net::tor_address::unknown_str(), tor.host_str()); + EXPECT_EQ(0u, tor.port()); + + std::istringstream stream{buffer}; + boost::archive::portable_binary_iarchive archive{stream}; + archive >> tor; + } + EXPECT_FALSE(tor.is_unknown()); + EXPECT_NE(net::tor_address{}, tor); + EXPECT_STREQ(v3_onion, tor.host_str()); + EXPECT_EQ(10u, tor.port()); +} + +TEST(tor_address, boost_serialize_unknown) +{ + std::string buffer{}; + { + const net::tor_address tor{}; + EXPECT_TRUE(tor.is_unknown()); + EXPECT_EQ(net::tor_address::unknown(), tor); + EXPECT_STREQ(net::tor_address::unknown_str(), tor.host_str()); + EXPECT_EQ(0u, tor.port()); + + std::ostringstream stream{}; + { + boost::archive::portable_binary_oarchive archive{stream}; + archive << tor; + } + buffer = stream.str(); + } + + net::tor_address tor{}; + { + EXPECT_TRUE(tor.is_unknown()); + EXPECT_EQ(net::tor_address{}, tor); + EXPECT_STREQ(net::tor_address::unknown_str(), tor.host_str()); + EXPECT_EQ(0u, tor.port()); + + std::istringstream stream{buffer}; + boost::archive::portable_binary_iarchive archive{stream}; + archive >> tor; + } + EXPECT_TRUE(tor.is_unknown()); + EXPECT_EQ(net::tor_address::unknown(), tor); + EXPECT_STREQ(net::tor_address::unknown_str(), tor.host_str()); + EXPECT_EQ(0u, tor.port()); +} + +TEST(get_network_address, onion) +{ + expect<epee::net_utils::network_address> address = + net::get_network_address("onion", 0); + EXPECT_EQ(net::error::unsupported_address, address); + + address = net::get_network_address(".onion", 0); + EXPECT_EQ(net::error::invalid_tor_address, address); + + address = net::get_network_address(v3_onion, 1000); + ASSERT_TRUE(bool(address)); + EXPECT_EQ(epee::net_utils::address_type::tor, address->get_type_id()); + EXPECT_STREQ(v3_onion, address->host_str().c_str()); + EXPECT_EQ(std::string{v3_onion} + ":1000", address->str()); + + address = net::get_network_address(std::string{v3_onion} + ":2000", 1000); + ASSERT_TRUE(bool(address)); + EXPECT_EQ(epee::net_utils::address_type::tor, address->get_type_id()); + EXPECT_STREQ(v3_onion, address->host_str().c_str()); + EXPECT_EQ(std::string{v3_onion} + ":2000", address->str()); + + address = net::get_network_address(std::string{v3_onion} + ":65536", 1000); + EXPECT_EQ(net::error::invalid_port, address); +} + + +TEST(get_network_address, ipv4) +{ + expect<epee::net_utils::network_address> address = + net::get_network_address("0.0.0.", 0); + EXPECT_EQ(net::error::unsupported_address, address); + + address = net::get_network_address("0.0.0.257", 0); + EXPECT_EQ(net::error::unsupported_address, address); + + address = net::get_network_address("0.0.0.254", 1000); + ASSERT_TRUE(bool(address)); + EXPECT_EQ(epee::net_utils::address_type::ipv4, address->get_type_id()); + EXPECT_STREQ("0.0.0.254", address->host_str().c_str()); + EXPECT_STREQ("0.0.0.254:1000", address->str().c_str()); + + address = net::get_network_address("23.0.0.254:2000", 1000); + ASSERT_TRUE(bool(address)); + EXPECT_EQ(epee::net_utils::address_type::ipv4, address->get_type_id()); + EXPECT_STREQ("23.0.0.254", address->host_str().c_str()); + EXPECT_STREQ("23.0.0.254:2000", address->str().c_str()); +} + +namespace +{ + using stream_type = boost::asio::ip::tcp; + + struct io_thread + { + boost::asio::io_service io_service; + boost::asio::io_service::work work; + stream_type::socket server; + stream_type::acceptor acceptor; + boost::thread io; + std::atomic<bool> connected; + + io_thread() + : io_service(), + work(io_service), + server(io_service), + acceptor(io_service), + io([this] () { try { this->io_service.run(); } catch (const std::exception& e) { MERROR(e.what()); }}), + connected(false) + { + acceptor.open(boost::asio::ip::tcp::v4()); + acceptor.bind(stream_type::endpoint{boost::asio::ip::tcp::v4(), 0}); + acceptor.listen(); + acceptor.async_accept(server, [this] (boost::system::error_code error) { + this->connected = true; + if (error) + throw boost::system::system_error{error}; + }); + } + + ~io_thread() noexcept + { + io_service.stop(); + if (io.joinable()) + io.join(); + } + }; + + struct checked_client + { + std::atomic<bool>* called_; + bool expected_; + + void operator()(boost::system::error_code error, net::socks::client::stream_type::socket&&) const + { + EXPECT_EQ(expected_, bool(error)) << "Socks server: " << error.message(); + ASSERT_TRUE(called_ != nullptr); + (*called_) = true; + } + }; +} + +TEST(socks_client, unsupported_command) +{ + boost::asio::io_service io_service{}; + stream_type::socket client{io_service}; + + auto test_client = net::socks::make_connect_client( + std::move(client), net::socks::version::v4, std::bind( [] {} ) + ); + ASSERT_TRUE(bool(test_client)); + EXPECT_TRUE(test_client->buffer().empty()); + + EXPECT_FALSE(test_client->set_connect_command("example.com", 8080)); + EXPECT_TRUE(test_client->buffer().empty()); + + EXPECT_FALSE(test_client->set_resolve_command("example.com")); + EXPECT_TRUE(test_client->buffer().empty()); +} + +TEST(socks_client, no_command) +{ + boost::asio::io_service io_service{}; + stream_type::socket client{io_service}; + + auto test_client = net::socks::make_connect_client( + std::move(client), net::socks::version::v4a, std::bind( [] {} ) + ); + ASSERT_TRUE(bool(test_client)); + EXPECT_FALSE(net::socks::client::send(std::move(test_client))); +} + +TEST(socks_client, connect_command) +{ + io_thread io{}; + stream_type::socket client{io.io_service}; + + std::atomic<bool> called{false}; + auto test_client = net::socks::make_connect_client( + std::move(client), net::socks::version::v4a, checked_client{std::addressof(called), false} + ); + ASSERT_TRUE(bool(test_client)); + + ASSERT_TRUE(test_client->set_connect_command("example.com", 8080)); + EXPECT_FALSE(test_client->buffer().empty()); + ASSERT_TRUE(net::socks::client::connect_and_send(std::move(test_client), io.acceptor.local_endpoint())); + while (!io.connected); + + const std::uint8_t expected_bytes[] = { + 4, 1, 0x1f, 0x90, 0x00, 0x00, 0x00, 0x01, 0x00, + 'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm', 0x00 + }; + + std::uint8_t actual_bytes[sizeof(expected_bytes)]; + boost::asio::read(io.server, boost::asio::buffer(actual_bytes)); + EXPECT_TRUE(std::memcmp(expected_bytes, actual_bytes, sizeof(actual_bytes)) == 0); + + const std::uint8_t reply_bytes[] = {0, 90, 0, 0, 0, 0, 0, 0}; + boost::asio::write(io.server, boost::asio::buffer(reply_bytes)); + + // yikes! + while (!called); +} + +TEST(socks_client, connect_command_failed) +{ + io_thread io{}; + stream_type::socket client{io.io_service}; + + std::atomic<bool> called{false}; + auto test_client = net::socks::make_connect_client( + std::move(client), net::socks::version::v4, checked_client{std::addressof(called), true} + ); + ASSERT_TRUE(bool(test_client)); + + ASSERT_TRUE( + test_client->set_connect_command( + epee::net_utils::ipv4_network_address{boost::endian::native_to_big(std::uint32_t(5000)), 3000} + ) + ); + EXPECT_FALSE(test_client->buffer().empty()); + ASSERT_TRUE(net::socks::client::connect_and_send(std::move(test_client), io.acceptor.local_endpoint())); + while (!io.connected); + + const std::uint8_t expected_bytes[] = { + 4, 1, 0x0b, 0xb8, 0x00, 0x00, 0x13, 0x88, 0x00 + }; + + std::uint8_t actual_bytes[sizeof(expected_bytes)]; + boost::asio::read(io.server, boost::asio::buffer(actual_bytes)); + EXPECT_TRUE(std::memcmp(expected_bytes, actual_bytes, sizeof(actual_bytes)) == 0); + + const std::uint8_t reply_bytes[] = {0, 91, 0, 0, 0, 0, 0, 0}; + boost::asio::write(io.server, boost::asio::buffer(reply_bytes)); + + // yikes! + while (!called); +} + +TEST(socks_client, resolve_command) +{ + static std::uint8_t reply_bytes[] = {0, 90, 0, 0, 0xff, 0, 0xad, 0}; + + struct resolve_client : net::socks::client + { + std::atomic<unsigned> called_; + bool expected_; + + resolve_client(stream_type::socket&& proxy) + : net::socks::client(std::move(proxy), net::socks::version::v4a_tor) + , called_(0) + , expected_(false) + {}; + + virtual void done(boost::system::error_code error, std::shared_ptr<client> self) override + { + EXPECT_EQ(this, self.get()); + EXPECT_EQ(expected_, bool(error)) << "Resolve failure: " << error.message(); + + if (!error) + { + ASSERT_EQ(sizeof(reply_bytes), buffer().size()); + EXPECT_EQ(0u, std::memcmp(buffer().data(), reply_bytes, sizeof(reply_bytes))); + } + + ++called_; + } + }; + + io_thread io{}; + stream_type::socket client{io.io_service}; + + auto test_client = std::make_shared<resolve_client>(std::move(client)); + ASSERT_TRUE(bool(test_client)); + + ASSERT_TRUE(test_client->set_resolve_command("example.com")); + EXPECT_FALSE(test_client->buffer().empty()); + ASSERT_TRUE(net::socks::client::connect_and_send(test_client, io.acceptor.local_endpoint())); + while (!io.connected); + + const std::uint8_t expected_bytes[] = { + 4, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm', 0x00 + }; + + std::uint8_t actual_bytes[sizeof(expected_bytes)]; + boost::asio::read(io.server, boost::asio::buffer(actual_bytes)); + EXPECT_TRUE(std::memcmp(expected_bytes, actual_bytes, sizeof(actual_bytes)) == 0); + + boost::asio::write(io.server, boost::asio::buffer(reply_bytes)); + + // yikes! + while (test_client->called_ == 0); + + test_client->expected_ = true; + ASSERT_TRUE(test_client->set_resolve_command("example.com")); + EXPECT_FALSE(test_client->buffer().empty()); + ASSERT_TRUE(net::socks::client::send(test_client)); + + boost::asio::read(io.server, boost::asio::buffer(actual_bytes)); + EXPECT_TRUE(std::memcmp(expected_bytes, actual_bytes, sizeof(actual_bytes)) == 0); + + reply_bytes[1] = 91; + boost::asio::write(io.server, boost::asio::buffer(reply_bytes)); + + // yikes! + while (test_client->called_ == 1); +} + + diff --git a/tests/unit_tests/notify.cpp b/tests/unit_tests/notify.cpp index cd70b7739..ceeba8649 100644 --- a/tests/unit_tests/notify.cpp +++ b/tests/unit_tests/notify.cpp @@ -67,7 +67,7 @@ TEST(notify, works) + " " + name_template + " %s"; tools::Notify notify(spec.c_str()); - notify.notify("1111111111111111111111111111111111111111111111111111111111111111"); + notify.notify("%s", "1111111111111111111111111111111111111111111111111111111111111111", NULL); bool ok = false; for (int i = 0; i < 10; ++i) diff --git a/tests/unit_tests/output_distribution.cpp b/tests/unit_tests/output_distribution.cpp index 649752ac7..45f2c135b 100644 --- a/tests/unit_tests/output_distribution.cpp +++ b/tests/unit_tests/output_distribution.cpp @@ -33,7 +33,7 @@ #include "cryptonote_core/cryptonote_core.h" #include "cryptonote_core/tx_pool.h" #include "cryptonote_core/blockchain.h" -#include "testdb.h" +#include "blockchain_db/testdb.h" static const uint64_t test_distribution[32] = { 0, 0, 0, 0, 0, 1, 5, 1, 4, 0, 0, 1, 0, 1, 2, 3, 1, 0, 2, 0, 1, 3, 8, 1, 3, 5, 7, 1, 5, 0, 2, 3 @@ -43,7 +43,7 @@ static const size_t test_distribution_size = sizeof(test_distribution) / sizeof( namespace { -class TestDB: public BaseTestDB +class TestDB: public cryptonote::BaseTestDB { public: TestDB(size_t bc_height = test_distribution_size): blockchain_height(bc_height) { m_open = true; } diff --git a/tests/unit_tests/pruning.cpp b/tests/unit_tests/pruning.cpp new file mode 100644 index 000000000..83c35df68 --- /dev/null +++ b/tests/unit_tests/pruning.cpp @@ -0,0 +1,240 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "gtest/gtest.h" + +#include "misc_log_ex.h" +#include "cryptonote_config.h" +#include "common/pruning.h" + +#define ASSERT_EX(x) do { bool ex = false; try { x; } catch(...) { ex = true; } ASSERT_TRUE(ex); } while(0) + +TEST(pruning, parts) +{ + ASSERT_EQ(tools::get_pruning_stripe(tools::make_pruning_seed(3, 2)), 3); + ASSERT_EQ(tools::get_pruning_stripe(tools::make_pruning_seed(1, 2)), 1); + ASSERT_EQ(tools::get_pruning_stripe(tools::make_pruning_seed(7, 7)), 7); + + ASSERT_EQ(tools::get_pruning_log_stripes(tools::make_pruning_seed(1, 2)), 2); + ASSERT_EQ(tools::get_pruning_log_stripes(tools::make_pruning_seed(1, 0)), 0); + ASSERT_EQ(tools::get_pruning_log_stripes(tools::make_pruning_seed(1, 7)), 7); + ASSERT_EQ(tools::get_pruning_log_stripes(tools::make_pruning_seed(7, 7)), 7); + + for (uint32_t log_stripes = 1; log_stripes <= tools::PRUNING_SEED_LOG_STRIPES_MASK; ++log_stripes) + { + for (uint32_t stripe = 1; stripe <= (1 << log_stripes); ++stripe) + { + ASSERT_EQ(tools::get_pruning_log_stripes(tools::make_pruning_seed(stripe, log_stripes)), log_stripes); + ASSERT_EQ(tools::get_pruning_stripe(tools::make_pruning_seed(stripe, log_stripes)), stripe); + } + } +} + +TEST(pruning, out_of_range) +{ + ASSERT_EX(tools::make_pruning_seed(5, 2)); + ASSERT_EX(tools::make_pruning_seed(0, 2)); +} + +TEST(pruning, fits) +{ + const uint32_t log_stripes = 3; + const uint32_t num_stripes = 1 << log_stripes; + for (uint32_t stripe = 1; stripe <= num_stripes; ++stripe) + { + const uint32_t seed = tools::make_pruning_seed(stripe, log_stripes); + ASSERT_NE(seed, 0); + ASSERT_EQ(tools::get_pruning_log_stripes(seed), log_stripes); + ASSERT_EQ(tools::get_pruning_stripe(seed), stripe); + } +} + +TEST(pruning, tip) +{ + static constexpr uint64_t H = CRYPTONOTE_PRUNING_TIP_BLOCKS + 1000; + static_assert(H >= CRYPTONOTE_PRUNING_TIP_BLOCKS, "H must be >= CRYPTONOTE_PRUNING_TIP_BLOCKS"); + for (uint64_t h = H - CRYPTONOTE_PRUNING_TIP_BLOCKS; h < H; ++h) + { + uint32_t pruning_seed = tools::get_pruning_seed(h, H, CRYPTONOTE_PRUNING_LOG_STRIPES); + ASSERT_EQ(pruning_seed, 0); + for (pruning_seed = 0; pruning_seed <= (1 << CRYPTONOTE_PRUNING_LOG_STRIPES); ++pruning_seed) + ASSERT_TRUE(tools::has_unpruned_block(h, H, pruning_seed)); + } +} + +TEST(pruning, seed) +{ + const uint64_t SS = CRYPTONOTE_PRUNING_STRIPE_SIZE; + const uint64_t NS = 1 << CRYPTONOTE_PRUNING_LOG_STRIPES; + const uint64_t TB = NS * SS; + + for (uint64_t cycle = 0; cycle < 10; ++cycle) + { + const uint64_t O = TB * cycle; + ASSERT_EQ(tools::get_pruning_stripe(O + 0, 10000000, CRYPTONOTE_PRUNING_LOG_STRIPES), 1); + ASSERT_EQ(tools::get_pruning_stripe(O + 1, 10000000, CRYPTONOTE_PRUNING_LOG_STRIPES), 1); + ASSERT_EQ(tools::get_pruning_stripe(O + SS-1, 10000000, CRYPTONOTE_PRUNING_LOG_STRIPES), 1); + ASSERT_EQ(tools::get_pruning_stripe(O + SS, 10000000, CRYPTONOTE_PRUNING_LOG_STRIPES), 2); + ASSERT_EQ(tools::get_pruning_stripe(O + SS*2-1, 10000000, CRYPTONOTE_PRUNING_LOG_STRIPES), 2); + ASSERT_EQ(tools::get_pruning_stripe(O + SS*2, 10000000, CRYPTONOTE_PRUNING_LOG_STRIPES), 3); + ASSERT_EQ(tools::get_pruning_stripe(O + SS*NS-1, 10000000, CRYPTONOTE_PRUNING_LOG_STRIPES), NS); + ASSERT_EQ(tools::get_pruning_stripe(O + SS*NS, 10000000, CRYPTONOTE_PRUNING_LOG_STRIPES), 1); + } +} + +TEST(pruning, match) +{ + static constexpr uint64_t H = CRYPTONOTE_PRUNING_TIP_BLOCKS + 1000; + static_assert(H >= CRYPTONOTE_PRUNING_TIP_BLOCKS, "H must be >= CRYPTONOTE_PRUNING_TIP_BLOCKS"); + for (uint64_t h = 0; h < H - CRYPTONOTE_PRUNING_TIP_BLOCKS; ++h) + { + uint32_t pruning_seed = tools::get_pruning_seed(h, H, CRYPTONOTE_PRUNING_LOG_STRIPES); + uint32_t pruning_stripe = tools::get_pruning_stripe(pruning_seed); + ASSERT_TRUE(pruning_stripe > 0 && pruning_stripe <= (1 << CRYPTONOTE_PRUNING_LOG_STRIPES)); + for (uint32_t other_pruning_stripe = 1; other_pruning_stripe <= (1 << CRYPTONOTE_PRUNING_LOG_STRIPES); ++other_pruning_stripe) + { + uint32_t other_pruning_seed = tools::make_pruning_seed(other_pruning_stripe, CRYPTONOTE_PRUNING_LOG_STRIPES); + ASSERT_TRUE(tools::has_unpruned_block(h, H, other_pruning_seed) == (other_pruning_seed == pruning_seed)); + } + } +} + +TEST(pruning, stripe_size) +{ + static constexpr uint64_t H = CRYPTONOTE_PRUNING_TIP_BLOCKS + CRYPTONOTE_PRUNING_STRIPE_SIZE * (1 << CRYPTONOTE_PRUNING_LOG_STRIPES) + 1000; + static_assert(H >= CRYPTONOTE_PRUNING_TIP_BLOCKS + CRYPTONOTE_PRUNING_STRIPE_SIZE * (1 << CRYPTONOTE_PRUNING_LOG_STRIPES), "H must be >= that stuff in front"); + for (uint32_t pruning_stripe = 1; pruning_stripe <= (1 << CRYPTONOTE_PRUNING_LOG_STRIPES); ++pruning_stripe) + { + uint32_t pruning_seed = tools::make_pruning_seed(pruning_stripe, CRYPTONOTE_PRUNING_LOG_STRIPES); + unsigned int current_run = 0, best_run = 0; + for (uint64_t h = 0; h < H - CRYPTONOTE_PRUNING_TIP_BLOCKS; ++h) + { + if (tools::has_unpruned_block(h, H, pruning_seed)) + { + ++current_run; + } + else if (current_run) + { + ASSERT_EQ(current_run, CRYPTONOTE_PRUNING_STRIPE_SIZE); + best_run = std::max(best_run, current_run); + current_run = 0; + } + } + ASSERT_EQ(best_run, CRYPTONOTE_PRUNING_STRIPE_SIZE); + } +} + +TEST(pruning, next_unpruned) +{ + static_assert((1 << CRYPTONOTE_PRUNING_LOG_STRIPES) >= 4, "CRYPTONOTE_PRUNING_LOG_STRIPES too low"); + + const uint64_t SS = CRYPTONOTE_PRUNING_STRIPE_SIZE; + const uint64_t NS = 1 << CRYPTONOTE_PRUNING_LOG_STRIPES; + const uint64_t TB = NS * SS; + + for (uint64_t h = 0; h < 100; ++h) + ASSERT_EQ(tools::get_next_unpruned_block_height(h, 10000000, 0), h); + + const uint32_t seed1 = tools::make_pruning_seed(1, CRYPTONOTE_PRUNING_LOG_STRIPES); + const uint32_t seed2 = tools::make_pruning_seed(2, CRYPTONOTE_PRUNING_LOG_STRIPES); + const uint32_t seed3 = tools::make_pruning_seed(3, CRYPTONOTE_PRUNING_LOG_STRIPES); + const uint32_t seed4 = tools::make_pruning_seed(4, CRYPTONOTE_PRUNING_LOG_STRIPES); + const uint32_t seedNS = tools::make_pruning_seed(NS, CRYPTONOTE_PRUNING_LOG_STRIPES); + + ASSERT_EQ(tools::get_next_unpruned_block_height(0, 10000000, seed1), 0); + ASSERT_EQ(tools::get_next_unpruned_block_height(1, 10000000, seed1), 1); + ASSERT_EQ(tools::get_next_unpruned_block_height(SS-1, 10000000, seed1), SS-1); + ASSERT_EQ(tools::get_next_unpruned_block_height(SS, 10000000, seed1), TB); + ASSERT_EQ(tools::get_next_unpruned_block_height(TB, 10000000, seed1), TB); + ASSERT_EQ(tools::get_next_unpruned_block_height(TB-1, 10000000, seed1), TB); + + ASSERT_EQ(tools::get_next_unpruned_block_height(0, 10000000, seed2), SS); + ASSERT_EQ(tools::get_next_unpruned_block_height(1, 10000000, seed2), SS); + ASSERT_EQ(tools::get_next_unpruned_block_height(SS-1, 10000000, seed2), SS); + ASSERT_EQ(tools::get_next_unpruned_block_height(SS, 10000000, seed2), SS); + ASSERT_EQ(tools::get_next_unpruned_block_height(2*SS-1, 10000000, seed2), 2*SS-1); + ASSERT_EQ(tools::get_next_unpruned_block_height(2*SS, 10000000, seed2), TB+SS); + ASSERT_EQ(tools::get_next_unpruned_block_height(TB+2*SS,10000000, seed2), TB*2+SS); + + ASSERT_EQ(tools::get_next_unpruned_block_height(0, 10000000, seed3), SS*2); + ASSERT_EQ(tools::get_next_unpruned_block_height(SS, 10000000, seed3), SS*2); + ASSERT_EQ(tools::get_next_unpruned_block_height(2*SS, 10000000, seed3), SS*2); + ASSERT_EQ(tools::get_next_unpruned_block_height(3*SS-1, 10000000, seed3), SS*3-1); + ASSERT_EQ(tools::get_next_unpruned_block_height(3*SS, 10000000, seed3), TB+SS*2); + ASSERT_EQ(tools::get_next_unpruned_block_height(TB+3*SS,10000000, seed3), TB*2+SS*2); + + ASSERT_EQ(tools::get_next_unpruned_block_height(SS, 10000000, seed4), 3*SS); + ASSERT_EQ(tools::get_next_unpruned_block_height(4*SS-1, 10000000, seed4), 4*SS-1); + ASSERT_EQ(tools::get_next_unpruned_block_height(4*SS, 10000000, seed4), TB+3*SS); + ASSERT_EQ(tools::get_next_unpruned_block_height(TB+4*SS,10000000, seed4), TB*2+3*SS); + + ASSERT_EQ(tools::get_next_unpruned_block_height(SS, 10000000, seedNS), (NS-1)*SS); + ASSERT_EQ(tools::get_next_unpruned_block_height(NS*SS-1,10000000, seedNS), NS*SS-1); + ASSERT_EQ(tools::get_next_unpruned_block_height(NS*SS, 10000000, seedNS), TB+(NS-1)*SS); + ASSERT_EQ(tools::get_next_unpruned_block_height(TB+NS*SS, 10000000, seedNS), TB*2+(NS-1)*SS); +} + +TEST(pruning, next_pruned) +{ + static_assert((1 << CRYPTONOTE_PRUNING_LOG_STRIPES) >= 4, "CRYPTONOTE_PRUNING_LOG_STRIPES too low"); + + const uint64_t SS = CRYPTONOTE_PRUNING_STRIPE_SIZE; + const uint64_t NS = 1 << CRYPTONOTE_PRUNING_LOG_STRIPES; + const uint64_t TB = NS * SS; + + const uint32_t seed1 = tools::make_pruning_seed(1, CRYPTONOTE_PRUNING_LOG_STRIPES); + const uint32_t seed2 = tools::make_pruning_seed(2, CRYPTONOTE_PRUNING_LOG_STRIPES); + const uint32_t seedNS_1 = tools::make_pruning_seed(NS-1, CRYPTONOTE_PRUNING_LOG_STRIPES); + const uint32_t seedNS = tools::make_pruning_seed(NS, CRYPTONOTE_PRUNING_LOG_STRIPES); + + for (uint64_t h = 0; h < 100; ++h) + ASSERT_EQ(tools::get_next_pruned_block_height(h, 10000000, 0), 10000000); + for (uint64_t h = 10000000 - 1 - CRYPTONOTE_PRUNING_TIP_BLOCKS; h < 10000000; ++h) + ASSERT_EQ(tools::get_next_pruned_block_height(h, 10000000, 0), 10000000); + + ASSERT_EQ(tools::get_next_pruned_block_height(1, 10000000, seed1), SS); + ASSERT_EQ(tools::get_next_pruned_block_height(SS-1, 10000000, seed1), SS); + ASSERT_EQ(tools::get_next_pruned_block_height(SS, 10000000, seed1), SS); + ASSERT_EQ(tools::get_next_pruned_block_height(TB-1, 10000000, seed1), TB-1); + ASSERT_EQ(tools::get_next_pruned_block_height(TB, 10000000, seed1), TB+SS); + + ASSERT_EQ(tools::get_next_pruned_block_height(1, 10000000, seed2), 1); + ASSERT_EQ(tools::get_next_pruned_block_height(SS-1, 10000000, seed2), SS-1); + ASSERT_EQ(tools::get_next_pruned_block_height(SS, 10000000, seed2), 2*SS); + ASSERT_EQ(tools::get_next_pruned_block_height(TB-1, 10000000, seed2), TB-1); + + ASSERT_EQ(tools::get_next_pruned_block_height(1, 10000000, seedNS_1), 1); + ASSERT_EQ(tools::get_next_pruned_block_height(SS-1, 10000000, seedNS_1), SS-1); + ASSERT_EQ(tools::get_next_pruned_block_height(SS, 10000000, seedNS_1), SS); + ASSERT_EQ(tools::get_next_pruned_block_height(TB-1, 10000000, seedNS_1), TB-1); + + ASSERT_EQ(tools::get_next_pruned_block_height(1, 10000000, seedNS), 1); + ASSERT_EQ(tools::get_next_pruned_block_height(SS-1, 10000000, seedNS), SS-1); + ASSERT_EQ(tools::get_next_pruned_block_height(SS, 10000000, seedNS), SS); + ASSERT_EQ(tools::get_next_pruned_block_height(TB-1, 10000000, seedNS), TB); +} diff --git a/tests/unit_tests/ringct.cpp b/tests/unit_tests/ringct.cpp index ccef5f3e7..3f302cb83 100644 --- a/tests/unit_tests/ringct.cpp +++ b/tests/unit_tests/ringct.cpp @@ -171,8 +171,10 @@ TEST(ringct, range_proofs) skpkGen(Sk, Pk); destinations.push_back(Pk); + const rct::RCTConfig rct_config { RangeProofBorromean, 0 }; + //compute rct data with mixin 500 - rctSig s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, hw::get_device("default")); + rctSig s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, rct_config, hw::get_device("default")); //verify rct data ASSERT_TRUE(verRct(s)); @@ -189,7 +191,7 @@ TEST(ringct, range_proofs) //compute rct data with mixin 500 - s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, hw::get_device("default")); + s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, rct_config, hw::get_device("default")); //verify rct data ASSERT_FALSE(verRct(s)); @@ -235,8 +237,10 @@ TEST(ringct, range_proofs_with_fee) skpkGen(Sk, Pk); destinations.push_back(Pk); + const rct::RCTConfig rct_config { RangeProofBorromean, 0 }; + //compute rct data with mixin 500 - rctSig s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, hw::get_device("default")); + rctSig s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, rct_config, hw::get_device("default")); //verify rct data ASSERT_TRUE(verRct(s)); @@ -253,7 +257,7 @@ TEST(ringct, range_proofs_with_fee) //compute rct data with mixin 500 - s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, hw::get_device("default")); + s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, rct_config, hw::get_device("default")); //verify rct data ASSERT_FALSE(verRct(s)); @@ -311,7 +315,8 @@ TEST(ringct, simple) //compute sig with mixin 2 xmr_amount txnfee = 1; - rctSig s = genRctSimple(message, sc, pc, destinations,inamounts, outamounts, amount_keys, NULL, NULL, txnfee, 2, hw::get_device("default")); + const rct::RCTConfig rct_config { RangeProofBorromean, 0 }; + rctSig s = genRctSimple(message, sc, pc, destinations,inamounts, outamounts, amount_keys, NULL, NULL, txnfee, 2, rct_config, hw::get_device("default")); //verify ring ct signature ASSERT_TRUE(verRctSimple(s)); @@ -345,7 +350,8 @@ static rct::rctSig make_sample_rct_sig(int n_inputs, const uint64_t input_amount } } - return genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, hw::get_device("default")); + const rct::RCTConfig rct_config { RangeProofBorromean, 0 }; + return genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, rct_config, hw::get_device("default")); } static rct::rctSig make_sample_simple_rct_sig(int n_inputs, const uint64_t input_amounts[], int n_outputs, const uint64_t output_amounts[], uint64_t fee) @@ -371,7 +377,8 @@ static rct::rctSig make_sample_simple_rct_sig(int n_inputs, const uint64_t input destinations.push_back(Pk); } - return genRctSimple(rct::zero(), sc, pc, destinations, inamounts, outamounts, amount_keys, NULL, NULL, fee, 3, hw::get_device("default")); + const rct::RCTConfig rct_config { RangeProofBorromean, 0 }; + return genRctSimple(rct::zero(), sc, pc, destinations, inamounts, outamounts, amount_keys, NULL, NULL, fee, 3, rct_config, hw::get_device("default")); } static bool range_proof_test(bool expected_valid, @@ -824,27 +831,6 @@ TEST(ringct, HPow2) static const xmr_amount test_amounts[]={0, 1, 2, 3, 4, 5, 10000, 10000000000000000000ull, 10203040506070809000ull, 123456789123456789}; -TEST(ringct, ecdh_roundtrip) -{ - key k; - ecdhTuple t0, t1; - - for (auto amount: test_amounts) { - skGen(k); - - t0.mask = skGen(); - t0.amount = d2h(amount); - - t1 = t0; - ecdhEncode(t1, k); - ecdhDecode(t1, k); - ASSERT_TRUE(t0.mask == t1.mask); - ASSERT_TRUE(equalKeys(t0.mask, t1.mask)); - ASSERT_TRUE(t0.amount == t1.amount); - ASSERT_TRUE(equalKeys(t0.amount, t1.amount)); - } -} - TEST(ringct, d2h) { key k, P1; diff --git a/tests/unit_tests/serialization.cpp b/tests/unit_tests/serialization.cpp index b4517af2f..343a11c37 100644 --- a/tests/unit_tests/serialization.cpp +++ b/tests/unit_tests/serialization.cpp @@ -550,12 +550,10 @@ TEST(Serialization, serializes_ringct_types) ecdh0.mask = rct::skGen(); ecdh0.amount = rct::skGen(); - ecdh0.senderPk = rct::skGen(); ASSERT_TRUE(serialization::dump_binary(ecdh0, blob)); ASSERT_TRUE(serialization::parse_binary(blob, ecdh1)); ASSERT_TRUE(!memcmp(&ecdh0.mask, &ecdh1.mask, sizeof(ecdh0.mask))); ASSERT_TRUE(!memcmp(&ecdh0.amount, &ecdh1.amount, sizeof(ecdh0.amount))); - // senderPk is not serialized for (size_t n = 0; n < 64; ++n) { @@ -591,7 +589,8 @@ TEST(Serialization, serializes_ringct_types) rct::skpkGen(Sk, Pk); destinations.push_back(Pk); //compute rct data with mixin 500 - s0 = rct::genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, hw::get_device("default")); + const rct::RCTConfig rct_config{ rct::RangeProofPaddedBulletproof, 0 }; + s0 = rct::genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, rct_config, hw::get_device("default")); mg0 = s0.p.MGs[0]; ASSERT_TRUE(serialization::dump_binary(mg0, blob)); diff --git a/tests/unit_tests/test_peerlist.cpp b/tests/unit_tests/test_peerlist.cpp index f638c6251..03aa48ea0 100644 --- a/tests/unit_tests/test_peerlist.cpp +++ b/tests/unit_tests/test_peerlist.cpp @@ -37,7 +37,7 @@ TEST(peer_list, peer_list_general) { nodetool::peerlist_manager plm; - plm.init(false); + plm.init(nodetool::peerlist_types{}, false); #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);} @@ -77,9 +77,180 @@ TEST(peer_list, merge_peer_lists) //([^ \t]*)\t([^ \t]*):([^ \t]*) \tlast_seen: d(\d+)\.h(\d+)\.m(\d+)\.s(\d+)\n //ADD_NODE_TO_PL("\2", \3, 0x\1, (1353346618 -(\4*60*60*24+\5*60*60+\6*60+\7 )));\n nodetool::peerlist_manager plm; - plm.init(false); + plm.init(nodetool::peerlist_types{}, false); std::vector<nodetool::peerlist_entry> outer_bs; #define ADD_NODE_TO_PL(ip_, port_, id_, timestamp_) { nodetool::peerlist_entry ple; epee::string_tools::get_ip_int32_from_string(ple.adr.ip, ip_); ple.last_seen = timestamp_; ple.adr.port = port_; ple.id = id_;outer_bs.push_back(ple);} +} + +namespace +{ + bool check_empty(nodetool::peerlist_storage& peers, std::initializer_list<epee::net_utils::zone> zones) + { + bool pass = false; + for (const epee::net_utils::zone zone : zones) + { + const nodetool::peerlist_types types{peers.take_zone(zone)}; + EXPECT_TRUE(types.white.empty()); + EXPECT_TRUE(types.gray.empty()); + EXPECT_TRUE(types.anchor.empty()); + pass = (types.white.empty() && types.gray.empty() && types.anchor.empty()); + } + return pass; + } +} + +TEST(peerlist_storage, store) +{ + + using address_type = epee::net_utils::address_type; + using zone = epee::net_utils::zone; + + nodetool::peerlist_storage peers{}; + EXPECT_TRUE(check_empty(peers, {zone::invalid, zone::public_, zone::tor, zone::i2p})); + + std::string buffer{}; + { + nodetool::peerlist_types types{}; + types.white.push_back({epee::net_utils::ipv4_network_address{1000, 10}, 44, 55}); + types.white.push_back({net::tor_address::unknown(), 64, 75}); + types.gray.push_back({net::tor_address::unknown(), 99, 88}); + types.gray.push_back({epee::net_utils::ipv4_network_address{2000, 20}, 84, 45}); + types.anchor.push_back({epee::net_utils::ipv4_network_address{999, 654}, 444, 555}); + types.anchor.push_back({net::tor_address::unknown(), 14, 33}); + types.anchor.push_back({net::tor_address::unknown(), 24, 22}); + + std::ostringstream stream{}; + EXPECT_TRUE(peers.store(stream, types)); + buffer = stream.str(); + } + EXPECT_TRUE(check_empty(peers, {zone::invalid, zone::public_, zone::tor, zone::i2p})); + { + std::istringstream stream{buffer}; + boost::optional<nodetool::peerlist_storage> read_peers = + nodetool::peerlist_storage::open(stream, true); + ASSERT_TRUE(bool(read_peers)); + peers = std::move(*read_peers); + } + EXPECT_TRUE(check_empty(peers, {zone::invalid, zone::i2p})); + + nodetool::peerlist_types types = peers.take_zone(zone::public_); + EXPECT_TRUE(check_empty(peers, {zone::invalid, zone::public_, zone::i2p})); + + ASSERT_EQ(1u, types.white.size()); + ASSERT_EQ(address_type::ipv4, types.white[0].adr.get_type_id()); + EXPECT_EQ(1000u, types.white[0].adr.template as<epee::net_utils::ipv4_network_address>().ip()); + EXPECT_EQ(10u, types.white[0].adr.template as<epee::net_utils::ipv4_network_address>().port()); + EXPECT_EQ(44u, types.white[0].id); + EXPECT_EQ(55u, types.white[0].last_seen); + + ASSERT_EQ(1u, types.gray.size()); + ASSERT_EQ(address_type::ipv4, types.gray[0].adr.get_type_id()); + EXPECT_EQ(2000u, types.gray[0].adr.template as<epee::net_utils::ipv4_network_address>().ip()); + EXPECT_EQ(20u, types.gray[0].adr.template as<epee::net_utils::ipv4_network_address>().port()); + EXPECT_EQ(84u, types.gray[0].id); + EXPECT_EQ(45u, types.gray[0].last_seen); + + ASSERT_EQ(1u, types.anchor.size()); + ASSERT_EQ(address_type::ipv4, types.anchor[0].adr.get_type_id()); + EXPECT_EQ(999u, types.anchor[0].adr.template as<epee::net_utils::ipv4_network_address>().ip()); + EXPECT_EQ(654u, types.anchor[0].adr.template as<epee::net_utils::ipv4_network_address>().port()); + EXPECT_EQ(444u, types.anchor[0].id); + EXPECT_EQ(555u, types.anchor[0].first_seen); + { + std::ostringstream stream{}; + EXPECT_TRUE(peers.store(stream, types)); + buffer = stream.str(); + } + EXPECT_TRUE(check_empty(peers, {zone::invalid, zone::public_, zone::i2p})); + + types = peers.take_zone(zone::tor); + EXPECT_TRUE(check_empty(peers, {zone::invalid, zone::public_, zone::i2p, zone::tor})); + + ASSERT_EQ(1u, types.white.size()); + ASSERT_EQ(address_type::tor, types.white[0].adr.get_type_id()); + EXPECT_STREQ(net::tor_address::unknown_str(), types.white[0].adr.template as<net::tor_address>().host_str()); + EXPECT_EQ(0u, types.white[0].adr.template as<net::tor_address>().port()); + EXPECT_EQ(64u, types.white[0].id); + EXPECT_EQ(75u, types.white[0].last_seen); + + ASSERT_EQ(1u, types.gray.size()); + ASSERT_EQ(address_type::tor, types.gray[0].adr.get_type_id()); + EXPECT_STREQ(net::tor_address::unknown_str(), types.gray[0].adr.template as<net::tor_address>().host_str()); + EXPECT_EQ(0u, types.gray[0].adr.template as<net::tor_address>().port()); + EXPECT_EQ(99u, types.gray[0].id); + EXPECT_EQ(88u, types.gray[0].last_seen); + + ASSERT_EQ(2u, types.anchor.size()); + ASSERT_EQ(address_type::tor, types.anchor[0].adr.get_type_id()); + EXPECT_STREQ(net::tor_address::unknown_str(), types.anchor[0].adr.template as<net::tor_address>().host_str()); + EXPECT_EQ(0u, types.anchor[0].adr.template as<net::tor_address>().port()); + EXPECT_EQ(14u, types.anchor[0].id); + EXPECT_EQ(33u, types.anchor[0].first_seen); + ASSERT_EQ(address_type::tor, types.anchor[1].adr.get_type_id()); + EXPECT_STREQ(net::tor_address::unknown_str(), types.anchor[1].adr.template as<net::tor_address>().host_str()); + EXPECT_EQ(0u, types.anchor[1].adr.template as<net::tor_address>().port()); + EXPECT_EQ(24u, types.anchor[1].id); + EXPECT_EQ(22u, types.anchor[1].first_seen); + + { + std::istringstream stream{buffer}; + boost::optional<nodetool::peerlist_storage> read_peers = + nodetool::peerlist_storage::open(stream, true); + ASSERT_TRUE(bool(read_peers)); + peers = std::move(*read_peers); + } + EXPECT_TRUE(check_empty(peers, {zone::invalid, zone::i2p})); + + types = peers.take_zone(zone::public_); + EXPECT_TRUE(check_empty(peers, {zone::invalid, zone::public_, zone::i2p})); + + ASSERT_EQ(1u, types.white.size()); + ASSERT_EQ(address_type::ipv4, types.white[0].adr.get_type_id()); + EXPECT_EQ(1000u, types.white[0].adr.template as<epee::net_utils::ipv4_network_address>().ip()); + EXPECT_EQ(10u, types.white[0].adr.template as<epee::net_utils::ipv4_network_address>().port()); + EXPECT_EQ(44u, types.white[0].id); + EXPECT_EQ(55u, types.white[0].last_seen); + + ASSERT_EQ(1u, types.gray.size()); + ASSERT_EQ(address_type::ipv4, types.gray[0].adr.get_type_id()); + EXPECT_EQ(2000u, types.gray[0].adr.template as<epee::net_utils::ipv4_network_address>().ip()); + EXPECT_EQ(20u, types.gray[0].adr.template as<epee::net_utils::ipv4_network_address>().port()); + EXPECT_EQ(84u, types.gray[0].id); + EXPECT_EQ(45u, types.gray[0].last_seen); + + ASSERT_EQ(1u, types.anchor.size()); + ASSERT_EQ(address_type::ipv4, types.anchor[0].adr.get_type_id()); + EXPECT_EQ(999u, types.anchor[0].adr.template as<epee::net_utils::ipv4_network_address>().ip()); + EXPECT_EQ(654u, types.anchor[0].adr.template as<epee::net_utils::ipv4_network_address>().port()); + EXPECT_EQ(444u, types.anchor[0].id); + EXPECT_EQ(555u, types.anchor[0].first_seen); + + types = peers.take_zone(zone::tor); + EXPECT_TRUE(check_empty(peers, {zone::invalid, zone::public_, zone::i2p, zone::tor})); + + ASSERT_EQ(1u, types.white.size()); + ASSERT_EQ(address_type::tor, types.white[0].adr.get_type_id()); + EXPECT_STREQ(net::tor_address::unknown_str(), types.white[0].adr.template as<net::tor_address>().host_str()); + EXPECT_EQ(0u, types.white[0].adr.template as<net::tor_address>().port()); + EXPECT_EQ(64u, types.white[0].id); + EXPECT_EQ(75u, types.white[0].last_seen); + ASSERT_EQ(1u, types.gray.size()); + ASSERT_EQ(address_type::tor, types.gray[0].adr.get_type_id()); + EXPECT_STREQ(net::tor_address::unknown_str(), types.gray[0].adr.template as<net::tor_address>().host_str()); + EXPECT_EQ(0u, types.gray[0].adr.template as<net::tor_address>().port()); + EXPECT_EQ(99u, types.gray[0].id); + EXPECT_EQ(88u, types.gray[0].last_seen); + ASSERT_EQ(2u, types.anchor.size()); + ASSERT_EQ(address_type::tor, types.anchor[0].adr.get_type_id()); + EXPECT_STREQ(net::tor_address::unknown_str(), types.anchor[0].adr.template as<net::tor_address>().host_str()); + EXPECT_EQ(0u, types.anchor[0].adr.template as<net::tor_address>().port()); + EXPECT_EQ(14u, types.anchor[0].id); + EXPECT_EQ(33u, types.anchor[0].first_seen); + ASSERT_EQ(address_type::tor, types.anchor[1].adr.get_type_id()); + EXPECT_STREQ(net::tor_address::unknown_str(), types.anchor[1].adr.template as<net::tor_address>().host_str()); + EXPECT_EQ(0u, types.anchor[1].adr.template as<net::tor_address>().port()); + EXPECT_EQ(24u, types.anchor[1].id); + EXPECT_EQ(22u, types.anchor[1].first_seen); } diff --git a/translations/monero.ts b/translations/monero.ts index 23eadff84..45d85abbd 100644 --- a/translations/monero.ts +++ b/translations/monero.ts @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> -<TS version="2.1"> +<TS version="2.0"> <context> <name>Monero::AddressBookImpl</name> <message> @@ -134,383 +134,384 @@ <context> <name>Monero::WalletImpl</name> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1354"/> + <location filename="../src/wallet/api/wallet.cpp" line="1383"/> <source>payment id has invalid format, expected 16 or 64 character hex string: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1363"/> + <location filename="../src/wallet/api/wallet.cpp" line="1392"/> <source>Failed to add short payment id: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1399"/> - <location filename="../src/wallet/api/wallet.cpp" line="1481"/> + <location filename="../src/wallet/api/wallet.cpp" line="1428"/> + <location filename="../src/wallet/api/wallet.cpp" line="1510"/> <source>daemon is busy. Please try again later.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1401"/> - <location filename="../src/wallet/api/wallet.cpp" line="1483"/> + <location filename="../src/wallet/api/wallet.cpp" line="1430"/> + <location filename="../src/wallet/api/wallet.cpp" line="1512"/> <source>no connection to daemon. Please make sure daemon is running.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1403"/> - <location filename="../src/wallet/api/wallet.cpp" line="1485"/> + <location filename="../src/wallet/api/wallet.cpp" line="1432"/> + <location filename="../src/wallet/api/wallet.cpp" line="1514"/> <source>RPC error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1405"/> + <location filename="../src/wallet/api/wallet.cpp" line="1434"/> <source>failed to get outputs to mix: %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1431"/> - <location filename="../src/wallet/api/wallet.cpp" line="1516"/> + <location filename="../src/wallet/api/wallet.cpp" line="1460"/> + <location filename="../src/wallet/api/wallet.cpp" line="1545"/> <source>not enough outputs for specified ring size</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1433"/> - <location filename="../src/wallet/api/wallet.cpp" line="1518"/> + <location filename="../src/wallet/api/wallet.cpp" line="1462"/> + <location filename="../src/wallet/api/wallet.cpp" line="1547"/> <source>found outputs to use</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1435"/> + <location filename="../src/wallet/api/wallet.cpp" line="1464"/> <source>Please sweep unmixable outputs.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1409"/> - <location filename="../src/wallet/api/wallet.cpp" line="1492"/> + <location filename="../src/wallet/api/wallet.cpp" line="1438"/> + <location filename="../src/wallet/api/wallet.cpp" line="1521"/> <source>not enough money to transfer, available only %s, sent amount %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="540"/> + <location filename="../src/wallet/api/wallet.cpp" line="541"/> <source>failed to parse address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="551"/> + <location filename="../src/wallet/api/wallet.cpp" line="552"/> <source>failed to parse secret spend key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="566"/> + <location filename="../src/wallet/api/wallet.cpp" line="567"/> <source>Neither view key nor spend key supplied, cancelled</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="574"/> + <location filename="../src/wallet/api/wallet.cpp" line="575"/> <source>failed to parse secret view key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="583"/> + <location filename="../src/wallet/api/wallet.cpp" line="584"/> <source>failed to verify secret spend key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="587"/> + <location filename="../src/wallet/api/wallet.cpp" line="588"/> <source>spend key does not match address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="593"/> + <location filename="../src/wallet/api/wallet.cpp" line="594"/> <source>failed to verify secret view key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="597"/> + <location filename="../src/wallet/api/wallet.cpp" line="598"/> <source>view key does not match address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="620"/> - <location filename="../src/wallet/api/wallet.cpp" line="637"/> + <location filename="../src/wallet/api/wallet.cpp" line="621"/> + <location filename="../src/wallet/api/wallet.cpp" line="638"/> <source>failed to generate new wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="685"/> + <location filename="../src/wallet/api/wallet.cpp" line="686"/> <source>Electrum seed is empty</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="694"/> + <location filename="../src/wallet/api/wallet.cpp" line="695"/> <source>Electrum-style word list failed verification</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="884"/> + <location filename="../src/wallet/api/wallet.cpp" line="885"/> <source>Failed to send import wallet request</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1034"/> + <location filename="../src/wallet/api/wallet.cpp" line="1049"/> <source>Failed to load unsigned transactions</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1053"/> + <location filename="../src/wallet/api/wallet.cpp" line="1068"/> <source>Failed to load transaction from file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1069"/> + <location filename="../src/wallet/api/wallet.cpp" line="1084"/> <source>Wallet is view only</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1077"/> + <location filename="../src/wallet/api/wallet.cpp" line="1092"/> <source>failed to save file </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1093"/> + <location filename="../src/wallet/api/wallet.cpp" line="1108"/> <source>Key images can only be imported with a trusted daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1106"/> + <location filename="../src/wallet/api/wallet.cpp" line="1121"/> <source>Failed to import key images: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1138"/> + <location filename="../src/wallet/api/wallet.cpp" line="1153"/> <source>Failed to get subaddress label: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1151"/> + <location filename="../src/wallet/api/wallet.cpp" line="1166"/> <source>Failed to set subaddress label: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1168"/> + <location filename="../src/wallet/api/wallet.cpp" line="1183"/> <source>Failed to get multisig info: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1185"/> + <location filename="../src/wallet/api/wallet.cpp" line="1200"/> + <location filename="../src/wallet/api/wallet.cpp" line="1214"/> <source>Failed to make multisig: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1200"/> + <location filename="../src/wallet/api/wallet.cpp" line="1229"/> <source>Failed to finalize multisig wallet creation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1203"/> + <location filename="../src/wallet/api/wallet.cpp" line="1232"/> <source>Failed to finalize multisig wallet creation: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1219"/> + <location filename="../src/wallet/api/wallet.cpp" line="1248"/> <source>Failed to export multisig images: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1237"/> + <location filename="../src/wallet/api/wallet.cpp" line="1266"/> <source>Failed to parse imported multisig images</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1247"/> + <location filename="../src/wallet/api/wallet.cpp" line="1276"/> <source>Failed to import multisig images: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1261"/> + <location filename="../src/wallet/api/wallet.cpp" line="1290"/> <source>Failed to check for partial multisig key images: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1289"/> + <location filename="../src/wallet/api/wallet.cpp" line="1318"/> <source>Failed to restore multisig transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1329"/> + <location filename="../src/wallet/api/wallet.cpp" line="1358"/> <source>Invalid destination address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="2143"/> + <location filename="../src/wallet/api/wallet.cpp" line="2179"/> <source>Invalid output: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1416"/> - <location filename="../src/wallet/api/wallet.cpp" line="1500"/> + <location filename="../src/wallet/api/wallet.cpp" line="2186"/> + <source>Failed to mark outputs as spent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2208"/> + <source>Failed to mark output as spent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2230"/> + <source>Failed to mark output as unspent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1445"/> + <location filename="../src/wallet/api/wallet.cpp" line="1529"/> <source>not enough money to transfer, overall balance only %s, sent amount %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1423"/> - <location filename="../src/wallet/api/wallet.cpp" line="1508"/> + <location filename="../src/wallet/api/wallet.cpp" line="1452"/> + <location filename="../src/wallet/api/wallet.cpp" line="1537"/> <source>not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1433"/> - <location filename="../src/wallet/api/wallet.cpp" line="1518"/> + <location filename="../src/wallet/api/wallet.cpp" line="1462"/> + <location filename="../src/wallet/api/wallet.cpp" line="1547"/> <source>output amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1438"/> - <location filename="../src/wallet/api/wallet.cpp" line="1522"/> + <location filename="../src/wallet/api/wallet.cpp" line="1467"/> + <location filename="../src/wallet/api/wallet.cpp" line="1551"/> <source>transaction was not constructed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1441"/> - <location filename="../src/wallet/api/wallet.cpp" line="1525"/> + <location filename="../src/wallet/api/wallet.cpp" line="1470"/> + <location filename="../src/wallet/api/wallet.cpp" line="1554"/> <source>transaction %s was rejected by daemon with status: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1446"/> - <location filename="../src/wallet/api/wallet.cpp" line="1530"/> + <location filename="../src/wallet/api/wallet.cpp" line="1475"/> + <location filename="../src/wallet/api/wallet.cpp" line="1559"/> <source>one of destinations is zero</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1448"/> - <location filename="../src/wallet/api/wallet.cpp" line="1532"/> + <location filename="../src/wallet/api/wallet.cpp" line="1477"/> + <location filename="../src/wallet/api/wallet.cpp" line="1561"/> <source>failed to find a suitable way to split transactions</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1450"/> - <location filename="../src/wallet/api/wallet.cpp" line="1534"/> + <location filename="../src/wallet/api/wallet.cpp" line="1479"/> + <location filename="../src/wallet/api/wallet.cpp" line="1563"/> <source>unknown transfer error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1452"/> - <location filename="../src/wallet/api/wallet.cpp" line="1536"/> + <location filename="../src/wallet/api/wallet.cpp" line="1481"/> + <location filename="../src/wallet/api/wallet.cpp" line="1565"/> <source>internal error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1454"/> - <location filename="../src/wallet/api/wallet.cpp" line="1538"/> + <location filename="../src/wallet/api/wallet.cpp" line="1483"/> + <location filename="../src/wallet/api/wallet.cpp" line="1567"/> <source>unexpected error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1456"/> - <location filename="../src/wallet/api/wallet.cpp" line="1540"/> + <location filename="../src/wallet/api/wallet.cpp" line="1485"/> + <location filename="../src/wallet/api/wallet.cpp" line="1569"/> <source>unknown error</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1487"/> + <location filename="../src/wallet/api/wallet.cpp" line="1516"/> <source>failed to get outputs to mix</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1615"/> - <location filename="../src/wallet/api/wallet.cpp" line="1642"/> - <location filename="../src/wallet/api/wallet.cpp" line="1690"/> - <location filename="../src/wallet/api/wallet.cpp" line="1718"/> - <location filename="../src/wallet/api/wallet.cpp" line="1746"/> - <location filename="../src/wallet/api/wallet.cpp" line="1767"/> - <location filename="../src/wallet/api/wallet.cpp" line="2222"/> + <location filename="../src/wallet/api/wallet.cpp" line="1644"/> + <location filename="../src/wallet/api/wallet.cpp" line="1671"/> + <location filename="../src/wallet/api/wallet.cpp" line="1719"/> + <location filename="../src/wallet/api/wallet.cpp" line="1747"/> + <location filename="../src/wallet/api/wallet.cpp" line="1775"/> + <location filename="../src/wallet/api/wallet.cpp" line="1796"/> + <location filename="../src/wallet/api/wallet.cpp" line="2258"/> <source>Failed to parse txid</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1632"/> + <location filename="../src/wallet/api/wallet.cpp" line="1661"/> <source>no tx keys found for this txid</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1650"/> - <location filename="../src/wallet/api/wallet.cpp" line="1659"/> + <location filename="../src/wallet/api/wallet.cpp" line="1679"/> + <location filename="../src/wallet/api/wallet.cpp" line="1688"/> <source>Failed to parse tx key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1668"/> <location filename="../src/wallet/api/wallet.cpp" line="1697"/> - <location filename="../src/wallet/api/wallet.cpp" line="1725"/> - <location filename="../src/wallet/api/wallet.cpp" line="1806"/> + <location filename="../src/wallet/api/wallet.cpp" line="1726"/> + <location filename="../src/wallet/api/wallet.cpp" line="1754"/> + <location filename="../src/wallet/api/wallet.cpp" line="1835"/> <source>Failed to parse address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1811"/> + <location filename="../src/wallet/api/wallet.cpp" line="1840"/> <source>Address must not be a subaddress</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1851"/> + <location filename="../src/wallet/api/wallet.cpp" line="1880"/> <source>The wallet must be in multisig ready state</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1873"/> + <location filename="../src/wallet/api/wallet.cpp" line="1902"/> <source>Given string is not a key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="2094"/> + <location filename="../src/wallet/api/wallet.cpp" line="2130"/> <source>Rescan spent can only be used with a trusted daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="2150"/> - <source>Failed to set blackballed outputs</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/wallet/api/wallet.cpp" line="2161"/> - <location filename="../src/wallet/api/wallet.cpp" line="2183"/> + <location filename="../src/wallet/api/wallet.cpp" line="2197"/> + <location filename="../src/wallet/api/wallet.cpp" line="2219"/> <source>Failed to parse output amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="2166"/> - <location filename="../src/wallet/api/wallet.cpp" line="2188"/> + <location filename="../src/wallet/api/wallet.cpp" line="2202"/> + <location filename="../src/wallet/api/wallet.cpp" line="2224"/> <source>Failed to parse output offset</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="2172"/> - <source>Failed to blackball output</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/wallet/api/wallet.cpp" line="2194"/> - <source>Failed to unblackball output</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/wallet/api/wallet.cpp" line="2205"/> - <location filename="../src/wallet/api/wallet.cpp" line="2244"/> + <location filename="../src/wallet/api/wallet.cpp" line="2241"/> + <location filename="../src/wallet/api/wallet.cpp" line="2280"/> <source>Failed to parse key image</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="2211"/> + <location filename="../src/wallet/api/wallet.cpp" line="2247"/> <source>Failed to get ring</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="2229"/> + <location filename="../src/wallet/api/wallet.cpp" line="2265"/> <source>Failed to get rings</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="2250"/> + <location filename="../src/wallet/api/wallet.cpp" line="2286"/> <source>Failed to set ring</source> <translation type="unfinished"></translation> </message> @@ -541,12 +542,12 @@ <context> <name>command_line</name> <message> - <location filename="../src/common/command_line.cpp" line="57"/> + <location filename="../src/common/command_line.cpp" line="54"/> <source>yes</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/common/command_line.cpp" line="71"/> + <location filename="../src/common/command_line.cpp" line="68"/> <source>no</source> <translation type="unfinished"></translation> </message> @@ -603,955 +604,803 @@ <context> <name>cryptonote::simple_wallet</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3452"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3895"/> <source>Daemon uses a different RPC major version (%u) than the wallet (%u): %s. Either update one of them, or use --allow-mismatched-daemon-version.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3483"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3926"/> <source>Enter the number corresponding to the language of your choice: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4936"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5486"/> <source>There is currently a %u block backlog at that fee level. Is this okay? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4987"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5441"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5537"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6037"/> <source>Spending from address index %d </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4991"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5541"/> <source>Sending %s. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4994"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5544"/> <source>Your transaction needs to be split into %llu transactions. This will result in a transaction fee being applied to each transaction, for a total fee of %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5000"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5550"/> <source>The transaction fee is %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5003"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5553"/> <source>, of which %s is dust from change</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5004"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5554"/> <source>A total of %s from dust change will be sent to dust address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5009"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5559"/> <source>. This transaction will unlock on block %llu, in approximately %s days (assuming 2 minutes per block)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5186"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5775"/> <source>Not enough money in unlocked balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5219"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5815"/> <source>No address given</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5283"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5879"/> <source>missing lockedblocks parameter</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5293"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5889"/> <source>bad locked_blocks parameter</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5593"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6213"/> <source>failed to parse Payment ID</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5616"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6236"/> <source>failed to parse key image</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5668"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6290"/> <source>No outputs found</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5673"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6295"/> <source>Multiple transactions are created, which is not supposed to happen</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5678"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6300"/> <source>The transaction uses multiple or no inputs, which is not supposed to happen</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5728"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6350"/> <source>Money successfully sent, transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5755"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6377"/> <source>missing threshold amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5760"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6382"/> <source>invalid amount threshold</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5770"/> - <source>donations are not enabled on the testnet or on the stagenet</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5777"/> - <source>usage: donate [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <amount> [<payment_id>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5871"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6516"/> <source>Claimed change does not go to a paid address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5876"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6521"/> <source>Claimed change is larger than payment to the change address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5885"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6530"/> <source>Change goes to more than one address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5907"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6552"/> <source>sending %s to %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5917"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6562"/> <source> dummy output(s)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5920"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6565"/> <source>with no destinations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5929"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6574"/> <source>no change</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5932"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6577"/> <source>Loaded %lu transactions, for %s, fee %s, %s, %s, with min ring size %lu, %s. %sIs this okay? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2761"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3204"/> <source>(Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3262"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3337"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5033"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3705"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3780"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5583"/> <source>Is this okay? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4061"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4509"/> <source>Daemon is local, assuming trusted</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3907"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4355"/> <source>Password for new watch-only wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="248"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="341"/> <source>false</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="552"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="645"/> <source>Commands: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="566"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="659"/> <source>Unknown command: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="573"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="666"/> <source>Command usage: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="576"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="669"/> <source>Command description: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="602"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="695"/> <source>wallet is watch-only and has no spend key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="628"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="693"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="842"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="875"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="954"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1006"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1058"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1137"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1211"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1279"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5956"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6020"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6057"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6154"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6365"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6455"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7581"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7656"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7698"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7765"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7804"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="721"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="787"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="939"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="984"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1067"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1124"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1190"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1256"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1350"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1466"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1547"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6601"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6665"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6702"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6799"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7010"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7094"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8397"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8474"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8517"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8630"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8670"/> <source>command not supported by HW wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="633"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="703"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="726"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="797"/> <source>wallet is watch-only and has no seed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="644"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="735"/> <source>wallet is multisig but not yet finalized</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="650"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="713"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="744"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="807"/> <source>wallet is non-deterministic and has no seed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="674"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="768"/> <source>Failed to retrieve seed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="698"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="792"/> <source>wallet is multisig and has no seed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="723"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="817"/> <source>Incorrect password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="745"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="912"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="961"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="839"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1021"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1074"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1141"/> <source>Your original password was incorrect.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="760"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="854"/> <source>Error with wallet rewrite: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="772"/> - <source>usage: payment_id</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="776"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7328"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="870"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8144"/> <source>Random payment ID: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="784"/> - <source>Cannot connect to daemon</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="792"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="883"/> <source>Current fee is %s %s per %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="808"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="899"/> <source>Error: failed to estimate backlog array size: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="813"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="904"/> <source>Error: bad estimated backlog array size</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="825"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="916"/> <source> (current)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="828"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="919"/> <source>%u block (%u minutes) backlog at priority %u%s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="830"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="921"/> <source>%u to %u block (%u to %u minutes) backlog at priority %u</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="833"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="924"/> <source>No backlog at priority </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="847"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="880"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="944"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="989"/> <source>This wallet is already multisig</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="852"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="885"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="949"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="994"/> <source>wallet is watch-only and cannot be made multisig</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="858"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="891"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="955"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1000"/> <source>This wallet has been used before, please use a new wallet to create a multisig wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="866"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="963"/> <source>Send this multisig info to all other participants, then use make_multisig <threshold> <info1> [<info2>...] with others' multisig info</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="867"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="964"/> <source>This includes the PRIVATE view key, so needs to be disclosed only to that multisig wallet's participants </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="897"/> - <source>usage: make_multisig <threshold> <multisiginfo1> [<multisiginfo2>...]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="905"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1014"/> <source>Invalid threshold</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="925"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1034"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1156"/> <source>Another step is needed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="927"/> - <source>Send this multisig info to all other participants, then use finalize_multisig <info1> [<info2>...] with others' multisig info</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="933"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1046"/> <source>Error creating multisig: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="940"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1053"/> <source>Error creating multisig: new wallet is not multisig</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="943"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1056"/> <source> multisig address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="967"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1011"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1063"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1080"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1129"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1195"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1261"/> <source>This wallet is not multisig</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="972"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1085"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1134"/> <source>This wallet is already finalized</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="980"/> - <source>usage: finalize_multisig <multisiginfo1> [<multisiginfo2>...]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="988"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1101"/> <source>Failed to finalize multisig</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="994"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1107"/> <source>Failed to finalize multisig: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1016"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1068"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1147"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1221"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1289"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1200"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1266"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1360"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1476"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1557"/> <source>This multisig wallet is not yet finalized</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1021"/> - <source>usage: export_multisig_info <filename></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1037"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7679"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7785"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1228"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8498"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8651"/> <source>failed to save file </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1044"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1236"/> <source>Error exporting multisig info: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1048"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1240"/> <source>Multisig info exported to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1073"/> - <source>usage: import_multisig_info <filename1> [<filename2>...] - one for each other participant</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1087"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7606"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7629"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7818"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1289"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8421"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8447"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8684"/> <source>failed to read file </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1101"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1306"/> <source>Multisig info imported</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1105"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1310"/> <source>Failed to import multisig info: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1116"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1321"/> <source>Failed to update spent status after importing multisig info: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1121"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1327"/> <source>Untrusted daemon, spent status may be incorrect. Use a trusted daemon and run "rescan_spent"</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1142"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1216"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1284"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1355"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1471"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1552"/> <source>This is not a multisig wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1152"/> - <source>usage: sign_multisig <filename></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1166"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1405"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1414"/> <source>Failed to sign multisig transaction</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1172"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1421"/> <source>Multisig error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1177"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1426"/> <source>Failed to sign multisig transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1186"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1199"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6001"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1435"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1448"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6646"/> <source>Transaction successfully signed to file </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1200"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1449"/> <source>It may be relayed to the network with submit_multisig</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1226"/> - <source>usage: submit_multisig <filename></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1242"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1309"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1508"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1578"/> <source>Failed to load multisig transaction from file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1247"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1314"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1514"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1583"/> <source>Multisig transaction signed by only %u signers, needs %u more signatures</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1256"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="8024"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1523"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8890"/> <source>Transaction successfully submitted, transaction </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1257"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="8025"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1524"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8891"/> <source>You can check its status by using the `show_transfers` command.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1267"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1344"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4244"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4534"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5083"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5205"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5505"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5739"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6045"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1534"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1613"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4749"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5061"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5639"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5669"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5794"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6099"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6126"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6361"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6690"/> <source>unknown error</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1294"/> - <source>usage: export_raw_multisig <filename></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1330"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1599"/> <source>Failed to export multisig transaction to file </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1334"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1603"/> <source>Saved exported multisig transaction file(s): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1339"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4239"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4529"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1608"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4744"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5056"/> <source>unexpected error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1356"/> - <source>usage: print_ring <key_image> | <txid></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1362"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1519"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1631"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1788"/> <source>Invalid key image</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1368"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1637"/> <source>Invalid txid</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1380"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1649"/> <source>Key image either not spent, or spent with mixin 0</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1395"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1664"/> <source>Failed to get key image ring: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1410"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1679"/> <source>File doesn't exist</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1432"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1701"/> <source>Invalid ring specification: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1440"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1709"/> <source>Invalid key image: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1445"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1714"/> <source>Invalid ring type, expected relative or abosolute: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1451"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1463"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1720"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1732"/> <source>Error reading line: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1474"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1743"/> <source>Invalid ring: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1483"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1752"/> <source>Invalid relative ring: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1495"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1764"/> <source>Invalid absolute ring: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1504"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1773"/> <source>Failed to set ring for key image: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1504"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1773"/> <source>Continuing.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1513"/> - <source>usage: set_ring <filename> | ( <key_image> absolute|relative <index> [<index>...] )</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1534"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1803"/> <source>Missing absolute or relative keyword</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1544"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1551"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1813"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1820"/> <source>invalid index: must be a strictly positive unsigned integer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1559"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1828"/> <source>invalid index: indices wrap</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1569"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1838"/> <source>invalid index: indices should be in strictly ascending order</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1576"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1845"/> <source>failed to set ring</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1645"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1914"/> <source>Bad argument: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1645"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1914"/> <source>should be "add"</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1654"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1923"/> <source>Failed to open file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1666"/> - <source>Failed to blackball output: </source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1693"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1723"/> - <source>Failed to unblackball output: </source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1717"/> - <source>Blackballed: </source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1719"/> - <source>not blackballed: </source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1738"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2007"/> <source>Failed to save known rings: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1779"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1798"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2069"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2088"/> <source>wallet is watch-only and cannot transfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1805"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1811"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1830"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2095"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2101"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2120"/> <source>ring size must be an integer >= </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1816"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5031"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2106"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5581"/> <source>WARNING: this is a non default ring size, which may harm your privacy. Default is recommended.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1835"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2125"/> <source>could not change default ring size</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1847"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1870"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1886"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2137"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2160"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2176"/> <source>priority must be either 0, 1, 2, 3, or 4, or one of: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1891"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2181"/> <source>could not change default priority</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1994"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2284"/> <source>invalid unit</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2012"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2074"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2302"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2364"/> <source>invalid count: must be an unsigned integer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2030"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2320"/> <source>invalid value</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2108"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2179"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2398"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2469"/> <source>Invalid height</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2225"/> - <source>start_mining [<number_of_threads>] [bg_mining] [ignore_battery]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2226"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2562"/> <source>Start mining in the daemon (bg_mining and ignore_battery are optional booleans).</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2229"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2565"/> <source>Stop mining in the daemon.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2232"/> - <source>set_daemon <host>[:<port>] [trusted|untrusted]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2233"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2569"/> <source>Set another daemon to connect to.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2236"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2572"/> <source>Save the current blockchain data.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2239"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2575"/> <source>Synchronize the transactions and balance.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2242"/> - <source>balance [detail]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2243"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2579"/> <source>Show the wallet's balance of the currently selected account.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2246"/> - <source>incoming_transfers [available|unavailable] [verbose] [index=<N1>[,<N2>[,...]]]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2247"/> - <source>Show the incoming transfers, all or filtered by availability and address index. - -Output format: -Amount, Spent("T"|"F"), "locked"|"unlocked", RingCT, Global Index, Transaction Hash, Address Index, [Public Key, Key Image]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2250"/> - <source>payments <PID_1> [<PID_2> ... <PID_N>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2251"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2589"/> <source>Show the payments for the given payment IDs.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2254"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2592"/> <source>Show the blockchain height.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2264"/> - <source>locked_sweep_all [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> <lockblocks> [<payment_id>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2265"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2603"/> <source>Send all unlocked balance to an address and lock it for <lockblocks> (max. 1000000). If the parameter "index<N1>[,<N2>,...]" is specified, the wallet sweeps outputs received by those address indices. If omitted, the wallet randomly chooses an address index to be used. <priority> is the priority of the sweep. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2268"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2606"/> <source>Send all unmixable outputs to yourself with ring_size 1</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2274"/> - <source>sweep_below <amount_threshold> [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> [<payment_id>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2275"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2613"/> <source>Send all unlocked outputs below the threshold to an address.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2279"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2617"/> <source>Send a single output of the given key image to an address without change.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2282"/> - <source>donate [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <amount> [<payment_id>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2283"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2621"/> <source>Donate <amount> to the development team (donate.getmonero.org).</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2286"/> - <source>sign_transfer [export_raw]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2287"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2625"/> <source>Sign a transaction from a file. If the parameter "export_raw" is specified, transaction raw hex data suitable for the daemon RPC /sendrawtransaction is exported.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2290"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2628"/> <source>Submit a signed transaction from a file.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2293"/> - <source>set_log <level>|{+,-,}<categories></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2294"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2632"/> <source>Change the current log detail (level must be <0-4>).</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2297"/> - <source>account - account new <label text with white spaces allowed> - account switch <index> - account label <index> <label text with white spaces allowed> - account tag <tag_name> <account_index_1> [<account_index_2> ...] - account untag <account_index_1> [<account_index_2> ...] - account tag_description <tag_name> <description></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2304"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2636"/> <source>If no arguments are specified, the wallet shows all the existing accounts along with their balances. If the "new" argument is specified, the wallet creates a new account with its label initialized by the provided label text (which can be empty). If the "switch" argument is specified, the wallet switches to the account specified by <index>. @@ -1562,423 +1411,234 @@ If the "tag_description" argument is specified, the tag <tag_name&g <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2313"/> - <source>address [ new <label text with white spaces allowed> | all | <index_min> [<index_max>] | label <index> <label text with white spaces allowed>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2314"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2646"/> <source>If no arguments are specified or <index> is specified, the wallet shows the default or specified address. If "all" is specified, the wallet shows all the existing addresses in the currently selected account. If "new " is specified, the wallet creates a new address with the provided label text (which can be empty). If "label" is specified, the wallet sets the label of the address specified by <index> to the provided label text.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2317"/> - <source>integrated_address [<payment_id> | <address>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2318"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2650"/> <source>Encode a payment ID into an integrated address for the current wallet public address (no argument uses a random payment ID), or decode an integrated address to standard address and payment ID</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2321"/> - <source>address_book [(add ((<address> [pid <id>])|<integrated address>) [<description possibly with whitespaces>])|(delete <index>)]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2322"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2654"/> <source>Print all entries in the address book, optionally adding/deleting an entry to/from it.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2325"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2657"/> <source>Save the wallet data.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2328"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2660"/> <source>Save a watch-only keys file.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2331"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2663"/> <source>Display the private view key.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2334"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2666"/> <source>Display the private spend key.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2337"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2669"/> <source>Display the Electrum-style mnemonic seed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2340"/> - <source>set <option> [<value>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2387"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2719"/> <source>Display the encrypted Electrum-style mnemonic seed.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2390"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2722"/> <source>Rescan the blockchain for spent outputs.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2393"/> - <source>get_tx_key <txid></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2394"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2726"/> <source>Get the transaction key (r) for a given <txid>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2397"/> - <source>set_tx_key <txid> <tx_key></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2398"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2730"/> <source>Set the transaction key (r) for a given <txid> in case the tx was made by some other device or 3rd party wallet.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2401"/> - <source>check_tx_key <txid> <txkey> <address></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2402"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2734"/> <source>Check the amount going to <address> in <txid>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2405"/> - <source>get_tx_proof <txid> <address> [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2406"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2738"/> <source>Generate a signature proving funds sent to <address> in <txid>, optionally with a challenge string <message>, using either the transaction secret key (when <address> is not your wallet's address) or the view secret key (otherwise), which does not disclose the secret key.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2409"/> - <source>check_tx_proof <txid> <address> <signature_file> [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2410"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2742"/> <source>Check the proof for funds going to <address> in <txid> with the challenge string <message> if any.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2413"/> - <source>get_spend_proof <txid> [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2414"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2746"/> <source>Generate a signature proving that you generated <txid> using the spend secret key, optionally with a challenge string <message>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2417"/> - <source>check_spend_proof <txid> <signature_file> [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2418"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2750"/> <source>Check a signature proving that the signer generated <txid>, optionally with a challenge string <message>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2421"/> - <source>get_reserve_proof (all|<amount>) [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2422"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2754"/> <source>Generate a signature proving that you own at least this much, optionally with a challenge string <message>. If 'all' is specified, you prove the entire sum of all of your existing accounts' balances. Otherwise, you prove the reserve of the smallest possible amount above <amount> available in your current account.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2427"/> - <source>check_reserve_proof <address> <signature_file> [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2428"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2760"/> <source>Check a signature proving that the owner of <address> holds at least this much, optionally with a challenge string <message>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2431"/> - <source>show_transfers [in|out|pending|failed|pool|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2432"/> - <source>Show the incoming/outgoing transfers within an optional height range. - -Output format: -In or Coinbase: Block Number, "block"|"in", Time, Amount, Transaction Hash, Payment ID, Subaddress Index, "-", Note\ -Out: Block Number, "out", Time, Amount*, Transaction Hash, Payment ID, Fee, Destinations, Input addresses**, "-", Note -Pool: "pool", "in", Time, Amount, Transaction Hash, Payment Id, Subaddress Index, "-", Note, Double Spend Note\ -Pending or Failed: "failed"|"pending", "out", Time, Amount*, Transaction Hash, Payment ID, Fee, Input addresses**, "-", Note - -* Excluding change and fee. -** Set of address indices used as inputs in this transfer.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2435"/> - <source>unspent_outputs [index=<N1>[,<N2>,...]] [<min_amount> [<max_amount>]]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2436"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2780"/> <source>Show the unspent outputs of a specified address within an optional amount range.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2439"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2784"/> <source>Rescan the blockchain from scratch, losing any information which can not be recovered from the blockchain itself.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2442"/> - <source>set_tx_note <txid> [free text note]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2443"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2788"/> <source>Set an arbitrary string note for a <txid>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2446"/> - <source>get_tx_note <txid></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2447"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2792"/> <source>Get a string note for a txid.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2450"/> - <source>set_description [free text note]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2451"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2796"/> <source>Set an arbitrary description for the wallet.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2454"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2800"/> <source>Get the description of the wallet.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2457"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2803"/> <source>Show the wallet's status.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2460"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2806"/> <source>Show the wallet's information.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2463"/> - <source>sign <file></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2464"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2810"/> <source>Sign the contents of a file.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2467"/> - <source>verify <filename> <address> <signature></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2468"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2814"/> <source>Verify a signature on the contents of a file.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2471"/> - <source>export_key_images <file></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2472"/> - <source>Export a signed set of key images to a <file>.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2475"/> - <source>import_key_images <file></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2476"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2822"/> <source>Import a signed key images list and verify their spent status.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2479"/> - <source>hw_reconnect</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2480"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2830"/> <source>Attempts to reconnect HW wallet.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2483"/> - <source>export_outputs <file></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2484"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2834"/> <source>Export a set of outputs owned by this wallet.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2487"/> - <source>import_outputs <file></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2488"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2838"/> <source>Import a set of outputs owned by this wallet.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2491"/> - <source>show_transfer <txid></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2492"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2842"/> <source>Show information about a transfer to/from this address.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2495"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2845"/> <source>Change the wallet's password.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2498"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2849"/> <source>Generate a new random full size payment id. These will be unencrypted on the blockchain, see integrated_address for encrypted short payment ids.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2501"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2852"/> <source>Print the information about the current fee and transaction backlog.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2503"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2854"/> <source>Export data needed to create a multisig wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2505"/> - <source>make_multisig <threshold> <string1> [<string>...]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2506"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2857"/> <source>Turn this wallet into a multisig wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2509"/> - <source>finalize_multisig <string> [<string>...]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2510"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2861"/> <source>Turn this wallet into a multisig wallet, extra step for N-1/N wallets</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2513"/> - <source>export_multisig_info <filename></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2514"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2869"/> <source>Export multisig info for other participants</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2517"/> - <source>import_multisig_info <filename> [<filename>...]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2518"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2873"/> <source>Import multisig info from other participants</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2521"/> - <source>sign_multisig <filename></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2522"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2877"/> <source>Sign a multisig transaction from a file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2525"/> - <source>submit_multisig <filename></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2526"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2881"/> <source>Submit a signed multisig transaction from a file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2529"/> - <source>export_raw_multisig_tx <filename></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2530"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2885"/> <source>Export a signed multisig transaction to a file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2533"/> - <source>print_ring <key_image> | <txid></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2534"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2972"/> <source>Print the ring(s) used to spend a given key image or transaction (if the ring size is > 1) Output format: @@ -1986,499 +1646,450 @@ Key Image, "absolute", list of rings</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2537"/> - <source>set_ring <filename> | ( <key_image> absolute|relative <index> [<index>...] )</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2538"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2978"/> <source>Set the ring used for a given key image, so it can be reused in a fork</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2541"/> - <source>save_known_rings</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2542"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2982"/> <source>Save known rings to the shared rings database</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2546"/> - <source>Blackball output(s) so they never get selected as fake outputs in a ring</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2550"/> - <source>Unblackballs an output so it may get selected as a fake output in a ring</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2554"/> - <source>Checks whether an output is blackballed</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2557"/> - <source>version</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2558"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2998"/> <source>Returns version information</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2561"/> - <source>help [<command>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2562"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3002"/> <source>Show the help section or the documentation about a <command>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2618"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3059"/> <source>needs an argument</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2632"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3073"/> <source>set seed: needs an argument. available options: language</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2641"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2642"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2643"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2645"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2648"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2653"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2654"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2656"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2658"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2659"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2660"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2663"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3082"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3083"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3084"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3086"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3089"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3094"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3095"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3097"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3099"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3100"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3101"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3104"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3105"/> <source>0 or 1</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2644"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3085"/> <source>integer >= </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2646"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3087"/> <source>full (slowest, no assumptions); optimize-coinbase (fast, assumes the whole coinbase is paid to a single address); no-coinbase (fastest, assumes we receive no coinbase transaction), default (same as optimize-coinbase)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2647"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3088"/> <source>0, 1, 2, 3, or 4, or one of </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2649"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3090"/> <source>0|1|2 (or never|action|decrypt)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2650"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3091"/> <source>monero, millinero, micronero, nanonero, piconero</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2651"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2655"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2662"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3092"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3096"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3103"/> <source>unsigned integer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2652"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4378"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4429"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3093"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> <source>amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2657"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3098"/> <source>block height</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2661"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3102"/> <source><major>:<minor></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2665"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3108"/> <source>set: unrecognized argument(s)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2674"/> - <source>usage: set_log <log_level_number_0-4> | <categories></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2684"/> - <source>wrong number range, use: set_log <log_level_number_0-4> | <categories></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2723"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3166"/> <source>Wallet name not valid. Please try again or use Ctrl-C to quit.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2735"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3178"/> <source>Attempting to generate or restore wallet, but specified file(s) exist. Exiting to not risk overwriting.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2740"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3183"/> <source>Wallet and key files found, loading...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2746"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3189"/> <source>Key file found but not wallet file. Regenerating...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2752"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3195"/> <source>Key file not found. Failed to open wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2760"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3203"/> <source>No wallet found with that name. Confirm creation of new wallet named: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2771"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3214"/> <source>Generating new wallet...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2789"/> - <source>NOTE: the following 25 words can be used to recover access to your wallet. Write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control. -</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2830"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3273"/> <source>Can't specify more than one of --testnet and --stagenet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2842"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3285"/> <source>can't specify more than one of --generate-new-wallet="wallet_name", --wallet-file="wallet_name", --generate-from-view-key="wallet_name", --generate-from-spend-key="wallet_name", --generate-from-keys="wallet_name", --generate-from-multisig-keys="wallet_name", --generate-from-json="jsonfilename" and --generate-from-device="wallet_name"</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2861"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3304"/> <source>can't specify both --restore-deterministic-wallet or --restore-multisig-wallet and --non-deterministic</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2867"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> <source>--restore-multisig-wallet uses --generate-new-wallet, not --wallet-file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2869"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3312"/> <source>--restore-deterministic-wallet uses --generate-new-wallet, not --wallet-file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2883"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3326"/> <source>specify a recovery parameter with the --electrum-seed="multisig seed here"</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2898"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3341"/> <source>specify a recovery parameter with the --electrum-seed="words list here"</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2912"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3355"/> <source>Multisig seed failed verification</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2921"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3364"/> <source>Electrum-style word list failed verification</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2952"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2972"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3007"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3027"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3047"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3062"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3110"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3135"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3151"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3190"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3395"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3415"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3450"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3470"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3490"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3505"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3578"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3594"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3633"/> <source>No data supplied, cancelled</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2958"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3033"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3141"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4823"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5373"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5623"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6173"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6241"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6305"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6521"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7377"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7636"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3401"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3476"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3584"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5371"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5969"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6243"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6818"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6886"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6950"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7154"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8193"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8454"/> <source>failed to parse address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2963"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3038"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3406"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3481"/> <source>This address is a subaddress which cannot be used here.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2978"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3068"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3421"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3511"/> <source>failed to parse view key secret key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2987"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3085"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3430"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3528"/> <source>failed to verify view key secret key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2991"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3089"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3170"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3434"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3532"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3613"/> <source>view key does not match standard address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2996"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3016"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3093"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3226"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3252"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3283"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3439"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3459"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3536"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3669"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3695"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3726"/> <source>account creation failed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3012"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3053"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3195"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3455"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3496"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3638"/> <source>failed to parse spend key secret key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3077"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3215"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3520"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3658"/> <source>failed to verify spend key secret key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3081"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3220"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3524"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3663"/> <source>spend key does not match standard address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3115"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3558"/> <source>Error: expected M/N, but got: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3120"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3563"/> <source>Error: expected N > 1 and N <= M, but got: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3125"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3568"/> <source>Error: M/N is currently unsupported. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3128"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3571"/> <source>Generating master wallet from %u of %u multisig wallet keys</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3157"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3600"/> <source>failed to parse secret view key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3165"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3608"/> <source>failed to verify secret view key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3185"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3628"/> <source>Secret spend key (%u of %u):</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3208"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3651"/> <source>Error: M/N is currently unsupported</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3258"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3701"/> <source>No restore height is specified.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3259"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3702"/> <source>Assumed you are creating a new account, restore will be done from current estimated blockchain height.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3260"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3703"/> <source>Use --restore-height if you want to restore an already setup account from a specific height</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3264"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3707"/> <source>account creation aborted</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3274"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3717"/> <source>specify a wallet path with --generate-new-wallet (not --wallet-file)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3318"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3345"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3761"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3788"/> <source>bad m_restore_height parameter: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3323"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3766"/> <source>date format must be YYYY-MM-DD</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3336"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3779"/> <source>Restore height is: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3359"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3802"/> <source>Restore height </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3360"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3803"/> <source>Still apply restore height? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3373"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3816"/> <source>can't specify --subaddress-lookahead and --wallet-file at the same time</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3377"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3820"/> <source>failed to open account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3381"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3943"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3996"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4081"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6209"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3824"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4391"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4444"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4529"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6854"/> <source>wallet is null</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3386"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3829"/> <source>Warning: using an untrusted daemon at %s, privacy will be lessened</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3389"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3832"/> <source>Failed to initialize ring database: privacy enhancing features will be inactive</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3444"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3887"/> <source>wallet failed to connect to daemon: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3445"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3888"/> <source>Daemon either is not started or wrong port was passed. Please make sure daemon is running or change the daemon address using the 'set_daemon' command.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3473"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3916"/> <source>List of available languages for your wallet's seed:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3474"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3917"/> <source>If your display freezes, exit blind with ^C, then run again with --use-english-language-names</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3492"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3497"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3935"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3940"/> <source>invalid language choice entered. Please try again. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3511"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3954"/> <source>invalid password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3557"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4000"/> <source>You had been using a deprecated version of the wallet. Please use the new seed that we provide. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3573"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3645"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4016"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4088"/> <source>Generated new wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3576"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4019"/> <source>View key: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3582"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3650"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3689"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3742"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4025"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4093"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4135"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4188"/> <source>failed to generate new wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3593"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4036"/> <source>Your wallet has been generated! To start synchronizing with the daemon, use the "refresh" command. Use the "help" command to see the list of available commands. @@ -2490,1754 +2101,2405 @@ your wallet again (your wallet keys are NOT at risk in any case). <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3684"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4130"/> <source>Generated new wallet on hw device: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3734"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4180"/> <source>failed to generate new mutlisig wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3737"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4183"/> <source>Generated new %u/%u multisig wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3753"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4199"/> <source>wallet file path not valid: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3763"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4209"/> <source>Key file not found. Failed to open wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3782"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4230"/> <source>Opened watch-only wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3784"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4232"/> <source>Opened %u/%u multisig wallet%s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3786"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4234"/> <source>Opened wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3804"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4252"/> <source>You had been using a deprecated version of the wallet. Please proceed to upgrade your wallet. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3819"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4267"/> <source>You had been using a deprecated version of the wallet. Your wallet file format is being upgraded now. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3827"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4275"/> <source>failed to load wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3844"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4292"/> <source>Use the "help" command to see the list of available commands. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3845"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4293"/> <source>Use "help <command>" to see a command's documentation. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3866"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4314"/> <source>failed to deinitialize wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3889"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4337"/> <source>Wallet data saved</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3903"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4351"/> <source>wallet is multisig and cannot save a watch-only version</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3911"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4359"/> <source>failed to read wallet password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3919"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4367"/> <source>Watch only wallet saved as: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3923"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4371"/> <source>Failed to save watch only wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3934"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4497"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7703"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4382"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5024"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8522"/> <source>this command requires a trusted daemon. Enable with --trusted-daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3975"/> - <source>invalid arguments. Please use start_mining [<number_of_threads>] [do_bg_mining] [ignore_battery]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3983"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4431"/> <source>Mining started in daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3985"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4433"/> <source>mining has NOT been started: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4005"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4453"/> <source>Mining stopped in daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4007"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4455"/> <source>mining has NOT been stopped: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4017"/> - <source>missing daemon URL argument</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4028"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4476"/> <source>Unexpected array length - Exited simple_wallet::set_daemon()</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4050"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4498"/> <source>Expected trusted or untrusted, got </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4067"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4515"/> <source>trusted</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4067"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4515"/> <source>untrusted</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4069"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4517"/> <source>This does not seem to be a valid daemon URL.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4089"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4537"/> <source>Blockchain saved</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4091"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4539"/> <source>blockchain can't be saved: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4104"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4141"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4552"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4589"/> <source>Height </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4105"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4142"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4590"/> <source>txid </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4107"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4144"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4555"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4592"/> <source>idx </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4121"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4569"/> <source>NOTE: this transaction uses an encrypted payment ID: consider using subaddresses instead</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4124"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4572"/> <source>WARNING: this transaction uses an unencrypted payment ID: consider using subaddresses instead</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4143"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4591"/> <source>spent </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4168"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4616"/> <source>Enter password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4195"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4698"/> <source>Starting refresh...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4208"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4712"/> <source>Refresh done, blocks received: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4215"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4511"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4720"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5038"/> <source>daemon is busy. Please try again later.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4219"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4515"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4724"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5042"/> <source>no connection to daemon. Please make sure daemon is running.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4224"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4524"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4729"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5051"/> <source>RPC error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4229"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4734"/> <source>refresh error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4234"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4739"/> <source>internal error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4249"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4754"/> <source>refresh failed: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4249"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4754"/> <source>Blocks received: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4275"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4780"/> <source> (Some owned outputs have partial key images - import_multisig_info needed)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4277"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4782"/> <source> (Some owned outputs have missing key images - import_key_images needed)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4278"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4783"/> <source>Currently selected account: [</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4278"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4783"/> <source>] </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4280"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4785"/> <source>(No tag assigned)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4280"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4785"/> <source>Tag: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4281"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4786"/> <source>Balance: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4282"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4787"/> <source>unlocked balance: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4287"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4792"/> <source>Balance per address:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4288"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> <source>Address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4288"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7192"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8008"/> <source>Balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4288"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7192"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8008"/> <source>Unlocked balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4288"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> <source>Outputs</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4288"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7192"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8008"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9122"/> <source>Label</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4296"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4801"/> <source>%8u %6s %21s %21s %7u %21s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4305"/> - <source>usage: balance [detail]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4317"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4359"/> - <source>usage: incoming_transfers [available|unavailable] [verbose] [index=<N1>[,<N2>[,...]]]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4377"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4893"/> <source>pubkey</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4377"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4893"/> <source>key image</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4378"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> <source>spent</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4378"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4388"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4910"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> <source>unlocked</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4378"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> <source>ringct</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4378"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> <source>global index</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4378"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> <source>tx id</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4378"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4429"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> <source>addr index</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4387"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4909"/> <source>T</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4387"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4909"/> <source>F</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4388"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4910"/> <source>locked</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4389"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4911"/> <source>RingCT</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4389"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4911"/> <source>-</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4401"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4924"/> <source>No incoming transfers</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4405"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4928"/> <source>No incoming available transfers</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4409"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4932"/> <source>No incoming unavailable transfers</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4420"/> - <source>expected at least one payment ID</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4429"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> <source>payment</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4429"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> <source>transaction</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4429"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> <source>height</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4429"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> <source>unlock time</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4441"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4968"/> <source>No payments with id </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4463"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4990"/> <source>payment ID has invalid format, expected 16 or 64 character hex string: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4489"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4555"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4892"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5305"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5016"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5106"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5442"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5901"/> <source>failed to get blockchain height: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4519"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5046"/> <source>failed to get spent status</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4545"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6388"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6426"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6483"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6514"/> - <source>failed to connect to the daemon</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4563"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5114"/> <source> Transaction %llu/%llu: txid=%s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4579"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5130"/> <source>failed to find construction data for tx input</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4584"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5135"/> <source> Input %llu/%llu: amount=%s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4600"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5151"/> <source>failed to get output: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4608"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5159"/> <source>output key's originating block height shouldn't be higher than the blockchain height</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4612"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5163"/> <source> Originating block heights: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4627"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5175"/> <source> |</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4627"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6915"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5175"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7706"/> <source>| </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4644"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5192"/> <source> Warning: Some input keys being spent are from </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4645"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5193"/> <source>the same transaction</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4645"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5193"/> <source>blocks that are temporally very close</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4646"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5194"/> <source>, which can break the anonymity of ring signature. Make sure this is intentional!</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4688"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5257"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5536"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5234"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5853"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6156"/> <source>Ring size must not be 0</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4700"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5269"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5548"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5246"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5865"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6168"/> <source>ring size %u is too small, minimum is %u</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4705"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5274"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5251"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5870"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6173"/> <source>ring size %u is too large, maximum is %u</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4712"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5258"/> <source>wrong number of arguments</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4747"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5293"/> <source>payment id failed to encode</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4792"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5340"/> <source>failed to parse short payment ID from URI</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4815"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4817"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5363"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5365"/> <source>Invalid last argument: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4834"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5382"/> <source>a single transaction cannot use more than one payment id</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4851"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5399"/> <source>failed to parse payment id, though it was detected</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5215"/> - <source>usage: %s [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] [outputs=<N>] <address> [<payment_id>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5318"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5562"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5914"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6182"/> <source>Failed to parse number of outputs</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5323"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5567"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5919"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6187"/> <source>Amount of outputs should be greater than 0</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5362"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5958"/> <source>payment id has invalid format, expected 16 or 64 character hex string: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4730"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4847"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5276"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5395"/> <source>Unencrypted payment IDs are bad for privacy: ask the recipient to use subaddresses instead</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4761"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5307"/> <source>bad locked_blocks parameter:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4766"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5298"/> - <source>Locked blocks too high, max 1000000 (˜4 yrs)</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="5978"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6251"/> + <source>a single transaction cannot use more than one payment id: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5382"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5631"/> - <source>a single transaction cannot use more than one payment id: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="5405"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5987"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6219"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6259"/> + <source>failed to set up payment id, though it was decoded correctly</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4857"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5391"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5599"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5639"/> - <source>failed to set up payment id, though it was decoded correctly</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1036"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1158"/> + <source>Send this multisig info to all other participants, then use exchange_multisig_keys <info1> [<info2>...] with others' multisig info</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1167"/> + <source>Multisig wallet has been successfully created. Current wallet type: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1172"/> + <source>Failed to perform multisig keys exchange: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1499"/> + <source>Failed to load multisig transaction from MMS</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1935"/> + <source>Failed to mark output spent: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1962"/> + <source>Failed to mark output unspent: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1986"/> + <source>Spent: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1988"/> + <source>Not spent: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1992"/> + <source>Failed to check whether output is spent: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2022"/> + <source>Please confirm the transaction on the device</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2510"/> + <source>Device name not specified</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2519"/> + <source>Device reconnect failed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2524"/> + <source>Device reconnect failed: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2583"/> + <source>Show the incoming transfers, all or filtered by availability and address index. + +Output format: +Amount, Spent("T"|"F"), "locked"|"unlocked", RingCT, Global Index, Transaction Hash, Address Index, [Public Key, Key Image] </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2673"/> + <source>Available options: + seed language + Set the wallet's 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 the default ring size (obsolete). + auto-refresh <1|0> + Whether to automatically synchronize new blocks from the daemon. + refresh-type <full|optimize-coinbase|no-coinbase|default> + Set the wallet's refresh behaviour. + priority [0|1|2|3|4] + Set the fee to default/unimportant/normal/elevated/priority. + confirm-missing-payment-id <1|0> + ask-password <0|1|2 (or never|action|decrypt)> + unit <monero|millinero|micronero|nanonero|piconero> + Set the 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] + Set a threshold for confirm-backlog to only warn if the transaction backlog is greater than n blocks. + refresh-from-block-height [n] + Set the height before which to ignore blocks. + auto-low-priority <1|0> + Whether to automatically use the low priority fee level when it's safe to do so. + segregate-pre-fork-outputs <1|0> + Set this if you intend to spend outputs on both Monero AND a key reusing fork. + key-reuse-mitigation2 <1|0> + Set this if you are not sure whether you will spend on a key reusing Monero fork later. +subaddress-lookahead <major>:<minor> + Set the lookahead sizes for the subaddress hash table. + Set this if you are not sure whether you will spend on a key reusing Monero fork later. + segregation-height <n> + Set to the height of a key reusing fork you want to use, 0 to use default.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2765"/> + <source>Show the incoming/outgoing transfers within an optional height range. + +Output format: +In or Coinbase: Block Number, "block"|"in", Time, Amount, Transaction Hash, Payment ID, Subaddress Index, "-", Note +Out: Block Number, "out", Time, Amount*, Transaction Hash, Payment ID, Fee, Destinations, Input addresses**, "-", Note +Pool: "pool", "in", Time, Amount, Transaction Hash, Payment Id, Subaddress Index, "-", Note, Double Spend Note +Pending or Failed: "failed"|"pending", "out", Time, Amount*, Transaction Hash, Payment ID, Fee, Input addresses**, "-", Note + +* Excluding change and fee. +** Set of address indices used as inputs in this transfer.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2775"/> + <source>export_transfers [in|out|all|pending|failed|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]] [output=<filepath>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2776"/> + <source>Export to CSV the incoming/outgoing transfers within an optional height range.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2818"/> + <source>Export a signed set of key images to a <filename>.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2826"/> + <source>Synchronizes key images with the hw wallet.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2865"/> + <source>Performs extra multisig keys exchange rounds. Needed for arbitrary M/N multisig wallets</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2889"/> + <source>Interface with the MMS (Multisig Messaging System) +<subcommand> is one of: + init, info, signer, list, next, sync, transfer, delete, send, receive, export, note, show, set, help + send_signer_config, start_auto_config, stop_auto_config, auto_config +Get help about a subcommand with: help mms <subcommand>, or mms help <subcommand></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2897"/> + <source>Initialize and configure the MMS for M/N = number of required signers/number of authorized signers multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2901"/> + <source>Display current MMS configuration</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2905"/> + <source>Set or modify authorized signer info (single-word label, transport address, Monero address), or list all signers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2909"/> + <source>List all messages</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2913"/> + <source>Evaluate the next possible multisig-related action(s) according to wallet state, and execute or offer for choice +By using 'sync' processing of waiting messages with multisig sync info can be forced regardless of wallet state</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2918"/> + <source>Force generation of multisig sync info regardless of wallet state, to recover from special situations like "stale data" errors</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2922"/> + <source>Initiate transfer with MMS support; arguments identical to normal 'transfer' command arguments, for info see there</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2926"/> + <source>Delete a single message by giving its id, or delete all messages by using 'all'</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2930"/> + <source>Send a single message by giving its id, or send all waiting messages</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2934"/> + <source>Check right away for new messages to receive</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2938"/> + <source>Write the content of a message to a file "mms_message_content"</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2942"/> + <source>Send a one-line message to an authorized signer, identified by its label, or show any waiting unread notes</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2946"/> + <source>Show detailed info about a single message</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2950"/> + <source>Available options: + auto-send <1|0> + Whether to automatically send newly generated messages right away. + </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2956"/> + <source>Send completed signer config to all other authorized signers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2960"/> + <source>Start auto-config at the auto-config manager's wallet by issuing auto-config tokens and optionally set others' labels</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2964"/> + <source>Delete any auto-config tokens and abort a auto-config process</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2968"/> + <source>Start auto-config by using the token received from the auto-config manager</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2986"/> + <source>Mark output(s) as spent so they never get selected as fake outputs in a ring</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2990"/> + <source>Marks an output as unspent so it may get selected as a fake output in a ring</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2994"/> + <source>Checks whether an output is marked as spent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3106"/> + <source><device_name[:device_spec]></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3127"/> + <source>wrong number range, use: %s</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3232"/> + <source>NOTE: the following %s can be used to recover access to your wallet. Write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3234"/> + <source>string</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3234"/> + <source>25 words</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4631"/> + <source>Device requires attention</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4639"/> + <source>Enter device PIN</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4641"/> + <source>Failed to read device PIN</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4806"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6476"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6809"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6817"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4648"/> + <source>Please enter the device passphrase on the device</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4655"/> + <source>Enter device passphrase</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4657"/> + <source>Failed to read device passphrase</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4673"/> + <source>The first refresh has finished for the HW-based wallet with received money. hw_key_images_sync is needed. </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4675"/> + <source>Do you want to do it now? (Y/Yes/N/No): </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4677"/> + <source>hw_key_images_sync skipped. Run command manually before a transfer.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4855"/> + <source>Invalid keyword: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4904"/> + <source>Heights: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5312"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5894"/> + <source>Locked blocks too high, max 1000000 (Ë4 yrs)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5354"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6417"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7115"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7600"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7608"/> <source>amount is wrong: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4807"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5355"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6417"/> <source>expected number from 0 to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4869"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5400"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5648"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5417"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5996"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6268"/> <source>No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4874"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4952"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5040"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5149"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5405"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5463"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5653"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5696"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5422"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5502"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5590"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5738"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6001"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6059"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6273"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6318"/> <source>transaction cancelled.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4908"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5420"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5458"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6016"/> <source>No outputs found, or daemon is not ready</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4931"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4941"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5481"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5491"/> <source>Is this okay anyway? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4941"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5491"/> <source>Failed to check for backlog: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4982"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5436"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5532"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6032"/> <source> Transaction </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4989"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5443"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5539"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6039"/> <source>WARNING: Outputs of multiple addresses are being used together, which might potentially compromise your privacy. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5004"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5554"/> <source>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5052"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5064"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5160"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5172"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5474"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5486"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5706"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5718"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5603"/> + <source>Unsigned transaction(s) successfully written to MMS</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5611"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5648"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5749"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5761"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6070"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6107"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6328"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6340"/> <source>Failed to write transaction(s) to file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5056"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5068"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5164"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5176"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5478"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5490"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5710"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5722"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5616"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5653"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5753"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5765"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6074"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6111"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6332"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6344"/> <source>Unsigned transaction(s) successfully written to file: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5119"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5625"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6086"/> + <source>Failed to cold sign transaction with HW wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5708"/> <source>No unmixable outputs found</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5132"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5721"/> <source>Sweeping </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5134"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5448"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5723"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6044"/> <source>Sweeping %s in %llu transactions for a total fee of %s. Is this okay? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5140"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5454"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5688"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5729"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6050"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6310"/> <source>Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7569"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6428"/> + <source>Failed to parse donation address: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6444"/> + <source>Donating %s %s to %s.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7493"/> + <source>usage: export_transfers [in|out|all|pending|failed|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]] [output=<path>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>direction</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>timestamp</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>running balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>hash</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>payment ID</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>fee</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>destination</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>index</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>note</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7572"/> + <source>CSV exported to </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7750"/> + <source>MMS received new message</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8385"/> <source>Normal</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7570"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8386"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9180"/> <source>Type: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7571"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8387"/> <source>Network type: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7572"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8388"/> <source>Testnet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7573"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8389"/> <source>Stagenet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7573"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8389"/> <source>Mainnet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7586"/> - <source>usage: sign <filename></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9015"/> + <source> (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7591"/> - <source>wallet is watch-only and cannot sign</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9042"/> + <source>Choose processing:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7596"/> - <source>This wallet is multisig and cannot sign</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9051"/> + <source>Sign tx</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7618"/> - <source>usage: verify <filename> <address> <signature></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9059"/> + <source>Send the tx for submission to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7643"/> - <source>Bad signature from </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9063"/> + <source>Send the tx for signing to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7647"/> - <source>Good signature from </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9070"/> + <source>Submit tx</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7661"/> - <source>usage: export_key_images <filename></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9073"/> + <source>unknown</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9079"/> + <source>Choice: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9091"/> + <source>Wrong choice</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9098"/> + <source>Id</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9098"/> + <source>I/O</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9098"/> + <source>Authorized Signer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>Message Type</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>Height</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>R</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>Message State</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>Since</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9116"/> + <source> ago</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9122"/> + <source>#</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9122"/> + <source>Transport Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9123"/> + <source>Auto-Config Token</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9123"/> + <source>Monero Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9127"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9135"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9137"/> + <source><not set></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9178"/> + <source>Message </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9179"/> + <source>In/out: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9181"/> + <source>State: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9181"/> + <source>%s since %s, %s ago</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9185"/> + <source>Sent: Never</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9189"/> + <source>Sent: %s, %s ago</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9192"/> + <source>Authorized signer: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9193"/> + <source>Content size: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9193"/> + <source> bytes</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9194"/> + <source>Content: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9194"/> + <source>(binary data)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9224"/> + <source>Send these messages now?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9234"/> + <source>Queued for sending.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9254"/> + <source>Invalid message id</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9263"/> + <source>usage: mms init <required_signers>/<authorized_signers> <own_label> <own_transport_address></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9269"/> + <source>The MMS is already initialized. Re-initialize by deleting all signer info and messages?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9284"/> + <source>Error in the number of required signers and/or authorized signers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9301"/> + <source>The MMS is not active.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9324"/> + <source>Invalid signer number </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9329"/> + <source>mms signer [<number> <label> [<transport_address> [<monero_address>]]]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9348"/> + <source>Invalid Monero address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9355"/> + <source>Wallet state does not allow changing Monero addresses anymore</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9367"/> + <source>Usage: mms list</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9380"/> + <source>Usage: mms next [sync]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9405"/> + <source>No next step: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9415"/> + <source>prepare_multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9421"/> + <source>make_multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9436"/> + <source>exchange_multisig_keys</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9451"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9571"/> + <source>export_multisig_info</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9460"/> + <source>import_multisig_info</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9473"/> + <source>sign_multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9483"/> + <source>submit_multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9493"/> + <source>Send tx</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9504"/> + <source>Process signer config</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9516"/> + <source>Replace current signer config with the one displayed above?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9530"/> + <source>Process auto config data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9544"/> + <source>Nothing ready to process</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9564"/> + <source>Usage: mms sync</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9588"/> + <source>Usage: mms delete (<message_id> | all)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9595"/> + <source>Delete all messages?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9621"/> + <source>Usage: mms send [<message_id>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9638"/> + <source>Usage: mms receive</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9655"/> + <source>Usage: mms export <message_id></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9667"/> + <source>Message content saved to: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9671"/> + <source>Failed to to save message content</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9695"/> + <source>Usage: mms note [<label> <text>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9702"/> + <source>No signer found with label </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9724"/> + <source>Usage: mms show <message_id></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7666"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9743"/> + <source>Usage: mms set <option_name> [<option_value>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9760"/> + <source>Wrong option value</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9765"/> + <source>Auto-send is on</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9765"/> + <source>Auto-send is off</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9770"/> + <source>Unknown option</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9778"/> + <source>Usage: mms help [<subcommand>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9794"/> + <source>Usage: mms send_signer_config</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9800"/> + <source>Signer config not yet complete</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9815"/> + <source>Usage: mms start_auto_config [<label> <label> ...]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9820"/> + <source>There are signers without a label set. Complete labels before auto-config or specify them as parameters here.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9826"/> + <source>Auto-config is already running. Cancel and restart?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9850"/> + <source>Usage: mms stop_auto_config</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9853"/> + <source>Delete any auto-config tokens and stop auto-config?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9866"/> + <source>Usage: mms auto_config <auto_config_token></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9873"/> + <source>Invalid auto-config token</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9879"/> + <source>Auto-config already running. Cancel and restart?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9911"/> + <source>The MMS is not active. Activate using the "mms init" command</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9988"/> + <source>Invalid MMS subcommand</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9993"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9997"/> + <source>Error in MMS command: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8407"/> + <source>wallet is watch-only and cannot sign</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8412"/> + <source>This wallet is multisig and cannot sign</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8461"/> + <source>Bad signature from </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8465"/> + <source>Good signature from </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8484"/> <source>wallet is watch-only and cannot export key images</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7690"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8509"/> <source>Signed key images exported to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7709"/> - <source>usage: import_key_images <filename></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8559"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8605"/> + <source>command only supported by HW wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7740"/> - <source>command only supported by HW wallet</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8564"/> + <source>hw wallet does not support cold KI sync</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7749"/> - <source>Failed to reconnect device</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8576"/> + <source>Please confirm the key image sync on the device</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7754"/> - <source>Failed to reconnect device: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8582"/> + <source>Key images synchronized to height </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7770"/> - <source>usage: export_outputs <filename></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8585"/> + <source>Running untrusted daemon, cannot determine which transaction output is spent. Use a trusted daemon with --trusted-daemon and run rescan_spent</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7796"/> - <source>Outputs exported to </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8588"/> + <source> spent, </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8588"/> + <source> unspent</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7809"/> - <source>usage: import_outputs <filename></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8592"/> + <source>Failed to import key images</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7841"/> - <source>usage: show_transfer <txid></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8597"/> + <source>Failed to import key images: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7947"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8614"/> + <source>Failed to reconnect device</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8619"/> + <source>Failed to reconnect device: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8662"/> + <source>Outputs exported to </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8813"/> <source>Double spend seen on the network: this transaction may or may not end up being mined</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7982"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8848"/> <source>Transaction ID not found</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="8017"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8883"/> <source>Transaction successfully saved to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="8017"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="8019"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8883"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8885"/> <source>, txid </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="8019"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8885"/> <source>Failed to save transaction to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="243"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="336"/> <source>true</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="296"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="389"/> <source>failed to parse refresh type</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="657"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="751"/> <source>Enter optional seed offset passphrase, empty to see raw seed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2926"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3369"/> <source>Enter seed offset passphrase, empty if none</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3838"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4286"/> <source>You may want to remove the file "%s" and try again</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5187"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5776"/> <source>Discarding %s of unmixable outputs that cannot be spent, which can be undone by "rescan_spent". Is this okay? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5799"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6442"/> <source>Donating %s %s to The Monero Project (donate.getmonero.org or %s).</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5961"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6606"/> <source>This is a multisig wallet, it can only sign with sign_multisig</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5966"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6611"/> <source>This is a watch only wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5971"/> - <source>usage: sign_transfer [export_raw]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5984"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6629"/> <source>Failed to sign transaction</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5990"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6635"/> <source>Failed to sign transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6011"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6656"/> <source>Transaction raw hex data exported to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6032"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6677"/> <source>Failed to load transaction from file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6061"/> - <source>usage: get_tx_key <txid></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6068"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6104"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6166"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6215"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6297"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6382"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6420"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7451"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7479"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7848"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6713"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6749"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6811"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6860"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6942"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7027"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7062"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8267"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8295"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8714"/> <source>failed to parse txid</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6082"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6727"/> <source>Tx key: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6087"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6732"/> <source>no tx keys found for this txid</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6097"/> - <source>usage: set_tx_key <txid> <tx_key></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6114"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6125"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6132"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6759"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6770"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6777"/> <source>failed to parse tx_key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6141"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6786"/> <source>Tx key successfully stored.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6145"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6790"/> <source>Failed to store tx key: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6159"/> - <source>usage: get_tx_proof <txid> <address> [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6184"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6399"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6494"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6829"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7041"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7130"/> <source>signature file saved to: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6186"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6401"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6496"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6831"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7043"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7132"/> <source>failed to save signature file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6190"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6278"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6356"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6835"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6923"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7001"/> <source>error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6200"/> - <source>usage: check_tx_key <txid> <txkey> <address></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6223"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6232"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6868"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6877"/> <source>failed to parse tx key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6254"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6327"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6899"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6972"/> <source>received</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6254"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6327"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6899"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6972"/> <source>in txid</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6257"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6330"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6902"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6975"/> <source>WARNING: this transaction is not yet included in the blockchain!</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6267"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6340"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6912"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6985"/> <source>WARNING: failed to determine number of confirmations!</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6273"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6346"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6918"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6991"/> <source>received nothing in txid</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6286"/> - <source>usage: check_tx_proof <txid> <address> <signature_file> [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6313"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6433"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6533"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6958"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7072"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7166"/> <source>failed to load signature file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6324"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6440"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6969"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7079"/> <source>Good signature</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6351"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6442"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6548"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6996"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7081"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7181"/> <source>Bad signature</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6369"/> - <source>usage: get_spend_proof <txid> [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6375"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7020"/> <source>wallet is watch-only and cannot generate the proof</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6413"/> - <source>usage: check_spend_proof <txid> <signature_file> [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6459"/> - <source>usage: get_reserve_proof (all|<amount>) [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6465"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7104"/> <source>The reserve proof can be generated only by a full wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6508"/> - <source>usage: check_reserve_proof <address> <signature_file> [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6526"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7159"/> <source>Address must not be a subaddress</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6606"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7440"/> <source>usage: show_transfers [in|out|all|pending|failed|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6659"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7266"/> <source>bad min_height parameter:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6671"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7278"/> <source>bad max_height parameter:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6692"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7296"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> <source>block</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6692"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7296"/> <source>in</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6726"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6778"/> - <source>out</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6754"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7365"/> <source>[Double spend seen on the network: this transaction may or may not end up being mined] </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6778"/> - <source>failed</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6778"/> - <source>pending</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6790"/> - <source>usage: unspent_outputs [index=<N1>[,<N2>,...]] [<min_amount> [<max_amount>]]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6824"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7615"/> <source><min_amount> should be smaller than <max_amount></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6850"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7641"/> <source>There is no unspent output in the specified address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6856"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7647"/> <source> Amount: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6856"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7647"/> <source>, number of keys: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6861"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7652"/> <source> </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6866"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7657"/> <source> Min block height: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6867"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7658"/> <source> Max block height: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6868"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7659"/> <source> Min amount found: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6869"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7660"/> <source> Max amount found: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6870"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7661"/> <source> Total count: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6910"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7701"/> <source> Bin size: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6911"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7702"/> <source> Outputs per *: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6913"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7704"/> <source>count ^ </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6915"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7706"/> <source> |</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6917"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7708"/> <source> +</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6917"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7708"/> <source>+--> block height </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6918"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7709"/> <source> ^</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6918"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7709"/> <source>^ </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6919"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7710"/> <source> </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6926"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7730"/> <source>Warning: this will lose any information which can not be recovered from the blockchain.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6927"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7731"/> <source>This includes destination addresses, tx secret keys, tx notes, etc</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6928"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7732"/> <source>Rescan anyway ? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6544"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7177"/> <source>Good signature -- total: %s, spent: %s, unspent: %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1588"/> - <source>usage: blackball <amount>/<offset> | <filename> [add]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1621"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1890"/> <source>First line is not an amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1635"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1904"/> <source>Invalid output: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1660"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1929"/> <source>Invalid output key, and file doesn't exist</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1677"/> - <source>usage: unblackball <amount>/<offset></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1683"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1710"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1952"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1979"/> <source>Invalid output</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1704"/> - <source>usage: blackballed <amount>/<offset></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1818"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2108"/> <source>WARNING: from v8, ring size will be fixed and this setting will be ignored.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1959"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2249"/> <source>invalid argument: must be either 0/never, 1/action, or 2/encrypt/decrypt</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2256"/> - <source>transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] (<URI> | <address> <amount>) [<payment_id>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2257"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2595"/> <source>Transfer <amount> to <address>. If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding URI_2 or <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2260"/> - <source>locked_transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] (<URI> | <addr> <amount>) <lockblocks> [<payment_id>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2261"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2599"/> <source>Transfer <amount> to <address> and lock it for <lockblocks> (max. 1000000). If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding URI_2 or <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2270"/> - <source>sweep_all [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] [outputs=<N>] <address> [<payment_id>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2271"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2609"/> <source>Send all unlocked balance to an address. If the parameter "index<N1>[,<N2>,...]" is specified, the wallet sweeps outputs received by those address indices. If omitted, the wallet randomly chooses an address index to be used. If the parameter "outputs=<N>" is specified and N > 0, wallet splits the transaction into N even outputs.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2278"/> - <source>sweep_single [<priority>] [<ring_size>] [outputs=<N>] <key_image> <address> [<payment_id>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2341"/> - <source>Available options: - seed language - Set the wallet's 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 the default ring size (default and minimum is 5). - auto-refresh <1|0> - Whether to automatically synchronize new blocks from the daemon. - refresh-type <full|optimize-coinbase|no-coinbase|default> - Set the wallet's refresh behaviour. - priority [0|1|2|3|4] - Set the fee to default/unimportant/normal/elevated/priority. - confirm-missing-payment-id <1|0> - ask-password <0|1|2 (or never|action|decrypt)> - unit <monero|millinero|micronero|nanonero|piconero> - Set the 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] - Set a threshold for confirm-backlog to only warn if the transaction backlog is greater than n blocks. - refresh-from-block-height [n] - Set the height before which to ignore blocks. - auto-low-priority <1|0> - Whether to automatically use the low priority fee level when it's safe to do so. - segregate-pre-fork-outputs <1|0> - Set this if you intend to spend outputs on both Monero AND a key reusing fork. - key-reuse-mitigation2 <1|0> - Set this if you are not sure whether you will spend on a key reusing Monero fork later. -subaddress-lookahead <major>:<minor> - Set the lookahead sizes for the subaddress hash table. - Set this if you are not sure whether you will spend on a key reusing Monero fork later. - segregation-height <n> - Set to the height of a key reusing fork you want to use, 0 to use default.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2545"/> - <source>blackball <amount>/<offset> | <filename> [add]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2549"/> - <source>unblackball <amount>/<offset></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2553"/> - <source>blackballed <amount>/<offset></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4160"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4608"/> <source>Password needed (%s) - use the refresh command</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5609"/> - <source>usage: sweep_single [<priority>] [<ring_size>] [outputs=<N>] <key_image> <address> [<payment_id>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6968"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7797"/> <source>wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6970"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7799"/> <source> (no daemon)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6972"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7801"/> <source> (out of sync)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7029"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7852"/> <source>(Untitled account)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7042"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7060"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7085"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7108"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7261"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7284"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7865"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7883"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7908"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7931"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8077"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8100"/> <source>failed to parse index: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7047"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7266"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7870"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8082"/> <source>specify an index between 0 and </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7144"/> - <source>usage: - account - account new <label text with white spaces allowed> - account switch <index> - account label <index> <label text with white spaces allowed> - account tag <tag_name> <account_index_1> [<account_index_2> ...] - account untag <account_index_1> [<account_index_2> ...] - account tag_description <tag_name> <description></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7172"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7988"/> <source> Grand total: Balance: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7172"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7988"/> <source>, unlocked balance: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7180"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7996"/> <source>Untagged accounts:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7186"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8002"/> <source>Tag %s is unregistered.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7189"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8005"/> <source>Accounts with tag: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7190"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8006"/> <source>Tag's description: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7192"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8008"/> <source>Account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7198"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8014"/> <source> %c%8u %6s %21s %21s %21s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7208"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8024"/> <source>----------------------------------------------------------------------------------</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7209"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8025"/> <source>%15s %21s %21s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7232"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8048"/> <source>Primary address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7232"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8048"/> <source>(used)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7253"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8069"/> <source>(Untitled address)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7293"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8109"/> <source><index_min> is already out of bound</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7298"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8114"/> <source><index_max> exceeds the bound</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7306"/> - <source>usage: address [ new <label text with white spaces allowed> | all | <index_min> [<index_max>] | label <index> <label text with white spaces allowed> ]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7317"/> - <source>usage: integrated_address [payment ID]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7324"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7336"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8140"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8152"/> <source>Integrated addresses can only be created for account 0</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7329"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8145"/> <source>Matching integrated address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7348"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8164"/> <source>Integrated address: %s, payment ID: %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7353"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8169"/> <source>Subaddress: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7353"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8169"/> <source>Standard address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7358"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8174"/> <source>failed to parse payment ID or address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7369"/> - <source>usage: address_book [(add (<address> [pid <long or short payment id>])|<integrated address> [<description possibly with whitespaces>])|(delete <index>)]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7399"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8215"/> <source>failed to parse payment ID</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7417"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8233"/> <source>failed to parse index</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7425"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8241"/> <source>Address book is empty.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7431"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8247"/> <source>Index: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7432"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7562"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8248"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8378"/> <source>Address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7433"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8249"/> <source>Payment ID: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7434"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7561"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8250"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8377"/> <source>Description: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7444"/> - <source>usage: set_tx_note [txid] free text note</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7472"/> - <source>usage: get_tx_note [txid]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7513"/> - <source>usage: get_description</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7519"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8335"/> <source>no description found</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7521"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8337"/> <source>description found: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7560"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8376"/> <source>Filename: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7565"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8381"/> <source>Watch only</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7567"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8383"/> <source>%u/%u multisig%s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5926"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6571"/> <source>%s change to %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6263"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6336"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6908"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6981"/> <source>This transaction has %u confirmations</source> <translation type="unfinished"></translation> </message> @@ -4295,365 +4557,505 @@ Grand total: <translation type="unfinished"></translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="150"/> - <source>Error finalizing multisig</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="157"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="153"/> <source>Generated multisig wallets for address </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="161"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="157"/> <source>Error creating multisig wallets: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="186"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="182"/> <source>This program generates a set of multisig wallets - use this simpler scheme only if all the participants trust each other</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="205"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="201"/> <source>Error: Can't specify more than one of --testnet and --stagenet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="212"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="208"/> <source>Error: expected N/M, but got: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="220"/> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="229"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="216"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="225"/> <source>Error: either --scheme or both of --threshold and --participants may be given</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="236"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="232"/> <source>Error: expected N > 1 and N <= M, but got N==%u and M==%d</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="245"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="241"/> <source>Error: --filename-base is required</source> <translation type="unfinished"></translation> </message> +</context> +<context> + <name>mms::message_store</name> + <message> + <location filename="../src/wallet/message_store.cpp" line="69"/> + <source>Use PyBitmessage instance at URL <arg></source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="251"/> - <source>Error: unsupported scheme: only N/N and N-1/N are supported</source> + <location filename="../src/wallet/message_store.cpp" line="70"/> + <source>Specify <arg> as username:password for PyBitmessage API</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="832"/> + <source>Auto-config cannot proceed because auto config data from other signers is not complete</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="857"/> + <source>The signer config is not complete.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="909"/> + <source>Wallet can't go multisig because key sets from other signers are missing or not complete.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="951"/> + <source>Wallet can't start another key exchange round because key sets from other signers are missing or not complete.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1015"/> + <source>Syncing not done because multisig sync data from other signers are missing or not complete.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1129"/> + <source>There are waiting messages, but nothing is ready to process under normal circumstances</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1132"/> + <source> +Use "mms next sync" if you want to force processing of the waiting sync data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1136"/> + <source> +Use "mms note" to display the waiting notes</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1141"/> + <source>There are no messages waiting to be processed.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1359"/> + <source>key set</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1361"/> + <source>additional key set</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1363"/> + <source>multisig sync data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1365"/> + <source>partially signed tx</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1367"/> + <source>fully signed tx</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1369"/> + <source>note</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1371"/> + <source>signer config</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1373"/> + <source>auto-config data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1375"/> + <source>unknown message type</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1384"/> + <source>in</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1386"/> + <source>out</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1388"/> + <source>unknown message direction</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1397"/> + <source>ready to send</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1399"/> + <source>sent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1401"/> + <source>waiting</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1403"/> + <source>processed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1405"/> + <source>cancelled</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1407"/> + <source>unknown message state</source> <translation type="unfinished"></translation> </message> </context> <context> <name>sw</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="119"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="125"/> <source>Generate new wallet and save it to <arg></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="120"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="126"/> <source>Generate new wallet from device and save it to <arg></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="121"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="127"/> <source>Generate incoming-only wallet from view key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="122"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="128"/> <source>Generate deterministic wallet from spend key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="123"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="129"/> <source>Generate wallet from private keys</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="124"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="130"/> <source>Generate a master wallet from multisig wallet keys</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="126"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="132"/> <source>Language for mnemonic</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="127"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="133"/> <source>Specify Electrum seed for wallet recovery/creation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="128"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="134"/> <source>Recover wallet using Electrum-style mnemonic seed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="129"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="135"/> <source>Recover multisig wallet using Electrum-style mnemonic seed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="130"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="136"/> <source>Generate non-deterministic view and spend keys</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="183"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="276"/> <source>failed to read wallet password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="190"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="283"/> <source>Enter a new password for the wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="190"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="283"/> <source>Wallet password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="268"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="361"/> <source>invalid argument: must be either 0/1, true/false, y/n, yes/no</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="324"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="417"/> <source>DNSSEC validation passed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="328"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="421"/> <source>WARNING: DNSSEC validation was unsuccessful, this address may not be correct!</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="331"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="424"/> <source>For URL: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="333"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="426"/> <source> Monero Address = </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="335"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="428"/> <source>Is this OK? (Y/n) </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="345"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="438"/> <source>you have cancelled the transfer request</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="366"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="459"/> <source>failed to parse index: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="379"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="472"/> <source>invalid format for subaddress lookahead; must be <major>:<minor></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="396"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="489"/> <source>no connection to daemon. Please make sure daemon is running.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="401"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="494"/> <source>RPC error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="405"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="498"/> <source>failed to get random outputs to mix: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="412"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="420"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="505"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="513"/> <source>Not enough money in unlocked balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="430"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="523"/> <source>Failed to find a way to create transactions. This is usually due to dust which is so small it cannot pay for itself in fees, or trying to send more money than the unlocked balance, or not leaving enough for fees</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="436"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="529"/> <source>not enough outputs for specified ring size</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="439"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="532"/> <source>output amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="439"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="532"/> <source>found outputs to use</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="441"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="534"/> <source>Please use sweep_unmixable.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="445"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="538"/> <source>transaction was not constructed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="450"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="543"/> <source>transaction %s was rejected by daemon with status: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="453"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="546"/> <source>Reason: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="462"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="555"/> <source>one of destinations is zero</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="467"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="560"/> <source>failed to find a suitable way to split transactions</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="473"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="566"/> <source>unknown transfer error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="478"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="571"/> <source>Multisig error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="484"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="577"/> <source>internal error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="489"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="582"/> <source>unexpected error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="493"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="586"/> <source>There was an error, which could mean the node may be trying to get you to retry creating a transaction, and zero in on which outputs you own. Or it could be a bona fide error. It may be prudent to disconnect from this node, and not try to send a transaction immediately. Alternatively, connect to another node so the original node cannot correlate information.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="503"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="596"/> <source>File %s likely stores wallet private keys! Use a different file name.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="506"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="599"/> <source>File %s already exists. Are you sure to overwrite it? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6580"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7195"/> <source> seconds</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6582"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7197"/> <source> minutes</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6584"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7199"/> <source> hours</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6586"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7201"/> <source> days</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6588"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7203"/> <source> months</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6589"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7204"/> <source>a long time</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="8074"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8940"/> <source>This is the command line monero wallet. It needs to connect to a monero daemon to work correctly. WARNING: Do not reuse your Monero keys on another fork, UNLESS this fork has key reuse mitigations built in. Doing so will harm your privacy.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="8099"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8965"/> <source>Unknown command: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="131"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="137"/> <source>Allow communicating with a daemon that uses a different RPC version</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="132"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="138"/> <source>Restore from specific blockchain height</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="133"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="139"/> <source>The newly created transaction will not be relayed to the monero network</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="134"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="140"/> <source>Create an address file for new wallets</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="136"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="142"/> <source>Display English language names</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="200"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="392"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="293"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="485"/> <source>daemon is busy. Please try again later.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="209"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="302"/> <source>possibly lost connection to daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="226"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="319"/> <source>Error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="8093"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8959"/> <source>Failed to initialize wallet</source> <translation type="unfinished"></translation> </message> @@ -4661,228 +5063,233 @@ WARNING: Do not reuse your Monero keys on another fork, UNLESS this fork has key <context> <name>tools::wallet2</name> <message> - <location filename="../src/wallet/wallet2.cpp" line="142"/> + <location filename="../src/wallet/wallet2.cpp" line="201"/> <source>Use daemon instance at <host>:<port></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="143"/> + <location filename="../src/wallet/wallet2.cpp" line="202"/> <source>Use daemon instance at host <arg> instead of localhost</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="147"/> + <location filename="../src/wallet/wallet2.cpp" line="206"/> <source>Wallet password file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="148"/> + <location filename="../src/wallet/wallet2.cpp" line="207"/> <source>Use daemon instance at port <arg> instead of 18081</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="150"/> + <location filename="../src/wallet/wallet2.cpp" line="209"/> <source>For testnet. Daemon must also be launched with --testnet flag</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="220"/> + <location filename="../src/wallet/wallet2.cpp" line="282"/> <source>can't specify daemon host or port more than once</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="291"/> + <location filename="../src/wallet/wallet2.cpp" line="355"/> <source>can't specify more than one of --password and --password-file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="304"/> + <location filename="../src/wallet/wallet2.cpp" line="368"/> <source>the password file specified could not be read</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="330"/> + <location filename="../src/wallet/wallet2.cpp" line="394"/> <source>Failed to load file </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="146"/> + <location filename="../src/wallet/wallet2.cpp" line="205"/> <source>Wallet password (escape/quote as needed)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="144"/> + <location filename="../src/wallet/wallet2.cpp" line="203"/> <source>Enable commands which rely on a trusted daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="145"/> + <location filename="../src/wallet/wallet2.cpp" line="204"/> <source>Disable commands which rely on a trusted daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="149"/> + <location filename="../src/wallet/wallet2.cpp" line="208"/> <source>Specify username[:password] for daemon RPC client</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="151"/> + <location filename="../src/wallet/wallet2.cpp" line="210"/> <source>For stagenet. Daemon must also be launched with --stagenet flag</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="153"/> + <location filename="../src/wallet/wallet2.cpp" line="212"/> <source>Set shared ring database path</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="164"/> + <location filename="../src/wallet/wallet2.cpp" line="223"/> <source>Number of rounds for the key derivation function</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="165"/> + <location filename="../src/wallet/wallet2.cpp" line="224"/> <source>HW device to use</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="251"/> + <location filename="../src/wallet/wallet2.cpp" line="225"/> + <source>HW device wallet derivation path (e.g., SLIP-10)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="313"/> <source>--trusted-daemon and --untrusted-daemon are both seen, assuming untrusted</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="261"/> + <location filename="../src/wallet/wallet2.cpp" line="323"/> <source>Daemon is local, assuming trusted</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="311"/> + <location filename="../src/wallet/wallet2.cpp" line="375"/> <source>no password specified; use --prompt-for-password to prompt for a password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="313"/> + <location filename="../src/wallet/wallet2.cpp" line="377"/> <source>Enter a new password for the wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="313"/> + <location filename="../src/wallet/wallet2.cpp" line="377"/> <source>Wallet password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="336"/> + <location filename="../src/wallet/wallet2.cpp" line="400"/> <source>Failed to parse JSON</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="343"/> + <location filename="../src/wallet/wallet2.cpp" line="407"/> <source>Version %u too new, we can only grok up to %u</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="359"/> + <location filename="../src/wallet/wallet2.cpp" line="423"/> <source>failed to parse view key secret key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="364"/> - <location filename="../src/wallet/wallet2.cpp" line="432"/> - <location filename="../src/wallet/wallet2.cpp" line="475"/> + <location filename="../src/wallet/wallet2.cpp" line="428"/> + <location filename="../src/wallet/wallet2.cpp" line="496"/> + <location filename="../src/wallet/wallet2.cpp" line="539"/> <source>failed to verify view key secret key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="375"/> + <location filename="../src/wallet/wallet2.cpp" line="439"/> <source>failed to parse spend key secret key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="380"/> - <location filename="../src/wallet/wallet2.cpp" line="442"/> - <location filename="../src/wallet/wallet2.cpp" line="501"/> + <location filename="../src/wallet/wallet2.cpp" line="444"/> + <location filename="../src/wallet/wallet2.cpp" line="506"/> + <location filename="../src/wallet/wallet2.cpp" line="565"/> <source>failed to verify spend key secret key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="392"/> + <location filename="../src/wallet/wallet2.cpp" line="456"/> <source>Electrum-style word list failed verification</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="412"/> + <location filename="../src/wallet/wallet2.cpp" line="476"/> <source>At least one of either an Electrum-style word list, private view key, or private spend key must be specified</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="416"/> + <location filename="../src/wallet/wallet2.cpp" line="480"/> <source>Both Electrum-style word list and private key(s) specified</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="426"/> + <location filename="../src/wallet/wallet2.cpp" line="490"/> <source>invalid address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="435"/> + <location filename="../src/wallet/wallet2.cpp" line="499"/> <source>view key does not match standard address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="445"/> + <location filename="../src/wallet/wallet2.cpp" line="509"/> <source>spend key does not match standard address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="453"/> + <location filename="../src/wallet/wallet2.cpp" line="517"/> <source>Cannot generate deprecated wallets from JSON</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="487"/> + <location filename="../src/wallet/wallet2.cpp" line="551"/> <source>failed to parse address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="493"/> + <location filename="../src/wallet/wallet2.cpp" line="557"/> <source>Address must be specified in order to create watch-only wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="510"/> + <location filename="../src/wallet/wallet2.cpp" line="574"/> <source>failed to generate new wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="1271"/> + <location filename="../src/wallet/wallet2.cpp" line="1382"/> <source>Password is needed to compute key image for incoming monero</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="1272"/> + <location filename="../src/wallet/wallet2.cpp" line="1383"/> <source>Invalid password: password is needed to compute key image for incoming monero</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="3496"/> - <location filename="../src/wallet/wallet2.cpp" line="4062"/> - <location filename="../src/wallet/wallet2.cpp" line="4495"/> + <location filename="../src/wallet/wallet2.cpp" line="3770"/> + <location filename="../src/wallet/wallet2.cpp" line="4374"/> + <location filename="../src/wallet/wallet2.cpp" line="4926"/> <source>Primary account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="9547"/> + <location filename="../src/wallet/wallet2.cpp" line="10157"/> <source>No funds received in this tx.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="10261"/> + <location filename="../src/wallet/wallet2.cpp" line="10899"/> <source>failed to read file </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="135"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="141"/> <source>Set subaddress lookahead sizes to <major>:<minor></source> <translation type="unfinished"></translation> </message> @@ -4935,80 +5342,80 @@ WARNING: Do not reuse your Monero keys on another fork, UNLESS this fork has key <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2877"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3081"/> <source>Transaction not possible. Available only %s, transaction amount %s = %s + %s (fee)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3495"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3947"/> <source>This is the RPC monero wallet. It needs to connect to a monero daemon to work correctly.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3321"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3773"/> <source>Can't specify more than one of --testnet and --stagenet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3336"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3788"/> <source>Can't specify more than one of --wallet-file and --generate-from-json</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3348"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3800"/> <source>Must specify --wallet-file or --generate-from-json or --wallet-dir</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3352"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3804"/> <source>Loading wallet...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3386"/> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3418"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3838"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3870"/> <source>Saving wallet...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3388"/> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3420"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3840"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3872"/> <source>Successfully saved</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3391"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3843"/> <source>Successfully loaded</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3395"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3847"/> <source>Wallet initialization failed: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3401"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3853"/> <source>Failed to initialize wallet RPC server</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3405"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3857"/> <source>Starting wallet RPC server</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3412"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3864"/> <source>Failed to run wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3415"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3867"/> <source>Stopped wallet RPC server</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3424"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3876"/> <source>Failed to save wallet: </source> <translation type="unfinished"></translation> </message> @@ -5016,9 +5423,9 @@ daemon to work correctly.</source> <context> <name>wallet_args</name> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="172"/> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3476"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="8042"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="168"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8908"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3928"/> <source>Wallet options</source> <translation type="unfinished"></translation> </message> @@ -5074,6 +5481,16 @@ daemon to work correctly.</source> <translation type="unfinished"></translation> </message> <message> + <location filename="../src/wallet/wallet_args.cpp" line="216"/> + <source>WARNING: You may not have a high enough lockable memory limit</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="218"/> + <source>see ulimit -l</source> + <translation type="unfinished"></translation> + </message> + <message> <location filename="../src/wallet/wallet_args.cpp" line="146"/> <source>Usage:</source> <translation type="unfinished"></translation> diff --git a/translations/monero_fr.ts b/translations/monero_fr.ts index 238ba17df..6576043d3 100644 --- a/translations/monero_fr.ts +++ b/translations/monero_fr.ts @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> -<TS version="2.1" language="fr_FR"> +<TS version="2.0" language="fr_FR"> <context> <name>Monero::AddressBookImpl</name> <message> @@ -29,7 +29,7 @@ <message> <location filename="../src/wallet/api/pending_transaction.cpp" line="91"/> <source>Attempting to save transaction to file, but specified file(s) exist. Exiting to not risk overwriting. File:</source> - <translation>Tentative d'enregistrement d'une transaction dans un fichier, mais le fichier spécifié existe déjà. Sortie pour ne pas risquer de l'écraser. Fichier :</translation> + <translation>Tentative d'enregistrement d'une transaction dans un fichier, mais le fichier spécifié existe déjà. Sortie pour ne pas risquer de l'écraser. Fichier :</translation> </message> <message> <location filename="../src/wallet/api/pending_transaction.cpp" line="98"/> @@ -49,17 +49,17 @@ <message> <location filename="../src/wallet/api/pending_transaction.cpp" line="128"/> <source>transaction %s was rejected by daemon with status: </source> - <translation>la transaction %s a été rejetée par le démon avec le statut : </translation> + <translation>la transaction %s a été rejetée par le démon avec le statut : </translation> </message> <message> <location filename="../src/wallet/api/pending_transaction.cpp" line="133"/> <source>. Reason: </source> - <translation>. Raison : </translation> + <translation>. Raison : </translation> </message> <message> <location filename="../src/wallet/api/pending_transaction.cpp" line="135"/> <source>Unknown exception: </source> - <translation>Exception inconnue : </translation> + <translation>Exception inconnue : </translation> </message> <message> <location filename="../src/wallet/api/pending_transaction.cpp" line="138"/> @@ -134,383 +134,384 @@ <context> <name>Monero::WalletImpl</name> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1354"/> + <location filename="../src/wallet/api/wallet.cpp" line="1383"/> <source>payment id has invalid format, expected 16 or 64 character hex string: </source> - <translation>format d'identifiant de paiement invalide, 16 ou 64 caractères hexadécimaux attendus : </translation> + <translation>format d'identifiant de paiement invalide, 16 ou 64 caractères hexadécimaux attendus : </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1363"/> + <location filename="../src/wallet/api/wallet.cpp" line="1392"/> <source>Failed to add short payment id: </source> - <translation>Échec de l'ajout de l'ID de paiement court : </translation> + <translation>Échec de l'ajout de l'ID de paiement court : </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1399"/> - <location filename="../src/wallet/api/wallet.cpp" line="1481"/> + <location filename="../src/wallet/api/wallet.cpp" line="1428"/> + <location filename="../src/wallet/api/wallet.cpp" line="1510"/> <source>daemon is busy. Please try again later.</source> <translation>le démon est occupé. Veuillez réessayer plus tard.</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1401"/> - <location filename="../src/wallet/api/wallet.cpp" line="1483"/> + <location filename="../src/wallet/api/wallet.cpp" line="1430"/> + <location filename="../src/wallet/api/wallet.cpp" line="1512"/> <source>no connection to daemon. Please make sure daemon is running.</source> <translation>pas de connexion au démon. Veuillez vous assurer que le démon fonctionne.</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1403"/> - <location filename="../src/wallet/api/wallet.cpp" line="1485"/> + <location filename="../src/wallet/api/wallet.cpp" line="1432"/> + <location filename="../src/wallet/api/wallet.cpp" line="1514"/> <source>RPC error: </source> - <translation>Erreur RPC : </translation> + <translation>Erreur RPC : </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1431"/> - <location filename="../src/wallet/api/wallet.cpp" line="1516"/> + <location filename="../src/wallet/api/wallet.cpp" line="1460"/> + <location filename="../src/wallet/api/wallet.cpp" line="1545"/> <source>not enough outputs for specified ring size</source> <translation>pas assez de sorties pour la taille de cercle spécifiée</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1433"/> - <location filename="../src/wallet/api/wallet.cpp" line="1518"/> + <location filename="../src/wallet/api/wallet.cpp" line="1462"/> + <location filename="../src/wallet/api/wallet.cpp" line="1547"/> <source>found outputs to use</source> <translation>sorties à utiliser trouvées</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1435"/> + <location filename="../src/wallet/api/wallet.cpp" line="1464"/> <source>Please sweep unmixable outputs.</source> <translation>Veuillez balayer les sorties non mélangeables.</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1409"/> - <location filename="../src/wallet/api/wallet.cpp" line="1492"/> + <location filename="../src/wallet/api/wallet.cpp" line="1438"/> + <location filename="../src/wallet/api/wallet.cpp" line="1521"/> <source>not enough money to transfer, available only %s, sent amount %s</source> <translation>pas assez de fonds pour le transfert, montant disponible %s, montant envoyé %s</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="540"/> + <location filename="../src/wallet/api/wallet.cpp" line="541"/> <source>failed to parse address</source> <translation>échec de l'analyse de l'adresse</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="551"/> + <location filename="../src/wallet/api/wallet.cpp" line="552"/> <source>failed to parse secret spend key</source> <translation>échec de l'analyse de la clé secrète de dépense</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="574"/> + <location filename="../src/wallet/api/wallet.cpp" line="575"/> <source>failed to parse secret view key</source> <translation>échec de l'analyse de la clé secrète d'audit</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="583"/> + <location filename="../src/wallet/api/wallet.cpp" line="584"/> <source>failed to verify secret spend key</source> <translation>échec de la vérification de la clé secrète de dépense</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="587"/> + <location filename="../src/wallet/api/wallet.cpp" line="588"/> <source>spend key does not match address</source> <translation>la clé de dépense ne correspond pas à l'adresse</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="593"/> + <location filename="../src/wallet/api/wallet.cpp" line="594"/> <source>failed to verify secret view key</source> <translation>échec de la vérification de la clé secrète d'audit</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="597"/> + <location filename="../src/wallet/api/wallet.cpp" line="598"/> <source>view key does not match address</source> <translation>la clé d'audit ne correspond pas à l'adresse</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="620"/> - <location filename="../src/wallet/api/wallet.cpp" line="637"/> + <location filename="../src/wallet/api/wallet.cpp" line="621"/> + <location filename="../src/wallet/api/wallet.cpp" line="638"/> <source>failed to generate new wallet: </source> - <translation>échec de la génération du nouveau portefeuille : </translation> + <translation>échec de la génération du nouveau portefeuille : </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="884"/> + <location filename="../src/wallet/api/wallet.cpp" line="885"/> <source>Failed to send import wallet request</source> <translation>Échec de l'envoi de la requête d'importation de portefeuille</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1034"/> + <location filename="../src/wallet/api/wallet.cpp" line="1049"/> <source>Failed to load unsigned transactions</source> <translation>Échec du chargement des transaction non signées</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1053"/> + <location filename="../src/wallet/api/wallet.cpp" line="1068"/> <source>Failed to load transaction from file</source> <translation>Échec du chargement de la transaction du fichier</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1069"/> + <location filename="../src/wallet/api/wallet.cpp" line="1084"/> <source>Wallet is view only</source> <translation>Portefeuille d'audit uniquement</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1077"/> + <location filename="../src/wallet/api/wallet.cpp" line="1092"/> <source>failed to save file </source> <translation>échec de l'enregistrement du fichier </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1093"/> + <location filename="../src/wallet/api/wallet.cpp" line="1108"/> <source>Key images can only be imported with a trusted daemon</source> <translation>Les images de clé ne peuvent être importées qu'avec un démon de confiance</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1106"/> + <location filename="../src/wallet/api/wallet.cpp" line="1121"/> <source>Failed to import key images: </source> - <translation>Échec de l'importation des images de clé : </translation> + <translation>Échec de l'importation des images de clé : </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1138"/> + <location filename="../src/wallet/api/wallet.cpp" line="1153"/> <source>Failed to get subaddress label: </source> - <translation>Échec de la récupération de l'étiquette de sous-adresse : </translation> + <translation>Échec de la récupération de l'étiquette de sous-adresse : </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1151"/> + <location filename="../src/wallet/api/wallet.cpp" line="1166"/> <source>Failed to set subaddress label: </source> - <translation>Échec de l'affectation de l'étiquette de sous-adresse : </translation> + <translation>Échec de l'affectation de l'étiquette de sous-adresse : </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="566"/> + <location filename="../src/wallet/api/wallet.cpp" line="567"/> <source>Neither view key nor spend key supplied, cancelled</source> <translation>Ni clé d'audit ni clé de dépense fournie, annulation</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="685"/> + <location filename="../src/wallet/api/wallet.cpp" line="686"/> <source>Electrum seed is empty</source> <translation>La phrase Electrum est vide</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="694"/> + <location filename="../src/wallet/api/wallet.cpp" line="695"/> <source>Electrum-style word list failed verification</source> <translation>Échec de la vérification de la liste de mots de style Electrum</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1168"/> + <location filename="../src/wallet/api/wallet.cpp" line="1183"/> <source>Failed to get multisig info: </source> <translation>Échec de la récupération des infos multisig : </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1185"/> + <location filename="../src/wallet/api/wallet.cpp" line="1200"/> + <location filename="../src/wallet/api/wallet.cpp" line="1214"/> <source>Failed to make multisig: </source> <translation>Échec de la création multisig : </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1200"/> + <location filename="../src/wallet/api/wallet.cpp" line="1229"/> <source>Failed to finalize multisig wallet creation</source> <translation>Échec de la finalisation de la création du portefeuille multisig</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1203"/> + <location filename="../src/wallet/api/wallet.cpp" line="1232"/> <source>Failed to finalize multisig wallet creation: </source> <translation>Échec de la finalisation de la création du portefeuille multisig : </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1219"/> + <location filename="../src/wallet/api/wallet.cpp" line="1248"/> <source>Failed to export multisig images: </source> <translation>Échec de l'exportation des images multisig : </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1237"/> + <location filename="../src/wallet/api/wallet.cpp" line="1266"/> <source>Failed to parse imported multisig images</source> <translation>Échec de l'analyse des images multisig importées</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1247"/> + <location filename="../src/wallet/api/wallet.cpp" line="1276"/> <source>Failed to import multisig images: </source> <translation>Échec de l'importation des images multisig : </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1261"/> + <location filename="../src/wallet/api/wallet.cpp" line="1290"/> <source>Failed to check for partial multisig key images: </source> <translation>Échec de la vérification des images de clé multisig partielles : </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1289"/> + <location filename="../src/wallet/api/wallet.cpp" line="1318"/> <source>Failed to restore multisig transaction: </source> <translation>Échec de la restauration de la transaction multisig : </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1329"/> + <location filename="../src/wallet/api/wallet.cpp" line="1358"/> <source>Invalid destination address</source> <translation>Adresse de destination invalide</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1405"/> + <location filename="../src/wallet/api/wallet.cpp" line="1434"/> <source>failed to get outputs to mix: %s</source> <translation>échec de la récupération de sorties à mélanger : %s</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1416"/> - <location filename="../src/wallet/api/wallet.cpp" line="1500"/> + <location filename="../src/wallet/api/wallet.cpp" line="1445"/> + <location filename="../src/wallet/api/wallet.cpp" line="1529"/> <source>not enough money to transfer, overall balance only %s, sent amount %s</source> <translation>pas assez de fonds pour le transfer, solde global disponible %s, montant envoyé %s</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1423"/> - <location filename="../src/wallet/api/wallet.cpp" line="1508"/> + <location filename="../src/wallet/api/wallet.cpp" line="1452"/> + <location filename="../src/wallet/api/wallet.cpp" line="1537"/> <source>not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)</source> <translation>pas assez de fonds pour le transfert, montant disponible %s, montant envoyé %s = %s + %s (frais)</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1433"/> - <location filename="../src/wallet/api/wallet.cpp" line="1518"/> + <location filename="../src/wallet/api/wallet.cpp" line="1462"/> + <location filename="../src/wallet/api/wallet.cpp" line="1547"/> <source>output amount</source> <translation>montant de la sortie</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1438"/> - <location filename="../src/wallet/api/wallet.cpp" line="1522"/> + <location filename="../src/wallet/api/wallet.cpp" line="1467"/> + <location filename="../src/wallet/api/wallet.cpp" line="1551"/> <source>transaction was not constructed</source> <translation>la transaction n'a pas été construite</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1441"/> - <location filename="../src/wallet/api/wallet.cpp" line="1525"/> + <location filename="../src/wallet/api/wallet.cpp" line="1470"/> + <location filename="../src/wallet/api/wallet.cpp" line="1554"/> <source>transaction %s was rejected by daemon with status: </source> - <translation>la transaction %s a été rejetée par le démon avec le statut : </translation> + <translation>la transaction %s a été rejetée par le démon avec le statut : </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1446"/> - <location filename="../src/wallet/api/wallet.cpp" line="1530"/> + <location filename="../src/wallet/api/wallet.cpp" line="1475"/> + <location filename="../src/wallet/api/wallet.cpp" line="1559"/> <source>one of destinations is zero</source> <translation>une des destinations est zéro</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1448"/> - <location filename="../src/wallet/api/wallet.cpp" line="1532"/> + <location filename="../src/wallet/api/wallet.cpp" line="1477"/> + <location filename="../src/wallet/api/wallet.cpp" line="1561"/> <source>failed to find a suitable way to split transactions</source> <translation>échec de la recherche d'une façon adéquate de scinder les transactions</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1450"/> - <location filename="../src/wallet/api/wallet.cpp" line="1534"/> + <location filename="../src/wallet/api/wallet.cpp" line="1479"/> + <location filename="../src/wallet/api/wallet.cpp" line="1563"/> <source>unknown transfer error: </source> - <translation>erreur de transfert inconnue : </translation> + <translation>erreur de transfert inconnue : </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1452"/> - <location filename="../src/wallet/api/wallet.cpp" line="1536"/> + <location filename="../src/wallet/api/wallet.cpp" line="1481"/> + <location filename="../src/wallet/api/wallet.cpp" line="1565"/> <source>internal error: </source> - <translation>erreur interne : </translation> + <translation>erreur interne : </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1454"/> - <location filename="../src/wallet/api/wallet.cpp" line="1538"/> + <location filename="../src/wallet/api/wallet.cpp" line="1483"/> + <location filename="../src/wallet/api/wallet.cpp" line="1567"/> <source>unexpected error: </source> - <translation>erreur inattendue : </translation> + <translation>erreur inattendue : </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1456"/> - <location filename="../src/wallet/api/wallet.cpp" line="1540"/> + <location filename="../src/wallet/api/wallet.cpp" line="1485"/> + <location filename="../src/wallet/api/wallet.cpp" line="1569"/> <source>unknown error</source> <translation>erreur inconnue</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1487"/> + <location filename="../src/wallet/api/wallet.cpp" line="1516"/> <source>failed to get outputs to mix</source> <translation>échec de la récupération de sorties à mélanger</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1615"/> - <location filename="../src/wallet/api/wallet.cpp" line="1642"/> - <location filename="../src/wallet/api/wallet.cpp" line="1690"/> - <location filename="../src/wallet/api/wallet.cpp" line="1718"/> - <location filename="../src/wallet/api/wallet.cpp" line="1746"/> - <location filename="../src/wallet/api/wallet.cpp" line="1767"/> - <location filename="../src/wallet/api/wallet.cpp" line="2222"/> + <location filename="../src/wallet/api/wallet.cpp" line="1644"/> + <location filename="../src/wallet/api/wallet.cpp" line="1671"/> + <location filename="../src/wallet/api/wallet.cpp" line="1719"/> + <location filename="../src/wallet/api/wallet.cpp" line="1747"/> + <location filename="../src/wallet/api/wallet.cpp" line="1775"/> + <location filename="../src/wallet/api/wallet.cpp" line="1796"/> + <location filename="../src/wallet/api/wallet.cpp" line="2258"/> <source>Failed to parse txid</source> <translation>Échec de l'analyse de l'ID de transaction</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1632"/> + <location filename="../src/wallet/api/wallet.cpp" line="1661"/> <source>no tx keys found for this txid</source> <translation>aucune clé de transaction trouvée pour cet ID de transaction</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1650"/> - <location filename="../src/wallet/api/wallet.cpp" line="1659"/> + <location filename="../src/wallet/api/wallet.cpp" line="1679"/> + <location filename="../src/wallet/api/wallet.cpp" line="1688"/> <source>Failed to parse tx key</source> <translation>Échec de l'analyse de la clé de transaction</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1668"/> <location filename="../src/wallet/api/wallet.cpp" line="1697"/> - <location filename="../src/wallet/api/wallet.cpp" line="1725"/> - <location filename="../src/wallet/api/wallet.cpp" line="1806"/> + <location filename="../src/wallet/api/wallet.cpp" line="1726"/> + <location filename="../src/wallet/api/wallet.cpp" line="1754"/> + <location filename="../src/wallet/api/wallet.cpp" line="1835"/> <source>Failed to parse address</source> <translation>Échec de l'analyse de l'adresse</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1811"/> + <location filename="../src/wallet/api/wallet.cpp" line="1840"/> <source>Address must not be a subaddress</source> <translation>L'adresse ne doit pas être une sous-adresse</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1851"/> + <location filename="../src/wallet/api/wallet.cpp" line="1880"/> <source>The wallet must be in multisig ready state</source> <translation>Le portefeuille doit être multisig et prêt</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1873"/> + <location filename="../src/wallet/api/wallet.cpp" line="1902"/> <source>Given string is not a key</source> <translation>La chaîne entrée n'est pas une clé</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="2094"/> + <location filename="../src/wallet/api/wallet.cpp" line="2130"/> <source>Rescan spent can only be used with a trusted daemon</source> <translation>Réexaminer les dépenses ne peut se faire qu'avec un démon de confiance</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="2143"/> + <location filename="../src/wallet/api/wallet.cpp" line="2179"/> <source>Invalid output: </source> <translation>Sortie invalide : </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="2150"/> - <source>Failed to set blackballed outputs</source> - <translation>Échec de l'affectation des sorties blackboulées</translation> + <location filename="../src/wallet/api/wallet.cpp" line="2186"/> + <source>Failed to mark outputs as spent</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="2161"/> - <location filename="../src/wallet/api/wallet.cpp" line="2183"/> - <source>Failed to parse output amount</source> - <translation>Échec de l'analyse du montant de la sortie</translation> + <location filename="../src/wallet/api/wallet.cpp" line="2208"/> + <source>Failed to mark output as spent</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="2166"/> - <location filename="../src/wallet/api/wallet.cpp" line="2188"/> - <source>Failed to parse output offset</source> - <translation>Échec de l'analyse de l'offset de la sortie</translation> + <location filename="../src/wallet/api/wallet.cpp" line="2230"/> + <source>Failed to mark output as unspent</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="2172"/> - <source>Failed to blackball output</source> - <translation>Échec du blackboulage de la sortie</translation> + <location filename="../src/wallet/api/wallet.cpp" line="2197"/> + <location filename="../src/wallet/api/wallet.cpp" line="2219"/> + <source>Failed to parse output amount</source> + <translation>Échec de l'analyse du montant de la sortie</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="2194"/> - <source>Failed to unblackball output</source> - <translation>Échec du déblackboulage de la sortie</translation> + <location filename="../src/wallet/api/wallet.cpp" line="2202"/> + <location filename="../src/wallet/api/wallet.cpp" line="2224"/> + <source>Failed to parse output offset</source> + <translation>Échec de l'analyse de l'offset de la sortie</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="2205"/> - <location filename="../src/wallet/api/wallet.cpp" line="2244"/> + <location filename="../src/wallet/api/wallet.cpp" line="2241"/> + <location filename="../src/wallet/api/wallet.cpp" line="2280"/> <source>Failed to parse key image</source> <translation>Échec de l'analyse de l'image de clé</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="2211"/> + <location filename="../src/wallet/api/wallet.cpp" line="2247"/> <source>Failed to get ring</source> <translation>Échec de la récupération du cercle</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="2229"/> + <location filename="../src/wallet/api/wallet.cpp" line="2265"/> <source>Failed to get rings</source> <translation>Échec de la récupération des cercles</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="2250"/> + <location filename="../src/wallet/api/wallet.cpp" line="2286"/> <source>Failed to set ring</source> <translation>Échec de l'affectation du cercle</translation> </message> @@ -541,12 +542,12 @@ <context> <name>command_line</name> <message> - <location filename="../src/common/command_line.cpp" line="57"/> + <location filename="../src/common/command_line.cpp" line="54"/> <source>yes</source> <translation>oui</translation> </message> <message> - <location filename="../src/common/command_line.cpp" line="71"/> + <location filename="../src/common/command_line.cpp" line="68"/> <source>no</source> <translation>non</translation> </message> @@ -603,1029 +604,1742 @@ <context> <name>cryptonote::simple_wallet</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="552"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="645"/> <source>Commands: </source> - <translation>Commandes : </translation> + <translation>Commandes : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3911"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4359"/> <source>failed to read wallet password</source> <translation>échec de la lecture du mot de passe du portefeuille</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3511"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3954"/> <source>invalid password</source> <translation>mot de passe invalide</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2632"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3073"/> <source>set seed: needs an argument. available options: language</source> - <translation>set seed : requiert un argument. options disponibles : language</translation> + <translation>set seed : requiert un argument. options disponibles : language</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2665"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3108"/> <source>set: unrecognized argument(s)</source> - <translation>set : argument(s) non reconnu(s)</translation> + <translation>set : argument(s) non reconnu(s)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3753"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4199"/> <source>wallet file path not valid: </source> - <translation>chemin du fichier portefeuille non valide : </translation> + <translation>chemin du fichier portefeuille non valide : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2735"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3178"/> <source>Attempting to generate or restore wallet, but specified file(s) exist. Exiting to not risk overwriting.</source> <translation>Tentative de génération ou de restauration d'un portefeuille, mais le fichier spécifié existe déjà. Sortie pour ne pas risquer de l'écraser.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="772"/> - <source>usage: payment_id</source> - <translation>usage : payment_id</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2618"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3059"/> <source>needs an argument</source> <translation>requiert un argument</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2641"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2642"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2643"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2645"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2648"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2653"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2654"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2656"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2658"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2659"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2660"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2663"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3082"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3083"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3084"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3086"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3089"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3094"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3095"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3097"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3099"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3100"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3101"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3104"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3105"/> <source>0 or 1</source> <translation>0 ou 1</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2651"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2655"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2662"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3092"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3096"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3103"/> <source>unsigned integer</source> <translation>entier non signé</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2789"/> - <source>NOTE: the following 25 words can be used to recover access to your wallet. Write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control. -</source> - <translation>VEUILLEZ NOTER : les 25 mots suivants peuvent être utilisés pour restaurer votre portefeuille. Veuillez les écrire sur papier et les garder dans un endroit sûr. Ne les gardez pas dans un courriel ou dans un service de stockage de fichiers hors de votre contrôle. -</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2869"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3312"/> <source>--restore-deterministic-wallet uses --generate-new-wallet, not --wallet-file</source> <translation>--restore-deterministic-wallet utilise --generate-new-wallet, pas --wallet-file</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2898"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3341"/> <source>specify a recovery parameter with the --electrum-seed="words list here"</source> <translation>spécifiez un paramètre de récupération avec --electrum-seed="liste de mots ici"</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3274"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3717"/> <source>specify a wallet path with --generate-new-wallet (not --wallet-file)</source> <translation>spécifiez un chemin de portefeuille avec --generate-new-wallet (pas --wallet-file)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3444"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3887"/> <source>wallet failed to connect to daemon: </source> - <translation>échec de la connexion du portefeuille au démon : </translation> + <translation>échec de la connexion du portefeuille au démon : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3452"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3895"/> <source>Daemon uses a different RPC major version (%u) than the wallet (%u): %s. Either update one of them, or use --allow-mismatched-daemon-version.</source> - <translation>Le démon utilise une version majeure de RPC (%u) différente de celle du portefeuille (%u) : %s. Mettez l'un des deux à jour, ou utilisez --allow-mismatched-daemon-version.</translation> + <translation>Le démon utilise une version majeure de RPC (%u) différente de celle du portefeuille (%u) : %s. Mettez l'un des deux à jour, ou utilisez --allow-mismatched-daemon-version.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3473"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3916"/> <source>List of available languages for your wallet's seed:</source> - <translation>Liste des langues disponibles pour la phrase mnémonique de votre portefeuille :</translation> + <translation>Liste des langues disponibles pour la phrase mnémonique de votre portefeuille :</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3483"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3926"/> <source>Enter the number corresponding to the language of your choice: </source> - <translation>Entrez le nombre correspondant à la langue de votre choix : </translation> + <translation>Entrez le nombre correspondant à la langue de votre choix : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3557"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4000"/> <source>You had been using a deprecated version of the wallet. Please use the new seed that we provide. </source> <translation>Vous avez utilisé une version obsolète du portefeuille. Veuillez dorénavant utiliser la nouvelle phrase mnémonique que nous fournissons. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3573"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3645"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4016"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4088"/> <source>Generated new wallet: </source> - <translation>Nouveau portefeuille généré : </translation> + <translation>Nouveau portefeuille généré : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3582"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3650"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3689"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3742"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4025"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4093"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4135"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4188"/> <source>failed to generate new wallet: </source> - <translation>échec de la génération du nouveau portefeuille : </translation> + <translation>échec de la génération du nouveau portefeuille : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3782"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4230"/> <source>Opened watch-only wallet</source> <translation>Ouverture du portefeuille d'audit</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3786"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4234"/> <source>Opened wallet</source> <translation>Ouverture du portefeuille</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3804"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4252"/> <source>You had been using a deprecated version of the wallet. Please proceed to upgrade your wallet. </source> <translation>Vous avez utilisé une version obsolète du portefeuille. Veuillez procéder à la mise à jour de votre portefeuille. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3819"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4267"/> <source>You had been using a deprecated version of the wallet. Your wallet file format is being upgraded now. </source> <translation>Vous avez utilisé une version obsolète du portefeuille. Le format de votre fichier portefeuille est en cours de mise à jour. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3827"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4275"/> <source>failed to load wallet: </source> - <translation>échec du chargement du portefeuille : </translation> + <translation>échec du chargement du portefeuille : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3844"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4292"/> <source>Use the "help" command to see the list of available commands. </source> <translation>Utilisez la commande "help" pour voir la liste des commandes disponibles. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3889"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4337"/> <source>Wallet data saved</source> <translation>Données du portefeuille sauvegardées</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3983"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4431"/> <source>Mining started in daemon</source> <translation>La mine a démarré dans le démon</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3985"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4433"/> <source>mining has NOT been started: </source> - <translation>la mine n'a PAS démarré : </translation> + <translation>la mine n'a PAS démarré : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4005"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4453"/> <source>Mining stopped in daemon</source> <translation>La mine a été stoppée dans le démon</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4007"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4455"/> <source>mining has NOT been stopped: </source> - <translation>la mine n'a PAS été stoppée : </translation> + <translation>la mine n'a PAS été stoppée : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4089"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4537"/> <source>Blockchain saved</source> <translation>Chaîne de blocs sauvegardée</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4104"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4141"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4552"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4589"/> <source>Height </source> <translation>Hauteur </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4143"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4591"/> <source>spent </source> <translation>dépensé </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4195"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4698"/> <source>Starting refresh...</source> <translation>Démarrage du rafraîchissement...</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4208"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4712"/> <source>Refresh done, blocks received: </source> - <translation>Rafraîchissement effectué, blocs reçus : </translation> + <translation>Rafraîchissement effectué, blocs reçus : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5362"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5958"/> <source>payment id has invalid format, expected 16 or 64 character hex string: </source> - <translation>format d'identifiant de paiement invalide, 16 ou 64 caractères hexadécimaux attendus : </translation> + <translation>format d'identifiant de paiement invalide, 16 ou 64 caractères hexadécimaux attendus : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4761"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5307"/> <source>bad locked_blocks parameter:</source> - <translation>mauvais paramètre locked_blocks :</translation> + <translation>mauvais paramètre locked_blocks :</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5382"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5631"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5978"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6251"/> <source>a single transaction cannot use more than one payment id: </source> - <translation>une unique transaction ne peut pas utiliser plus d'un ID de paiement : </translation> + <translation>une unique transaction ne peut pas utiliser plus d'un ID de paiement : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4857"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5391"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5599"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5639"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5405"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5987"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6219"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6259"/> <source>failed to set up payment id, though it was decoded correctly</source> <translation>échec de la définition de l'ID de paiement, bien qu'il ait été décodé correctement</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4874"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4952"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5040"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5149"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5405"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5463"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5653"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5696"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1036"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1158"/> + <source>Send this multisig info to all other participants, then use exchange_multisig_keys <info1> [<info2>...] with others' multisig info</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1167"/> + <source>Multisig wallet has been successfully created. Current wallet type: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1172"/> + <source>Failed to perform multisig keys exchange: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1499"/> + <source>Failed to load multisig transaction from MMS</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1935"/> + <source>Failed to mark output spent: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1962"/> + <source>Failed to mark output unspent: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1986"/> + <source>Spent: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1988"/> + <source>Not spent: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1992"/> + <source>Failed to check whether output is spent: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2022"/> + <source>Please confirm the transaction on the device</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2510"/> + <source>Device name not specified</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2519"/> + <source>Device reconnect failed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2524"/> + <source>Device reconnect failed: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2583"/> + <source>Show the incoming transfers, all or filtered by availability and address index. + +Output format: +Amount, Spent("T"|"F"), "locked"|"unlocked", RingCT, Global Index, Transaction Hash, Address Index, [Public Key, Key Image] </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2673"/> + <source>Available options: + seed language + Set the wallet's 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 the default ring size (obsolete). + auto-refresh <1|0> + Whether to automatically synchronize new blocks from the daemon. + refresh-type <full|optimize-coinbase|no-coinbase|default> + Set the wallet's refresh behaviour. + priority [0|1|2|3|4] + Set the fee to default/unimportant/normal/elevated/priority. + confirm-missing-payment-id <1|0> + ask-password <0|1|2 (or never|action|decrypt)> + unit <monero|millinero|micronero|nanonero|piconero> + Set the 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] + Set a threshold for confirm-backlog to only warn if the transaction backlog is greater than n blocks. + refresh-from-block-height [n] + Set the height before which to ignore blocks. + auto-low-priority <1|0> + Whether to automatically use the low priority fee level when it's safe to do so. + segregate-pre-fork-outputs <1|0> + Set this if you intend to spend outputs on both Monero AND a key reusing fork. + key-reuse-mitigation2 <1|0> + Set this if you are not sure whether you will spend on a key reusing Monero fork later. +subaddress-lookahead <major>:<minor> + Set the lookahead sizes for the subaddress hash table. + Set this if you are not sure whether you will spend on a key reusing Monero fork later. + segregation-height <n> + Set to the height of a key reusing fork you want to use, 0 to use default.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2765"/> + <source>Show the incoming/outgoing transfers within an optional height range. + +Output format: +In or Coinbase: Block Number, "block"|"in", Time, Amount, Transaction Hash, Payment ID, Subaddress Index, "-", Note +Out: Block Number, "out", Time, Amount*, Transaction Hash, Payment ID, Fee, Destinations, Input addresses**, "-", Note +Pool: "pool", "in", Time, Amount, Transaction Hash, Payment Id, Subaddress Index, "-", Note, Double Spend Note +Pending or Failed: "failed"|"pending", "out", Time, Amount*, Transaction Hash, Payment ID, Fee, Input addresses**, "-", Note + +* Excluding change and fee. +** Set of address indices used as inputs in this transfer.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2775"/> + <source>export_transfers [in|out|all|pending|failed|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]] [output=<filepath>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2776"/> + <source>Export to CSV the incoming/outgoing transfers within an optional height range.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2818"/> + <source>Export a signed set of key images to a <filename>.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2826"/> + <source>Synchronizes key images with the hw wallet.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2865"/> + <source>Performs extra multisig keys exchange rounds. Needed for arbitrary M/N multisig wallets</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2889"/> + <source>Interface with the MMS (Multisig Messaging System) +<subcommand> is one of: + init, info, signer, list, next, sync, transfer, delete, send, receive, export, note, show, set, help + send_signer_config, start_auto_config, stop_auto_config, auto_config +Get help about a subcommand with: help mms <subcommand>, or mms help <subcommand></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2897"/> + <source>Initialize and configure the MMS for M/N = number of required signers/number of authorized signers multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2901"/> + <source>Display current MMS configuration</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2905"/> + <source>Set or modify authorized signer info (single-word label, transport address, Monero address), or list all signers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2909"/> + <source>List all messages</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2913"/> + <source>Evaluate the next possible multisig-related action(s) according to wallet state, and execute or offer for choice +By using 'sync' processing of waiting messages with multisig sync info can be forced regardless of wallet state</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2918"/> + <source>Force generation of multisig sync info regardless of wallet state, to recover from special situations like "stale data" errors</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2922"/> + <source>Initiate transfer with MMS support; arguments identical to normal 'transfer' command arguments, for info see there</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2926"/> + <source>Delete a single message by giving its id, or delete all messages by using 'all'</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2930"/> + <source>Send a single message by giving its id, or send all waiting messages</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2934"/> + <source>Check right away for new messages to receive</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2938"/> + <source>Write the content of a message to a file "mms_message_content"</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2942"/> + <source>Send a one-line message to an authorized signer, identified by its label, or show any waiting unread notes</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2946"/> + <source>Show detailed info about a single message</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2950"/> + <source>Available options: + auto-send <1|0> + Whether to automatically send newly generated messages right away. + </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2956"/> + <source>Send completed signer config to all other authorized signers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2960"/> + <source>Start auto-config at the auto-config manager's wallet by issuing auto-config tokens and optionally set others' labels</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2964"/> + <source>Delete any auto-config tokens and abort a auto-config process</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2968"/> + <source>Start auto-config by using the token received from the auto-config manager</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2986"/> + <source>Mark output(s) as spent so they never get selected as fake outputs in a ring</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2990"/> + <source>Marks an output as unspent so it may get selected as a fake output in a ring</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2994"/> + <source>Checks whether an output is marked as spent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3106"/> + <source><device_name[:device_spec]></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3127"/> + <source>wrong number range, use: %s</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3232"/> + <source>NOTE: the following %s can be used to recover access to your wallet. Write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3234"/> + <source>string</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3234"/> + <source>25 words</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4631"/> + <source>Device requires attention</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4639"/> + <source>Enter device PIN</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4641"/> + <source>Failed to read device PIN</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4648"/> + <source>Please enter the device passphrase on the device</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4655"/> + <source>Enter device passphrase</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4657"/> + <source>Failed to read device passphrase</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4673"/> + <source>The first refresh has finished for the HW-based wallet with received money. hw_key_images_sync is needed. </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4675"/> + <source>Do you want to do it now? (Y/Yes/N/No): </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4677"/> + <source>hw_key_images_sync skipped. Run command manually before a transfer.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4855"/> + <source>Invalid keyword: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4904"/> + <source>Heights: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5312"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5894"/> + <source>Locked blocks too high, max 1000000 (Ë4 yrs)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5422"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5502"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5590"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5738"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6001"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6059"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6273"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6318"/> <source>transaction cancelled.</source> <translation>transaction annulée.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4931"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4941"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5481"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5491"/> <source>Is this okay anyway? (Y/Yes/N/No): </source> - <translation>Est-ce correct quand même ? (Y/Yes/Oui/N/No/Non) : </translation> + <translation>Est-ce correct quand même ? (Y/Yes/Oui/N/No/Non) : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4936"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5486"/> <source>There is currently a %u block backlog at that fee level. Is this okay? (Y/Yes/N/No): </source> - <translation>Il y a actuellement un arriéré de %u blocs à ce niveau de frais. Est-ce correct quand même ? (Y/Yes/Oui/N/No/Non) : </translation> + <translation>Il y a actuellement un arriéré de %u blocs à ce niveau de frais. Est-ce correct quand même ? (Y/Yes/Oui/N/No/Non) : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4941"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5491"/> <source>Failed to check for backlog: </source> - <translation>Échec de la vérification du backlog : </translation> + <translation>Échec de la vérification du backlog : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4982"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5436"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5532"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6032"/> <source> Transaction </source> <translation> Transaction </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4987"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5441"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5537"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6037"/> <source>Spending from address index %d </source> <translation>Dépense depuis l'adresse d'index %d </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4989"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5443"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5539"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6039"/> <source>WARNING: Outputs of multiple addresses are being used together, which might potentially compromise your privacy. </source> - <translation>ATTENTION : Des sorties de multiples adresses sont utilisées ensemble, ce qui pourrait potentiellement compromettre votre confidentialité. + <translation>ATTENTION : Des sorties de multiples adresses sont utilisées ensemble, ce qui pourrait potentiellement compromettre votre confidentialité. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4991"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5541"/> <source>Sending %s. </source> <translation>Envoi de %s. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4994"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5544"/> <source>Your transaction needs to be split into %llu transactions. This will result in a transaction fee being applied to each transaction, for a total fee of %s</source> <translation>Votre transaction doit être scindée en %llu transactions. Il en résulte que des frais de transaction doivent être appliqués à chaque transaction, pour un total de %s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5000"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5550"/> <source>The transaction fee is %s</source> <translation>Les frais de transaction sont de %s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5003"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5553"/> <source>, of which %s is dust from change</source> <translation>, dont %s est de la poussière de monnaie rendue</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5004"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5554"/> <source>.</source> <translation>.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5004"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5554"/> <source>A total of %s from dust change will be sent to dust address</source> <translation>Un total de %s de poussière de monnaie rendue sera envoyé à une adresse de poussière</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5009"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5559"/> <source>. This transaction will unlock on block %llu, in approximately %s days (assuming 2 minutes per block)</source> <translation>. Cette transaction sera déverrouillée au bloc %llu, dans approximativement %s jours (en supposant 2 minutes par bloc)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5052"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5064"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5160"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5172"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5474"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5486"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5706"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5718"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5603"/> + <source>Unsigned transaction(s) successfully written to MMS</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5611"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5648"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5749"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5761"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6070"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6107"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6328"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6340"/> <source>Failed to write transaction(s) to file</source> <translation>Échec de l'écriture de(s) transaction(s) dans le fichier</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5056"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5068"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5164"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5176"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5478"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5490"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5710"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5722"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5616"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5653"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5753"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5765"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6074"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6111"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6332"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6344"/> <source>Unsigned transaction(s) successfully written to file: </source> - <translation>Transaction(s) non signée(s) écrite(s) dans le fichier avec succès : </translation> + <translation>Transaction(s) non signée(s) écrite(s) dans le fichier avec succès : </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5625"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6086"/> + <source>Failed to cold sign transaction with HW wallet</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5119"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5708"/> <source>No unmixable outputs found</source> <translation>Aucune sortie non mélangeable trouvée</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5219"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5815"/> <source>No address given</source> <translation>Aucune adresse fournie</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5593"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6213"/> <source>failed to parse Payment ID</source> <translation>échec de l'analyse de l'ID de paiement</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5616"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6236"/> <source>failed to parse key image</source> <translation>échec de l'analyse de l'image de clé</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5668"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6290"/> <source>No outputs found</source> <translation>Pas de sorties trouvées</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5673"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6295"/> <source>Multiple transactions are created, which is not supposed to happen</source> <translation>De multiples transactions sont crées, ce qui n'est pas supposé arriver</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5678"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6300"/> <source>The transaction uses multiple or no inputs, which is not supposed to happen</source> <translation>La transaction utilise aucune ou de multiples entrées, ce qui n'est pas supposé arriver</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5755"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6377"/> <source>missing threshold amount</source> <translation>montant seuil manquant</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5760"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6382"/> <source>invalid amount threshold</source> <translation>montant seuil invalide</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5777"/> - <source>usage: donate [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <amount> [<payment_id>]</source> - <translation>usage : donate [index=<N1>[,<N2>,...]] [<priorité>] [<taille_cercle>] <montant> [<ID_paiement>]</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="9015"/> + <source> (Y/Yes/N/No): </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9042"/> + <source>Choose processing:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9051"/> + <source>Sign tx</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9059"/> + <source>Send the tx for submission to </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9063"/> + <source>Send the tx for signing to </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9070"/> + <source>Submit tx</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5871"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9073"/> + <source>unknown</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9079"/> + <source>Choice: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9091"/> + <source>Wrong choice</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9098"/> + <source>Id</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9098"/> + <source>I/O</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9098"/> + <source>Authorized Signer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>Message Type</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>Height</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>R</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>Message State</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>Since</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9116"/> + <source> ago</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9122"/> + <source>#</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9122"/> + <source>Transport Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9123"/> + <source>Auto-Config Token</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9123"/> + <source>Monero Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9127"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9135"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9137"/> + <source><not set></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9178"/> + <source>Message </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9179"/> + <source>In/out: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9181"/> + <source>State: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9181"/> + <source>%s since %s, %s ago</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9185"/> + <source>Sent: Never</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9189"/> + <source>Sent: %s, %s ago</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9192"/> + <source>Authorized signer: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9193"/> + <source>Content size: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9193"/> + <source> bytes</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9194"/> + <source>Content: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9194"/> + <source>(binary data)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9224"/> + <source>Send these messages now?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9234"/> + <source>Queued for sending.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9254"/> + <source>Invalid message id</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9263"/> + <source>usage: mms init <required_signers>/<authorized_signers> <own_label> <own_transport_address></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9269"/> + <source>The MMS is already initialized. Re-initialize by deleting all signer info and messages?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9284"/> + <source>Error in the number of required signers and/or authorized signers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9301"/> + <source>The MMS is not active.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9324"/> + <source>Invalid signer number </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9329"/> + <source>mms signer [<number> <label> [<transport_address> [<monero_address>]]]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9348"/> + <source>Invalid Monero address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9355"/> + <source>Wallet state does not allow changing Monero addresses anymore</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9367"/> + <source>Usage: mms list</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9380"/> + <source>Usage: mms next [sync]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9405"/> + <source>No next step: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9415"/> + <source>prepare_multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9421"/> + <source>make_multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9436"/> + <source>exchange_multisig_keys</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9451"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9571"/> + <source>export_multisig_info</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9460"/> + <source>import_multisig_info</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9473"/> + <source>sign_multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9483"/> + <source>submit_multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9493"/> + <source>Send tx</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9504"/> + <source>Process signer config</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9516"/> + <source>Replace current signer config with the one displayed above?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9530"/> + <source>Process auto config data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9544"/> + <source>Nothing ready to process</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9564"/> + <source>Usage: mms sync</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9588"/> + <source>Usage: mms delete (<message_id> | all)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9595"/> + <source>Delete all messages?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9621"/> + <source>Usage: mms send [<message_id>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9638"/> + <source>Usage: mms receive</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9655"/> + <source>Usage: mms export <message_id></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9667"/> + <source>Message content saved to: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9671"/> + <source>Failed to to save message content</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9695"/> + <source>Usage: mms note [<label> <text>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9702"/> + <source>No signer found with label </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9724"/> + <source>Usage: mms show <message_id></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9743"/> + <source>Usage: mms set <option_name> [<option_value>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9760"/> + <source>Wrong option value</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9765"/> + <source>Auto-send is on</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9765"/> + <source>Auto-send is off</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9770"/> + <source>Unknown option</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9778"/> + <source>Usage: mms help [<subcommand>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9794"/> + <source>Usage: mms send_signer_config</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9800"/> + <source>Signer config not yet complete</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9815"/> + <source>Usage: mms start_auto_config [<label> <label> ...]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9820"/> + <source>There are signers without a label set. Complete labels before auto-config or specify them as parameters here.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9826"/> + <source>Auto-config is already running. Cancel and restart?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9850"/> + <source>Usage: mms stop_auto_config</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9853"/> + <source>Delete any auto-config tokens and stop auto-config?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9866"/> + <source>Usage: mms auto_config <auto_config_token></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9873"/> + <source>Invalid auto-config token</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9879"/> + <source>Auto-config already running. Cancel and restart?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9911"/> + <source>The MMS is not active. Activate using the "mms init" command</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9988"/> + <source>Invalid MMS subcommand</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9993"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9997"/> + <source>Error in MMS command: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6516"/> <source>Claimed change does not go to a paid address</source> <translation>La monnaie réclamée ne va pas à une adresse payée</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5876"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6521"/> <source>Claimed change is larger than payment to the change address</source> <translation>La monnaie réclamée est supérieure au paiement à l'adresse de monnaie</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5907"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6552"/> <source>sending %s to %s</source> <translation>envoi de %s à %s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5917"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6562"/> <source> dummy output(s)</source> <translation> sortie(s) factice(s)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5920"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6565"/> <source>with no destinations</source> <translation>sans destination</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5932"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6577"/> <source>Loaded %lu transactions, for %s, fee %s, %s, %s, with min ring size %lu, %s. %sIs this okay? (Y/Yes/N/No): </source> - <translation>%lu transactions chargées, pour %s, frais %s, %s, %s, taille de cercle minimum %lu, %s. %sEst-ce correct ? (Y/Yes/Oui/N/No/Non) : </translation> + <translation>%lu transactions chargées, pour %s, frais %s, %s, %s, taille de cercle minimum %lu, %s. %sEst-ce correct ? (Y/Yes/Oui/N/No/Non) : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5961"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6606"/> <source>This is a multisig wallet, it can only sign with sign_multisig</source> <translation>Ceci est un portefeuille multisig, il ne peut signer qu'avec sign_multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5984"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6629"/> <source>Failed to sign transaction</source> <translation>Échec de signature de transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5990"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6635"/> <source>Failed to sign transaction: </source> - <translation>Échec de signature de transaction : </translation> + <translation>Échec de signature de transaction : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6011"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6656"/> <source>Transaction raw hex data exported to </source> <translation>Données brutes hex de la transaction exportées vers </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6032"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6677"/> <source>Failed to load transaction from file</source> <translation>Échec du chargement de la transaction du fichier</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4224"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4524"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4729"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5051"/> <source>RPC error: </source> - <translation>Erreur RPC : </translation> + <translation>Erreur RPC : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="602"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="695"/> <source>wallet is watch-only and has no spend key</source> <translation>c'est un portefeuille d'audit et il n'a pas de clé de dépense</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="745"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="912"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="961"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="839"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1021"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1074"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1141"/> <source>Your original password was incorrect.</source> <translation>Votre mot de passe original est incorrect.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="760"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="854"/> <source>Error with wallet rewrite: </source> - <translation>Erreur avec la réécriture du portefeuille : </translation> + <translation>Erreur avec la réécriture du portefeuille : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1994"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2284"/> <source>invalid unit</source> <translation>unité invalide</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2012"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2074"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2302"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2364"/> <source>invalid count: must be an unsigned integer</source> - <translation>nombre invalide : un entier non signé est attendu</translation> + <translation>nombre invalide : un entier non signé est attendu</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2030"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2320"/> <source>invalid value</source> <translation>valeur invalide</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2674"/> - <source>usage: set_log <log_level_number_0-4> | <categories></source> - <translation>usage : set_log <niveau_de_journalisation_0-4> | <catégories></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2761"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3204"/> <source>(Y/Yes/N/No): </source> - <translation>(Y/Yes/Oui/N/No/Non) : </translation> + <translation>(Y/Yes/Oui/N/No/Non) : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3318"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3345"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3761"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3788"/> <source>bad m_restore_height parameter: </source> - <translation>mauvais paramètre m_restore_height : </translation> + <translation>mauvais paramètre m_restore_height : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3323"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3766"/> <source>date format must be YYYY-MM-DD</source> <translation>le format de date doit être AAAA-MM-JJ</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3336"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3779"/> <source>Restore height is: </source> - <translation>La hauteur de restauration est : </translation> + <translation>La hauteur de restauration est : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3262"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3337"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5033"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3705"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3780"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5583"/> <source>Is this okay? (Y/Yes/N/No): </source> - <translation>Est-ce correct ? (Y/Yes/Oui/N/No/Non) : </translation> + <translation>Est-ce correct ? (Y/Yes/Oui/N/No/Non) : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4061"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4509"/> <source>Daemon is local, assuming trusted</source> <translation>Le démon est local, supposons qu'il est de confiance</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3907"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4355"/> <source>Password for new watch-only wallet</source> <translation>Mot de passe pour le nouveau portefeuille d'audit</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4234"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4739"/> <source>internal error: </source> - <translation>erreur interne : </translation> + <translation>erreur interne : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1339"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4239"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4529"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1608"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4744"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5056"/> <source>unexpected error: </source> - <translation>erreur inattendue : </translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1267"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1344"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4244"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4534"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5083"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5205"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5505"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5739"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6045"/> + <translation>erreur inattendue : </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1534"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1613"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4749"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5061"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5639"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5669"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5794"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6099"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6126"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6361"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6690"/> <source>unknown error</source> <translation>erreur inconnue</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4249"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4754"/> <source>refresh failed: </source> - <translation>échec du rafraîchissement : </translation> + <translation>échec du rafraîchissement : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4249"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4754"/> <source>Blocks received: </source> - <translation>Blocs reçus : </translation> + <translation>Blocs reçus : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4282"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4787"/> <source>unlocked balance: </source> - <translation>solde débloqué : </translation> + <translation>solde débloqué : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2652"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4378"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4429"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3093"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> <source>amount</source> <translation>montant</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="248"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="341"/> <source>false</source> <translation>faux</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="566"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="659"/> <source>Unknown command: </source> - <translation>Commande inconnue : </translation> + <translation>Commande inconnue : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="573"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="666"/> <source>Command usage: </source> - <translation>Usage de la commande : </translation> + <translation>Usage de la commande : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="576"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="669"/> <source>Command description: </source> - <translation>Description de la commande : </translation> + <translation>Description de la commande : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="644"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="735"/> <source>wallet is multisig but not yet finalized</source> <translation>le portefeuille est multisig mais pas encore finalisé</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="674"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="768"/> <source>Failed to retrieve seed</source> <translation>Échec de la récupération de la phrase mnémonique</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="698"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="792"/> <source>wallet is multisig and has no seed</source> <translation>le portefeuille est multisig et n'a pas de phrase mnémonique</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="784"/> - <source>Cannot connect to daemon</source> - <translation>Impossible de se connecter au démon</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="808"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="899"/> <source>Error: failed to estimate backlog array size: </source> - <translation>Erreur : échec de l'estimation de la taille du tableau d'arriéré : </translation> + <translation>Erreur : échec de l'estimation de la taille du tableau d'arriéré : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="813"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="904"/> <source>Error: bad estimated backlog array size</source> - <translation>Erreur : mauvaise estimation de la taille du tableau d'arriéré</translation> + <translation>Erreur : mauvaise estimation de la taille du tableau d'arriéré</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="825"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="916"/> <source> (current)</source> <translation> (actuel)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="828"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="919"/> <source>%u block (%u minutes) backlog at priority %u%s</source> <translation>arriéré de %u bloc(s) (%u minutes) à la priorité %u%s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="830"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="921"/> <source>%u to %u block (%u to %u minutes) backlog at priority %u</source> <translation>arriéré de %u à %u bloc(s) (%u à %u minutes) à la priorité %u</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="833"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="924"/> <source>No backlog at priority </source> <translation>Pas d'arriéré à la priorité </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="847"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="880"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="944"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="989"/> <source>This wallet is already multisig</source> <translation>Le portefeuille est déjà multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="852"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="885"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="949"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="994"/> <source>wallet is watch-only and cannot be made multisig</source> <translation>c'est un portefeuille d'audit et il ne peut pas être tranformé en multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="858"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="891"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="955"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1000"/> <source>This wallet has been used before, please use a new wallet to create a multisig wallet</source> <translation>Ce portefeuille a été utilisé auparavant, veuillez utiliser un nouveau portefeuille pour créer un portefeuille multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="866"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="963"/> <source>Send this multisig info to all other participants, then use make_multisig <threshold> <info1> [<info2>...] with others' multisig info</source> <translation>Envoyez ces infos multisig à tous les autres participants, ensuite utilisez make_multisig <seuil> <info1> [<info2>...] avec les infos multisig des autres</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="867"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="964"/> <source>This includes the PRIVATE view key, so needs to be disclosed only to that multisig wallet's participants </source> <translation>Ceci inclut la clé PRIVÉE d'audit, donc ne doit être divulgué qu'aux participants de ce portefeuille multisig </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="897"/> - <source>usage: make_multisig <threshold> <multisiginfo1> [<multisiginfo2>...]</source> - <translation>usage : make_multisig <seuil> <multisiginfo1> [<multisiginfo2>...]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="905"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1014"/> <source>Invalid threshold</source> <translation>Seuil invalide</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="925"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1034"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1156"/> <source>Another step is needed</source> <translation>Une autre étape est nécessaire</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="927"/> - <source>Send this multisig info to all other participants, then use finalize_multisig <info1> [<info2>...] with others' multisig info</source> - <translation>Envoyez ces infos multisig à tous les autres participants, ensuite utilisez finalize_multisig <info1> [<info2>...] avec les infos multisig des autres</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="933"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1046"/> <source>Error creating multisig: </source> - <translation>Erreur de création multisig : </translation> + <translation>Erreur de création multisig : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="940"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1053"/> <source>Error creating multisig: new wallet is not multisig</source> - <translation>Erreur de création multisig : le nouveau portefeuille n'est pas multisig</translation> + <translation>Erreur de création multisig : le nouveau portefeuille n'est pas multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="943"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1056"/> <source> multisig address: </source> - <translation> adresse multisig : </translation> + <translation> adresse multisig : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="967"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1011"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1063"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1080"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1129"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1195"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1261"/> <source>This wallet is not multisig</source> <translation>Ce portefeuille n'est pas multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="972"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1085"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1134"/> <source>This wallet is already finalized</source> <translation>Ce portefeuille est déjà finalisé</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="980"/> - <source>usage: finalize_multisig <multisiginfo1> [<multisiginfo2>...]</source> - <translation>usage : finalize_multisig <multisiginfo1> [<multisiginfo2>...]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="988"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1101"/> <source>Failed to finalize multisig</source> <translation>Échec de finalisation multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="994"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1107"/> <source>Failed to finalize multisig: </source> - <translation>Échec de finalisation multisig : </translation> + <translation>Échec de finalisation multisig : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1016"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1068"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1147"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1221"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1289"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1200"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1266"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1360"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1476"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1557"/> <source>This multisig wallet is not yet finalized</source> <translation>Ce portefeuille multisig n'est pas encore finalisé</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1021"/> - <source>usage: export_multisig_info <filename></source> - <translation>usage : export_multisig_info <nom_fichier></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1044"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1236"/> <source>Error exporting multisig info: </source> - <translation>Erreur d'importation des infos multisig : </translation> + <translation>Erreur d'importation des infos multisig : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1048"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1240"/> <source>Multisig info exported to </source> <translation>Infos multisig exportées vers </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1073"/> - <source>usage: import_multisig_info <filename1> [<filename2>...] - one for each other participant</source> - <translation>usage : import_multisig_info <nom_fichier1> [<nom_fichier2>...] - un pour chaque autre participant</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1101"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1306"/> <source>Multisig info imported</source> <translation>Infos multisig importées</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1105"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1310"/> <source>Failed to import multisig info: </source> - <translation>Échec de l'importation des infos multisig : </translation> + <translation>Échec de l'importation des infos multisig : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1116"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1321"/> <source>Failed to update spent status after importing multisig info: </source> - <translation>Échec de la mise à jour de l'état des dépenses après l'importation des infos multisig : </translation> + <translation>Échec de la mise à jour de l'état des dépenses après l'importation des infos multisig : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1121"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1327"/> <source>Untrusted daemon, spent status may be incorrect. Use a trusted daemon and run "rescan_spent"</source> <translation>Pas un démon de confiance, l'état des dépenses peut être incorrect. Utilisez un démon de confiance et executez "rescan_spent"</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1142"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1216"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1284"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1355"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1471"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1552"/> <source>This is not a multisig wallet</source> <translation>Ceci n'est pas un portefeuille multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1152"/> - <source>usage: sign_multisig <filename></source> - <translation>usage : sign_multisig <nom_fichier></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1166"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1405"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1414"/> <source>Failed to sign multisig transaction</source> <translation>Échec de la signature de la transaction multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1172"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1421"/> <source>Multisig error: </source> - <translation>Erreur multisig : </translation> + <translation>Erreur multisig : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1177"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1426"/> <source>Failed to sign multisig transaction: </source> - <translation>Échec de la signature de la transaction multisig : </translation> + <translation>Échec de la signature de la transaction multisig : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1200"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1449"/> <source>It may be relayed to the network with submit_multisig</source> <translation>Elle peut être transmise au réseau avec submit_multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1226"/> - <source>usage: submit_multisig <filename></source> - <translation>usage : submit_multisig <nom_fichier></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1242"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1309"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1508"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1578"/> <source>Failed to load multisig transaction from file</source> <translation>Échec du chargement de la transaction multisig du fichier</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1247"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1314"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1514"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1583"/> <source>Multisig transaction signed by only %u signers, needs %u more signatures</source> <translation>Transaction multisig signée par %u signataire(s) seulement, nécessite %u signature(s) de plus</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1256"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="8024"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1523"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8890"/> <source>Transaction successfully submitted, transaction </source> <translation>Transaction transmise avec succès, transaction </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1257"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="8025"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1524"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8891"/> <source>You can check its status by using the `show_transfers` command.</source> <translation>Vous pouvez vérifier son statut en utilisant la commane 'show_transfers'.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1294"/> - <source>usage: export_raw_multisig <filename></source> - <translation>usage : export_raw_multisig <nom_fichier></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1330"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1599"/> <source>Failed to export multisig transaction to file </source> <translation>Échec de l'exportation de la transaction multisig vers le fichier </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1334"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1603"/> <source>Saved exported multisig transaction file(s): </source> - <translation>Transaction multisig enregistrée dans le(s) fichier(s) : </translation> + <translation>Transaction multisig enregistrée dans le(s) fichier(s) : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1805"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1811"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1830"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2095"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2101"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2120"/> <source>ring size must be an integer >= </source> <translation>la taille de cercle doit être un nombre entier >= </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1835"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2125"/> <source>could not change default ring size</source> <translation>échec du changement de la taille de cercle par défaut</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2108"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2179"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2398"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2469"/> <source>Invalid height</source> <translation>Hauteur invalide</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2225"/> - <source>start_mining [<number_of_threads>] [bg_mining] [ignore_battery]</source> - <translation>start_mining [<nombre_de_threads>] [mine_arrière_plan] [ignorer_batterie]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2226"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2562"/> <source>Start mining in the daemon (bg_mining and ignore_battery are optional booleans).</source> <translation>Démarrer la mine dans le démon (mine_arrière_plan et ignorer_batterie sont des booléens facultatifs).</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2229"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2565"/> <source>Stop mining in the daemon.</source> <translation>Arrêter la mine dans le démon.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2233"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2569"/> <source>Set another daemon to connect to.</source> <translation>Spécifier un autre démon auquel se connecter.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2236"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2572"/> <source>Save the current blockchain data.</source> <translation>Sauvegarder les données actuelles de la châine de blocs.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2239"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2575"/> <source>Synchronize the transactions and balance.</source> <translation>Synchroniser les transactions et le solde.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2242"/> - <source>balance [detail]</source> - <translation>solde [détail]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2243"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2579"/> <source>Show the wallet's balance of the currently selected account.</source> <translation>Afficher le solde du compte actuellement sélectionné.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2246"/> - <source>incoming_transfers [available|unavailable] [verbose] [index=<N1>[,<N2>[,...]]]</source> - <translation>incoming_transfers [available|unavailable] [verbose] [index=<N1>[,<N2>[,...]]]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2247"/> - <source>Show the incoming transfers, all or filtered by availability and address index. - -Output format: -Amount, Spent("T"|"F"), "locked"|"unlocked", RingCT, Global Index, Transaction Hash, Address Index, [Public Key, Key Image]</source> - <translation type="unfinished">Afficher les transferts entrants, tous ou filtrés par disponibilité et index d'adresse.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2250"/> - <source>payments <PID_1> [<PID_2> ... <PID_N>]</source> - <translation>payments <PID_1> [<PID_2> ... <PID_N>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2251"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2589"/> <source>Show the payments for the given payment IDs.</source> <translation>Afficher les paiements pour les IDs de paiement donnés.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2254"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2592"/> <source>Show the blockchain height.</source> <translation>Afficher la hauteur de la chaîne de blocs.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2268"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2606"/> <source>Send all unmixable outputs to yourself with ring_size 1</source> <translation>Envoyer toutes les sorties non mélangeables à vous-même avec une taille de cercle de 1</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2274"/> - <source>sweep_below <amount_threshold> [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> [<payment_id>]</source> - <translation>sweep_below <montant_seuil> [index=<N1>[,<N2>,...]] [<priorité>] [<taille_cercle>] <adresse> [<ID_paiement>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2275"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2613"/> <source>Send all unlocked outputs below the threshold to an address.</source> <translation>Envoyer toutes les sorties débloquées d'un montant inférieur au seuil à une adresse.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2279"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2617"/> <source>Send a single output of the given key image to an address without change.</source> <translation>Envoyer une unique sortie ayant une image de clé donnée à une adresse sans rendu de monnaie.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2282"/> - <source>donate [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <amount> [<payment_id>]</source> - <translation>donate [index=<N1>[,<N2>,...]] [<priorité>] [<taille_cercle>] <montant> [<ID_paiement>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2283"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2621"/> <source>Donate <amount> to the development team (donate.getmonero.org).</source> <translation>Donner <montant> à l'équipe de développement (donate.getmonero.org).</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2290"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2628"/> <source>Submit a signed transaction from a file.</source> <translation>Transmettre une transaction signée d'un fichier.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2293"/> - <source>set_log <level>|{+,-,}<categories></source> - <translation>set_log <niveau>|{+,-,}<catégories></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2294"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2632"/> <source>Change the current log detail (level must be <0-4>).</source> <translation>Changer le niveau de détail du journal (le niveau doit être <0-4>).</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2297"/> - <source>account - account new <label text with white spaces allowed> - account switch <index> - account label <index> <label text with white spaces allowed> - account tag <tag_name> <account_index_1> [<account_index_2> ...] - account untag <account_index_1> [<account_index_2> ...] - account tag_description <tag_name> <description></source> - <translation>account - account new <texte étiquette avec espaces autorisés> - account switch <index> - account label <index> <texte étiquette avec espaces autorisés> - account tag <mot_clé> <index_compte_1> [<index_compte_2> ...] - account untag <index_compte_1> [<index_compte_2> ...] - account tag_description <mot_clé> <description></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2304"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2636"/> <source>If no arguments are specified, the wallet shows all the existing accounts along with their balances. If the "new" argument is specified, the wallet creates a new account with its label initialized by the provided label text (which can be empty). If the "switch" argument is specified, the wallet switches to the account specified by <index>. @@ -1642,137 +2356,82 @@ Si l'argument "untag" est spécifié, les mots clés assignés au Si l'argument "tag_description" est spécifié, le texte arbitraire <description> est assigné au mot clé <mot_clé>.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2313"/> - <source>address [ new <label text with white spaces allowed> | all | <index_min> [<index_max>] | label <index> <label text with white spaces allowed>]</source> - <translation>address [ new <texte étiquette avec espaces autorisés> | all | <index_min> [<index_max>] | label <index> <texte étiquette avec espaces autorisés>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2317"/> - <source>integrated_address [<payment_id> | <address>]</source> - <translation>integrated_address [<ID_paiement> | <adresse>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2318"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2650"/> <source>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>Encoder un ID de paiement dans une adresse intégrée pour l'adresse publique du portefeuille actuel (en l'absence d'argument un ID de paiement aléatoire est utilisé), ou décoder une adresse intégrée en une adresse standard et un ID de paiement</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2321"/> - <source>address_book [(add ((<address> [pid <id>])|<integrated address>) [<description possibly with whitespaces>])|(delete <index>)]</source> - <translation>address_book [(add ((<adresse> [pid <id>])|<adresse intégrée>) [<description avec éventuellement des espaces>])|(delete <index>)]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2322"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2654"/> <source>Print all entries in the address book, optionally adding/deleting an entry to/from it.</source> <translation>Afficher toutes les entrées du carnet d'adresses, optionnellement en y ajoutant/supprimant une entrée.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2325"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2657"/> <source>Save the wallet data.</source> <translation>Sauvegarder les données du portefeuille.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2328"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2660"/> <source>Save a watch-only keys file.</source> <translation>Sauvegarder un fichier de clés d'audit.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2331"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2663"/> <source>Display the private view key.</source> <translation>Afficher la clé privée d'audit.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2334"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2666"/> <source>Display the private spend key.</source> <translation>Afficher la clé privée de dépense.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2337"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2669"/> <source>Display the Electrum-style mnemonic seed</source> <translation>Afficher la phrase mnémonique de style Electrum</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2340"/> - <source>set <option> [<value>]</source> - <translation>set <option> [<valeur>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2387"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2719"/> <source>Display the encrypted Electrum-style mnemonic seed.</source> <translation>Afficher la phrase mnémonique de style Electrum chiffrée.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2390"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2722"/> <source>Rescan the blockchain for spent outputs.</source> <translation>Rescanner la chaîne de blocs pour trouver les sorties dépensées.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2393"/> - <source>get_tx_key <txid></source> - <translation>get_tx_key <ID_transaction></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2394"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2726"/> <source>Get the transaction key (r) for a given <txid>.</source> <translation>Obtenir la clé de transaction (r) pour un <ID_transaction> donné.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2401"/> - <source>check_tx_key <txid> <txkey> <address></source> - <translation>check_tx_key <ID_transaction> <clé_transaction> <adresse></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2402"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2734"/> <source>Check the amount going to <address> in <txid>.</source> <translation>Vérifier le montant allant à <adresse> dans <ID_transaction>.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2405"/> - <source>get_tx_proof <txid> <address> [<message>]</source> - <translation>get_tx_proof <ID_transaction> <adresse> [<message>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2406"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2738"/> <source>Generate a signature proving funds sent to <address> in <txid>, optionally with a challenge string <message>, using either the transaction secret key (when <address> is not your wallet's address) or the view secret key (otherwise), which does not disclose the secret key.</source> <translation>Générer une signature prouvant l'envoi de fonds à <adresse> dans <ID_transaction>, optionnellement avec un <message> comme challenge, en utilisant soit la clé secrète de transaction (quand <adresse> n'est pas l'adresse de votre portefeuille) soit la clé secrète d'audit (dans le cas contraire), tout en ne divulgant pas la clé secrète.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2409"/> - <source>check_tx_proof <txid> <address> <signature_file> [<message>]</source> - <translation>check_tx_proof <ID_transaction> <adresse> <fichier_signature> [<message>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2410"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2742"/> <source>Check the proof for funds going to <address> in <txid> with the challenge string <message> if any.</source> <translation>Vérifier la validité de la preuve de fonds allant à <adresse> dans <ID_transaction> avec le <message> de challenge s'il y en a un.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2413"/> - <source>get_spend_proof <txid> [<message>]</source> - <translation>get_spend_proof <ID_transaction> [<message>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2414"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2746"/> <source>Generate a signature proving that you generated <txid> using the spend secret key, optionally with a challenge string <message>.</source> <translation>Générer une signature prouvant que vous avez créé <ID_transaction> en utilisant la clé secrète de dépense, optionnellement avec un <message> comme challenge.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2417"/> - <source>check_spend_proof <txid> <signature_file> [<message>]</source> - <translation>check_spend_proof <ID_transaction> <fichier_signature> [<message>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2418"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2750"/> <source>Check a signature proving that the signer generated <txid>, optionally with a challenge string <message>.</source> <translation>Vérifier la validité de la preuve que le signataire a créé <ID_transaction>, optionnellement avec un <message> comme challenge.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2421"/> - <source>get_reserve_proof (all|<amount>) [<message>]</source> - <translation>get_reserve_proof (all|<montant>) [<message>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2422"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2754"/> <source>Generate a signature proving that you own at least this much, optionally with a challenge string <message>. If 'all' is specified, you prove the entire sum of all of your existing accounts' balances. Otherwise, you prove the reserve of the smallest possible amount above <amount> available in your current account.</source> @@ -1781,357 +2440,238 @@ Si 'all' est spécifié, vous prouvez la somme totale des soldes de to Sinon, vous prouvez le plus petit solde supérieur à <montant> dans votre compte actuel.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2427"/> - <source>check_reserve_proof <address> <signature_file> [<message>]</source> - <translation>check_reserve_proof <adresse> <fichier_signature> [<message>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2428"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2760"/> <source>Check a signature proving that the owner of <address> holds at least this much, optionally with a challenge string <message>.</source> <translation>Vérifier la validité d'une signature prouvant que le propriétaire d'une <adresse> détient au moins un montant, optionnellement avec un <message> comme challenge.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2432"/> - <source>Show the incoming/outgoing transfers within an optional height range. - -Output format: -In or Coinbase: Block Number, "block"|"in", Time, Amount, Transaction Hash, Payment ID, Subaddress Index, "-", Note\ -Out: Block Number, "out", Time, Amount*, Transaction Hash, Payment ID, Fee, Destinations, Input addresses**, "-", Note -Pool: "pool", "in", Time, Amount, Transaction Hash, Payment Id, Subaddress Index, "-", Note, Double Spend Note\ -Pending or Failed: "failed"|"pending", "out", Time, Amount*, Transaction Hash, Payment ID, Fee, Input addresses**, "-", Note - -* Excluding change and fee. -** Set of address indices used as inputs in this transfer.</source> - <translation>Afficher les transferts entrants/sortants dans un interval de hauteurs facultatif.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2435"/> - <source>unspent_outputs [index=<N1>[,<N2>,...]] [<min_amount> [<max_amount>]]</source> - <translation>unspent_outputs [index=<N1>[,<N2>,...]] [<montant_min> [<montant_max>]]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2436"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2780"/> <source>Show the unspent outputs of a specified address within an optional amount range.</source> <translation>Afficher les sorties non dépensées d'une adresse spécifique dans un interval de montants facultatif.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2442"/> - <source>set_tx_note <txid> [free text note]</source> - <translation>set_tx_note <ID_transaction> [texte de la note]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2443"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2788"/> <source>Set an arbitrary string note for a <txid>.</source> <translation>Définir un texte arbitraire comme note pour <ID_transaction>.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2446"/> - <source>get_tx_note <txid></source> - <translation>get_tx_note <ID_transaction></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2447"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2792"/> <source>Get a string note for a txid.</source> <translation>Obtenir le texte de la note pour <ID_transaction>.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2450"/> - <source>set_description [free text note]</source> - <translation>set_description [texte]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2451"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2796"/> <source>Set an arbitrary description for the wallet.</source> <translation>Définir un texte arbitraire comme description du portefeuille.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2454"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2800"/> <source>Get the description of the wallet.</source> <translation>Obtenir la description du portefeuille.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2457"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2803"/> <source>Show the wallet's status.</source> <translation>Afficher l'état du portefeuille.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2460"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2806"/> <source>Show the wallet's information.</source> <translation>Afficher les informations du portefeuille.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2463"/> - <source>sign <file></source> - <translation>sign <fichier></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2464"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2810"/> <source>Sign the contents of a file.</source> <translation>Signer le contenu d'un fichier.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2467"/> - <source>verify <filename> <address> <signature></source> - <translation>verify <fichier> <adresse> <signature></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2468"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2814"/> <source>Verify a signature on the contents of a file.</source> <translation>Vérifier la signature du contenu d'un fichier.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2471"/> - <source>export_key_images <file></source> - <translation>export_key_images <fichier></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2472"/> - <source>Export a signed set of key images to a <file>.</source> - <translation>Exported un ensemble signé d'images de clé vers un <fichier>.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2475"/> - <source>import_key_images <file></source> - <translation>import_key_images <fichier></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2476"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2822"/> <source>Import a signed key images list and verify their spent status.</source> <translation>Importer un ensemble signé d'images de clé et vérifier si elles correspondent à des dépenses.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2483"/> - <source>export_outputs <file></source> - <translation>export_outputs <fichier></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2484"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2834"/> <source>Export a set of outputs owned by this wallet.</source> <translation>Exporter un ensemble de sorties possédées par ce portefeuille.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2487"/> - <source>import_outputs <file></source> - <translation>import_outputs <fichier></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2488"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2838"/> <source>Import a set of outputs owned by this wallet.</source> <translation>Importer un ensemble de sorties possédées par ce portefeuille.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2491"/> - <source>show_transfer <txid></source> - <translation>show_transfer <ID_transaction></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2492"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2842"/> <source>Show information about a transfer to/from this address.</source> <translation>Afficher les information à propos d'un transfert vers/depuis cette adresse.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2495"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2845"/> <source>Change the wallet's password.</source> <translation>Changer le mot de passe du portefeuille.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2498"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2849"/> <source>Generate a new random full size payment id. These will be unencrypted on the blockchain, see integrated_address for encrypted short payment ids.</source> <translation>Générer un nouvel ID de paiement long aléatoire. Ceux-ci sont en clair dans la chaîne de blocs, voir integrated_address pour les IDs de paiement courts cryptés.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2501"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2852"/> <source>Print the information about the current fee and transaction backlog.</source> <translation>Afficher les informations à propos des frais et arriéré de transactions actuels.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2503"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2854"/> <source>Export data needed to create a multisig wallet</source> <translation>Exporter les données nécessaires pour créer un portefeuille multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2505"/> - <source>make_multisig <threshold> <string1> [<string>...]</source> - <translation>make_multisig <seuil> <chaîne_caractères1> [<chaîne_caractères>...]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2506"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2857"/> <source>Turn this wallet into a multisig wallet</source> <translation>Transformer ce portefeuille en portefeuille multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2509"/> - <source>finalize_multisig <string> [<string>...]</source> - <translation>finalize_multisig <chaîne_caractères> [<chaîne_caractères>...]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2510"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2861"/> <source>Turn this wallet into a multisig wallet, extra step for N-1/N wallets</source> <translation>Transformer ce portefeuille en portefeuille multisig, étape supplémentaire pour les portefeuilles N-1/N</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2513"/> - <source>export_multisig_info <filename></source> - <translation>export_multisig_info <fichier></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2514"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2869"/> <source>Export multisig info for other participants</source> <translation>Exporter les infos multisig pour les autres participants</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2517"/> - <source>import_multisig_info <filename> [<filename>...]</source> - <translation>import_multisig_info <fichier> [<fichier>...]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2518"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2873"/> <source>Import multisig info from other participants</source> <translation>Importer les infos multisig des autres participants</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2521"/> - <source>sign_multisig <filename></source> - <translation>sign_multisig <fichier></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2522"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2877"/> <source>Sign a multisig transaction from a file</source> <translation>Signer une transaction multisig d'un fichier</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2525"/> - <source>submit_multisig <filename></source> - <translation>submit_multisig <fichier></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2526"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2881"/> <source>Submit a signed multisig transaction from a file</source> <translation>Transmettre une transaction multisig signée d'un fichier</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2529"/> - <source>export_raw_multisig_tx <filename></source> - <translation>export_raw_multisig_tx <fichier></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2530"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2885"/> <source>Export a signed multisig transaction to a file</source> <translation>Exporter une transaction multisig signée vers un fichier</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2561"/> - <source>help [<command>]</source> - <translation>help [<commande>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2562"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3002"/> <source>Show the help section or the documentation about a <command>.</source> <translation>Afficher la section d'aide ou la documentation d'une <commande>.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2644"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3085"/> <source>integer >= </source> <translation>entier >= </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2657"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3098"/> <source>block height</source> <translation>hauteur de bloc</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2760"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3203"/> <source>No wallet found with that name. Confirm creation of new wallet named: </source> - <translation>Aucun portefeuille avec ce nom trouvé. Confirmer la création d'un nouveau portefeuille nommé : </translation> + <translation>Aucun portefeuille avec ce nom trouvé. Confirmer la création d'un nouveau portefeuille nommé : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2861"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3304"/> <source>can't specify both --restore-deterministic-wallet or --restore-multisig-wallet and --non-deterministic</source> <translation>impossible de spécifier à la fois --restore-deterministic-wallet ou --restore-multisig-wallet et --non-deterministic</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2867"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> <source>--restore-multisig-wallet uses --generate-new-wallet, not --wallet-file</source> <translation>--restore-multisig-wallet utilise --generate-new-wallet, pas --wallet-file</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2883"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3326"/> <source>specify a recovery parameter with the --electrum-seed="multisig seed here"</source> <translation>spécifiez un paramètre de récupération avec --electrum-seed="phrase mnémonique multisig ici"</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2912"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3355"/> <source>Multisig seed failed verification</source> <translation>Échec de la vérification de la phrase mnémonique multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2963"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3038"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3406"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3481"/> <source>This address is a subaddress which cannot be used here.</source> <translation>Cette adresse est une sous-adresse qui ne peut pas être utilisée ici.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3115"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3558"/> <source>Error: expected M/N, but got: </source> - <translation>Erreur : M/N attendu, mais lu : </translation> + <translation>Erreur : M/N attendu, mais lu : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3120"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3563"/> <source>Error: expected N > 1 and N <= M, but got: </source> - <translation>Erreur : N > 1 et N <= M attendu, mais lu : </translation> + <translation>Erreur : N > 1 et N <= M attendu, mais lu : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3125"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3568"/> <source>Error: M/N is currently unsupported. </source> - <translation>Erreur : M/N n'est actuellement pas supporté. </translation> + <translation>Erreur : M/N n'est actuellement pas supporté. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3128"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3571"/> <source>Generating master wallet from %u of %u multisig wallet keys</source> <translation>Génération du portefeuille principal à partir de %u de %u clés de portefeuille multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3157"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3600"/> <source>failed to parse secret view key</source> <translation>échec de l'analyse de la clé secrète d'audit</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3165"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3608"/> <source>failed to verify secret view key</source> <translation>échec de la vérification de la clé secrète d'audit</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3185"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3628"/> <source>Secret spend key (%u of %u):</source> - <translation>Clé secrète de dépense (%u de %u) :</translation> + <translation>Clé secrète de dépense (%u de %u) :</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3208"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3651"/> <source>Error: M/N is currently unsupported</source> - <translation>Erreur : M/N n'est actuellement pas supporté</translation> + <translation>Erreur : M/N n'est actuellement pas supporté</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3359"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3802"/> <source>Restore height </source> <translation>Hauteur de restauration </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3360"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3803"/> <source>Still apply restore height? (Y/Yes/N/No): </source> - <translation>Appliquer la hauteur de restauration quand même ? (Y/Yes/Oui/N/No/Non) : </translation> + <translation>Appliquer la hauteur de restauration quand même ? (Y/Yes/Oui/N/No/Non) : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3386"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3829"/> <source>Warning: using an untrusted daemon at %s, privacy will be lessened</source> - <translation>Attention : en n'utilisant %s qui n'est pas un démon de confiance, la confidentialité sera réduite</translation> + <translation>Attention : en n'utilisant %s qui n'est pas un démon de confiance, la confidentialité sera réduite</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3445"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3888"/> <source>Daemon either is not started or wrong port was passed. Please make sure daemon is running or change the daemon address using the 'set_daemon' command.</source> <translation>Le démon n'est pas lancé ou un mauvais port a été fourni. Veuillez vous assurer que le démon fonctionne ou changez l'adresse de démon avec la commande 'set_daemon'.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3593"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4036"/> <source>Your wallet has been generated! To start synchronizing with the daemon, use the "refresh" command. Use the "help" command to see the list of available commands. @@ -2150,843 +2690,730 @@ votre portefeuille à nouveau (mais les clés de votre portefeuille ne risquent </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3734"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4180"/> <source>failed to generate new mutlisig wallet</source> <translation>échec de la génération du nouveau portefeuille multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3737"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4183"/> <source>Generated new %u/%u multisig wallet: </source> - <translation>Nouveau portefeuille multisig %u/%u généré : </translation> + <translation>Nouveau portefeuille multisig %u/%u généré : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3784"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4232"/> <source>Opened %u/%u multisig wallet%s</source> <translation>Portefeuille multisig %u/%u ouvert%s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3845"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4293"/> <source>Use "help <command>" to see a command's documentation. </source> <translation>Utilisez "help <commande>" pour voir la documentation d'une commande. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3903"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4351"/> <source>wallet is multisig and cannot save a watch-only version</source> <translation>c'est un portefeuille multisig et il ne peut pas sauvegarder une version d'audit</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4017"/> - <source>missing daemon URL argument</source> - <translation>URL du démon manquante en argument</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4028"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4476"/> <source>Unexpected array length - Exited simple_wallet::set_daemon()</source> <translation>Taille de tableau inattendue - Sortie de simple_wallet::set_daemon()</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4069"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4517"/> <source>This does not seem to be a valid daemon URL.</source> <translation>Ceci semble ne pas être une URL de démon valide.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4105"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4142"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4590"/> <source>txid </source> <translation>ID transaction </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4107"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4144"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4555"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4592"/> <source>idx </source> <translation>index </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4275"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4780"/> <source> (Some owned outputs have partial key images - import_multisig_info needed)</source> <translation> (Certaines sorties ont des images de clé partielles - import_multisig_info requis)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4278"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4783"/> <source>Currently selected account: [</source> - <translation>Compte actuellement sélectionné : [</translation> + <translation>Compte actuellement sélectionné : [</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4278"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4783"/> <source>] </source> <translation>] </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4280"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4785"/> <source>Tag: </source> - <translation>Mot clé : </translation> + <translation>Mot clé : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4280"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4785"/> <source>(No tag assigned)</source> <translation>(Pas de mot clé assigné)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4287"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4792"/> <source>Balance per address:</source> - <translation>Solde par adresse :</translation> + <translation>Solde par adresse :</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4288"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> <source>Address</source> <translation>Adresse</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4288"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7192"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8008"/> <source>Balance</source> <translation>Solde</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4288"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7192"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8008"/> <source>Unlocked balance</source> <translation>Solde débloqué</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4288"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> <source>Outputs</source> <translation>Sorties</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4288"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7192"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8008"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9122"/> <source>Label</source> <translation>Étiquette</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4296"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4801"/> <source>%8u %6s %21s %21s %7u %21s</source> <translation>%8u %6s %21s %21s %7u %21s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4305"/> - <source>usage: balance [detail]</source> - <translation>usage : balance [detail]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4317"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4359"/> - <source>usage: incoming_transfers [available|unavailable] [verbose] [index=<N1>[,<N2>[,...]]]</source> - <translation>usage: incoming_transfers [available|unavailable] [verbose] [index=<N1>[,<N2>[,...]]]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4378"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> <source>spent</source> <translation>dépensé</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4378"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> <source>global index</source> <translation>index global</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4378"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> <source>tx id</source> <translation>ID de transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4378"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4429"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> <source>addr index</source> <translation>index adresse</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4401"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4924"/> <source>No incoming transfers</source> <translation>Aucun transfert entrant</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4405"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4928"/> <source>No incoming available transfers</source> <translation>Aucun transfert entrant disponible</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4409"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4932"/> <source>No incoming unavailable transfers</source> <translation>Aucun transfert entrant non disponible</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4420"/> - <source>expected at least one payment ID</source> - <translation>au moins un ID de paiement attendu</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4429"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> <source>payment</source> <translation>paiement</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4429"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> <source>transaction</source> <translation>transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4429"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> <source>height</source> <translation>hauteur</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4429"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> <source>unlock time</source> <translation>durée de déverrouillage</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4441"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4968"/> <source>No payments with id </source> <translation>Aucun paiement avec l'ID </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4489"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4555"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4892"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5305"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5016"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5106"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5442"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5901"/> <source>failed to get blockchain height: </source> - <translation>échec de la récupération de la hauteur de la chaîne de blocs : </translation> + <translation>échec de la récupération de la hauteur de la chaîne de blocs : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4545"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6388"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6426"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6483"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6514"/> - <source>failed to connect to the daemon</source> - <translation>échec de la connexion au démon</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4563"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5114"/> <source> Transaction %llu/%llu: txid=%s</source> <translation> -Transaction %llu/%llu : ID=%s</translation> +Transaction %llu/%llu : ID=%s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4584"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5135"/> <source> Input %llu/%llu: amount=%s</source> <translation> -Entrée %llu/%llu : montant=%s</translation> +Entrée %llu/%llu : montant=%s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4600"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5151"/> <source>failed to get output: </source> - <translation>échec de la récupération de la sortie : </translation> + <translation>échec de la récupération de la sortie : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4608"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5159"/> <source>output key's originating block height shouldn't be higher than the blockchain height</source> <translation>la hauteur du bloc d'origine de la clé de la sortie ne devrait pas être supérieure à celle de la chaîne de blocs</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4612"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5163"/> <source> Originating block heights: </source> <translation> -Hauteurs des blocs d'origine : </translation> +Hauteurs des blocs d'origine : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4627"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5175"/> <source> |</source> <translation> |</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4627"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6915"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5175"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7706"/> <source>| </source> <translation>| </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4644"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5192"/> <source> Warning: Some input keys being spent are from </source> <translation> -Attention : Certaines clés d'entrées étant dépensées sont issues de </translation> +Attention : Certaines clés d'entrées étant dépensées sont issues de </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4646"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5194"/> <source>, which can break the anonymity of ring signature. Make sure this is intentional!</source> <translation>, ce qui peut casser l'anonymat du cercle de signature. Assurez-vous que c'est intentionnel !</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4688"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5257"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5536"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5234"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5853"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6156"/> <source>Ring size must not be 0</source> <translation>La taille de cercle ne doit pas être 0</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4700"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5269"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5548"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5246"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5865"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6168"/> <source>ring size %u is too small, minimum is %u</source> <translation>la taille de cercle %u est trop petite, le minimum est %u</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4712"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5258"/> <source>wrong number of arguments</source> <translation>mauvais nombre d'arguments</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4869"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5400"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5648"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5417"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5996"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6268"/> <source>No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): </source> - <translation>Aucun ID de paiement n'est inclus dans cette transaction. Est-ce correct ? (Y/Yes/Oui/N/No/Non) : </translation> + <translation>Aucun ID de paiement n'est inclus dans cette transaction. Est-ce correct ? (Y/Yes/Oui/N/No/Non) : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4908"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5420"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5458"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6016"/> <source>No outputs found, or daemon is not ready</source> <translation>Aucune sortie trouvée, ou le démon n'est pas prêt</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7740"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6428"/> + <source>Failed to parse donation address: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6444"/> + <source>Donating %s %s to %s.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7493"/> + <source>usage: export_transfers [in|out|all|pending|failed|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]] [output=<path>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>direction</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>timestamp</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>running balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>hash</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>payment ID</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>fee</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>destination</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>index</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>note</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7572"/> + <source>CSV exported to </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7750"/> + <source>MMS received new message</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8559"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8605"/> <source>command only supported by HW wallet</source> <translation>commande supportée uniquement par un portefeuille matériel</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7749"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8564"/> + <source>hw wallet does not support cold KI sync</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8576"/> + <source>Please confirm the key image sync on the device</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8582"/> + <source>Key images synchronized to height </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8585"/> + <source>Running untrusted daemon, cannot determine which transaction output is spent. Use a trusted daemon with --trusted-daemon and run rescan_spent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8588"/> + <source> spent, </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8588"/> + <source> unspent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8592"/> + <source>Failed to import key images</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8597"/> + <source>Failed to import key images: </source> + <translation type="unfinished">Échec de l'importation des images de clé : </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8614"/> <source>Failed to reconnect device</source> <translation>Échec de la reconnexion à l'appareil</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7754"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8619"/> <source>Failed to reconnect device: </source> <translation>Échec de la reconnexion à l'appareil : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="8017"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8883"/> <source>Transaction successfully saved to </source> <translation>Transaction sauvegardée avec succès dans </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="8017"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="8019"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8883"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8885"/> <source>, txid </source> <translation>, ID transaction </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="8019"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8885"/> <source>Failed to save transaction to </source> <translation>Échec de la sauvegarde de la transaction dans </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5134"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5448"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5723"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6044"/> <source>Sweeping %s in %llu transactions for a total fee of %s. Is this okay? (Y/Yes/N/No): </source> - <translation>Balayage de %s dans %llu transactions pour des frais totaux de %s. Est-ce correct ? (Y/Yes/Oui/N/No/Non) : </translation> + <translation>Balayage de %s dans %llu transactions pour des frais totaux de %s. Est-ce correct ? (Y/Yes/Oui/N/No/Non) : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5140"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5454"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5688"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5729"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6050"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6310"/> <source>Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No): </source> - <translation>Balayage de %s pour des frais totaux de %s. Est-ce correct ? (Y/Yes/Oui/N/No/Non) : </translation> + <translation>Balayage de %s pour des frais totaux de %s. Est-ce correct ? (Y/Yes/Oui/N/No/Non) : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5966"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6611"/> <source>This is a watch only wallet</source> <translation>Ceci est un portefeuille d'audit</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7841"/> - <source>usage: show_transfer <txid></source> - <translation>usage : show_transfer <ID_de_transaction></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7947"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8813"/> <source>Double spend seen on the network: this transaction may or may not end up being mined</source> - <translation>Double dépense détectée sur le réseau : cette transaction sera peut-être invalidée</translation> + <translation>Double dépense détectée sur le réseau : cette transaction sera peut-être invalidée</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7982"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8848"/> <source>Transaction ID not found</source> <translation>ID de transaction non trouvé</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="243"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="336"/> <source>true</source> <translation>vrai</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="296"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="389"/> <source>failed to parse refresh type</source> <translation>échec de l'analyse du type de rafraîchissement</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="628"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="693"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="842"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="875"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="954"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1006"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1058"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1137"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1211"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1279"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5956"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6020"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6057"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6154"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6365"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6455"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7581"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7656"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7698"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7765"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7804"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="721"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="787"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="939"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="984"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1067"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1124"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1190"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1256"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1350"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1466"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1547"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6601"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6665"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6702"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6799"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7010"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7094"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8397"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8474"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8517"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8630"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8670"/> <source>command not supported by HW wallet</source> <translation>commande non supportée par le portefeuille matériel</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="633"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="703"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="726"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="797"/> <source>wallet is watch-only and has no seed</source> <translation>c'est un portefeuille d'audit et il n'a pas de phrase mnémonique</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="650"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="713"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="744"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="807"/> <source>wallet is non-deterministic and has no seed</source> <translation>c'est un portefeuille non déterministe et il n'a pas de phrase mnémonique</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="657"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="751"/> <source>Enter optional seed offset passphrase, empty to see raw seed</source> <translation>Entrer une phrase de passe facultative pour le décalage de la phrase mnémonique, effacer pour voir la phrase mnémonique brute</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="723"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="817"/> <source>Incorrect password</source> <translation>Mot de passe invalide</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="792"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="883"/> <source>Current fee is %s %s per %s</source> <translation>Les frais sont actuellement de %s %s par %s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1356"/> - <source>usage: print_ring <key_image|txid></source> - <translation>usage : print_ring <image clé|ID transaction></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1362"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1519"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1631"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1788"/> <source>Invalid key image</source> <translation>Image de clé invalide</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1368"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1637"/> <source>Invalid txid</source> <translation>ID de transaction invalide</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1380"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1649"/> <source>Key image either not spent, or spent with mixin 0</source> <translation>Image de clé soit non dépensée, soit dépensée avec 0 mélange</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1395"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1664"/> <source>Failed to get key image ring: </source> <translation>Échec de la récupération du cercle de l'image de clé : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1410"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1679"/> <source>File doesn't exist</source> <translation>Le fichier d'existe pas</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1432"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1701"/> <source>Invalid ring specification: </source> <translation>Spécification de cercle invalide : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1440"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1709"/> <source>Invalid key image: </source> <translation>Image de clé invalide : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1445"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1714"/> <source>Invalid ring type, expected relative or abosolute: </source> <translation>Type de cercle invalide, "relative" ou "absolute" attendu : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1451"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1463"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1720"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1732"/> <source>Error reading line: </source> <translation>Erreur lors de la lecture de la ligne : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1474"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1743"/> <source>Invalid ring: </source> <translation>Cercle invalide : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1483"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1752"/> <source>Invalid relative ring: </source> <translation>Cercle relatif invalide : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1495"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1764"/> <source>Invalid absolute ring: </source> <translation>Cercle absolu invalide : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1504"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1773"/> <source>Failed to set ring for key image: </source> <translation>Échec de l'affectation du cercle pour l'image de clé : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1504"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1773"/> <source>Continuing.</source> <translation>On continue.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1513"/> - <source>usage: set_ring <filename> | ( <key_image> absolute|relative <index> [<index>...] )</source> - <translation>usage : set_ring <nom_fichier> | ( <image_clé> absolute|relative <index> [<index>...] )</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1534"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1803"/> <source>Missing absolute or relative keyword</source> <translation>Mot clé "absolute" ou "relative" manquant</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1544"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1551"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1813"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1820"/> <source>invalid index: must be a strictly positive unsigned integer</source> <translation>index invalide : doit être un nombre entier strictement positif</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1559"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1828"/> <source>invalid index: indices wrap</source> <translation>index invalide : boucle des indices</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1569"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1838"/> <source>invalid index: indices should be in strictly ascending order</source> <translation>index invalide : les indices doivent être en ordre strictement croissant</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1576"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1845"/> <source>failed to set ring</source> <translation>échec de l'affectation du cercle</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1588"/> - <source>usage: blackball <amount>/<offset> | <filename> [add]</source> - <translation>usage : blackball <montant>/<offset> | <nom_fichier> [add]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1621"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1890"/> <source>First line is not an amount</source> <translation>La première ligne n'est pas un montant</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1635"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1904"/> <source>Invalid output: </source> <translation>Sortie invalide : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1645"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1914"/> <source>Bad argument: </source> <translation>Mauvais argument : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1645"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1914"/> <source>should be "add"</source> <translation>devrait être "add"</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1654"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1923"/> <source>Failed to open file</source> <translation>Échec de l'ouverture du fichier</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1660"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1929"/> <source>Invalid output key, and file doesn't exist</source> <translation>Clé de sortie invalide, et le fichier n'existe pas</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1666"/> - <source>Failed to blackball output: </source> - <translation>Échec du blackboulage de la sortie : </translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1677"/> - <source>usage: unblackball <amount>/<offset></source> - <translation>usage : unblackball <montant>/<offset></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1683"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1710"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1952"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1979"/> <source>Invalid output</source> <translation>Sortie invalide</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1693"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1723"/> - <source>Failed to unblackball output: </source> - <translation>Échec du déblackboulage de la sortie : </translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1704"/> - <source>usage: blackballed <amount>/<offset></source> - <translation>usage : blackballed <montant>/<offset></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1717"/> - <source>Blackballed: </source> - <translation>Blackboulé : </translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1719"/> - <source>not blackballed: </source> - <translation>non blackboulé : </translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1738"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2007"/> <source>Failed to save known rings: </source> <translation>Échec de la sauvegarde des cercles connus : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1779"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1798"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2069"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2088"/> <source>wallet is watch-only and cannot transfer</source> <translation>c'est un portefeuille d'audit et il ne peut pas transférer</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1816"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5031"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2106"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5581"/> <source>WARNING: this is a non default ring size, which may harm your privacy. Default is recommended.</source> <translation>ATTENTION : ceci c'est pas la taille de cercle par défaut, ce qui peut nuire à votre confidentialité. La valeur par défaut est recommandée.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1818"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2108"/> <source>WARNING: from v8, ring size will be fixed and this setting will be ignored.</source> <translation>ATTENTION : ) partir de v8, la taille de cercle sera fixée et ce paramètre sera ignoré.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1847"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1870"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1886"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2137"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2160"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2176"/> <source>priority must be either 0, 1, 2, 3, or 4, or one of: </source> <translation>la priorité doit être 0, 1, 2, 3, 4 ou l'une de : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1891"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2181"/> <source>could not change default priority</source> <translation>échec du changement de la priorité par défaut</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1959"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2249"/> <source>invalid argument: must be either 0/never, 1/action, or 2/encrypt/decrypt</source> <translation>argument invalide : doit être soit 0/never, 1/action, ou 2/encrypt/decrypt</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2232"/> - <source>set_daemon <host>[:<port>] [trusted|untrusted]</source> - <translation>set_daemon <hôte>[:<port>] [trusted|untrusted]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2256"/> - <source>transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] (<URI> | <address> <amount>) [<payment_id>]</source> - <translation>transfer [index=<N1>[,<N2>,...]] [<priorité>] [<taille_cercle>] (<URI> | <adresse> <montant>) [<ID_paiement>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2257"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2595"/> <source>Transfer <amount> to <address>. If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding URI_2 or <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> - <translation>Transférer <montant> à <adresse> Si le paramètre "index=<N1>[,<N2>,...]" est spécifié, le portefeuille utilise les sorties reçues par les adresses de ces indices. Si il est omis, le portefeuille choisit les indices d'adresse à utiliser aléatoirement. Dans tous les cas, il essaye de ne pas combiner des sorties de multiples adresses. <priorité> est la priorité de la transaction. Plus la priorité est haute, plus les frais de transaction sont élévés. Les valeurs valides par ordre de priorité (de la plus basse à la plus haute) sont : unimportant, normal, elevated, priority. Si elle est omise, la valeur par défaut (voir la commande "set priority") est utilisée. <taille_cercle> est le nombre d'entrées à inclure pour l'intraçabilité. De multiples paiements peuvent être réalisés d'un coup en ajoutant <URI_2> ou <adresse_2> <montant_2> et cetera (avant l'ID de paiement, si il est inclus)</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2260"/> - <source>locked_transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] (<URI> | <addr> <amount>) <lockblocks> [<payment_id>]</source> - <translation>locked_transfer [index=<N1>[,<N2>,...]] [<priorité>] [<taille_cercle>] (<URI> | <adresse> <montant>) <blocs_verrou> [<ID_paiement>]</translation> + <translation>Transférer <montant> à <adresse> Si le paramètre "index=<N1>[,<N2>,...]" est spécifié, le portefeuille utilise les sorties reçues par les adresses de ces indices. Si il est omis, le portefeuille choisit les indices d'adresse à utiliser aléatoirement. Dans tous les cas, il essaye de ne pas combiner des sorties de multiples adresses. <priorité> est la priorité de la transaction. Plus la priorité est haute, plus les frais de transaction sont élévés. Les valeurs valides par ordre de priorité (de la plus basse à la plus haute) sont : unimportant, normal, elevated, priority. Si elle est omise, la valeur par défaut (voir la commande "set priority") est utilisée. <taille_cercle> est le nombre d'entrées à inclure pour l'intraçabilité. De multiples paiements peuvent être réalisés d'un coup en ajoutant <URI_2> ou <adresse_2> <montant_2> et cetera (avant l'ID de paiement, si il est inclus)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2261"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2599"/> <source>Transfer <amount> to <address> and lock it for <lockblocks> (max. 1000000). If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding URI_2 or <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> - <translation>Transférer <montant> à <adresse> et le verrouiller pendant <blocs_verrou> (max 1000000). Si le paramètre "index=<N1>[,<N2>,...]" est spécifié, le portefeuille utilise les sorties reçues par les adresses de ces indices. Si il est omis, le portefeuille choisit les indices d'adresse à utiliser aléatoirement. Dans tous les cas, il essaye de ne pas combiner des sorties de multiples adresses. <priorité> est la priorité de la transaction. Plus la priorité est haute, plus les frais de transaction sont élévés. Les valeurs valides par ordre de priorité (de la plus basse à la plus haute) sont : unimportant, normal, elevated, priority. Si elle est omise, la valeur par défaut (voir la commande "set priority") est utilisée. <taille_cercle> est le nombre d'entrées à inclure pour l'intraçabilité. De multiples paiements peuvent être réalisés d'un coup en ajoutant <URI_2> ou <adresse_2> <montant_2> et cetera (avant l'ID de paiement, si il est inclus)</translation> + <translation>Transférer <montant> à <adresse> et le verrouiller pendant <blocs_verrou> (max 1000000). Si le paramètre "index=<N1>[,<N2>,...]" est spécifié, le portefeuille utilise les sorties reçues par les adresses de ces indices. Si il est omis, le portefeuille choisit les indices d'adresse à utiliser aléatoirement. Dans tous les cas, il essaye de ne pas combiner des sorties de multiples adresses. <priorité> est la priorité de la transaction. Plus la priorité est haute, plus les frais de transaction sont élévés. Les valeurs valides par ordre de priorité (de la plus basse à la plus haute) sont : unimportant, normal, elevated, priority. Si elle est omise, la valeur par défaut (voir la commande "set priority") est utilisée. <taille_cercle> est le nombre d'entrées à inclure pour l'intraçabilité. De multiples paiements peuvent être réalisés d'un coup en ajoutant <URI_2> ou <adresse_2> <montant_2> et cetera (avant l'ID de paiement, si il est inclus)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2264"/> - <source>locked_sweep_all [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> <lockblocks> [<payment_id>]</source> - <translation>locked_sweep_all [index=<N1>[,<N2>,...]] [<priorité>] [<taille_cercle>] <adresse> <blocs_verrou> [<ID_paiement>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2265"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2603"/> <source>Send all unlocked balance to an address and lock it for <lockblocks> (max. 1000000). If the parameter "index<N1>[,<N2>,...]" is specified, the wallet sweeps outputs received by those address indices. If omitted, the wallet randomly chooses an address index to be used. <priority> is the priority of the sweep. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability.</source> - <translation>Transférer tout le solde débloqué à une adresse et le verrouiller pendant <blocs_verrou> (max 1000000). Si le paramètre "index=<N1>[,<N2>,...]" est spécifié, le portefeuille utilise les sorties reçues par ces indices d'adresse. Si il est omis, le portefeuille choisit un index d'adresse à utiliser aléatoirement. <priorité> est la priorité du balayage. Plus la priorité est haute, plus les frais de transaction sont élévés. Les valeurs valides par ordre de priorité (de la plus basse à la plus haute) sont : unimportant, normal, elevated, priority. Si elle est omise, la valeur par défaut (voir la commande "set priority") est utilisée. <taille_cercle> est le nombre d'entrées à inclure pour l'intraçabilité.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2270"/> - <source>sweep_all [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] [outputs=<N>] <address> [<payment_id>]</source> - <translation>sweep_all [index=<N1>[,<N2>,...]] [<priorité>] [<taille_cercle>] [outputs=<N>] <adresse> [<ID_paiement>]</translation> + <translation>Transférer tout le solde débloqué à une adresse et le verrouiller pendant <blocs_verrou> (max 1000000). Si le paramètre "index=<N1>[,<N2>,...]" est spécifié, le portefeuille utilise les sorties reçues par ces indices d'adresse. Si il est omis, le portefeuille choisit un index d'adresse à utiliser aléatoirement. <priorité> est la priorité du balayage. Plus la priorité est haute, plus les frais de transaction sont élévés. Les valeurs valides par ordre de priorité (de la plus basse à la plus haute) sont : unimportant, normal, elevated, priority. Si elle est omise, la valeur par défaut (voir la commande "set priority") est utilisée. <taille_cercle> est le nombre d'entrées à inclure pour l'intraçabilité.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2271"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2609"/> <source>Send all unlocked balance to an address. If the parameter "index<N1>[,<N2>,...]" is specified, the wallet sweeps outputs received by those address indices. If omitted, the wallet randomly chooses an address index to be used. If the parameter "outputs=<N>" is specified and N > 0, wallet splits the transaction into N even outputs.</source> <translation>Envoyer tout le solde débloqué à une adresse. Si le paramètre "index<N1>[,<N2>,...]" est spécifié, le portefeuille balaye les sorties reçues par ces indices d'adresse. Si il est omis, le portefeuille choisit un index d'adresse à utiliser aléatoirement. Si le paramètre "outputs=<N>" est spécifié et N > 0, le portefeuille scinde la transaction en N sorties égales.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2278"/> - <source>sweep_single [<priority>] [<ring_size>] [outputs=<N>] <key_image> <address> [<payment_id>]</source> - <translation>sweep_single [<priorité>] [<taille_cercle>] [outputs=<N>] <image_clé> <adresse> [<ID_paiement>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2286"/> - <source>sign_transfer [export_raw]</source> - <translation>sign_transfer [export_raw]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2287"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2625"/> <source>Sign a transaction from a file. If the parameter "export_raw" is specified, transaction raw hex data suitable for the daemon RPC /sendrawtransaction is exported.</source> <translation>Signer une transaction à partir d'un fichier. Si le paramètre "export_raw" est spécifié, les données brutes hexadécimales adaptées au RPC /sendrawtransaction du démon sont exportées.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2314"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2646"/> <source>If no arguments are specified or <index> is specified, the wallet shows the default or specified address. If "all" is specified, the wallet shows all the existing addresses in the currently selected account. If "new " is specified, the wallet creates a new address with the provided label text (which can be empty). If "label" is specified, the wallet sets the label of the address specified by <index> to the provided label text.</source> <translation>Si aucun argument n'est spécifié ou si <index> est spécifié, le portefeuille affiche l'adresse par défaut ou l'adresse spécifiée. Si "all" est spécifié, le portefeuille affiche toutes les adresses existantes dans le comptes actuellement sélectionné. Si "new" est spécifié, le portefeuille crée une nouvelle adresse avec le texte d'étiquette fourni (qui peut être vide). Si "label" est spécifié, le portefeuille affecte le texte fourni à l'étiquette de l'adresse spécifiée par <index>.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2341"/> - <source>Available options: - seed language - Set the wallet's 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 the default ring size (default and minimum is 5). - auto-refresh <1|0> - Whether to automatically synchronize new blocks from the daemon. - refresh-type <full|optimize-coinbase|no-coinbase|default> - Set the wallet's refresh behaviour. - priority [0|1|2|3|4] - Set the fee to default/unimportant/normal/elevated/priority. - confirm-missing-payment-id <1|0> - ask-password <0|1|2 (or never|action|decrypt)> - unit <monero|millinero|micronero|nanonero|piconero> - Set the 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] - Set a threshold for confirm-backlog to only warn if the transaction backlog is greater than n blocks. - refresh-from-block-height [n] - Set the height before which to ignore blocks. - auto-low-priority <1|0> - Whether to automatically use the low priority fee level when it's safe to do so. - segregate-pre-fork-outputs <1|0> - Set this if you intend to spend outputs on both Monero AND a key reusing fork. - key-reuse-mitigation2 <1|0> - Set this if you are not sure whether you will spend on a key reusing Monero fork later. -subaddress-lookahead <major>:<minor> - Set the lookahead sizes for the subaddress hash table. - Set this if you are not sure whether you will spend on a key reusing Monero fork later. - segregation-height <n> - Set to the height of a key reusing fork you want to use, 0 to use default.</source> - <translation>Options disponibles : - seed langue - Définir la langue de la phrase mnémonique. - always-confirm-transfers <1|0> - Confirmation des transactions non scindées. - print-ring-members <1|0> - Affichage d'informations détaillées sur les membres du cercle lors de la confirmation. - store-tx-info <1|0> - Sauvegarde des informations des transactions sortantes (adresse de destination, ID de paiement, clé secrète de transaction) pour référence ultérieure. - default-ring-size <n> - Définir la taille de cercle par défaut (la valeur par défaut est le minimum 5). - auto-refresh <1|0> - Synchronisation automatique des nouveaux blocs du démon. - refresh-type <full|optimize-coinbase|no-coinbase|default> - Définir le comportement du rafraîchissement du portefeuille. - priority [0|1|2|3|4] - Utiliser les frais pour la priorité par défaut/peu importante/normale/élevée/prioritaire. - confirm-missing-payment-id <1|0> - ask-password <0|1|2 (ou never|action|decrypt)> - unit <monero|millinero|micronero|nanonero|piconero> - Définir la (sous-)unité monero par défaut. - min-outputs-count [n] - Essayer de garder au moins ce nombre de sorties d'une valeur d'au moins min-outputs-value. - min-outputs-value [n] - Essayer de garder au moins min-outputs-count sorties d'au moins cette valeur. - merge-destinations <1|0> - Fusion des paiements multiples vers la même adresse de destination. - confirm-backlog <1|0> - Avertir s'il y a un arriéré de transactions. - confirm-backlog-threshold [n] - Définir un seuil pour confirm-backlog pour avertir seulement si l'arriéré de transactions est supérieur à n blocs. - refresh-from-block-height [n] - Définir la hauteur avant laquelle les blocs sont ignorés. - auto-low-priority <1|0> - Utilisation automatique du niveau de frais pour la priorité basse, lorsqu'il est sûr de le faire. - segregate-pre-fork-outputs <1|0> - Activez ceci si vous prévoyez de dépenser des sorties à la fois avec Monero ET un fork réutilisant les clés. - key-reuse-mitigation2 <1|0> - Activez ceci si vous n'êtes pas sûr de ne jamais utiliser un fork réutilisant les clés. - subaddress-lookahead <majeur>:<mineur> - Définir les nombres de sous-adresse à inclure par anticipation dans la table de hachage des sous-adresses. - segregation-height <n> - Définir la hauteur d'un fork réutilisant les clés que vous voulez utiliser, 0 par défaut.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2397"/> - <source>set_tx_key <txid> <tx_key></source> - <translation>set_tx_key <ID_transaction> <clé_transaction></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2398"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2730"/> <source>Set the transaction key (r) for a given <txid> in case the tx was made by some other device or 3rd party wallet.</source> <translation>Définir la clé de transaction (r) pour un <ID_transaction> donné au cas où cette clé ait été créée par un appareil ou portefeuille tiers.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2431"/> - <source>show_transfers [in|out|pending|failed|pool|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]</source> - <translation>show_transfers [in|out|pending|failed|pool|coinbase] [index=<N1>[,<N2>,...]] [<hauteur_min> [<hauteur_max>]]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2439"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2784"/> <source>Rescan the blockchain from scratch, losing any information which can not be recovered from the blockchain itself.</source> <translation>Rescanner la chaîne de blocs à partir du début, en perdant toute information qui ne peut pas être retrouvée à partir de la chaîne elle même.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2479"/> - <source>hw_reconnect</source> - <translation>hw_reconnect</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2480"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2830"/> <source>Attempts to reconnect HW wallet.</source> <translation>Essayer de se reconnecter à un portefeuille matériel.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2533"/> - <source>print_ring <key_image> | <txid></source> - <translation>print_ring <image_clé> | <ID_transaction></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2534"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2972"/> <source>Print the ring(s) used to spend a given key image or transaction (if the ring size is > 1) Output format: @@ -2994,1297 +3421,1076 @@ Key Image, "absolute", list of rings</source> <translation type="unfinished">Afficher le(s) cercle(s) utilisé(s) pour dépenser une image de clé ou une transaction (si la taille de cercle est > 1)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2537"/> - <source>set_ring <filename> | ( <key_image> absolute|relative <index> [<index>...] )</source> - <translation>set_ring <nom_fichier> | ( <image_clé> absolute|relative <index> [<index>...] )</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2538"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2978"/> <source>Set the ring used for a given key image, so it can be reused in a fork</source> <translation>Définir le cercle utilisé pour une image de clé donnée, afin de pouvoir le réutiliser dans un fork</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2541"/> - <source>save_known_rings</source> - <translation>save_known_rings</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2542"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2982"/> <source>Save known rings to the shared rings database</source> <translation>Sauvegarder les cercles connus dans la base de données des cercles partagés</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2545"/> - <source>blackball <amount>/<offset> | <filename> [add]</source> - <translation>blackball <montant>/<offset> | <nom_fichier> [add]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2546"/> - <source>Blackball output(s) so they never get selected as fake outputs in a ring</source> - <translation>Blackbouler des sorties pour qu'elles ne soient jamais sélectionnées comme leurres dans un cercle</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2549"/> - <source>unblackball <amount>/<offset></source> - <translation>unblackball <montant>/<offset></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2550"/> - <source>Unblackballs an output so it may get selected as a fake output in a ring</source> - <translation>Déblackbouler une sortie pour qu'elle puisse être sélectionnée comme leurre dans un cercle</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2553"/> - <source>blackballed <amount>/<offset></source> - <translation>blackballed <montant>/<offset></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2554"/> - <source>Checks whether an output is blackballed</source> - <translation>Vérifier si une sortie est blackboulée</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2557"/> - <source>version</source> - <translation>version</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2558"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2998"/> <source>Returns version information</source> <translation>Retourne les informations de version</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2646"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3087"/> <source>full (slowest, no assumptions); optimize-coinbase (fast, assumes the whole coinbase is paid to a single address); no-coinbase (fastest, assumes we receive no coinbase transaction), default (same as optimize-coinbase)</source> <translation>full (le plus lent, aucune supposition); optimize-coinbase (rapide, suppose que la récompense de bloc est payée à une unique adresse); no-coinbase (le plus rapide, suppose que l'on ne reçoit aucune récompense de bloc), default (comme optimize-coinbase)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2647"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3088"/> <source>0, 1, 2, 3, or 4, or one of </source> <translation>0, 1, 2, 3, 4 ou l'une de </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2649"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3090"/> <source>0|1|2 (or never|action|decrypt)</source> <translation>0|1|2 (ou never|action|decrypt)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2650"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3091"/> <source>monero, millinero, micronero, nanonero, piconero</source> <translation>monero, millinero, micronero, nanonero, piconero</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2661"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3102"/> <source><major>:<minor></source> <translation><majeur>:<mineur></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2684"/> - <source>wrong number range, use: set_log <log_level_number_0-4> | <categories></source> - <translation>nombre hors interval, utilisez : set_log <niveau_de_journalisation_0-4> | <catégories></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2723"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3166"/> <source>Wallet name not valid. Please try again or use Ctrl-C to quit.</source> <translation>Nom de portefeuille non valide. Veuillez réessayer ou utilisez Ctrl-C pour quitter.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2740"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3183"/> <source>Wallet and key files found, loading...</source> <translation>Fichier portefeuille et fichier de clés trouvés, chargement...</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2746"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3189"/> <source>Key file found but not wallet file. Regenerating...</source> <translation>Fichier de clés trouvé mais pas le fichier portefeuille. Régénération...</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2752"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3195"/> <source>Key file not found. Failed to open wallet: </source> - <translation>Fichier de clés non trouvé. Échec de l'ouverture du portefeuille : </translation> + <translation>Fichier de clés non trouvé. Échec de l'ouverture du portefeuille : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2771"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3214"/> <source>Generating new wallet...</source> <translation>Génération du nouveau portefeuille...</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2830"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3273"/> <source>Can't specify more than one of --testnet and --stagenet</source> <translation>Impossible de spécifier plus d'une option parmis --testnet et --stagenet</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2842"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3285"/> <source>can't specify more than one of --generate-new-wallet="wallet_name", --wallet-file="wallet_name", --generate-from-view-key="wallet_name", --generate-from-spend-key="wallet_name", --generate-from-keys="wallet_name", --generate-from-multisig-keys="wallet_name", --generate-from-json="jsonfilename" and --generate-from-device="wallet_name"</source> <translation>impossible de spécifier plus d'une option parmis --generate-new-wallet="nom_portefeuille", --wallet-file="nom_portefeuille", --generate-from-view-key="nom_portefeuille", --generate-from-spend-key="nom_portefeuille", --generate-from-keys="nom_portefeuille", --generate-from-multisig-keys="nom_portefeuille", --generate-from-json="nom_fichier_json" et --generate-from-device="nom_portefeuille"</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2921"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3364"/> <source>Electrum-style word list failed verification</source> <translation>Échec de la vérification de la liste de mots de style Electrum</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2926"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3369"/> <source>Enter seed offset passphrase, empty if none</source> <translation>Entrer une phrase de passe pour le décalage de la phrase mnémonique, vide si aucun</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2952"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2972"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3007"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3027"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3047"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3062"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3110"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3135"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3151"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3190"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3395"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3415"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3450"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3470"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3490"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3505"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3578"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3594"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3633"/> <source>No data supplied, cancelled</source> <translation>Pas de données fournies, annulation</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2958"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3033"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3141"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4823"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5373"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5623"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6173"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6241"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6305"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6521"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7377"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7636"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3401"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3476"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3584"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5371"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5969"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6243"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6818"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6886"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6950"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7154"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8193"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8454"/> <source>failed to parse address</source> <translation>échec de l'analyse de l'adresse</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2978"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3068"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3421"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3511"/> <source>failed to parse view key secret key</source> <translation>échec de l'analyse de la clé secrète d'audit</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2987"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3085"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3430"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3528"/> <source>failed to verify view key secret key</source> <translation>échec de la vérification de la clé secrète d'audit</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2991"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3089"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3170"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3434"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3532"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3613"/> <source>view key does not match standard address</source> <translation>la clé d'audit ne correspond pas à l'adresse standard</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2996"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3016"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3093"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3226"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3252"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3283"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3439"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3459"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3536"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3669"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3695"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3726"/> <source>account creation failed</source> <translation>échec de la création du compte</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3012"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3053"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3195"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3455"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3496"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3638"/> <source>failed to parse spend key secret key</source> <translation>échec de l'analyse de la clé secrète de dépense</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3077"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3215"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3520"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3658"/> <source>failed to verify spend key secret key</source> <translation>échec de la vérification de la clé secrète de dépense</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3081"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3220"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3524"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3663"/> <source>spend key does not match standard address</source> <translation>la clé de dépense ne correspond pas à l'adresse standard</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3258"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3701"/> <source>No restore height is specified.</source> <translation>Aucune hauteur de restauration n'est spécifiée.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3259"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3702"/> <source>Assumed you are creating a new account, restore will be done from current estimated blockchain height.</source> <translation>Nous supposons que vous créez un nouveau compte, la restauration sera faite à partir d'une hauteur de la chaîne de blocs estimée.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3260"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3703"/> <source>Use --restore-height if you want to restore an already setup account from a specific height</source> <translation>Utilisez --restore-height si vous voulez restaurer un compte existant à partir d'une hauteur spécifique</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3264"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3707"/> <source>account creation aborted</source> <translation>création du compte annulée</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3373"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3816"/> <source>can't specify --subaddress-lookahead and --wallet-file at the same time</source> <translation>Impossible de spécifier --subaddress-lookahead et --wallet-file en même temps</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3377"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3820"/> <source>failed to open account</source> <translation>échec de l'ouverture du compte</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3381"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3943"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3996"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4081"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6209"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3824"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4391"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4444"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4529"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6854"/> <source>wallet is null</source> <translation>portefeuille est nul</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3389"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3832"/> <source>Failed to initialize ring database: privacy enhancing features will be inactive</source> <translation>Impossible d'initialiser la base de données des cercles : les fonctions d'amélioration de la confidentialité seront inactives</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3474"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3917"/> <source>If your display freezes, exit blind with ^C, then run again with --use-english-language-names</source> <translation>Si votre affichage se bloque, quittez en aveugle avec ^C, puis lancer à nouveau en utilisant --use-english-language-names</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3492"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3497"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3935"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3940"/> <source>invalid language choice entered. Please try again. </source> <translation>choix de langue passé invalide. Veuillez réessayer. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3576"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4019"/> <source>View key: </source> - <translation>Clé d'audit : </translation> + <translation>Clé d'audit : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3684"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4130"/> <source>Generated new wallet on hw device: </source> <translation>Nouveau portefeuille généré sur l'appareil : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3763"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4209"/> <source>Key file not found. Failed to open wallet</source> <translation>Fichier des clés non trouvé. Échec d'ouverture du portefeuille</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3838"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4286"/> <source>You may want to remove the file "%s" and try again</source> <translation>Vous pourriez vouloir supprimer le fichier "%s" et réessayer</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3866"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4314"/> <source>failed to deinitialize wallet</source> <translation>échec de la désinitialisation du portefeuille</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3919"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4367"/> <source>Watch only wallet saved as: </source> <translation>Portefeuille d'audit sauvegardé vers : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3923"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4371"/> <source>Failed to save watch only wallet: </source> - <translation>Échec de la sauvegarde du portefeuille d'audit : </translation> + <translation>Échec de la sauvegarde du portefeuille d'audit : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3934"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4497"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7703"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4382"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5024"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8522"/> <source>this command requires a trusted daemon. Enable with --trusted-daemon</source> <translation>cette commande requiert un démon de confiance. Activer avec --trusted-daemon</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3975"/> - <source>invalid arguments. Please use start_mining [<number_of_threads>] [do_bg_mining] [ignore_battery]</source> - <translation>arguments invalides. Veuillez utiliser start_mining [<nombre_de_threads>] [do_bg_mining] [ignore_battery]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4050"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4498"/> <source>Expected trusted or untrusted, got </source> <translation>"trusted" ou "untrusted" attendu, mais lu </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4067"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4515"/> <source>trusted</source> <translation>de confiance</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4067"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4515"/> <source>untrusted</source> <translation>non fiable</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4091"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4539"/> <source>blockchain can't be saved: </source> - <translation>la chaîne de blocs ne peut pas être sauvegardée : </translation> + <translation>la chaîne de blocs ne peut pas être sauvegardée : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4121"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4569"/> <source>NOTE: this transaction uses an encrypted payment ID: consider using subaddresses instead</source> <translation>NOTE: cette transaction utilise un ID de paiement chiffré: veuillez considérer l'utilisation de sous-adresses à la place</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4124"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4572"/> <source>WARNING: this transaction uses an unencrypted payment ID: consider using subaddresses instead</source> <translation>ATTENTION: cette transaction utilise un ID de paiement non chiffré: veuillez considérer l'utilisation de sous-adresses à la place</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4160"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4608"/> <source>Password needed (%s) - use the refresh command</source> <translation>Mot de passe requis (%s) - utilisez la commande refresh</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4168"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4616"/> <source>Enter password</source> <translation>Entrez le mot de passe</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4215"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4511"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4720"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5038"/> <source>daemon is busy. Please try again later.</source> <translation>le démon est occupé. Veuillez réessayer plus tard.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4219"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4515"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4724"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5042"/> <source>no connection to daemon. Please make sure daemon is running.</source> <translation>pas de connexion au démon. Veuillez vous assurer que le démon fonctionne.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4229"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4734"/> <source>refresh error: </source> - <translation>erreur du rafraîchissement : </translation> + <translation>erreur du rafraîchissement : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4277"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4782"/> <source> (Some owned outputs have missing key images - import_key_images needed)</source> <translation> (Il manque les images de clé de certaines sorties - import_key_images requis)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4281"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4786"/> <source>Balance: </source> - <translation>Solde : </translation> + <translation>Solde : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4377"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4893"/> <source>pubkey</source> <translation>clé publique</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4377"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4893"/> <source>key image</source> <translation>image de clé</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4378"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4388"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4910"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> <source>unlocked</source> <translation>déverrouillé</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4378"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> <source>ringct</source> <translation>ringct</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4387"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4909"/> <source>T</source> <translation>V</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4387"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4909"/> <source>F</source> <translation>F</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4388"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4910"/> <source>locked</source> <translation>vérrouillé</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4389"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4911"/> <source>RingCT</source> <translation>RingCT</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4389"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4911"/> <source>-</source> <translation>-</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4463"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4990"/> <source>payment ID has invalid format, expected 16 or 64 character hex string: </source> - <translation>format d'identifiant de paiement invalide, 16 ou 64 caractères hexadécimaux attendus : </translation> + <translation>format d'identifiant de paiement invalide, 16 ou 64 caractères hexadécimaux attendus : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4519"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5046"/> <source>failed to get spent status</source> <translation>échec de la récupération du statut de dépense</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4579"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5130"/> <source>failed to find construction data for tx input</source> <translation>échec de la recherche des données pour contruire l'entrée de la transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4645"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5193"/> <source>the same transaction</source> <translation>la même transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4645"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5193"/> <source>blocks that are temporally very close</source> <translation>blocs très proches dans le temps</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4705"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5274"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5251"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5870"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6173"/> <source>ring size %u is too large, maximum is %u</source> <translation>la taille de cercle %u est trop grande, le maximum est %u</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4730"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4847"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5276"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5395"/> <source>Unencrypted payment IDs are bad for privacy: ask the recipient to use subaddresses instead</source> <translation>Les ID de paiment non chiffrés sont mauvais pour la confidentialité : demandez au bénéficiaire d'utiliser les sous-adresses à la place</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4747"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5293"/> <source>payment id failed to encode</source> <translation>échec de l'encodage de l'ID de paiement</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4766"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5298"/> - <source>Locked blocks too high, max 1000000 (˜4 yrs)</source> - <translation>Nombre de blocs verrou trop élévé, 1000000 max (˜4 ans)</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4792"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5340"/> <source>failed to parse short payment ID from URI</source> <translation>échec de l'analyse de l'ID de paiement court à partir de l'URI</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4815"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4817"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5363"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5365"/> <source>Invalid last argument: </source> <translation>Dernier argument invalide : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4834"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5382"/> <source>a single transaction cannot use more than one payment id</source> <translation>une unique transaction ne peut pas utiliser plus d'un ID de paiement</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4851"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5399"/> <source>failed to parse payment id, though it was detected</source> <translation>échec de l'analyse de l'ID de paiement, bien qu'il ait été détecté</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5186"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5775"/> <source>Not enough money in unlocked balance</source> <translation>Pas assez de fonds dans le solde débloqué</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5187"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5776"/> <source>Discarding %s of unmixable outputs that cannot be spent, which can be undone by "rescan_spent". Is this okay? (Y/Yes/N/No): </source> <translation>On se débarrasse de %s de sorties non mélangeables qui ne peuvent pas être dépensées, ce qui peut être défait avec "rescan_spent". Est-ce d'accord ? (Y/Yes/N/No) : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5215"/> - <source>usage: %s [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] [outputs=<N>] <address> [<payment_id>]</source> - <translation>usage: %s [index=<N1>[,<N2>,...]] [<priorité>] [<taille_cercle>] [outputs=<N>] <adresse> [<ID_paiement>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5283"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5879"/> <source>missing lockedblocks parameter</source> <translation>paramètre blocs_verrou manquant</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5293"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5889"/> <source>bad locked_blocks parameter</source> <translation>mauvais paramètre blocs_verrou</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5318"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5562"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5914"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6182"/> <source>Failed to parse number of outputs</source> <translation>Échec de l'analyse du nombre de sorties</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5323"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5567"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5919"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6187"/> <source>Amount of outputs should be greater than 0</source> <translation>Le nombre de sorties doit être supérieur à 0</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5609"/> - <source>usage: sweep_single [<priority>] [<ring_size>] [outputs=<N>] <key_image> <address> [<payment_id>]</source> - <translation>usage : sweep_single [<priorité>] [<taille_cercle>] [outputs=<N>] <image_clé> <adresse> [<ID_paiement>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5770"/> - <source>donations are not enabled on the testnet or on the stagenet</source> - <translation>les dons ne sont pas activés sur les réseaux testnet et stagenet</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5799"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6442"/> <source>Donating %s %s to The Monero Project (donate.getmonero.org or %s).</source> <translation>Don de %s %s à The Monero Project (donate.getmonero.org ou %s).</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5971"/> - <source>usage: sign_transfer [export_raw]</source> - <translation>usage : sign_transfer [export_raw]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6097"/> - <source>usage: set_tx_key <txid> <tx_key></source> - <translation>usage : set_tx_key <ID_transaction> <clé_transaction></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6114"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6125"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6132"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6759"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6770"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6777"/> <source>failed to parse tx_key</source> <translation>échec de l'analyse de la clé de transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6141"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6786"/> <source>Tx key successfully stored.</source> <translation>Clé de transaction sauvegardée avec succès.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6145"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6790"/> <source>Failed to store tx key: </source> <translation>Échec de la sauvegarde de la clé de transaction : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6324"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6440"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6969"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7079"/> <source>Good signature</source> <translation>Bonne signature</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6351"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6442"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6548"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6996"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7081"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7181"/> <source>Bad signature</source> <translation>Mauvaise signature</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6606"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7440"/> <source>usage: show_transfers [in|out|all|pending|failed|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]</source> - <translation>usage : show_transfers [in|out|all|pending|failed|coinbase] [index=<N1>[,<N2>,...]] [<hauteur_min> [<hauteur_max>]]</translation> + <translation>usage : show_transfers [in|out|all|pending|failed|coinbase] [index=<N1>[,<N2>,...]] [<hauteur_min> [<hauteur_max>]]</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6692"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7296"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> <source>block</source> <translation>bloc</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6926"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7730"/> <source>Warning: this will lose any information which can not be recovered from the blockchain.</source> <translation>Attention : ceci pedra toute information qui ne peut pas être retrouvée à partir de la chaîne de blocs.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6927"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7731"/> <source>This includes destination addresses, tx secret keys, tx notes, etc</source> <translation>Ceci inclut les adresses de destination, les clé secrètes de transaction, les notes de transaction, etc</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6928"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7732"/> <source>Rescan anyway ? (Y/Yes/N/No): </source> <translation>Rescanner quand même ? (Y/Yes/N/No) : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7317"/> - <source>usage: integrated_address [payment ID]</source> - <translation>usage : integrated_address [ID paiement]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7353"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8169"/> <source>Standard address: </source> - <translation>Adresse standard : </translation> + <translation>Adresse standard : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7358"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8174"/> <source>failed to parse payment ID or address</source> <translation>échec de l'analyse de l'ID de paiement ou de l'adresse</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7369"/> - <source>usage: address_book [(add (<address> [pid <long or short payment id>])|<integrated address> [<description possibly with whitespaces>])|(delete <index>)]</source> - <translation>usage : address_book [(add (<adresse> [pid <ID de paiement long ou court>])|<adresse integrée> [<description avec des espaces possible>])|(delete <index>)]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7399"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8215"/> <source>failed to parse payment ID</source> <translation>échec de l'analyse de l'ID de paiement</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7417"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8233"/> <source>failed to parse index</source> <translation>échec de l'analyse de l'index</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7425"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8241"/> <source>Address book is empty.</source> <translation>Le carnet d'adresses est vide.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7431"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8247"/> <source>Index: </source> - <translation>Index : </translation> + <translation>Index : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7432"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7562"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8248"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8378"/> <source>Address: </source> - <translation>Adresse : </translation> + <translation>Adresse : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7433"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8249"/> <source>Payment ID: </source> - <translation>ID de paiement : </translation> + <translation>ID de paiement : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7434"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7561"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8250"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8377"/> <source>Description: </source> - <translation>Description : </translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7444"/> - <source>usage: set_tx_note [txid] free text note</source> - <translation>usage : set_tx_note [ID transaction] note de texte libre</translation> + <translation>Description : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7472"/> - <source>usage: get_tx_note [txid]</source> - <translation>usage : get_tx_note [ID transaction]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7571"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8387"/> <source>Network type: </source> <translation>Type de réseau : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7572"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8388"/> <source>Testnet</source> <translation>Testnet</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7573"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8389"/> <source>Stagenet</source> <translation>Stagenet</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7573"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8389"/> <source>Mainnet</source> <translation>Mainnet</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7586"/> - <source>usage: sign <filename></source> - <translation>usage : sign <fichier></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7591"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8407"/> <source>wallet is watch-only and cannot sign</source> <translation>c'est un portefeuille d'audit et il ne peut pas signer</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1087"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7606"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7629"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7818"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1289"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8421"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8447"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8684"/> <source>failed to read file </source> <translation>échec de la lecture du fichier </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6286"/> - <source>usage: check_tx_proof <txid> <address> <signature_file> [<message>]</source> - <translation>usage : check_tx_proof <ID_transaction> <adresse> <fichier_signature> [<message>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6313"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6433"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6533"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6958"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7072"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7166"/> <source>failed to load signature file</source> <translation>échec du chargement du fichier signature</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6369"/> - <source>usage: get_spend_proof <txid> [<message>]</source> - <translation>usage : get_spend_proof <ID_transaction> [<message>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6375"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7020"/> <source>wallet is watch-only and cannot generate the proof</source> <translation>c'est un portefeuille d'audit et il ne peut générer de preuve</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6413"/> - <source>usage: check_spend_proof <txid> <signature_file> [<message>]</source> - <translation>usage : check_spend_proof <ID_transaction> <fichier_signature> [<message>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6459"/> - <source>usage: get_reserve_proof (all|<amount>) [<message>]</source> - <translation>usage : get_reserve_proof (all|<montant>) [<message>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6465"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7104"/> <source>The reserve proof can be generated only by a full wallet</source> <translation>La preuve de réserve ne peut être généré que par un portefeuille complet</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6508"/> - <source>usage: check_reserve_proof <address> <signature_file> [<message>]</source> - <translation>usage : check_reserve_proof <adresse> <fichier_signature> [<message>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6526"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7159"/> <source>Address must not be a subaddress</source> <translation>L'adresse ne doit pas être une sous-adresse</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6544"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7177"/> <source>Good signature -- total: %s, spent: %s, unspent: %s</source> - <translation>Bonne signature -- total : %s, dépensé : %s, non dépensé : %s</translation> + <translation>Bonne signature -- total : %s, dépensé : %s, non dépensé : %s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6754"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7365"/> <source>[Double spend seen on the network: this transaction may or may not end up being mined] </source> - <translation>[Double dépense détectée sur le réseau : cette transaction sera peut-être invalidée] </translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6790"/> - <source>usage: unspent_outputs [index=<N1>[,<N2>,...]] [<min_amount> [<max_amount>]]</source> - <translation>usage : unspent_outputs [index=<N1>[,<N2>,...]] [<montant_min> [<montant_max>]]</translation> + <translation>[Double dépense détectée sur le réseau : cette transaction sera peut-être invalidée] </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6850"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7641"/> <source>There is no unspent output in the specified address</source> <translation>Il n'y a pas de sortie non dépensée pour l'adresse spécifiée</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6970"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7799"/> <source> (no daemon)</source> <translation> (pas de démon)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6972"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7801"/> <source> (out of sync)</source> <translation> (désynchronisé)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7029"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7852"/> <source>(Untitled account)</source> <translation>(compte sans nom)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7042"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7060"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7085"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7108"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7261"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7284"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7865"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7883"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7908"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7931"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8077"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8100"/> <source>failed to parse index: </source> - <translation>échec de l'analyse de l'index : </translation> + <translation>échec de l'analyse de l'index : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7047"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7266"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7870"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8082"/> <source>specify an index between 0 and </source> <translation>specifiez un index entre 0 et </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7144"/> - <source>usage: - account - account new <label text with white spaces allowed> - account switch <index> - account label <index> <label text with white spaces allowed> - account tag <tag_name> <account_index_1> [<account_index_2> ...] - account untag <account_index_1> [<account_index_2> ...] - account tag_description <tag_name> <description></source> - <translation>usage : - account - account new <texte étiquette avec espaces autorisés> - account switch <index> - account label <index> <texte étiquette avec espaces autorisés> - account tag <mot_clé> <index_compte_1> [<index_compte_2> ...] - account untag <index_compte_1> [<index_compte_2> ...] - account tag_description <mot_clé> <description></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7172"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7988"/> <source> Grand total: Balance: </source> <translation> -Somme finale : - Solde : </translation> +Somme finale : + Solde : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7172"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7988"/> <source>, unlocked balance: </source> - <translation>, solde débloqué : </translation> + <translation>, solde débloqué : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7180"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7996"/> <source>Untagged accounts:</source> - <translation>Comptes sans mot clé :</translation> + <translation>Comptes sans mot clé :</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7186"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8002"/> <source>Tag %s is unregistered.</source> <translation>Le mot clé %s n'est pas enregistré.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7189"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8005"/> <source>Accounts with tag: </source> - <translation>Comptes avec mot clé : </translation> + <translation>Comptes avec mot clé : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7190"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8006"/> <source>Tag's description: </source> - <translation>Description du mot clé : </translation> + <translation>Description du mot clé : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7192"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8008"/> <source>Account</source> <translation>Compte</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7198"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8014"/> <source> %c%8u %6s %21s %21s %21s</source> <translation> %c%8u %6s %21s %21s %21s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7208"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8024"/> <source>----------------------------------------------------------------------------------</source> <translation>----------------------------------------------------------------------------------</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7209"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8025"/> <source>%15s %21s %21s</source> <translation>%15s %21s %21s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7232"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8048"/> <source>Primary address</source> <translation>Adresse primaire</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7232"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8048"/> <source>(used)</source> <translation>(utilisé)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7253"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8069"/> <source>(Untitled address)</source> <translation>(adresse sans nom)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7293"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8109"/> <source><index_min> is already out of bound</source> <translation><index_min> est déjà hors limite</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7298"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8114"/> <source><index_max> exceeds the bound</source> <translation><index_max> excède la limite</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7306"/> - <source>usage: address [ new <label text with white spaces allowed> | all | <index_min> [<index_max>] | label <index> <label text with white spaces allowed> ]</source> - <translation>usage : address [ new <texte étiquette avec espaces autorisés> | all | <index_min> [<index_max>] | label <index> <texte étiquette avec espaces autorisés>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7324"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7336"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8140"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8152"/> <source>Integrated addresses can only be created for account 0</source> <translation>Les adresses intégrées ne peuvent être créées que pour le compte 0</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7348"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8164"/> <source>Integrated address: %s, payment ID: %s</source> - <translation>Adresse intégrée : %s, ID de paiement : %s</translation> + <translation>Adresse intégrée : %s, ID de paiement : %s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7353"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8169"/> <source>Subaddress: </source> - <translation>Sous-adresse : </translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7513"/> - <source>usage: get_description</source> - <translation>usage : get_description</translation> + <translation>Sous-adresse : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7519"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8335"/> <source>no description found</source> <translation>pas de description trouvée</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7521"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8337"/> <source>description found: </source> - <translation>description trouvée : </translation> + <translation>description trouvée : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7560"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8376"/> <source>Filename: </source> - <translation>Fichier : </translation> + <translation>Fichier : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7565"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8381"/> <source>Watch only</source> <translation>Audit</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7567"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8383"/> <source>%u/%u multisig%s</source> <translation>Multisig %u/%u%s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7569"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8385"/> <source>Normal</source> <translation>Normal</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7570"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8386"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9180"/> <source>Type: </source> - <translation>Type : </translation> + <translation>Type : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7596"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8412"/> <source>This wallet is multisig and cannot sign</source> <translation>C'est un portefeuille multisig et il ne peut pas signer</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7618"/> - <source>usage: verify <filename> <address> <signature></source> - <translation>usage : verify <fichier> <adresse> <signature></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7643"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8461"/> <source>Bad signature from </source> <translation>Mauvaise signature de </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7647"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8465"/> <source>Good signature from </source> <translation>Bonne signature de </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7661"/> - <source>usage: export_key_images <filename></source> - <translation>usage : export_key_images <fichier></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7666"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8484"/> <source>wallet is watch-only and cannot export key images</source> <translation>c'est un portefeuille d'audit et il ne peut pas exporter les images de clé</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1037"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7679"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7785"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1228"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8498"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8651"/> <source>failed to save file </source> <translation>échec de l'enregistrement du fichier </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7690"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8509"/> <source>Signed key images exported to </source> <translation>Images de clé signées exportées vers </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7709"/> - <source>usage: import_key_images <filename></source> - <translation>usage : import_key_images <fichier></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7770"/> - <source>usage: export_outputs <filename></source> - <translation>usage : export_outputs <fichier></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7796"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8662"/> <source>Outputs exported to </source> <translation>Sorties exportées vers </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7809"/> - <source>usage: import_outputs <filename></source> - <translation>usage : import_outputs <fichier></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4806"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6476"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6809"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6817"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5354"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6417"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7115"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7600"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7608"/> <source>amount is wrong: </source> - <translation>montant erroné : </translation> + <translation>montant erroné : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4807"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5355"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6417"/> <source>expected number from 0 to </source> <translation>attend un nombre de 0 à </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5132"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5721"/> <source>Sweeping </source> <translation>Balayage de </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5728"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6350"/> <source>Money successfully sent, transaction: </source> - <translation>Fonds envoyés avec succès, transaction : </translation> + <translation>Fonds envoyés avec succès, transaction : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5885"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6530"/> <source>Change goes to more than one address</source> <translation>La monnaie rendue va à plus d'une adresse</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5926"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6571"/> <source>%s change to %s</source> <translation>%s de monnaie rendue à %s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5929"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6574"/> <source>no change</source> <translation>sans monnaie rendue</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1186"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1199"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6001"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1435"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1448"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6646"/> <source>Transaction successfully signed to file </source> <translation>Transaction signée avec succès dans le fichier </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6061"/> - <source>usage: get_tx_key <txid></source> - <translation>usage : get_tx_key <ID transaction></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6068"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6104"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6166"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6215"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6297"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6382"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6420"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7451"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7479"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7848"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6713"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6749"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6811"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6860"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6942"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7027"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7062"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8267"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8295"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8714"/> <source>failed to parse txid</source> <translation>échec de l'analyse de l'ID de transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6082"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6727"/> <source>Tx key: </source> - <translation>Clé de transaction : </translation> + <translation>Clé de transaction : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6087"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6732"/> <source>no tx keys found for this txid</source> <translation>aucune clé de transaction trouvée pour cet ID de transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6159"/> - <source>usage: get_tx_proof <txid> <address> [<message>]</source> - <translation>usage : get_tx_proof <ID_transaction> <adresse> [<message>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6184"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6399"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6494"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6829"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7041"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7130"/> <source>signature file saved to: </source> - <translation>fichier signature sauvegardé dans : </translation> + <translation>fichier signature sauvegardé dans : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6186"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6401"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6496"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6831"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7043"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7132"/> <source>failed to save signature file</source> <translation>échec de la sauvegarde du fichier signature</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6200"/> - <source>usage: check_tx_key <txid> <txkey> <address></source> - <translation>usage : check_tx_key <ID transaction> <clé transaction> <adresse></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6223"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6232"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6868"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6877"/> <source>failed to parse tx key</source> <translation>échec de l'analyse de la clé de transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6190"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6278"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6356"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6835"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6923"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7001"/> <source>error: </source> - <translation>erreur : </translation> + <translation>erreur : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6254"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6327"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6899"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6972"/> <source>received</source> <translation>a reçu</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6254"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6327"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6899"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6972"/> <source>in txid</source> <translation>dans la transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6273"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6346"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6918"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6991"/> <source>received nothing in txid</source> <translation>n'a rien reçu dans la transaction</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6257"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6330"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6902"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6975"/> <source>WARNING: this transaction is not yet included in the blockchain!</source> - <translation>ATTENTION : cette transaction n'est pas encore inclue dans la chaîne de blocs !</translation> + <translation>ATTENTION : cette transaction n'est pas encore inclue dans la chaîne de blocs !</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6263"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6336"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6908"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6981"/> <source>This transaction has %u confirmations</source> <translation>Cette transaction a %u confirmations</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6267"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6340"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6912"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6985"/> <source>WARNING: failed to determine number of confirmations!</source> - <translation>ATTENTION : échec de la détermination du nombre de confirmations !</translation> + <translation>ATTENTION : échec de la détermination du nombre de confirmations !</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6659"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7266"/> <source>bad min_height parameter:</source> - <translation>mauvais paramètre hauteur_minimum :</translation> + <translation>mauvais paramètre hauteur_minimum :</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6671"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7278"/> <source>bad max_height parameter:</source> - <translation>mauvais paramètre hauteur_maximum :</translation> + <translation>mauvais paramètre hauteur_maximum :</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6692"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7296"/> <source>in</source> <translation>reçu</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6726"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6778"/> - <source>out</source> - <translation>payé</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6778"/> - <source>failed</source> - <translation>échoué</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6778"/> - <source>pending</source> - <translation>en attente</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6824"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7615"/> <source><min_amount> should be smaller than <max_amount></source> <translation><montant_minimum> doit être inférieur à <montant_maximum></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6856"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7647"/> <source> Amount: </source> <translation> -Montant : </translation> +Montant : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6856"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7647"/> <source>, number of keys: </source> - <translation>, nombre de clés : </translation> + <translation>, nombre de clés : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6861"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7652"/> <source> </source> <translation> </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6866"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7657"/> <source> Min block height: </source> <translation> -Hauteur de bloc minimum : </translation> +Hauteur de bloc minimum : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6867"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7658"/> <source> Max block height: </source> <translation> -Hauteur de bloc maximum : </translation> +Hauteur de bloc maximum : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6868"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7659"/> <source> Min amount found: </source> <translation> -Montant minimum trouvé : </translation> +Montant minimum trouvé : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6869"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7660"/> <source> Max amount found: </source> <translation> -Montant maximum trouvé : </translation> +Montant maximum trouvé : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6870"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7661"/> <source> Total count: </source> <translation> -Compte total : </translation> +Compte total : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6910"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7701"/> <source> Bin size: </source> <translation> -Taille de classe : </translation> +Taille de classe : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6911"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7702"/> <source> Outputs per *: </source> <translation> -Sorties par * : </translation> +Sorties par * : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6913"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7704"/> <source>count ^ </source> @@ -4293,54 +4499,54 @@ Sorties par * : </translation> </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6915"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7706"/> <source> |</source> <translation> |</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6917"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7708"/> <source> +</source> <translation> +</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6917"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7708"/> <source>+--> block height </source> <translation>+--> hauteur de bloc </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6918"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7709"/> <source> ^</source> <translation> ^</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6918"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7709"/> <source>^ </source> <translation>^ </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6919"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7710"/> <source> </source> <translation> </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6968"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7797"/> <source>wallet</source> <translation>portefeuille</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="776"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="7328"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="870"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8144"/> <source>Random payment ID: </source> - <translation>ID de paiement aléatoire : </translation> + <translation>ID de paiement aléatoire : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="7329"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8145"/> <source>Matching integrated address: </source> - <translation>Adresse intégrée correspondante : </translation> + <translation>Adresse intégrée correspondante : </translation> </message> </context> <context> @@ -4396,297 +4602,437 @@ Sorties par * : </translation> <translation>Erreur de vérification des infos multisig supplémentaires</translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="150"/> - <source>Error finalizing multisig</source> - <translation>Erreur de finalisation multisig</translation> - </message> - <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="157"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="153"/> <source>Generated multisig wallets for address </source> <translation>Portefeuilles multisig générés pour l'adresse </translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="161"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="157"/> <source>Error creating multisig wallets: </source> - <translation>Erreur de création des portefeuilles multisig : </translation> + <translation>Erreur de création des portefeuilles multisig : </translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="186"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="182"/> <source>This program generates a set of multisig wallets - use this simpler scheme only if all the participants trust each other</source> <translation>Ce programme génère un ensemble de portefeuilles multisig - n'utilisez cette méthode plus simple que si tous les participants se font confiance</translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="205"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="201"/> <source>Error: Can't specify more than one of --testnet and --stagenet</source> <translation>Erreur: Impossible de spécifier plus d'une option parmis --testnet et --stagenet</translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="212"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="208"/> <source>Error: expected N/M, but got: </source> - <translation>Erreur : N/M attendu, mais lu : </translation> + <translation>Erreur : N/M attendu, mais lu : </translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="220"/> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="229"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="216"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="225"/> <source>Error: either --scheme or both of --threshold and --participants may be given</source> - <translation>Erreur : soit --scheme soit --threshold et --participants doivent être indiqués</translation> + <translation>Erreur : soit --scheme soit --threshold et --participants doivent être indiqués</translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="236"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="232"/> <source>Error: expected N > 1 and N <= M, but got N==%u and M==%d</source> - <translation>Erreur : N > 1 et N <= M attendu, mais lu N==%u et M==%d</translation> + <translation>Erreur : N > 1 et N <= M attendu, mais lu N==%u et M==%d</translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="245"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="241"/> <source>Error: --filename-base is required</source> - <translation>Erreur : --filename-base est requis</translation> + <translation>Erreur : --filename-base est requis</translation> + </message> +</context> +<context> + <name>mms::message_store</name> + <message> + <location filename="../src/wallet/message_store.cpp" line="69"/> + <source>Use PyBitmessage instance at URL <arg></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="70"/> + <source>Specify <arg> as username:password for PyBitmessage API</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="832"/> + <source>Auto-config cannot proceed because auto config data from other signers is not complete</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="857"/> + <source>The signer config is not complete.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="909"/> + <source>Wallet can't go multisig because key sets from other signers are missing or not complete.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="951"/> + <source>Wallet can't start another key exchange round because key sets from other signers are missing or not complete.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1015"/> + <source>Syncing not done because multisig sync data from other signers are missing or not complete.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1129"/> + <source>There are waiting messages, but nothing is ready to process under normal circumstances</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1132"/> + <source> +Use "mms next sync" if you want to force processing of the waiting sync data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1136"/> + <source> +Use "mms note" to display the waiting notes</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1141"/> + <source>There are no messages waiting to be processed.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1359"/> + <source>key set</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1361"/> + <source>additional key set</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1363"/> + <source>multisig sync data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1365"/> + <source>partially signed tx</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="251"/> - <source>Error: unsupported scheme: only N/N and N-1/N are supported</source> - <translation>Erreur : schéma non supporté : seuls N/N et N-1/N sont supportés</translation> + <location filename="../src/wallet/message_store.cpp" line="1367"/> + <source>fully signed tx</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1369"/> + <source>note</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1371"/> + <source>signer config</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1373"/> + <source>auto-config data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1375"/> + <source>unknown message type</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1384"/> + <source>in</source> + <translation type="unfinished">reçu</translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1386"/> + <source>out</source> + <translation type="unfinished">payé</translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1388"/> + <source>unknown message direction</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1397"/> + <source>ready to send</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1399"/> + <source>sent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1401"/> + <source>waiting</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1403"/> + <source>processed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1405"/> + <source>cancelled</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1407"/> + <source>unknown message state</source> + <translation type="unfinished"></translation> </message> </context> <context> <name>sw</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="119"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="125"/> <source>Generate new wallet and save it to <arg></source> <translation>Générer un nouveau portefeuille et le sauvegarder dans <arg></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="120"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="126"/> <source>Generate new wallet from device and save it to <arg></source> <translation>Générer un nouveau portefeuille à partir de l'appareil et le sauvegarder dans <arg></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="121"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="127"/> <source>Generate incoming-only wallet from view key</source> <translation>Générer un portefeuille d'audit à partir d'une clé d'audit</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="122"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="128"/> <source>Generate deterministic wallet from spend key</source> <translation>Générer un portefeuille déterministe à partir d'une clé de dépense</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="123"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="129"/> <source>Generate wallet from private keys</source> <translation>Générer un portefeuille à partir de clés privées</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="124"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="130"/> <source>Generate a master wallet from multisig wallet keys</source> <translation>Générer un portefeuille principal à partir de clés de portefeuille multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="126"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="132"/> <source>Language for mnemonic</source> <translation>Langue de la phrase mnémonique</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="127"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="133"/> <source>Specify Electrum seed for wallet recovery/creation</source> <translation>Spécifier la phrase mnémonique Electrum pour la récupération/création d'un portefeuille</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="128"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="134"/> <source>Recover wallet using Electrum-style mnemonic seed</source> <translation>Récupérer un portefeuille en utilisant une phrase mnémonique de style Electrum</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="129"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="135"/> <source>Recover multisig wallet using Electrum-style mnemonic seed</source> <translation>Récupérer un portefeuille multisig en utilisant une phrase mnémonique de style Electrum</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="130"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="136"/> <source>Generate non-deterministic view and spend keys</source> <translation>Générer des clés d'audit et de dépense non déterministes</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="268"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="361"/> <source>invalid argument: must be either 0/1, true/false, y/n, yes/no</source> <translation>argument invalide : doit être soit 0/1, true/false, y/n, yes/no</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="324"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="417"/> <source>DNSSEC validation passed</source> <translation>Validation DNSSEC réussie</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="328"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="421"/> <source>WARNING: DNSSEC validation was unsuccessful, this address may not be correct!</source> <translation>ATTENTION: la validation DNSSEC a échoué, cette adresse n'est peut être pas correcte !</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="331"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="424"/> <source>For URL: </source> <translation>Pour l'URL : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="333"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="426"/> <source> Monero Address = </source> <translation> Adresse Monero = </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="335"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="428"/> <source>Is this OK? (Y/n) </source> <translation>Est-ce correct ? (Y/n) </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="345"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="438"/> <source>you have cancelled the transfer request</source> <translation>vous avez annulé la demande de transfert</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="366"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="459"/> <source>failed to parse index: </source> - <translation>échec de l'analyse de l'index : </translation> + <translation>échec de l'analyse de l'index : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="379"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="472"/> <source>invalid format for subaddress lookahead; must be <major>:<minor></source> <translation>format invalide pour l'anticipation des sous-addresses; doit être <majeur>:<mineur></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="396"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="489"/> <source>no connection to daemon. Please make sure daemon is running.</source> <translation>pas de connexion au démon. Veuillez vous assurer que le démon fonctionne.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="401"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="494"/> <source>RPC error: </source> - <translation>Erreur RPC : </translation> + <translation>Erreur RPC : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="405"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="498"/> <source>failed to get random outputs to mix: </source> - <translation>échec de la récupération de sorties aléatoires à mélanger : </translation> + <translation>échec de la récupération de sorties aléatoires à mélanger : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="412"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="420"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="505"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="513"/> <source>Not enough money in unlocked balance</source> <translation>Pas assez de fonds dans le solde débloqué</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="430"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="523"/> <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>Impossible de trouver une façon de créer les transactions. Ceci est souvent dû à de la poussière si petite qu'elle ne peut pas payer ses propres frais, ou à une tentative d'envoi d'un montant supérieur au solde débloqué, ou à un montant restant insuffisant pour payer les frais</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="436"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="529"/> <source>not enough outputs for specified ring size</source> <translation>pas assez de sorties pour la taille de cercle spécifiée</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="439"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="532"/> <source>output amount</source> <translation>montant de la sortie</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="439"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="532"/> <source>found outputs to use</source> <translation>sorties à utiliser trouvées</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="441"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="534"/> <source>Please use sweep_unmixable.</source> <translation>Veuillez utiliser sweep_unmixable.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="445"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="538"/> <source>transaction was not constructed</source> <translation>la transaction n'a pas été construite</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="450"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="543"/> <source>transaction %s was rejected by daemon with status: </source> - <translation>la transaction %s a été rejetée par le démon avec le statut : </translation> + <translation>la transaction %s a été rejetée par le démon avec le statut : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="453"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="546"/> <source>Reason: </source> <translation>Raison : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="462"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="555"/> <source>one of destinations is zero</source> <translation>une des destinations est zéro</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="467"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="560"/> <source>failed to find a suitable way to split transactions</source> <translation>échec de la recherche d'une façon adéquate de scinder les transactions</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="473"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="566"/> <source>unknown transfer error: </source> - <translation>erreur de transfert inconnue : </translation> + <translation>erreur de transfert inconnue : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="478"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="571"/> <source>Multisig error: </source> - <translation>Erreur multisig : </translation> + <translation>Erreur multisig : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="484"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="577"/> <source>internal error: </source> - <translation>erreur interne : </translation> + <translation>erreur interne : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="489"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="582"/> <source>unexpected error: </source> - <translation>erreur inattendue : </translation> + <translation>erreur inattendue : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="493"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="586"/> <source>There was an error, which could mean the node may be trying to get you to retry creating a transaction, and zero in on which outputs you own. Or it could be a bona fide error. It may be prudent to disconnect from this node, and not try to send a transaction immediately. Alternatively, connect to another node so the original node cannot correlate information.</source> <translation>Il y a eu une erreur, ce qui pourrait signifier que le noeud essaye de vous faire réessayer de créer une transaction, pour tenter d'identifier quelles sorties sont les votres. Ou il pourrait s'agir d'une erreur de bonne foi. Il pourrait être prudent de se déconnecter de ce noeud, et de ne pas essayer d'envoyer une transaction immédiatement. Ou sinon, se connecter à un autre noeud pour que le noeud original ne puisse pas corréler les informations.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="503"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="596"/> <source>File %s likely stores wallet private keys! Use a different file name.</source> <translation>Le fichier %s contient probablement des clés privées de portefeuille ! Utilisez un nom de fichier différent.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="506"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="599"/> <source>File %s already exists. Are you sure to overwrite it? (Y/Yes/N/No): </source> <translation>Le fichier %s existe déjà. Êtes vous sûr de vouloir l'écraser ? (Y/Yes/N/No) : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6580"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7195"/> <source> seconds</source> <translation> secondes</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6582"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7197"/> <source> minutes</source> <translation> minutes</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6584"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7199"/> <source> hours</source> <translation> heures</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6586"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7201"/> <source> days</source> <translation> jours</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6588"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7203"/> <source> months</source> <translation> mois</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6589"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7204"/> <source>a long time</source> <translation>longtemps</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="8074"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8940"/> <source>This is the command line monero wallet. It needs to connect to a monero daemon to work correctly. WARNING: Do not reuse your Monero keys on another fork, UNLESS this fork has key reuse mitigations built in. Doing so will harm your privacy.</source> @@ -4695,68 +5041,68 @@ Il a besoin de se connecter à un démon monero pour fonctionner correctement. ATTENTION : Ne réutilisez pas vos clés Monero avec un autre fork, À MOINS QUE ce fork inclue des mitigations contre la réutilisation des clés. Faire ceci nuira à votre confidentialité.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="8099"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8965"/> <source>Unknown command: </source> - <translation>Commande inconnue : </translation> + <translation>Commande inconnue : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="131"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="137"/> <source>Allow communicating with a daemon that uses a different RPC version</source> <translation>Autoriser la communication avec un démon utilisant une version de RPC différente</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="132"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="138"/> <source>Restore from specific blockchain height</source> <translation>Restaurer à partir d'une hauteur de bloc spécifique</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="133"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="139"/> <source>The newly created transaction will not be relayed to the monero network</source> <translation>La transaction nouvellement créée ne sera pas transmise au réseau monero</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="134"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="140"/> <source>Create an address file for new wallets</source> <translation>Créer un fichier d'adresse pour les nouveaux portefeuilles</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="136"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="142"/> <source>Display English language names</source> <translation>Afficher les noms de langue en anglais</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="183"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="276"/> <source>failed to read wallet password</source> <translation>échec de la lecture du mot de passe du portefeuille</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="190"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="283"/> <source>Enter a new password for the wallet</source> <translation>Entrer un nouveau mot de passe pour le portefeuille</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="190"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="283"/> <source>Wallet password</source> <translation>Mot de passe du portefeuille</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="200"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="392"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="293"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="485"/> <source>daemon is busy. Please try again later.</source> <translation>le démon est occupé. Veuillez réessayer plus tard.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="209"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="302"/> <source>possibly lost connection to daemon</source> <translation>connexion avec le démon peut-être perdue</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="226"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="319"/> <source>Error: </source> - <translation>Erreur : </translation> + <translation>Erreur : </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="8093"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8959"/> <source>Failed to initialize wallet</source> <translation>Échec de l'initialisation du portefeuille</translation> </message> @@ -4764,228 +5110,233 @@ ATTENTION : Ne réutilisez pas vos clés Monero avec un autre fork, À MOINS QUE <context> <name>tools::wallet2</name> <message> - <location filename="../src/wallet/wallet2.cpp" line="142"/> + <location filename="../src/wallet/wallet2.cpp" line="201"/> <source>Use daemon instance at <host>:<port></source> <translation>Utiliser l'instance de démon située à <hôte>:<port></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="143"/> + <location filename="../src/wallet/wallet2.cpp" line="202"/> <source>Use daemon instance at host <arg> instead of localhost</source> <translation>Utiliser l'instance de démon située à l'hôte <arg> au lieu de localhost</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="147"/> + <location filename="../src/wallet/wallet2.cpp" line="206"/> <source>Wallet password file</source> <translation>Fichier mot de passe du portefeuille</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="148"/> + <location filename="../src/wallet/wallet2.cpp" line="207"/> <source>Use daemon instance at port <arg> instead of 18081</source> <translation>Utiliser l'instance de démon située au port <arg> au lieu de 18081</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="150"/> + <location filename="../src/wallet/wallet2.cpp" line="209"/> <source>For testnet. Daemon must also be launched with --testnet flag</source> <translation>Pour testnet, le démon doit aussi être lancé avec l'option --testnet</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="220"/> + <location filename="../src/wallet/wallet2.cpp" line="282"/> <source>can't specify daemon host or port more than once</source> <translation>impossible de spécifier l'hôte ou le port du démon plus d'une fois</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="291"/> + <location filename="../src/wallet/wallet2.cpp" line="355"/> <source>can't specify more than one of --password and --password-file</source> <translation>impossible de spécifier plus d'une option parmis --password et --password-file</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="304"/> + <location filename="../src/wallet/wallet2.cpp" line="368"/> <source>the password file specified could not be read</source> <translation>le fichier mot de passe spécifié n'a pas pu être lu</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="330"/> + <location filename="../src/wallet/wallet2.cpp" line="394"/> <source>Failed to load file </source> <translation>Échec du chargement du fichier </translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="146"/> + <location filename="../src/wallet/wallet2.cpp" line="205"/> <source>Wallet password (escape/quote as needed)</source> <translation>Mot de passe du portefeuille (échapper/citer si nécessaire)</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="144"/> + <location filename="../src/wallet/wallet2.cpp" line="203"/> <source>Enable commands which rely on a trusted daemon</source> <translation>Activer les commandes qui dépendent d'un démon de confiance</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="145"/> + <location filename="../src/wallet/wallet2.cpp" line="204"/> <source>Disable commands which rely on a trusted daemon</source> <translation>Désactiver les commandes qui dépendent d'un démon de confiance</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="149"/> + <location filename="../src/wallet/wallet2.cpp" line="208"/> <source>Specify username[:password] for daemon RPC client</source> <translation>Spécifier le nom_utilisateur:[mot_de_passe] pour le client RPC du démon</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="151"/> + <location filename="../src/wallet/wallet2.cpp" line="210"/> <source>For stagenet. Daemon must also be launched with --stagenet flag</source> <translation>Pour stagenet, le démon doit aussi être lancé avec l'option --stagenet</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="153"/> + <location filename="../src/wallet/wallet2.cpp" line="212"/> <source>Set shared ring database path</source> <translation>Définir le chemin de la base de donnée de cercles partagés</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="164"/> + <location filename="../src/wallet/wallet2.cpp" line="223"/> <source>Number of rounds for the key derivation function</source> <translation>Nombre de rondes de la fonction de dérivation de clé</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="165"/> + <location filename="../src/wallet/wallet2.cpp" line="224"/> <source>HW device to use</source> <translation>Portefeuille matériel à utiliser</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="251"/> + <location filename="../src/wallet/wallet2.cpp" line="225"/> + <source>HW device wallet derivation path (e.g., SLIP-10)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="313"/> <source>--trusted-daemon and --untrusted-daemon are both seen, assuming untrusted</source> <translation>--trusted-daemon et --untrusted-daemon présents simultanément, --untrusted-daemon choisi</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="261"/> + <location filename="../src/wallet/wallet2.cpp" line="323"/> <source>Daemon is local, assuming trusted</source> <translation>Le démon est local, supposons qu'il est de confiance</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="311"/> + <location filename="../src/wallet/wallet2.cpp" line="375"/> <source>no password specified; use --prompt-for-password to prompt for a password</source> <translation>pas de mot de passe spécifié; utilisez --prompt-for-password pour demander un mot de passe</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="313"/> + <location filename="../src/wallet/wallet2.cpp" line="377"/> <source>Enter a new password for the wallet</source> <translation>Entrer un nouveau mot de passe pour le portefeuille</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="313"/> + <location filename="../src/wallet/wallet2.cpp" line="377"/> <source>Wallet password</source> <translation>Mot de passe du portefeuille</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="336"/> + <location filename="../src/wallet/wallet2.cpp" line="400"/> <source>Failed to parse JSON</source> <translation>Échec de l'analyse JSON</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="343"/> + <location filename="../src/wallet/wallet2.cpp" line="407"/> <source>Version %u too new, we can only grok up to %u</source> <translation>Version %u trop récente, on comprend au mieux %u</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="359"/> + <location filename="../src/wallet/wallet2.cpp" line="423"/> <source>failed to parse view key secret key</source> <translation>échec de l'analyse de la clé secrète d'audit</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="364"/> - <location filename="../src/wallet/wallet2.cpp" line="432"/> - <location filename="../src/wallet/wallet2.cpp" line="475"/> + <location filename="../src/wallet/wallet2.cpp" line="428"/> + <location filename="../src/wallet/wallet2.cpp" line="496"/> + <location filename="../src/wallet/wallet2.cpp" line="539"/> <source>failed to verify view key secret key</source> <translation>échec de la vérification de la clé secrète d'audit</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="375"/> + <location filename="../src/wallet/wallet2.cpp" line="439"/> <source>failed to parse spend key secret key</source> <translation>échec de l'analyse de la clé secrète de dépense</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="380"/> - <location filename="../src/wallet/wallet2.cpp" line="442"/> - <location filename="../src/wallet/wallet2.cpp" line="501"/> + <location filename="../src/wallet/wallet2.cpp" line="444"/> + <location filename="../src/wallet/wallet2.cpp" line="506"/> + <location filename="../src/wallet/wallet2.cpp" line="565"/> <source>failed to verify spend key secret key</source> <translation>échec de la vérification de la clé secrète de dépense</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="392"/> + <location filename="../src/wallet/wallet2.cpp" line="456"/> <source>Electrum-style word list failed verification</source> <translation>Échec de la vérification de la liste de mots de style Electrum</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="412"/> + <location filename="../src/wallet/wallet2.cpp" line="476"/> <source>At least one of either an Electrum-style word list, private view key, or private spend key must be specified</source> <translation>Il faut spécifier au moins une des options parmis la liste de mots de style Electrum, la clé privée d'audit et la clé privée de dépense</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="416"/> + <location filename="../src/wallet/wallet2.cpp" line="480"/> <source>Both Electrum-style word list and private key(s) specified</source> <translation>Liste de mots de style Electrum et clé privée spécifiées en même temps</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="426"/> + <location filename="../src/wallet/wallet2.cpp" line="490"/> <source>invalid address</source> <translation>adresse invalide</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="435"/> + <location filename="../src/wallet/wallet2.cpp" line="499"/> <source>view key does not match standard address</source> <translation>la clé d'audit ne correspond pas à l'adresse standard</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="445"/> + <location filename="../src/wallet/wallet2.cpp" line="509"/> <source>spend key does not match standard address</source> <translation>la clé de dépense ne correspond pas à l'adresse standard</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="453"/> + <location filename="../src/wallet/wallet2.cpp" line="517"/> <source>Cannot generate deprecated wallets from JSON</source> <translation>Impossible de générer un portefeuille obsolète à partir de JSON</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="487"/> + <location filename="../src/wallet/wallet2.cpp" line="551"/> <source>failed to parse address: </source> - <translation>échec de l'analyse de l'adresse : </translation> + <translation>échec de l'analyse de l'adresse : </translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="493"/> + <location filename="../src/wallet/wallet2.cpp" line="557"/> <source>Address must be specified in order to create watch-only wallet</source> <translation>L'adresse doit être spécifiée afin de créer un portefeuille d'audit</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="510"/> + <location filename="../src/wallet/wallet2.cpp" line="574"/> <source>failed to generate new wallet: </source> - <translation>échec de la génération du nouveau portefeuille : </translation> + <translation>échec de la génération du nouveau portefeuille : </translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="1271"/> + <location filename="../src/wallet/wallet2.cpp" line="1382"/> <source>Password is needed to compute key image for incoming monero</source> <translation>Le mot de passe est requis pour calculer l'image de clé pour les moneros entrants</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="1272"/> + <location filename="../src/wallet/wallet2.cpp" line="1383"/> <source>Invalid password: password is needed to compute key image for incoming monero</source> <translation>Mot de passe invalide : le mot de passe est requis pour calculer l'image de clé pour les moneros entrants</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="3496"/> - <location filename="../src/wallet/wallet2.cpp" line="4062"/> - <location filename="../src/wallet/wallet2.cpp" line="4495"/> + <location filename="../src/wallet/wallet2.cpp" line="3770"/> + <location filename="../src/wallet/wallet2.cpp" line="4374"/> + <location filename="../src/wallet/wallet2.cpp" line="4926"/> <source>Primary account</source> <translation>Compte primaire</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="9547"/> + <location filename="../src/wallet/wallet2.cpp" line="10157"/> <source>No funds received in this tx.</source> <translation>Aucun fonds n'a été reçu dans cette transaction.</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="10261"/> + <location filename="../src/wallet/wallet2.cpp" line="10899"/> <source>failed to read file </source> <translation>échec de la lecture du fichier </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="135"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="141"/> <source>Set subaddress lookahead sizes to <major>:<minor></source> <translation>Définir les tailles d'anticipation des sous-addresses à <majeur>:<mineur></translation> </message> @@ -5000,7 +5351,7 @@ ATTENTION : Ne réutilisez pas vos clés Monero avec un autre fork, À MOINS QUE <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="182"/> <source>Failed to create directory %s: %s</source> - <translation>Échec de la création du répertoire %s : %s</translation> + <translation>Échec de la création du répertoire %s : %s</translation> </message> <message> <location filename="../src/wallet/wallet_rpc_server.cpp" line="193"/> @@ -5038,91 +5389,91 @@ ATTENTION : Ne réutilisez pas vos clés Monero avec un autre fork, À MOINS QUE <translation>Le mot clé %s n'est pas enregistré.</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2877"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3081"/> <source>Transaction not possible. Available only %s, transaction amount %s = %s + %s (fee)</source> - <translation>Transaction impossible. Solde disponible : %s, montant de la transaction %s = %s + %s (frais)</translation> + <translation>Transaction impossible. Solde disponible : %s, montant de la transaction %s = %s + %s (frais)</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3495"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3947"/> <source>This is the RPC monero wallet. It needs to connect to a monero daemon to work correctly.</source> <translation>Ceci est le portefeuille monero par RPC. Il a besoin de se connecter à un démon monero pour fonctionner correctement.</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3336"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3788"/> <source>Can't specify more than one of --wallet-file and --generate-from-json</source> <translation>Impossible de spécifier plus d'une option parmis --wallet-file et --generate-from-json</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3321"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3773"/> <source>Can't specify more than one of --testnet and --stagenet</source> <translation>Impossible de spécifier plus d'une option parmis --testnet et --stagenet</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3348"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3800"/> <source>Must specify --wallet-file or --generate-from-json or --wallet-dir</source> <translation>--wallet-file, --generate-from-json ou --wallet-dir doit être spécifié</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3352"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3804"/> <source>Loading wallet...</source> <translation>Chargement du portefeuille...</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3386"/> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3418"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3838"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3870"/> <source>Saving wallet...</source> <translation>Sauvegarde du portefeuille...</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3388"/> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3420"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3840"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3872"/> <source>Successfully saved</source> <translation>Sauvegardé avec succès</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3391"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3843"/> <source>Successfully loaded</source> <translation>Chargé avec succès</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3395"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3847"/> <source>Wallet initialization failed: </source> - <translation>Échec de l'initialisation du portefeuille : </translation> + <translation>Échec de l'initialisation du portefeuille : </translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3401"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3853"/> <source>Failed to initialize wallet RPC server</source> <translation>Échec de l'initialisation du serveur RPC du portefeuille</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3405"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3857"/> <source>Starting wallet RPC server</source> <translation>Démarrage du serveur RPC du portefeuille</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3412"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3864"/> <source>Failed to run wallet: </source> - <translation>Échec du lancement du portefeuille : </translation> + <translation>Échec du lancement du portefeuille : </translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3415"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3867"/> <source>Stopped wallet RPC server</source> <translation>Arrêt du serveur RPC du portefeuille</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3424"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3876"/> <source>Failed to save wallet: </source> - <translation>Échec de la sauvegarde du portefeuille : </translation> + <translation>Échec de la sauvegarde du portefeuille : </translation> </message> </context> <context> <name>wallet_args</name> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="172"/> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="3476"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="8042"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="168"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8908"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3928"/> <source>Wallet options</source> <translation>Options du portefeuille</translation> </message> @@ -5171,7 +5522,7 @@ connecter à un démon monero pour fonctionner correctement.</translation> <message> <location filename="../src/wallet/wallet_args.cpp" line="210"/> <source>Logging to: </source> - <translation>Journalisation dans : </translation> + <translation>Journalisation dans : </translation> </message> <message> <location filename="../src/wallet/wallet_args.cpp" line="212"/> @@ -5179,9 +5530,19 @@ connecter à un démon monero pour fonctionner correctement.</translation> <translation>Journalisation dans %s</translation> </message> <message> + <location filename="../src/wallet/wallet_args.cpp" line="216"/> + <source>WARNING: You may not have a high enough lockable memory limit</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="218"/> + <source>see ulimit -l</source> + <translation type="unfinished"></translation> + </message> + <message> <location filename="../src/wallet/wallet_args.cpp" line="146"/> <source>Usage:</source> - <translation>Usage :</translation> + <translation>Usage :</translation> </message> </context> </TS> diff --git a/translations/monero_it.ts b/translations/monero_it.ts index 09872fea8..18b43e6d7 100644 --- a/translations/monero_it.ts +++ b/translations/monero_it.ts @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> -<TS version="2.1" language="it" sourcelanguage="en"> +<TS version="2.0" language="it" sourcelanguage="en"> <context> <name>Monero::AddressBookImpl</name> <message> @@ -11,7 +11,7 @@ <message> <location filename="../src/wallet/api/address_book.cpp" line="63"/> <source>Invalid payment ID. Short payment ID should only be used in an integrated address</source> - <translation>ID pagamento non valido. L'ID pagamento corto dovrebbe essere usato solo in un indirizzo integrato</translation> + <translation>ID pagamento non valido. L'ID pagamento corto dovrebbe essere usato solo in un indirizzo integrato</translation> </message> <message> <location filename="../src/wallet/api/address_book.cpp" line="70"/> @@ -21,51 +21,61 @@ <message> <location filename="../src/wallet/api/address_book.cpp" line="77"/> <source>Integrated address and long payment ID can't be used at the same time</source> - <translation>L'indirizzo integrato e l'ID pagamento lungo non possono essere utilizzati contemporaneamente</translation> + <translation>L'indirizzo integrato e l'ID pagamento lungo non possono essere utilizzati contemporaneamente</translation> </message> </context> <context> <name>Monero::PendingTransactionImpl</name> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="90"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="91"/> <source>Attempting to save transaction to file, but specified file(s) exist. Exiting to not risk overwriting. File:</source> <translation>Sto tentando di salvare la transazione nel file, ma il file specificato è già esistente. Sto uscendo per non rischiare di sovrascriverlo. File:</translation> </message> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="97"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="98"/> <source>Failed to write transaction(s) to file</source> <translation>Impossibile scrivere transazione/i su file</translation> </message> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="115"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="121"/> <source>daemon is busy. Please try again later.</source> <translation>il daemon è impegnato. Prova più tardi.</translation> </message> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="118"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="124"/> <source>no connection to daemon. Please make sure daemon is running.</source> <translation>nessuna connessione con il daemon. Controlla che sia operativo.</translation> </message> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="122"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="128"/> <source>transaction %s was rejected by daemon with status: </source> <translation>la transazione %s è stata respinta dal daemon con status: </translation> </message> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="127"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="133"/> <source>. Reason: </source> <translation>. Motivo: </translation> </message> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="129"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="135"/> <source>Unknown exception: </source> <translation>Eccezione sconosciuta: </translation> </message> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="132"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="138"/> <source>Unhandled exception</source> <translation>Eccezione non gestita</translation> </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="211"/> + <source>Couldn't multisig sign data: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="233"/> + <source>Couldn't sign multisig transaction: </source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Monero::UnsignedTransactionImpl</name> @@ -124,281 +134,407 @@ <context> <name>Monero::WalletImpl</name> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1111"/> + <location filename="../src/wallet/api/wallet.cpp" line="1383"/> <source>payment id has invalid format, expected 16 or 64 character hex string: </source> <translation>L'id pagamento è in un formato invalido, dovrebbe essere una stringa esadecimale di 16 o 64 caratteri: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1121"/> + <location filename="../src/wallet/api/wallet.cpp" line="1392"/> <source>Failed to add short payment id: </source> <translation>Impossibile aggiungere id pagamento corto</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1154"/> - <location filename="../src/wallet/api/wallet.cpp" line="1258"/> + <location filename="../src/wallet/api/wallet.cpp" line="1428"/> + <location filename="../src/wallet/api/wallet.cpp" line="1510"/> <source>daemon is busy. Please try again later.</source> <translation>il daemon è impegnato. Riprova più tardi.</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1157"/> - <location filename="../src/wallet/api/wallet.cpp" line="1261"/> + <location filename="../src/wallet/api/wallet.cpp" line="1430"/> + <location filename="../src/wallet/api/wallet.cpp" line="1512"/> <source>no connection to daemon. Please make sure daemon is running.</source> <translation>nessuna connessione con il daemon. Accertati che sia operativo.</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1160"/> - <location filename="../src/wallet/api/wallet.cpp" line="1264"/> + <location filename="../src/wallet/api/wallet.cpp" line="1432"/> + <location filename="../src/wallet/api/wallet.cpp" line="1514"/> <source>RPC error: </source> <translation>errore RPC: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1197"/> - <location filename="../src/wallet/api/wallet.cpp" line="1301"/> + <location filename="../src/wallet/api/wallet.cpp" line="1460"/> + <location filename="../src/wallet/api/wallet.cpp" line="1545"/> <source>not enough outputs for specified ring size</source> <translation>insufficiente numero di output per il ring size specificato</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1199"/> - <location filename="../src/wallet/api/wallet.cpp" line="1303"/> + <location filename="../src/wallet/api/wallet.cpp" line="1462"/> + <location filename="../src/wallet/api/wallet.cpp" line="1547"/> <source>found outputs to use</source> <translation>trovati output che possono essere usati</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1201"/> + <location filename="../src/wallet/api/wallet.cpp" line="1464"/> <source>Please sweep unmixable outputs.</source> <translation>Pulisci gli output non mixabili.</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1267"/> - <source>failed to get random outputs to mix</source> - <translation>impossibile recuperare output casuali da mixare</translation> - </message> - <message> - <location filename="../src/wallet/api/wallet.cpp" line="1170"/> - <location filename="../src/wallet/api/wallet.cpp" line="1274"/> + <location filename="../src/wallet/api/wallet.cpp" line="1438"/> + <location filename="../src/wallet/api/wallet.cpp" line="1521"/> <source>not enough money to transfer, available only %s, sent amount %s</source> <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="474"/> + <location filename="../src/wallet/api/wallet.cpp" line="541"/> <source>failed to parse address</source> <translation>parsing indirizzo fallito</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="486"/> + <location filename="../src/wallet/api/wallet.cpp" line="552"/> <source>failed to parse secret spend key</source> <translation>impossibile effettuare il parsing della chiave segreta di spesa</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="496"/> - <source>No view key supplied, cancelled</source> - <translation>Non è stata fornita nessuna chiave di visualizzazione</translation> - </message> - <message> - <location filename="../src/wallet/api/wallet.cpp" line="503"/> + <location filename="../src/wallet/api/wallet.cpp" line="575"/> <source>failed to parse secret view key</source> <translation>impossibile effettuare il parsing della chiave segreta di visualizzazione</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="513"/> + <location filename="../src/wallet/api/wallet.cpp" line="584"/> <source>failed to verify secret spend key</source> <translation>impossibile verificare la chiave segreta di spesa</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="518"/> + <location filename="../src/wallet/api/wallet.cpp" line="588"/> <source>spend key does not match address</source> <translation>la chiave di spesa non corrisponde all'indirizzo</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="524"/> + <location filename="../src/wallet/api/wallet.cpp" line="594"/> <source>failed to verify secret view key</source> <translation>verifica chiave segreta di visualizzazione fallita</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="529"/> + <location filename="../src/wallet/api/wallet.cpp" line="598"/> <source>view key does not match address</source> <translation>la chiave di visualizzazione non corrisponde all'indirizzo</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="548"/> + <location filename="../src/wallet/api/wallet.cpp" line="621"/> + <location filename="../src/wallet/api/wallet.cpp" line="638"/> <source>failed to generate new wallet: </source> <translation>impossibile generare il nuovo portafoglio: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="773"/> + <location filename="../src/wallet/api/wallet.cpp" line="885"/> <source>Failed to send import wallet request</source> <translation>Impossibile inviare la richiesta di importazione portafoglio</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="919"/> + <location filename="../src/wallet/api/wallet.cpp" line="1049"/> <source>Failed to load unsigned transactions</source> <translation>Impossibile caricare transazioni non firmate</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="940"/> + <location filename="../src/wallet/api/wallet.cpp" line="1068"/> <source>Failed to load transaction from file</source> <translation>Impossibile caricare la transazione da file</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="958"/> + <location filename="../src/wallet/api/wallet.cpp" line="1084"/> <source>Wallet is view only</source> <translation>Il portafoglio è di tipo solo visualizzazione</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="967"/> + <location filename="../src/wallet/api/wallet.cpp" line="1092"/> <source>failed to save file </source> <translation>impossibile salvare il file </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="986"/> + <location filename="../src/wallet/api/wallet.cpp" line="1108"/> <source>Key images can only be imported with a trusted daemon</source> <translation>Le key image possono essere importate solo con un daemon fidato</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="999"/> + <location filename="../src/wallet/api/wallet.cpp" line="1121"/> <source>Failed to import key images: </source> <translation>Impossibile importare le key images: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1032"/> + <location filename="../src/wallet/api/wallet.cpp" line="1153"/> <source>Failed to get subaddress label: </source> - <translation>Impossibile recuperare l'etichetta del sottoindirizzo: </translation> + <translation>Impossibile recuperare l'etichetta del sottoindirizzo: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1046"/> + <location filename="../src/wallet/api/wallet.cpp" line="1166"/> <source>Failed to set subaddress label: </source> - <translation>Impossibile assegnare l'etichetta del sottoindirizzo: </translation> + <translation>Impossibile assegnare l'etichetta del sottoindirizzo: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1163"/> - <source>failed to get random outputs to mix: %s</source> - <translation>impossibile recuperare output casuali da mixare: %s</translation> + <location filename="../src/wallet/api/wallet.cpp" line="567"/> + <source>Neither view key nor spend key supplied, cancelled</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1179"/> - <location filename="../src/wallet/api/wallet.cpp" line="1283"/> + <location filename="../src/wallet/api/wallet.cpp" line="686"/> + <source>Electrum seed is empty</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="695"/> + <source>Electrum-style word list failed verification</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1183"/> + <source>Failed to get multisig info: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1200"/> + <location filename="../src/wallet/api/wallet.cpp" line="1214"/> + <source>Failed to make multisig: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1229"/> + <source>Failed to finalize multisig wallet creation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1232"/> + <source>Failed to finalize multisig wallet creation: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1248"/> + <source>Failed to export multisig images: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1266"/> + <source>Failed to parse imported multisig images</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1276"/> + <source>Failed to import multisig images: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1290"/> + <source>Failed to check for partial multisig key images: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1318"/> + <source>Failed to restore multisig transaction: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1358"/> + <source>Invalid destination address</source> + <translation type="unfinished">Indirizzo destinatario non valido</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1434"/> + <source>failed to get outputs to mix: %s</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1445"/> + <location filename="../src/wallet/api/wallet.cpp" line="1529"/> <source>not enough money to transfer, overall balance only %s, sent amount %s</source> <translation>fondi non sufficienti per il trasferimento, saldo totale %s, importo inviato %s</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1188"/> - <location filename="../src/wallet/api/wallet.cpp" line="1292"/> + <location filename="../src/wallet/api/wallet.cpp" line="1452"/> + <location filename="../src/wallet/api/wallet.cpp" line="1537"/> <source>not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)</source> <translation>fondi non sufficienti per il trasferimento, disponibili solo %s, ammontare transazione %s = %s + %s (commissione)</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1199"/> - <location filename="../src/wallet/api/wallet.cpp" line="1303"/> + <location filename="../src/wallet/api/wallet.cpp" line="1462"/> + <location filename="../src/wallet/api/wallet.cpp" line="1547"/> <source>output amount</source> <translation>ammontare output</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1205"/> - <location filename="../src/wallet/api/wallet.cpp" line="1308"/> + <location filename="../src/wallet/api/wallet.cpp" line="1467"/> + <location filename="../src/wallet/api/wallet.cpp" line="1551"/> <source>transaction was not constructed</source> <translation>transazione non costruita</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1209"/> - <location filename="../src/wallet/api/wallet.cpp" line="1312"/> + <location filename="../src/wallet/api/wallet.cpp" line="1470"/> + <location filename="../src/wallet/api/wallet.cpp" line="1554"/> <source>transaction %s was rejected by daemon with status: </source> <translation>la transazione %s è stata rifiutata dal daemon con status: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1216"/> - <location filename="../src/wallet/api/wallet.cpp" line="1319"/> + <location filename="../src/wallet/api/wallet.cpp" line="1475"/> + <location filename="../src/wallet/api/wallet.cpp" line="1559"/> <source>one of destinations is zero</source> <translation>una delle destinazioni è zero</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1219"/> - <location filename="../src/wallet/api/wallet.cpp" line="1322"/> + <location filename="../src/wallet/api/wallet.cpp" line="1477"/> + <location filename="../src/wallet/api/wallet.cpp" line="1561"/> <source>failed to find a suitable way to split transactions</source> <translation>impossibile trovare un modo per dividere le transazioni</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1222"/> - <location filename="../src/wallet/api/wallet.cpp" line="1325"/> + <location filename="../src/wallet/api/wallet.cpp" line="1479"/> + <location filename="../src/wallet/api/wallet.cpp" line="1563"/> <source>unknown transfer error: </source> <translation>errore trasferimento sconosciuto: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1225"/> - <location filename="../src/wallet/api/wallet.cpp" line="1328"/> + <location filename="../src/wallet/api/wallet.cpp" line="1481"/> + <location filename="../src/wallet/api/wallet.cpp" line="1565"/> <source>internal error: </source> <translation>errore interno: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1228"/> - <location filename="../src/wallet/api/wallet.cpp" line="1331"/> + <location filename="../src/wallet/api/wallet.cpp" line="1483"/> + <location filename="../src/wallet/api/wallet.cpp" line="1567"/> <source>unexpected error: </source> <translation>errore inaspettato: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1231"/> - <location filename="../src/wallet/api/wallet.cpp" line="1334"/> + <location filename="../src/wallet/api/wallet.cpp" line="1485"/> + <location filename="../src/wallet/api/wallet.cpp" line="1569"/> <source>unknown error</source> <translation>errore sconosciuto</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1412"/> - <location filename="../src/wallet/api/wallet.cpp" line="1441"/> - <location filename="../src/wallet/api/wallet.cpp" line="1494"/> - <location filename="../src/wallet/api/wallet.cpp" line="1525"/> - <location filename="../src/wallet/api/wallet.cpp" line="1556"/> - <location filename="../src/wallet/api/wallet.cpp" line="1579"/> + <location filename="../src/wallet/api/wallet.cpp" line="1516"/> + <source>failed to get outputs to mix</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1644"/> + <location filename="../src/wallet/api/wallet.cpp" line="1671"/> + <location filename="../src/wallet/api/wallet.cpp" line="1719"/> + <location filename="../src/wallet/api/wallet.cpp" line="1747"/> + <location filename="../src/wallet/api/wallet.cpp" line="1775"/> + <location filename="../src/wallet/api/wallet.cpp" line="1796"/> + <location filename="../src/wallet/api/wallet.cpp" line="2258"/> <source>Failed to parse txid</source> <translation>Impossibile effettuare parsing del txid</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1430"/> + <location filename="../src/wallet/api/wallet.cpp" line="1661"/> <source>no tx keys found for this txid</source> <translation>nessuna chiave tx trovata per questo txid</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1450"/> - <location filename="../src/wallet/api/wallet.cpp" line="1460"/> + <location filename="../src/wallet/api/wallet.cpp" line="1679"/> + <location filename="../src/wallet/api/wallet.cpp" line="1688"/> <source>Failed to parse tx key</source> <translation>Impossibile effettuare parsing della chiave tx</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1470"/> - <location filename="../src/wallet/api/wallet.cpp" line="1502"/> - <location filename="../src/wallet/api/wallet.cpp" line="1533"/> - <location filename="../src/wallet/api/wallet.cpp" line="1621"/> + <location filename="../src/wallet/api/wallet.cpp" line="1697"/> + <location filename="../src/wallet/api/wallet.cpp" line="1726"/> + <location filename="../src/wallet/api/wallet.cpp" line="1754"/> + <location filename="../src/wallet/api/wallet.cpp" line="1835"/> <source>Failed to parse address</source> - <translation>Impossibile effettuare parsing dell'indirizzo</translation> + <translation>Impossibile effettuare parsing dell'indirizzo</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1627"/> + <location filename="../src/wallet/api/wallet.cpp" line="1840"/> <source>Address must not be a subaddress</source> - <translation>L'indirizzo non può essere un sottoindirizzo</translation> + <translation>L'indirizzo non può essere un sottoindirizzo</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1880"/> + <source>The wallet must be in multisig ready state</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1849"/> + <location filename="../src/wallet/api/wallet.cpp" line="1902"/> + <source>Given string is not a key</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2130"/> <source>Rescan spent can only be used with a trusted daemon</source> <translation>"Riscannerizza spesi" può essere utilizzato solo da un daemon fidato</translation> </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2179"/> + <source>Invalid output: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2186"/> + <source>Failed to mark outputs as spent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2197"/> + <location filename="../src/wallet/api/wallet.cpp" line="2219"/> + <source>Failed to parse output amount</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2202"/> + <location filename="../src/wallet/api/wallet.cpp" line="2224"/> + <source>Failed to parse output offset</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2208"/> + <source>Failed to mark output as spent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2230"/> + <source>Failed to mark output as unspent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2241"/> + <location filename="../src/wallet/api/wallet.cpp" line="2280"/> + <source>Failed to parse key image</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2247"/> + <source>Failed to get ring</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2265"/> + <source>Failed to get rings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2286"/> + <source>Failed to set ring</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Wallet</name> <message> - <location filename="../src/wallet/api/wallet.cpp" line="246"/> + <location filename="../src/wallet/api/wallet.cpp" line="301"/> <source>Failed to parse address</source> - <translation>Impossibile effettuare parsing dell'indirizzo</translation> + <translation>Impossibile effettuare parsing dell'indirizzo</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="253"/> + <location filename="../src/wallet/api/wallet.cpp" line="308"/> <source>Failed to parse key</source> <translation>Impossibile effettuare parsing della chiave</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="261"/> + <location filename="../src/wallet/api/wallet.cpp" line="316"/> <source>failed to verify key</source> <translation>impossibile effettuare la verifica della chiave</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="271"/> + <location filename="../src/wallet/api/wallet.cpp" line="326"/> <source>key does not match address</source> <translation>la chiave non corrisponde all'indirizzo</translation> </message> @@ -406,12 +542,12 @@ <context> <name>command_line</name> <message> - <location filename="../src/common/command_line.cpp" line="57"/> + <location filename="../src/common/command_line.cpp" line="54"/> <source>yes</source> <translation>sì</translation> </message> <message> - <location filename="../src/common/command_line.cpp" line="71"/> + <location filename="../src/common/command_line.cpp" line="68"/> <source>no</source> <translation>no</translation> </message> @@ -449,18 +585,18 @@ <translation>permette connessioni esterne non criptate in entrata. Considera in alternativa un tunnel SSH o un proxy SSL. Sovrascrivi con --</translation> </message> <message> - <location filename="../src/rpc/rpc_args.cpp" line="95"/> + <location filename="../src/rpc/rpc_args.cpp" line="101"/> <source>Username specified with --</source> <translation>Nome utente specificato con --</translation> </message> <message> - <location filename="../src/rpc/rpc_args.cpp" line="95"/> - <location filename="../src/rpc/rpc_args.cpp" line="105"/> + <location filename="../src/rpc/rpc_args.cpp" line="101"/> + <location filename="../src/rpc/rpc_args.cpp" line="111"/> <source> cannot be empty</source> <translation> non può essere vuoto</translation> </message> <message> - <location filename="../src/rpc/rpc_args.cpp" line="105"/> + <location filename="../src/rpc/rpc_args.cpp" line="111"/> <source> requires RPC server password --</source> <translation type="unfinished"></translation> </message> @@ -468,1036 +604,925 @@ <context> <name>cryptonote::simple_wallet</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="479"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="645"/> <source>Commands: </source> <translation>Comandi: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3008"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4359"/> <source>failed to read wallet password</source> <translation>impossibile leggere la password del portafoglio</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2699"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3954"/> <source>invalid password</source> <translation>password non valida</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1905"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3073"/> <source>set seed: needs an argument. available options: language</source> <translation>imposta seed: richiede un argomento. opzioni disponibili: lingua</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1933"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3108"/> <source>set: unrecognized argument(s)</source> <translation>imposta: argomento/i non riconosciuto/i</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2869"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4199"/> <source>wallet file path not valid: </source> <translation>percorso file portafoglio non valido: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1987"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3178"/> <source>Attempting to generate or restore wallet, but specified file(s) exist. Exiting to not risk overwriting.</source> <translation>Sto tentando di generare o ripristinare il portafoglio, ma i(l) file specificato/i esiste/esistono già. Sto uscendo per non rischiare di sovrascrivere.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="662"/> - <source>usage: payment_id</source> - <translation>uso: payment_id</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1891"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3059"/> <source>needs an argument</source> <translation>ha bisogno di un argomento</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1914"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1915"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1916"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1918"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1921"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1922"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1926"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1927"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1929"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1931"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3082"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3083"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3084"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3086"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3089"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3094"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3095"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3097"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3099"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3100"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3101"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3104"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3105"/> <source>0 or 1</source> <translation>0 o 1</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1920"/> - <source>0, 1, 2, 3, or 4</source> - <translation>0, 1, 2, 3, o 4</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1924"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1928"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3092"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3096"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3103"/> <source>unsigned integer</source> <translation>intero senza segno</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2041"/> - <source>NOTE: the following 25 words can be used to recover access to your wallet. Write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control. -</source> - <translation>ATTENZIONE: le seguenti 25 parole possono essere usate per ripristinare il tuo portafoglio. Prendine nota e conservale in un posto sicuro. Non conservarle nella tua casella di posta elettronica o utilizzando servizi di cloud storage.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2121"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3341"/> <source>specify a recovery parameter with the --electrum-seed="words list here"</source> <translation>specificare un parametro di ripristino con --electrum-seed="lista parole qui"</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2635"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3887"/> <source>wallet failed to connect to daemon: </source> <translation>impossibile connettere il portafoglio al daemon: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2643"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3895"/> <source>Daemon uses a different RPC major version (%u) than the wallet (%u): %s. Either update one of them, or use --allow-mismatched-daemon-version.</source> <translation>Il daemon usa una versione principale RPC (%u) diversa da quella del portafoglio (%u): %s. Aggiorna una delle due, o usa --allow-mismatched-daemon-version.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2662"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3916"/> <source>List of available languages for your wallet's seed:</source> <translation>Lista delle lingue disponibili per il seed del tuo portafoglio:</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2671"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3926"/> <source>Enter the number corresponding to the language of your choice: </source> <translation>Inserisci il numero corrispondente al linguaggio da te scelto: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2737"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4000"/> <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 seed che ti abbiamo fornito.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2751"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2809"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4016"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4088"/> <source>Generated new wallet: </source> <translation>Nuovo portafoglio generato: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2757"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2814"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2858"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4025"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4093"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4135"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4188"/> <source>failed to generate new wallet: </source> <translation>impossibile generare nuovo portafoglio: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2887"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4230"/> <source>Opened watch-only wallet</source> <translation>Portafoglio solo-vista aperto</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2891"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4234"/> <source>Opened wallet</source> <translation>Portafoglio aperto</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2901"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4252"/> <source>You had been using a deprecated version of the wallet. Please proceed to upgrade your wallet. </source> <translation>Stai utilizzando una versione disapprovata del portafoglio. Per favore procedi nell'upgrade del portafoglio.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2916"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4267"/> <source>You had been using a deprecated version of the wallet. Your wallet file format is being upgraded now. </source> <translation>Stai utilizzando una versione disapprovata del portafoglio. Il formato del tuo portafoglio sta venendo aggiornato adesso.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2924"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4275"/> <source>failed to load wallet: </source> <translation>impossibile caricare portafoglio: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2941"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4292"/> <source>Use the "help" command to see the list of available commands. </source> <translation>Usa il comando "help" per visualizzare la lista dei comandi disponibili.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2986"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4337"/> <source>Wallet data saved</source> <translation>Dati del portafoglio salvati</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3072"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4431"/> <source>Mining started in daemon</source> <translation>Mining avviato nel daemon</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3074"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4433"/> <source>mining has NOT been started: </source> <translation>il mining NON è stato avviato: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3093"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4453"/> <source>Mining stopped in daemon</source> <translation>Mining nel daemon interrotto</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3095"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4455"/> <source>mining has NOT been stopped: </source> <translation>il mining NON è stato interrotto: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3150"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4537"/> <source>Blockchain saved</source> <translation>Blockchain salvata</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3165"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3183"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3196"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4552"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4589"/> <source>Height </source> <translation>Blocco </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3197"/> - <source>transaction </source> - <translation>transazione </translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3185"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4591"/> <source>spent </source> <translation>speso/i </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3198"/> - <source>unsupported transaction format</source> - <translation>formato transazione non supportato</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3219"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4698"/> <source>Starting refresh...</source> <translation>Sto iniziando il refresh...</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3232"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4712"/> <source>Refresh done, blocks received: </source> <translation>Refresh finito, blocchi ricevuti: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3758"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4230"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5958"/> <source>payment id has invalid format, expected 16 or 64 character hex string: </source> <translation>l'id pagamento ha un formato invalido, dovrebbe essere una stringa hex di 16 o 64 caratteri: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3773"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5307"/> <source>bad locked_blocks parameter:</source> <translation>parametro locked_blocks non corretto:</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3801"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4248"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4462"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5978"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6251"/> <source>a single transaction cannot use more than one payment id: </source> <translation>una singola transazione non può usare più di un id pagamento: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3810"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4257"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4430"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4470"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5405"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5987"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6219"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6259"/> <source>failed to set up payment id, though it was decoded correctly</source> <translation>impossibile impostare id pagamento, anche se è stato decodificado correttamente</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3835"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3916"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3987"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4096"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4271"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4329"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4484"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4527"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5251"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5870"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6173"/> + <source>ring size %u is too large, maximum is %u</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5276"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5395"/> + <source>Unencrypted payment IDs are bad for privacy: ask the recipient to use subaddresses instead</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5293"/> + <source>payment id failed to encode</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5312"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5894"/> + <source>Locked blocks too high, max 1000000 (Ë4 yrs)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5340"/> + <source>failed to parse short payment ID from URI</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5363"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5365"/> + <source>Invalid last argument: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5382"/> + <source>a single transaction cannot use more than one payment id</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5399"/> + <source>failed to parse payment id, though it was detected</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5422"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5502"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5590"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5738"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6001"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6059"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6273"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6318"/> <source>transaction cancelled.</source> <translation>transazione cancellata.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3955"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5541"/> <source>Sending %s. </source> <translation>Sto inviando %s. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3958"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5544"/> <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 commissione verrà applicata per ogni transazione, per un totale di %s commissioni</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3964"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5550"/> <source>The transaction fee is %s</source> <translation>La commissione per la transazione è %s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3967"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5553"/> <source>, of which %s is dust from change</source> <translation>, della quale %s è polvere dovuta allo scambio</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3968"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5554"/> <source>.</source> <translation>.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3968"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5554"/> <source>A total of %s from dust change will be sent to dust address</source> <translation>Un totale di %s in polvere verrà inviato all'indirizzo della polvere</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3973"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5559"/> <source>. This transaction will unlock on block %llu, in approximately %s days (assuming 2 minutes per block)</source> <translation>. Questa transazione verrà sbloccata al blocco %llu, in approssimativamente %s giorni (supponendo 2 minuti per blocco)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3999"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4011"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4107"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4119"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4340"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4352"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4537"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4549"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5603"/> + <source>Unsigned transaction(s) successfully written to MMS</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5611"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5648"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5749"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5761"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6070"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6107"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6328"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6340"/> <source>Failed to write transaction(s) to file</source> <translation>Impossibile scrivere transazione/i su file</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4003"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4015"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4111"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4123"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4344"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4356"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4541"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5616"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5653"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5753"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5765"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6074"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6111"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6332"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6344"/> <source>Unsigned transaction(s) successfully written to file: </source> <translation>Transazioni/e non firmata/e scritte/a con successo su file: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4066"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5625"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6086"/> + <source>Failed to cold sign transaction with HW wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5708"/> <source>No unmixable outputs found</source> <translation>Nessun output non-mixabile trovato</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4149"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5775"/> + <source>Not enough money in unlocked balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5776"/> + <source>Discarding %s of unmixable outputs that cannot be spent, which can be undone by "rescan_spent". Is this okay? (Y/Yes/N/No): </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5815"/> <source>No address given</source> <translation>Non è stato fornito nessun indirizzo</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4702"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5879"/> + <source>missing lockedblocks parameter</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5889"/> + <source>bad locked_blocks parameter</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5914"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6182"/> + <source>Failed to parse number of outputs</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5919"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6187"/> + <source>Amount of outputs should be greater than 0</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6428"/> + <source>Failed to parse donation address: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6442"/> + <source>Donating %s %s to The Monero Project (donate.getmonero.org or %s).</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6444"/> + <source>Donating %s %s to %s.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6516"/> <source>Claimed change does not go to a paid address</source> <translation>Il cambiamento richiesto non porta a un indirizzo pagato</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4707"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6521"/> <source>Claimed change is larger than payment to the change address</source> <translation>Il cambiamento richiesto è più largo del pagamento all'indirizzo di cambio</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4738"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6552"/> <source>sending %s to %s</source> <translation>sto mandando %s a %s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4748"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6562"/> <source> dummy output(s)</source> <translation> output dummy</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4751"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6565"/> <source>with no destinations</source> <translation>senza destinazioni</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4763"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6577"/> <source>Loaded %lu transactions, for %s, fee %s, %s, %s, with min ring size %lu, %s. %sIs this okay? (Y/Yes/N/No): </source> <translation>Caricate %lu transazioni, per %s, commissione %s, %s, %s, con ring size minimo %lu, %s. %sOK?(Y/Yes/N/No): </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4787"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6606"/> <source>This is a multisig wallet, it can only sign with sign_multisig</source> <translation>Questo è un portafoglio multisig, può firmare solo con sign_multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4797"/> - <source>usage: sign_transfer [export]</source> - <translation>uso: sign_transfer [export]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4809"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6629"/> <source>Failed to sign transaction</source> <translation>Impossibile firmare la transazione</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4815"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6635"/> <source>Failed to sign transaction: </source> <translation>Impossibile firmare la transazione: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4836"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6656"/> <source>Transaction raw hex data exported to </source> <translation>Dati esadecimali grezzi della transazione esportati su </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4852"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6677"/> <source>Failed to load transaction from file</source> <translation>Impossibile caricare la transazione da file</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3248"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3551"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4729"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5051"/> <source>RPC error: </source> <translation>errore RPC: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="522"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="695"/> <source>wallet is watch-only and has no spend key</source> <translation>il portafoglio è solo-vista e non ha una chiave di spesa</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="636"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="780"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="848"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="839"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1021"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1074"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1141"/> <source>Your original password was incorrect.</source> <translation>La tua password originale era scorretta</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="650"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="854"/> <source>Error with wallet rewrite: </source> <translation>Errore riscrittura wallet: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1289"/> - <source>priority must be 0, 1, 2, 3, or 4 </source> - <translation>la priorità deve essere 0, 1, 2, 3, or 4 </translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1301"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1316"/> - <source>priority must be 0, 1, 2, 3, or 4</source> - <translation>la priorità deve essere 0, 1, 2, 3, or 4</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1404"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2284"/> <source>invalid unit</source> <translation>unità invalida</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1422"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1484"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2302"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2364"/> <source>invalid count: must be an unsigned integer</source> <translation>conteggio invalido: deve essere un intero senza segno</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1440"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2320"/> <source>invalid value</source> <translation>valore invalido</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1942"/> - <source>usage: set_log <log_level_number_0-4> | <categories></source> - <translation>uso: set_log <log_level_number_0-4> | <categories></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2013"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3204"/> <source>(Y/Yes/N/No): </source> <translation>(S/Sì/N/No): </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2509"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2536"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3761"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3788"/> <source>bad m_restore_height parameter: </source> <translation>parametro m_restore_height non corretto: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2514"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3766"/> <source>date format must be YYYY-MM-DD</source> <translation>il formato della data deve essere YYYY-MM-DD</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2527"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3779"/> <source>Restore height is: </source> <translation>Ripristina altezza è: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2528"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3980"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3705"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3780"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5583"/> <source>Is this okay? (Y/Yes/N/No): </source> <translation>Va bene? (S/Sì/N/No): </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2575"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4509"/> <source>Daemon is local, assuming trusted</source> <translation>Il daemon è locale, viene considerato fidato</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3004"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4355"/> <source>Password for new watch-only wallet</source> <translation>Password per il nuovo portafoglio solo-vista</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3063"/> - <source>invalid arguments. Please use start_mining [<number_of_threads>] [do_bg_mining] [ignore_battery], <number_of_threads> should be from 1 to </source> - <translation>argomenti invalidi. Usa start_mining [<number_of_threads>] [do_bg_mining] [ignore_battery], <number_of_threads> dovrebbe risultare da 1 a </translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3258"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4739"/> <source>internal error: </source> <translation>errore interno: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1185"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3263"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3556"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1608"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4744"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5056"/> <source>unexpected error: </source> <translation>errore inaspettato: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1119"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1190"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3268"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3561"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4030"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4138"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4371"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4570"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4865"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1534"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1613"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4749"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5061"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5639"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5669"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5794"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6099"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6126"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6361"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6690"/> <source>unknown error</source> <translation>errore sconosciuto</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3273"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4754"/> <source>refresh failed: </source> <translation>refresh fallito: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3273"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4754"/> <source>Blocks received: </source> <translation>Blocchi ricevuti: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3304"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4787"/> <source>unlocked balance: </source> <translation>bilancio sbloccato: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1925"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3093"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> <source>amount</source> <translation>ammontare</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="219"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="341"/> <source>false</source> <translation>falso</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="493"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="659"/> <source>Unknown command: </source> <translation>Comando sconosciuto: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="500"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="666"/> <source>Command usage: </source> <translation>Uso del comando: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="503"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="669"/> <source>Command description: </source> <translation>Descrizione del comando: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="551"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="735"/> <source>wallet is multisig but not yet finalized</source> <translation>il portafoglio è multisig ma ancora non finalizzato</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="567"/> - <source>Enter optional seed encryption passphrase, empty to see raw seed</source> - <translation>Immetti passphrase opzionale per la cifratura del seed, lascia vuoto per vedere il seed grezzo</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="584"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="768"/> <source>Failed to retrieve seed</source> <translation>Impossibile recuperare il seed</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="603"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="792"/> <source>wallet is multisig and has no seed</source> <translation>il portafoglio è multisig e non ha seed</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="674"/> - <source>Cannot connect to daemon</source> - <translation>Impossibile connettersi al daemon</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="679"/> - <source>Current fee is %s monero per kB</source> - <translation>La commissione attuale è %s Monero(j) per kB</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="695"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="899"/> <source>Error: failed to estimate backlog array size: </source> - <translation>Errore: impossibile stimare la dimensione dell'array di backlog: </translation> + <translation>Errore: impossibile stimare la dimensione dell'array di backlog: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="700"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="904"/> <source>Error: bad estimated backlog array size</source> - <translation>Errore: errata stima della dimensione dell'array di backlog</translation> + <translation>Errore: errata stima della dimensione dell'array di backlog</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="712"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="916"/> <source> (current)</source> <translation> (attuale)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="715"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="919"/> <source>%u block (%u minutes) backlog at priority %u%s</source> <translation>Backlog blocco %u (%u minuti) a priorità %u%s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="717"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="921"/> <source>%u to %u block (%u to %u minutes) backlog at priority %u</source> <translation>Backlog blocco %u a %u (%u a %u minuti) a priorità %u</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="720"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="924"/> <source>No backlog at priority </source> <translation>Nessun backlog a priorità </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="729"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="762"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="944"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="989"/> <source>This wallet is already multisig</source> <translation>Questo portafoglio è già multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="734"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="767"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="949"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="994"/> <source>wallet is watch-only and cannot be made multisig</source> <translation>il portafoglio è sola-visualizzazione e non può essere reso multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="740"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="773"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="955"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1000"/> <source>This wallet has been used before, please use a new wallet to create a multisig wallet</source> <translation>Questo portafoglio è stato usato precedentmente, per cortesia utilizza un nuovo portafoglio per creare un portafoglio multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="747"/> - <source>Your password is incorrect.</source> - <translation>La tua password è errata.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="753"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="963"/> <source>Send this multisig info to all other participants, then use make_multisig <threshold> <info1> [<info2>...] with others' multisig info</source> <translation>Invia queste informazioni multisig a tutti gli altri partecipanti, poi utilizza make_multisig <threshold> <info1> [<info2>...] con le informazioni multisig degli altri</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="754"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="964"/> <source>This includes the PRIVATE view key, so needs to be disclosed only to that multisig wallet's participants </source> <translation>Questo include la chiave PRIVATA di visualizzazione, pertanto deve essere comunicata solo ai partecipanti di quel portafoglio multisig </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="786"/> - <source>usage: make_multisig <threshold> <multisiginfo1> [<multisiginfo2>...]</source> - <translation>utilizzo: make_multisig <threshold> <multisiginfo1> [<multisiginfo2>...]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="794"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1014"/> <source>Invalid threshold</source> <translation>Soglia invalida</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="807"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1034"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1156"/> <source>Another step is needed</source> <translation>Ancora un ultimo passo</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="809"/> - <source>Send this multisig info to all other participants, then use finalize_multisig <info1> [<info2>...] with others' multisig info</source> - <translation>Invia queste informazioni multisig a tutti gli altri partecipanti, poi utilizza finalize_multisig <info1> [<info2>...] con le informazioni multisig degli altri</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="815"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1046"/> <source>Error creating multisig: </source> <translation>Impossibile creare multisig: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="822"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1053"/> <source>Error creating multisig: new wallet is not multisig</source> <translation>Impossibile creare multisig: il nuovo portafoglio non è multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="825"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1056"/> <source> multisig address: </source> <translation> indirizzo multisig: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="836"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="880"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="927"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1080"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1129"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1195"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1261"/> <source>This wallet is not multisig</source> <translation>Questo portafoglio non è multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="841"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1085"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1134"/> <source>This wallet is already finalized</source> <translation>Questo portafoglio è già finalizzato</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="854"/> - <source>usage: finalize_multisig <multisiginfo1> [<multisiginfo2>...]</source> - <translation>utilizzo: finalize_multisig <multisiginfo1> [<multisiginfo2>...]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="862"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1101"/> <source>Failed to finalize multisig</source> <translation>Impossibile finalizzare multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="868"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1107"/> <source>Failed to finalize multisig: </source> <translation>Impossibile finalizzare multisig: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="885"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="932"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1006"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1074"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1136"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1200"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1266"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1360"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1476"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1557"/> <source>This multisig wallet is not yet finalized</source> <translation>Questo portafoglio multisig non è ancora finalizzato</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="890"/> - <source>usage: export_multisig_info <filename></source> - <translation>utilizzo: export_multisig_info <filename></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="913"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1236"/> <source>Error exporting multisig info: </source> <translation>Impossibile esportare informazioni sul multisig: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="917"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1240"/> <source>Multisig info exported to </source> <translation>Informazioni sul multisig esportate su </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="937"/> - <source>usage: import_multisig_info <filename1> [<filename2>...] - one for each other participant</source> - <translation>utilizzo: import_multisig_info <filename1> [<filename2>...] - uno per ogni altro partecipante</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="965"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1306"/> <source>Multisig info imported</source> <translation>Informazioni su multisig importate</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="969"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1310"/> <source>Failed to import multisig info: </source> <translation>Impossibile importare informazioni sul multisig: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="980"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1321"/> <source>Failed to update spent status after importing multisig info: </source> <translation>Impossibile aggiornare lo stato di spesa dopo aver importato le informazioni sul multisig: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="985"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1327"/> <source>Untrusted daemon, spent status may be incorrect. Use a trusted daemon and run "rescan_spent"</source> <translation>Daemon non fidato, lo stato di spesa potrebbe non essere corretto. Usare un daemon fidato ed eseguire "rescan_spent" </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1001"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1069"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1131"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1355"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1471"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1552"/> <source>This is not a multisig wallet</source> <translation>Questo non è un portafoglio multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1011"/> - <source>usage: sign_multisig <filename></source> - <translation>uso: sign_multisig <filename></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1024"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1405"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1414"/> <source>Failed to sign multisig transaction</source> <translation>Impossibile firmare la transazione multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1030"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1421"/> <source>Multisig error: </source> <translation>Errore multisig: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1035"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1426"/> <source>Failed to sign multisig transaction: </source> <translation>Impossibile firmare la transazione multisig: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1058"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1449"/> <source>It may be relayed to the network with submit_multisig</source> <translation>Potrebbe essere trasmesso alla rete con submit_multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1079"/> - <source>usage: submit_multisig <filename></source> - <translation>uso: submit_multisig <filename></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1094"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1155"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1508"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1578"/> <source>Failed to load multisig transaction from file</source> <translation>Impossibile caricare la transazione multisig da file</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1099"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1160"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1514"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1583"/> <source>Multisig transaction signed by only %u signers, needs %u more signatures</source> <translation>Transazione multisig firmata da solo %u firmatari, necessita di altre %u firme</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1108"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6750"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1523"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8890"/> <source>Transaction successfully submitted, transaction </source> <translation>Transazione inviata con successo, transazione </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1109"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6751"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1524"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8891"/> <source>You can check its status by using the `show_transfers` command.</source> - <translation>E' possibile controllare il suo stato mediante il comando `show_transfers`.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1141"/> - <source>usage: export_raw_multisig <filename></source> - <translation>utilizzo: export_raw_multisig <filename></translation> + <translation>E' possibile controllare il suo stato mediante il comando `show_transfers`.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1176"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1599"/> <source>Failed to export multisig transaction to file </source> <translation>Impossibile esportare la transazione multisig su file </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1180"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1603"/> <source>Saved exported multisig transaction file(s): </source> <translation>Transazioni esportate salvate su(i) file: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1252"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1258"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1272"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2095"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2101"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2120"/> <source>ring size must be an integer >= </source> <translation>il ring size deve essere un intero >= </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1277"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2125"/> <source>could not change default ring size</source> <translation>impossibile modificare il ring size di default</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1518"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2398"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2469"/> <source>Invalid height</source> <translation>Altezza invalida</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1564"/> - <source>start_mining [<number_of_threads>] [bg_mining] [ignore_battery]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1565"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2562"/> <source>Start mining in the daemon (bg_mining and ignore_battery are optional booleans).</source> <translation>Avvia il mining sul daemon (bg_mining e ignore_battery sono booleani opzionali).</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1568"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2565"/> <source>Stop mining in the daemon.</source> <translation>Arresta il mining sul daemon.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1571"/> - <source>set_daemon <host>[:<port>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1572"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2569"/> <source>Set another daemon to connect to.</source> <translation>Seleziona un altro daemon cui connettersi.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1575"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2572"/> <source>Save the current blockchain data.</source> <translation>Salva i dati blockchain correnti.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1578"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2575"/> <source>Synchronize the transactions and balance.</source> <translation>Sincronizza le transazioni ed il saldo.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1581"/> - <source>balance [detail]</source> - <translation>saldo [dettaglio]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1582"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2579"/> <source>Show the wallet's balance of the currently selected account.</source> <translation>Mostra il saldo del portafoglio del conto attualmente selezionato.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1585"/> - <source>incoming_transfers [available|unavailable] [verbose] [index=<N1>[,<N2>[,...]]]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1586"/> - <source>Show the incoming transfers, all or filtered by availability and address index. - -Output format: -Amount, Spent("T"|"F"), "locked"|"unlocked", RingCT, Global Index, Transaction Hash, Address Index, [Public Key, Key Image]</source> - <translation type="unfinished">Mostra i trasferimenti in entrata, tutti o filtrati per disponibilità ed indice di indirizzo.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1589"/> - <source>payments <PID_1> [<PID_2> ... <PID_N>]</source> - <translation>pagamenti <PID_1> [<PID_2> ... <PID_N>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1590"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2589"/> <source>Show the payments for the given payment IDs.</source> <translation>Mostra i pagamenti per gli id pagamento specificati.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1593"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2592"/> <source>Show the blockchain height.</source> - <translation>Mostra l'altezza della blockchain.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1596"/> - <source>transfer_original [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> <amount> [<payment_id>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1597"/> - <source>Transfer <amount> to <address> using an older transaction building algorithm. If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> - <translation>Trasferisce <amount> a <address> usando un algoritmo più vecchio per la costruzione della transazione. Se viene specificato il parametro "index=<N1>[,<N2>,...]", il portafoglio usa output ricevuti dagli indirizzi di questi indici. Se il parametro viene omesso, il portafoglio sceglie casualmente gli indici di indirizzo da utilizzare. In ogni caso, fa del suo meglio per non combinare output su indirizzi multipli. <priority> è la priorità della transazione. Più alta è la priorità, più alta è la commissione riconosciuta per la transazione. I valori ammissibili in ordine di priorità (dal più basso al più alto) sono: non importante, normale, elevato, prioritaria. Se la priorità è omessa, viene utilizzato il valore di default (vedi il comando "set priority"). <ring_size> è il numero di input da includere per la non tracciabilità. Possono essere effettuati pagamenti multipli in una sola volta aggiungendo <address_2> <amount_2> etc. (prima dell'ID di pagamento, se incluso)</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1599"/> - <source>transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> <amount> [<payment_id>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1600"/> - <source>Transfer <amount> to <address>. If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> - <translation>Trasferisce <amount> a <address>. Se viene specificato il parametro "index=<N1>[,<N2>,...]", il portafoglio usa output ricevuti dagli indirizzi di questi indici. Se il parametro viene omesso, il portafoglio sceglie casualmente gli indici di indirizzo da utilizzare. In ogni caso, fa del suo meglio per non combinare output su indirizzi multipli. <priority> è la priorità della transazione. Più alta è la priorità, più alta è la commissione riconosciuta per la transazione. I valori ammissibili in ordine di priorità (dal più basso al più alto) sono: non importante, normale, elevato, prioritaria. Se la priorità è omessa, viene utilizzato il valore di default (vedi il comando "set priority"). <ring_size> è il numero di input da includere per la non tracciabilità. Possono essere effettuati pagamenti multipli in una sola volta aggiungendo <address_2> <amount_2> etc. (prima dell'ID di pagamento, se incluso)</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1603"/> - <source>locked_transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <addr> <amount> <lockblocks> [<payment_id>]</source> - <translation type="unfinished"></translation> + <translation>Mostra l'altezza della blockchain.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1604"/> - <source>Transfer <amount> to <address> and lock it for <lockblocks> (max. 1000000). If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> - <translation>Trasferisce <amount> to <address> e lo blocca per <lockblocks> (max. 1000000). Se viene specificato il parametro "index=<N1>[,<N2>,...]", il portafoglio usa output ricevuti dagli indirizzi di questi indici. Se il parametro viene omesso, il portafoglio sceglie casualmente gli indici di indirizzo da utilizzare. In ogni caso, fa del suo meglio per non combinare output su indirizzi multipli. <priority> è la priorità della transazione. Più alta è la priorità, più alta è la commissione riconosciuta per la transazione. I valori ammissibili in ordine di priorità (dal più basso al più alto) sono: non importante, normale, elevato, prioritaria. Se la priorità è omessa, viene utilizzato il valore di default (vedi il comando "set priority"). <ring_size> è il numero di input da includere per la non tracciabilità. Possono essere effettuati pagamenti multipli in una sola volta aggiungendo <address_2> <amount_2> etc. (prima dell'ID di pagamento, se incluso) </translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1607"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2606"/> <source>Send all unmixable outputs to yourself with ring_size 1</source> <translation>Invia tutti gli output non mixabili a te stesso usando ring_size 1</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1609"/> - <source>sweep_all [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> [<payment_id>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1610"/> - <source>Send all unlocked balance to an address. If the parameter "index<N1>[,<N2>,...]" is specified, the wallet sweeps outputs received by those address indices. If omitted, the wallet randomly chooses an address index to be used.</source> - <translation>Invia tutto il saldo sbloccato ad un indirizzo. Se viene specificato il parametro "index<N1>[,<N2>,...]", il portafoglio spazza gli output ricevuti da questi indici di indirizzo. Se il parametro viene omesso, il portafoglio sceglie casualmente un indice di indirizzo da utilizzare.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1613"/> - <source>sweep_below <amount_threshold> [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> [<payment_id>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1614"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2613"/> <source>Send all unlocked outputs below the threshold to an address.</source> <translation>Invia tutti gli output sbloccati sotto la soglia ad un indirizzo.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1617"/> - <source>sweep_single [<priority>] [<ring_size>] <key_image> <address> [<payment_id>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1618"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2617"/> <source>Send a single output of the given key image to an address without change.</source> <translation>Invia un singolo output della key image specificata ad un indirizzo senza modifica.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1621"/> - <source>donate [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <amount> [<payment_id>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1622"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2621"/> <source>Donate <amount> to the development team (donate.getmonero.org).</source> <translation>Dona <amount> al team di sviluppo (donate.getmonero.org).</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1625"/> - <source>sign_transfer <file></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1626"/> - <source>Sign a transaction from a <file>.</source> - <translation>Firma una transazione da <file>.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1629"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2628"/> <source>Submit a signed transaction from a file.</source> <translation>Invia una transazione firmata da file.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1632"/> - <source>set_log <level>|{+,-,}<categories></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1633"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2632"/> <source>Change the current log detail (level must be <0-4>).</source> <translation>Modifica il dettaglio di log (il livello deve essere <0-4>).</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1636"/> - <source>account - account new <label text with white spaces allowed> - account switch <index> - account label <index> <label text with white spaces allowed> - account tag <tag_name> <account_index_1> [<account_index_2> ...] - account untag <account_index_1> [<account_index_2> ...] - account tag_description <tag_name> <description></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1643"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2636"/> <source>If no arguments are specified, the wallet shows all the existing accounts along with their balances. If the "new" argument is specified, the wallet creates a new account with its label initialized by the provided label text (which can be empty). If the "switch" argument is specified, the wallet switches to the account specified by <index>. @@ -1508,558 +1533,320 @@ If the "tag_description" argument is specified, the tag <tag_name&g <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1652"/> - <source>address [ new <label text with white spaces allowed> | all | <index_min> [<index_max>] | label <index> <label text with white spaces allowed>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1653"/> - <source>If no arguments are specified or <index> is specified, the wallet shows the default or specified address. If "all" is specified, the walllet shows all the existing addresses in the currently selected account. If "new " is specified, the wallet creates a new address with the provided label text (which can be empty). If "label" is specified, the wallet sets the label of the address specified by <index> to the provided label text.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1656"/> - <source>integrated_address [<payment_id> | <address>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1657"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2650"/> <source>Encode a payment ID into an integrated address for the current wallet public address (no argument uses a random payment ID), or decode an integrated address to standard address and payment ID</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1660"/> - <source>address_book [(add ((<address> [pid <id>])|<integrated address>) [<description possibly with whitespaces>])|(delete <index>)]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1661"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2654"/> <source>Print all entries in the address book, optionally adding/deleting an entry to/from it.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1664"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2657"/> <source>Save the wallet data.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1667"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2660"/> <source>Save a watch-only keys file.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1670"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2663"/> <source>Display the private view key.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1673"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2666"/> <source>Display the private spend key.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1676"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2669"/> <source>Display the Electrum-style mnemonic seed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1679"/> - <source>set <option> [<value>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1680"/> - <source>Available options: - seed language - Set the wallet's 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 the default ring size (default and minimum is 5). - auto-refresh <1|0> - Whether to automatically synchronize new blocks from the daemon. - refresh-type <full|optimize-coinbase|no-coinbase|default> - Set the wallet's refresh behaviour. - priority [0|1|2|3|4] - Set the fee to default/unimportant/normal/elevated/priority. - confirm-missing-payment-id <1|0> - ask-password <1|0> - unit <monero|millinero|micronero|nanonero|piconero> - Set the 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] - Set a threshold for confirm-backlog to only warn if the transaction backlog is greater than n blocks. - refresh-from-block-height [n] - Set the height before which to ignore blocks. - auto-low-priority <1|0> - Whether to automatically use the low priority fee level when it's safe to do so.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1717"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2719"/> <source>Display the encrypted Electrum-style mnemonic seed.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1720"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2722"/> <source>Rescan the blockchain for spent outputs.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1723"/> - <source>get_tx_key <txid></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1724"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2726"/> <source>Get the transaction key (r) for a given <txid>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1727"/> - <source>check_tx_key <txid> <txkey> <address></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1728"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2734"/> <source>Check the amount going to <address> in <txid>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1731"/> - <source>get_tx_proof <txid> <address> [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1732"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2738"/> <source>Generate a signature proving funds sent to <address> in <txid>, optionally with a challenge string <message>, using either the transaction secret key (when <address> is not your wallet's address) or the view secret key (otherwise), which does not disclose the secret key.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1735"/> - <source>check_tx_proof <txid> <address> <signature_file> [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1736"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2742"/> <source>Check the proof for funds going to <address> in <txid> with the challenge string <message> if any.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1739"/> - <source>get_spend_proof <txid> [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1740"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2746"/> <source>Generate a signature proving that you generated <txid> using the spend secret key, optionally with a challenge string <message>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1743"/> - <source>check_spend_proof <txid> <signature_file> [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1744"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2750"/> <source>Check a signature proving that the signer generated <txid>, optionally with a challenge string <message>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1747"/> - <source>get_reserve_proof (all|<amount>) [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1748"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2754"/> <source>Generate a signature proving that you own at least this much, optionally with a challenge string <message>. If 'all' is specified, you prove the entire sum of all of your existing accounts' balances. Otherwise, you prove the reserve of the smallest possible amount above <amount> available in your current account.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1753"/> - <source>check_reserve_proof <address> <signature_file> [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1754"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2760"/> <source>Check a signature proving that the owner of <address> holds at least this much, optionally with a challenge string <message>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1757"/> - <source>show_transfers [in|out|pending|failed|pool] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1758"/> - <source>Show the incoming/outgoing transfers within an optional height range. - -Output format: -In or Coinbase: Block Number, "block"|"in", Time, Amount, Transaction Hash, Payment ID, Subaddress Index, "-", Note\ -Out: Block Number, "out", Time, Amount*, Transaction Hash, Payment ID, Fee, Destinations, Input addresses**, "-", Note -Pool: "pool", "in", Time, Amount, Transaction Hash, Payment Id, Subaddress Index, "-", Note, Double Spend Note\ -Pending or Failed: "failed"|"pending", "out", Time, Amount*, Transaction Hash, Payment ID, Fee, Input addresses**, "-", Note - -* Excluding change and fee. -** Set of address indices used as inputs in this transfer.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1761"/> - <source>unspent_outputs [index=<N1>[,<N2>,...]] [<min_amount> [<max_amount>]]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1762"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2780"/> <source>Show the unspent outputs of a specified address within an optional amount range.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1765"/> - <source>Rescan the blockchain from scratch.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1768"/> - <source>set_tx_note <txid> [free text note]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1769"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2788"/> <source>Set an arbitrary string note for a <txid>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1772"/> - <source>get_tx_note <txid></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1773"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2792"/> <source>Get a string note for a txid.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1776"/> - <source>set_description [free text note]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1777"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2796"/> <source>Set an arbitrary description for the wallet.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1780"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2800"/> <source>Get the description of the wallet.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1783"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2803"/> <source>Show the wallet's status.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1786"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2806"/> <source>Show the wallet's information.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1789"/> - <source>sign <file></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1790"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2810"/> <source>Sign the contents of a file.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1793"/> - <source>verify <filename> <address> <signature></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1794"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2814"/> <source>Verify a signature on the contents of a file.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1797"/> - <source>export_key_images <file></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1798"/> - <source>Export a signed set of key images to a <file>.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1801"/> - <source>import_key_images <file></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1802"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2822"/> <source>Import a signed key images list and verify their spent status.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1805"/> - <source>export_outputs <file></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1806"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2834"/> <source>Export a set of outputs owned by this wallet.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1809"/> - <source>import_outputs <file></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1810"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2838"/> <source>Import a set of outputs owned by this wallet.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1813"/> - <source>show_transfer <txid></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1814"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2842"/> <source>Show information about a transfer to/from this address.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1817"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2845"/> <source>Change the wallet's password.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1820"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2849"/> <source>Generate a new random full size payment id. These will be unencrypted on the blockchain, see integrated_address for encrypted short payment ids.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1823"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2852"/> <source>Print the information about the current fee and transaction backlog.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1825"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2854"/> <source>Export data needed to create a multisig wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1827"/> - <source>make_multisig <threshold> <string1> [<string>...]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1828"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2857"/> <source>Turn this wallet into a multisig wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1831"/> - <source>finalize_multisig <string> [<string>...]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1832"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2861"/> <source>Turn this wallet into a multisig wallet, extra step for N-1/N wallets</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1835"/> - <source>export_multisig_info <filename></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1836"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2869"/> <source>Export multisig info for other participants</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1839"/> - <source>import_multisig_info <filename> [<filename>...]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1840"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2873"/> <source>Import multisig info from other participants</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1843"/> - <source>sign_multisig <filename></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1844"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2877"/> <source>Sign a multisig transaction from a file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1847"/> - <source>submit_multisig <filename></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1848"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2881"/> <source>Submit a signed multisig transaction from a file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1851"/> - <source>export_raw_multisig_tx <filename></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1852"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2885"/> <source>Export a signed multisig transaction to a file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1855"/> - <source>help [<command>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1856"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3002"/> <source>Show the help section or the documentation about a <command>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1917"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3085"/> <source>integer >= </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1930"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3098"/> <source>block height</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2012"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3203"/> <source>No wallet found with that name. Confirm creation of new wallet named: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2068"/> - <source>can't specify more than one of --generate-new-wallet="wallet_name", --wallet-file="wallet_name", --generate-from-view-key="wallet_name", --generate-from-spend-key="wallet_name", --generate-from-keys="wallet_name", --generate-from-multisig-keys="wallet_name" and --generate-from-json="jsonfilename"</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2084"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3304"/> <source>can't specify both --restore-deterministic-wallet or --restore-multisig-wallet and --non-deterministic</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2090"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> <source>--restore-multisig-wallet uses --generate-new-wallet, not --wallet-file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2106"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3326"/> <source>specify a recovery parameter with the --electrum-seed="multisig seed here"</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2133"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3355"/> <source>Multisig seed failed verification</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2149"/> - <source>Enter seed encryption passphrase, empty if none</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2185"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2259"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3406"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3481"/> <source>This address is a subaddress which cannot be used here.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2337"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3558"/> <source>Error: expected M/N, but got: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2342"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3563"/> <source>Error: expected N > 1 and N <= M, but got: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2347"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3568"/> <source>Error: M/N is currently unsupported. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2350"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3571"/> <source>Generating master wallet from %u of %u multisig wallet keys</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2379"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3600"/> <source>failed to parse secret view key</source> <translation type="unfinished">impossibile fare il parsing della chiave segreta di visualizzazione</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2388"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3608"/> <source>failed to verify secret view key</source> <translation type="unfinished">verifica chiave segreta di visualizzazione fallita</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2408"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3628"/> <source>Secret spend key (%u of %u):</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2432"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3651"/> <source>Error: M/N is currently unsupported</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2550"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3802"/> <source>Restore height </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2551"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3803"/> <source>Still apply restore height? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2582"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3829"/> <source>Warning: using an untrusted daemon at %s, privacy will be lessened</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2636"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3888"/> <source>Daemon either is not started or wrong port was passed. Please make sure daemon is running or change the daemon address using the 'set_daemon' command.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2768"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4036"/> <source>Your wallet has been generated! To start synchronizing with the daemon, use the "refresh" command. Use the "help" command to see the list of available commands. @@ -2071,1471 +1858,2662 @@ your wallet again (your wallet keys are NOT at risk in any case). <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2850"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4180"/> <source>failed to generate new mutlisig wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2853"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4183"/> <source>Generated new %u/%u multisig wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2889"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4232"/> <source>Opened %u/%u multisig wallet%s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2942"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4293"/> <source>Use "help <command>" to see a command's documentation. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3000"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4351"/> <source>wallet is multisig and cannot save a watch-only version</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3105"/> - <source>missing daemon URL argument</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3116"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4476"/> <source>Unexpected array length - Exited simple_wallet::set_daemon()</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3130"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4517"/> <source>This does not seem to be a valid daemon URL.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3166"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3184"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4590"/> <source>txid </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3168"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3186"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4555"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4592"/> <source>idx </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3299"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4780"/> <source> (Some owned outputs have partial key images - import_multisig_info needed)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3300"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4783"/> <source>Currently selected account: [</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3300"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4783"/> <source>] </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3302"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4785"/> <source>Tag: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3302"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4785"/> <source>(No tag assigned)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3309"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4792"/> <source>Balance per address:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> <source>Address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5921"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8008"/> <source>Balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5921"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8008"/> <source>Unlocked balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> <source>Outputs</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5921"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8008"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9122"/> <source>Label</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3318"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4801"/> <source>%8u %6s %21s %21s %7u %21s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3327"/> - <source>usage: balance [detail]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3339"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3381"/> - <source>usage: incoming_transfers [available|unavailable] [verbose] [index=<N1>[,<N2>[,...]]]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> <source>spent</source> <translation>spesi</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> <source>global index</source> <translation>indice globale</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> <source>tx id</source> <translation>tx id</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> <source>addr index</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3423"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4924"/> <source>No incoming transfers</source> <translation>Nessun trasferimento in entrata</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3427"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4928"/> <source>No incoming available transfers</source> <translation>Nessun trasferimento in entrata disponibile</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3431"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4932"/> <source>No incoming unavailable transfers</source> <translation>Nessun trasferimento indisponibile in entrata</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3442"/> - <source>expected at least one payment ID</source> - <translation>deve esserci almeno un payment ID</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> <source>payment</source> <translation>pagamento</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> <source>transaction</source> <translation>transazione</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> <source>height</source> <translation>altezza</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> <source>unlock time</source> <translation>tempo sbloccato</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3463"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4968"/> <source>No payments with id </source> <translation>Nessun pagamento con id </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3516"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3582"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3853"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5016"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5106"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5442"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5901"/> <source>failed to get blockchain height: </source> <translation>impossibile recuperare altezza blockchain: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3572"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5136"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5174"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5226"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5259"/> - <source>failed to connect to the daemon</source> - <translation>impossibile connettersi al daemon</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3590"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5114"/> <source> Transaction %llu/%llu: txid=%s</source> <translation> Transazione %llu/%llu: txid=%s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3600"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5135"/> <source> Input %llu/%llu: amount=%s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3616"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5151"/> <source>failed to get output: </source> <translation>impossibile recuperare output: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3624"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5159"/> <source>output key's originating block height shouldn't be higher than the blockchain height</source> <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="3628"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5163"/> <source> Originating block heights: </source> <translation> Originando blocchi: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3643"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5175"/> <source> |</source> <translation> |</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3643"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5651"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5175"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7706"/> <source>| </source> <translation>| </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3660"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5192"/> <source> Warning: Some input keys being spent are from </source> <translation> Avviso: alcune chiavi di input spese vengono da </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3662"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5194"/> <source>, which can break the anonymity of ring signature. Make sure this is intentional!</source> <translation>, che potrebbe compromettere l'anonimità della ring signature. Assicurati di farlo intenzionalmente!</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3705"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4184"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5234"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5853"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6156"/> <source>Ring size must not be 0</source> <translation>Il ring size non può essere 0</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3717"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4196"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5246"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5865"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6168"/> <source>ring size %u is too small, minimum is %u</source> <translation>il ring size %u è troppo piccolo, il minimo è %u</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3724"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5258"/> <source>wrong number of arguments</source> <translation>numero di argomenti errato</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3830"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4266"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4479"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5417"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5996"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6268"/> <source>No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): </source> <translation>Nessun id pagamento è incluso in questa transazione. Questo è corretto? (S/Sì/N/No): </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3872"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4286"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5458"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6016"/> <source>No outputs found, or daemon is not ready</source> <translation>Nessun output trovato, o il daemon non è pronto</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6743"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6759"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6770"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6777"/> + <source>failed to parse tx_key</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6786"/> + <source>Tx key successfully stored.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6790"/> + <source>Failed to store tx key: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7296"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>block</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7440"/> + <source>usage: show_transfers [in|out|all|pending|failed|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7493"/> + <source>usage: export_transfers [in|out|all|pending|failed|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]] [output=<path>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>direction</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>timestamp</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>running balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>hash</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>payment ID</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>fee</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>destination</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>index</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>note</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7572"/> + <source>CSV exported to </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7730"/> + <source>Warning: this will lose any information which can not be recovered from the blockchain.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7731"/> + <source>This includes destination addresses, tx secret keys, tx notes, etc</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7732"/> + <source>Rescan anyway ? (Y/Yes/N/No): </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7750"/> + <source>MMS received new message</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8387"/> + <source>Network type: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8388"/> + <source>Testnet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8389"/> + <source>Stagenet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8389"/> + <source>Mainnet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8559"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8605"/> + <source>command only supported by HW wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8564"/> + <source>hw wallet does not support cold KI sync</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8576"/> + <source>Please confirm the key image sync on the device</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8582"/> + <source>Key images synchronized to height </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8585"/> + <source>Running untrusted daemon, cannot determine which transaction output is spent. Use a trusted daemon with --trusted-daemon and run rescan_spent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8588"/> + <source> spent, </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8588"/> + <source> unspent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8592"/> + <source>Failed to import key images</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8597"/> + <source>Failed to import key images: </source> + <translation type="unfinished">Impossibile importare le key images: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8614"/> + <source>Failed to reconnect device</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8619"/> + <source>Failed to reconnect device: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8883"/> <source>Transaction successfully saved to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6743"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6745"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8883"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8885"/> <source>, txid </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6745"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8885"/> <source>Failed to save transaction to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4081"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4314"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5723"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6044"/> <source>Sweeping %s in %llu transactions for a total fee of %s. Is this okay? (Y/Yes/N/No): </source> <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="4087"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4320"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4519"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5729"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6050"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6310"/> <source>Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No): </source> <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="4630"/> - <source>Donating </source> - <translation>Donando </translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4792"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6611"/> <source>This is a watch only wallet</source> <translation>Questo è un portafoglio solo-vista</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6571"/> - <source>usage: show_transfer <txid></source> - <translation>utilizzo: show_transfer <txid></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6673"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8813"/> <source>Double spend seen on the network: this transaction may or may not end up being mined</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6708"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8848"/> <source>Transaction ID not found</source> <translation>ID transazione non trovato</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="214"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="336"/> <source>true</source> <translation>vero</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="267"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="389"/> <source>failed to parse refresh type</source> <translation>impossibile fare il parsing del tipo di refresh</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="541"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="608"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="721"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="787"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="939"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="984"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1067"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1124"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1190"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1256"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1350"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1466"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1547"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6601"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6665"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6702"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6799"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7010"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7094"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8397"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8474"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8517"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8630"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8670"/> + <source>command not supported by HW wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="726"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="797"/> <source>wallet is watch-only and has no seed</source> <translation>il portafoglio è solo-vista e non possiede un seed</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="557"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="613"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="744"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="807"/> <source>wallet is non-deterministic and has no seed</source> <translation>il portafoglio è non-deterministico e non possiede un seed</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1226"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1245"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="751"/> + <source>Enter optional seed offset passphrase, empty to see raw seed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="817"/> + <source>Incorrect password</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="883"/> + <source>Current fee is %s %s per %s</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1036"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1158"/> + <source>Send this multisig info to all other participants, then use exchange_multisig_keys <info1> [<info2>...] with others' multisig info</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1167"/> + <source>Multisig wallet has been successfully created. Current wallet type: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1172"/> + <source>Failed to perform multisig keys exchange: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1499"/> + <source>Failed to load multisig transaction from MMS</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1631"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1788"/> + <source>Invalid key image</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1637"/> + <source>Invalid txid</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1649"/> + <source>Key image either not spent, or spent with mixin 0</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1664"/> + <source>Failed to get key image ring: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1679"/> + <source>File doesn't exist</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1701"/> + <source>Invalid ring specification: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1709"/> + <source>Invalid key image: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1714"/> + <source>Invalid ring type, expected relative or abosolute: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1720"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1732"/> + <source>Error reading line: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1743"/> + <source>Invalid ring: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1752"/> + <source>Invalid relative ring: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1764"/> + <source>Invalid absolute ring: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1773"/> + <source>Failed to set ring for key image: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1773"/> + <source>Continuing.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1803"/> + <source>Missing absolute or relative keyword</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1813"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1820"/> + <source>invalid index: must be a strictly positive unsigned integer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1828"/> + <source>invalid index: indices wrap</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1838"/> + <source>invalid index: indices should be in strictly ascending order</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1845"/> + <source>failed to set ring</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1890"/> + <source>First line is not an amount</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1904"/> + <source>Invalid output: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1914"/> + <source>Bad argument: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1914"/> + <source>should be "add"</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1923"/> + <source>Failed to open file</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1929"/> + <source>Invalid output key, and file doesn't exist</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1935"/> + <source>Failed to mark output spent: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1952"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1979"/> + <source>Invalid output</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1962"/> + <source>Failed to mark output unspent: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1986"/> + <source>Spent: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1988"/> + <source>Not spent: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1992"/> + <source>Failed to check whether output is spent: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2007"/> + <source>Failed to save known rings: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2022"/> + <source>Please confirm the transaction on the device</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2069"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2088"/> <source>wallet is watch-only and cannot transfer</source> <translation>il portafoglio è solo-vista e non può eseguire trasferimenti</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1321"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2106"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5581"/> + <source>WARNING: this is a non default ring size, which may harm your privacy. Default is recommended.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2108"/> + <source>WARNING: from v8, ring size will be fixed and this setting will be ignored.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2137"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2160"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2176"/> + <source>priority must be either 0, 1, 2, 3, or 4, or one of: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2181"/> <source>could not change default priority</source> <translation>impossibile cambiare priorità standard</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1919"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2249"/> + <source>invalid argument: must be either 0/never, 1/action, or 2/encrypt/decrypt</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2510"/> + <source>Device name not specified</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2519"/> + <source>Device reconnect failed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2524"/> + <source>Device reconnect failed: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2583"/> + <source>Show the incoming transfers, all or filtered by availability and address index. + +Output format: +Amount, Spent("T"|"F"), "locked"|"unlocked", RingCT, Global Index, Transaction Hash, Address Index, [Public Key, Key Image] </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2595"/> + <source>Transfer <amount> to <address>. If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding URI_2 or <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2599"/> + <source>Transfer <amount> to <address> and lock it for <lockblocks> (max. 1000000). If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding URI_2 or <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2603"/> + <source>Send all unlocked balance to an address and lock it for <lockblocks> (max. 1000000). If the parameter "index<N1>[,<N2>,...]" is specified, the wallet sweeps outputs received by those address indices. If omitted, the wallet randomly chooses an address index to be used. <priority> is the priority of the sweep. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2609"/> + <source>Send all unlocked balance to an address. If the parameter "index<N1>[,<N2>,...]" is specified, the wallet sweeps outputs received by those address indices. If omitted, the wallet randomly chooses an address index to be used. If the parameter "outputs=<N>" is specified and N > 0, wallet splits the transaction into N even outputs.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2625"/> + <source>Sign a transaction from a file. If the parameter "export_raw" is specified, transaction raw hex data suitable for the daemon RPC /sendrawtransaction is exported.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2646"/> + <source>If no arguments are specified or <index> is specified, the wallet shows the default or specified address. If "all" is specified, the wallet shows all the existing addresses in the currently selected account. If "new " is specified, the wallet creates a new address with the provided label text (which can be empty). If "label" is specified, the wallet sets the label of the address specified by <index> to the provided label text.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2673"/> + <source>Available options: + seed language + Set the wallet's 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 the default ring size (obsolete). + auto-refresh <1|0> + Whether to automatically synchronize new blocks from the daemon. + refresh-type <full|optimize-coinbase|no-coinbase|default> + Set the wallet's refresh behaviour. + priority [0|1|2|3|4] + Set the fee to default/unimportant/normal/elevated/priority. + confirm-missing-payment-id <1|0> + ask-password <0|1|2 (or never|action|decrypt)> + unit <monero|millinero|micronero|nanonero|piconero> + Set the 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] + Set a threshold for confirm-backlog to only warn if the transaction backlog is greater than n blocks. + refresh-from-block-height [n] + Set the height before which to ignore blocks. + auto-low-priority <1|0> + Whether to automatically use the low priority fee level when it's safe to do so. + segregate-pre-fork-outputs <1|0> + Set this if you intend to spend outputs on both Monero AND a key reusing fork. + key-reuse-mitigation2 <1|0> + Set this if you are not sure whether you will spend on a key reusing Monero fork later. +subaddress-lookahead <major>:<minor> + Set the lookahead sizes for the subaddress hash table. + Set this if you are not sure whether you will spend on a key reusing Monero fork later. + segregation-height <n> + Set to the height of a key reusing fork you want to use, 0 to use default.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2730"/> + <source>Set the transaction key (r) for a given <txid> in case the tx was made by some other device or 3rd party wallet.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2765"/> + <source>Show the incoming/outgoing transfers within an optional height range. + +Output format: +In or Coinbase: Block Number, "block"|"in", Time, Amount, Transaction Hash, Payment ID, Subaddress Index, "-", Note +Out: Block Number, "out", Time, Amount*, Transaction Hash, Payment ID, Fee, Destinations, Input addresses**, "-", Note +Pool: "pool", "in", Time, Amount, Transaction Hash, Payment Id, Subaddress Index, "-", Note, Double Spend Note +Pending or Failed: "failed"|"pending", "out", Time, Amount*, Transaction Hash, Payment ID, Fee, Input addresses**, "-", Note + +* Excluding change and fee. +** Set of address indices used as inputs in this transfer.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2775"/> + <source>export_transfers [in|out|all|pending|failed|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]] [output=<filepath>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2776"/> + <source>Export to CSV the incoming/outgoing transfers within an optional height range.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2784"/> + <source>Rescan the blockchain from scratch, losing any information which can not be recovered from the blockchain itself.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2818"/> + <source>Export a signed set of key images to a <filename>.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2826"/> + <source>Synchronizes key images with the hw wallet.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2830"/> + <source>Attempts to reconnect HW wallet.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2865"/> + <source>Performs extra multisig keys exchange rounds. Needed for arbitrary M/N multisig wallets</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2889"/> + <source>Interface with the MMS (Multisig Messaging System) +<subcommand> is one of: + init, info, signer, list, next, sync, transfer, delete, send, receive, export, note, show, set, help + send_signer_config, start_auto_config, stop_auto_config, auto_config +Get help about a subcommand with: help mms <subcommand>, or mms help <subcommand></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2897"/> + <source>Initialize and configure the MMS for M/N = number of required signers/number of authorized signers multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2901"/> + <source>Display current MMS configuration</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2905"/> + <source>Set or modify authorized signer info (single-word label, transport address, Monero address), or list all signers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2909"/> + <source>List all messages</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2913"/> + <source>Evaluate the next possible multisig-related action(s) according to wallet state, and execute or offer for choice +By using 'sync' processing of waiting messages with multisig sync info can be forced regardless of wallet state</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2918"/> + <source>Force generation of multisig sync info regardless of wallet state, to recover from special situations like "stale data" errors</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2922"/> + <source>Initiate transfer with MMS support; arguments identical to normal 'transfer' command arguments, for info see there</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2926"/> + <source>Delete a single message by giving its id, or delete all messages by using 'all'</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2930"/> + <source>Send a single message by giving its id, or send all waiting messages</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2934"/> + <source>Check right away for new messages to receive</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2938"/> + <source>Write the content of a message to a file "mms_message_content"</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2942"/> + <source>Send a one-line message to an authorized signer, identified by its label, or show any waiting unread notes</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2946"/> + <source>Show detailed info about a single message</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2950"/> + <source>Available options: + auto-send <1|0> + Whether to automatically send newly generated messages right away. + </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2956"/> + <source>Send completed signer config to all other authorized signers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2960"/> + <source>Start auto-config at the auto-config manager's wallet by issuing auto-config tokens and optionally set others' labels</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2964"/> + <source>Delete any auto-config tokens and abort a auto-config process</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2968"/> + <source>Start auto-config by using the token received from the auto-config manager</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2972"/> + <source>Print the ring(s) used to spend a given key image or transaction (if the ring size is > 1) + +Output format: +Key Image, "absolute", list of rings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2978"/> + <source>Set the ring used for a given key image, so it can be reused in a fork</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2982"/> + <source>Save known rings to the shared rings database</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2986"/> + <source>Mark output(s) as spent so they never get selected as fake outputs in a ring</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2990"/> + <source>Marks an output as unspent so it may get selected as a fake output in a ring</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2994"/> + <source>Checks whether an output is marked as spent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2998"/> + <source>Returns version information</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3087"/> <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>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="1923"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3088"/> + <source>0, 1, 2, 3, or 4, or one of </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3090"/> + <source>0|1|2 (or never|action|decrypt)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3091"/> <source>monero, millinero, micronero, nanonero, piconero</source> <translation>monero, millinero, micronero, nanonero, piconero</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1975"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3102"/> + <source><major>:<minor></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3106"/> + <source><device_name[:device_spec]></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3127"/> + <source>wrong number range, use: %s</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3166"/> <source>Wallet name not valid. Please try again or use Ctrl-C to quit.</source> <translation>Nome del portafoglio non valido. Prova di nuovo o usa Ctrl-C per uscire</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1992"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3183"/> <source>Wallet and key files found, loading...</source> <translation>Portafoglio e chiavi trovate, sto caricando...</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1998"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3189"/> <source>Key file found but not wallet file. Regenerating...</source> <translation>Ho trovato la chiave ma non il portafoglio. Sto rigenerando...</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2004"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3195"/> <source>Key file not found. Failed to open wallet: </source> <translation>Chiave non trovata. Impossibile aprire portafoglio: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2023"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3214"/> <source>Generating new wallet...</source> <translation>Sto generando un nuovo portafoglio...</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2092"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3232"/> + <source>NOTE: the following %s can be used to recover access to your wallet. Write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3234"/> + <source>string</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3234"/> + <source>25 words</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3273"/> + <source>Can't specify more than one of --testnet and --stagenet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3285"/> + <source>can't specify more than one of --generate-new-wallet="wallet_name", --wallet-file="wallet_name", --generate-from-view-key="wallet_name", --generate-from-spend-key="wallet_name", --generate-from-keys="wallet_name", --generate-from-multisig-keys="wallet_name", --generate-from-json="jsonfilename" and --generate-from-device="wallet_name"</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3312"/> <source>--restore-deterministic-wallet uses --generate-new-wallet, not --wallet-file</source> <translation>--restore-deterministic-wallet usa --generate-new-wallet, non --wallet-file</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2141"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3364"/> <source>Electrum-style word list failed verification</source> <translation>La lista di parole stile Electrum ha fallito la verifica</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2174"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2194"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2229"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2248"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2268"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2284"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2332"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2357"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2373"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2413"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3369"/> + <source>Enter seed offset passphrase, empty if none</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3395"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3415"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3450"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3470"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3490"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3505"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3578"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3594"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3633"/> <source>No data supplied, cancelled</source> <translation>Nessun dato fornito, cancellato</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2180"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2254"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2363"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3791"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4240"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4454"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4926"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4994"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5058"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5266"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6106"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6353"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3401"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3476"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3584"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5371"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5969"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6243"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6818"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6886"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6950"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7154"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8193"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8454"/> <source>failed to parse address</source> <translation>impossibile fare il parsing dell'indirizzo</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2200"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2290"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3421"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3511"/> <source>failed to parse view key secret key</source> <translation>impossibile fare il parsing chiave di visualizzazione chiave segreta</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2210"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2308"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3430"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3528"/> <source>failed to verify view key secret key</source> <translation>impossibile verificare chiave di visualizzazione chiave segreta</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2214"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2312"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2393"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3434"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3532"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3613"/> <source>view key does not match standard address</source> <translation>la chiave di visualizzazione non corrisponde all'indirizzo standard</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2219"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2238"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2316"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2450"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2480"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3439"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3459"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3536"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3669"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3695"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3726"/> <source>account creation failed</source> <translation>creazione dell'account fallita</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2234"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2274"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2418"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3455"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3496"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3638"/> <source>failed to parse spend key secret key</source> <translation>impossibile fare il parsing chiave di spesa chiave segreta</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2300"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2439"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3520"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3658"/> <source>failed to verify spend key secret key</source> <translation>impossibile verificare chiave di spesa chiave segreta</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2304"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2444"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3524"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3663"/> <source>spend key does not match standard address</source> <translation>la chiave di spesa non corrisponde all'indirizzo standard</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2471"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3701"/> + <source>No restore height is specified.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3702"/> + <source>Assumed you are creating a new account, restore will be done from current estimated blockchain height.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3703"/> + <source>Use --restore-height if you want to restore an already setup account from a specific height</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3707"/> + <source>account creation aborted</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3717"/> <source>specify a wallet path with --generate-new-wallet (not --wallet-file)</source> <translation>specifica un percorso per il portafoglio con --generate-new-wallet (non --wallet-file)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2562"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3816"/> + <source>can't specify --subaddress-lookahead and --wallet-file at the same time</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3820"/> <source>failed to open account</source> <translation>impossibile aprire account</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2566"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3030"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3085"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3142"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4962"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3824"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4391"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4444"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4529"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6854"/> <source>wallet is null</source> <translation>il portafoglio è nullo</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2680"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2685"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3832"/> + <source>Failed to initialize ring database: privacy enhancing features will be inactive</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3917"/> + <source>If your display freezes, exit blind with ^C, then run again with --use-english-language-names</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3935"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3940"/> <source>invalid language choice entered. Please try again. </source> <translation>linguaggio selezionato scorretto. Prova di nuovo.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2753"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4019"/> <source>View key: </source> <translation>Chiave di visualizzazione: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2935"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4130"/> + <source>Generated new wallet on hw device: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4209"/> + <source>Key file not found. Failed to open wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4286"/> <source>You may want to remove the file "%s" and try again</source> <translation>Potresti voler rimuovere il file "%s" e provare di nuovo</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2963"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4314"/> <source>failed to deinitialize wallet</source> <translation>deinizializzazione portafoglio fallita</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3021"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3524"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6410"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4367"/> + <source>Watch only wallet saved as: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4371"/> + <source>Failed to save watch only wallet: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4382"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5024"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8522"/> <source>this command requires a trusted daemon. Enable with --trusted-daemon</source> <translation>questo comando richiede un daemon fidato. Abilita questa opzione con --trusted-daemon</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3152"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4498"/> + <source>Expected trusted or untrusted, got </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4515"/> + <source>trusted</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4515"/> + <source>untrusted</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4539"/> <source>blockchain can't be saved: </source> <translation>impossibile salvare la blockchain: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3239"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3538"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4569"/> + <source>NOTE: this transaction uses an encrypted payment ID: consider using subaddresses instead</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4572"/> + <source>WARNING: this transaction uses an unencrypted payment ID: consider using subaddresses instead</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4608"/> + <source>Password needed (%s) - use the refresh command</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4616"/> + <source>Enter password</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4631"/> + <source>Device requires attention</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4639"/> + <source>Enter device PIN</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4641"/> + <source>Failed to read device PIN</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4648"/> + <source>Please enter the device passphrase on the device</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4655"/> + <source>Enter device passphrase</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4657"/> + <source>Failed to read device passphrase</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4673"/> + <source>The first refresh has finished for the HW-based wallet with received money. hw_key_images_sync is needed. </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4675"/> + <source>Do you want to do it now? (Y/Yes/N/No): </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4677"/> + <source>hw_key_images_sync skipped. Run command manually before a transfer.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4720"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5038"/> <source>daemon is busy. Please try again later.</source> <translation>il daemon è impegnato. Prova più tardi</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3243"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3542"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4724"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5042"/> <source>no connection to daemon. Please make sure daemon is running.</source> <translation>nessuna connessione con il daemon. Assicurati che sia in funzione</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3253"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4734"/> <source>refresh error: </source> <translation>errore refresh: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3303"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4782"/> + <source> (Some owned outputs have missing key images - import_key_images needed)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4786"/> <source>Balance: </source> <translation>Bilancio: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3399"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4855"/> + <source>Invalid keyword: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4893"/> <source>pubkey</source> <translation>pubkey</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3399"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4893"/> <source>key image</source> <translation>immagine chiave</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3410"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4910"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> <source>unlocked</source> <translation>sbloccato</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> <source>ringct</source> <translation>ringct</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3409"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4904"/> + <source>Heights: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4909"/> <source>T</source> <translation>T</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3409"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4909"/> <source>F</source> <translation>F</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3410"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4910"/> <source>locked</source> <translation>bloccato</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3411"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4911"/> <source>RingCT</source> <translation>RingCT</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3411"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4911"/> <source>-</source> <translation>-</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3485"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4990"/> <source>payment ID has invalid format, expected 16 or 64 character hex string: </source> <translation>l'id pagamento è in un formato invalido, dovrebbe essere una stringa hex di 16 o 64 caratteri</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3546"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5046"/> <source>failed to get spent status</source> <translation>impossibile recuperare status spesi</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3661"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5130"/> + <source>failed to find construction data for tx input</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5193"/> <source>the same transaction</source> <translation>la stessa transazione</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3661"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5193"/> <source>blocks that are temporally very close</source> <translation>i blocchi che sono temporalmente molto vicini</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3778"/> - <source>Locked blocks too high, max 1000000 (˜4 yrs)</source> - <translation>I blocchi bloccati sono troppo alti, max 1000000 (˜4 anni)</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="9015"/> + <source> (Y/Yes/N/No): </source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3895"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3905"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9042"/> + <source>Choose processing:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9051"/> + <source>Sign tx</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9059"/> + <source>Send the tx for submission to </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9063"/> + <source>Send the tx for signing to </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9070"/> + <source>Submit tx</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9073"/> + <source>unknown</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9079"/> + <source>Choice: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9091"/> + <source>Wrong choice</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9098"/> + <source>Id</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9098"/> + <source>I/O</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9098"/> + <source>Authorized Signer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>Message Type</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>Height</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>R</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>Message State</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>Since</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9116"/> + <source> ago</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9122"/> + <source>#</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9122"/> + <source>Transport Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9123"/> + <source>Auto-Config Token</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9123"/> + <source>Monero Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9127"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9135"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9137"/> + <source><not set></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9178"/> + <source>Message </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9179"/> + <source>In/out: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9181"/> + <source>State: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9181"/> + <source>%s since %s, %s ago</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9185"/> + <source>Sent: Never</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9189"/> + <source>Sent: %s, %s ago</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9192"/> + <source>Authorized signer: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9193"/> + <source>Content size: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9193"/> + <source> bytes</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9194"/> + <source>Content: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9194"/> + <source>(binary data)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9224"/> + <source>Send these messages now?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9234"/> + <source>Queued for sending.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9254"/> + <source>Invalid message id</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9263"/> + <source>usage: mms init <required_signers>/<authorized_signers> <own_label> <own_transport_address></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9269"/> + <source>The MMS is already initialized. Re-initialize by deleting all signer info and messages?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9284"/> + <source>Error in the number of required signers and/or authorized signers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9301"/> + <source>The MMS is not active.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9324"/> + <source>Invalid signer number </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9329"/> + <source>mms signer [<number> <label> [<transport_address> [<monero_address>]]]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9348"/> + <source>Invalid Monero address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9355"/> + <source>Wallet state does not allow changing Monero addresses anymore</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9367"/> + <source>Usage: mms list</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9380"/> + <source>Usage: mms next [sync]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9405"/> + <source>No next step: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9415"/> + <source>prepare_multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9421"/> + <source>make_multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9436"/> + <source>exchange_multisig_keys</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9451"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9571"/> + <source>export_multisig_info</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9460"/> + <source>import_multisig_info</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9473"/> + <source>sign_multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9483"/> + <source>submit_multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9493"/> + <source>Send tx</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9504"/> + <source>Process signer config</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9516"/> + <source>Replace current signer config with the one displayed above?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9530"/> + <source>Process auto config data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9544"/> + <source>Nothing ready to process</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9564"/> + <source>Usage: mms sync</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9588"/> + <source>Usage: mms delete (<message_id> | all)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9595"/> + <source>Delete all messages?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9621"/> + <source>Usage: mms send [<message_id>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9638"/> + <source>Usage: mms receive</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9655"/> + <source>Usage: mms export <message_id></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9667"/> + <source>Message content saved to: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9671"/> + <source>Failed to to save message content</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9695"/> + <source>Usage: mms note [<label> <text>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9702"/> + <source>No signer found with label </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9724"/> + <source>Usage: mms show <message_id></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9743"/> + <source>Usage: mms set <option_name> [<option_value>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9760"/> + <source>Wrong option value</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9765"/> + <source>Auto-send is on</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9765"/> + <source>Auto-send is off</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9770"/> + <source>Unknown option</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9778"/> + <source>Usage: mms help [<subcommand>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9794"/> + <source>Usage: mms send_signer_config</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9800"/> + <source>Signer config not yet complete</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9815"/> + <source>Usage: mms start_auto_config [<label> <label> ...]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9820"/> + <source>There are signers without a label set. Complete labels before auto-config or specify them as parameters here.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9826"/> + <source>Auto-config is already running. Cancel and restart?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9850"/> + <source>Usage: mms stop_auto_config</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9853"/> + <source>Delete any auto-config tokens and stop auto-config?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9866"/> + <source>Usage: mms auto_config <auto_config_token></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9873"/> + <source>Invalid auto-config token</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9879"/> + <source>Auto-config already running. Cancel and restart?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9911"/> + <source>The MMS is not active. Activate using the "mms init" command</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9988"/> + <source>Invalid MMS subcommand</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9993"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9997"/> + <source>Error in MMS command: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5481"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5491"/> <source>Is this okay anyway? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3900"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5486"/> <source>There is currently a %u block backlog at that fee level. Is this okay? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3905"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5491"/> <source>Failed to check for backlog: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3946"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4302"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5532"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6032"/> <source> Transaction </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3951"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4307"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5537"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6037"/> <source>Spending from address index %d </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3953"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4309"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5539"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6039"/> <source>WARNING: Outputs of multiple addresses are being used together, which might potentially compromise your privacy. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4424"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6213"/> <source>failed to parse Payment ID</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4440"/> - <source>usage: sweep_single [<priority>] [<ring_size>] <key_image> <address> [<payment_id>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4447"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6236"/> <source>failed to parse key image</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4499"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6290"/> <source>No outputs found</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4504"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6295"/> <source>Multiple transactions are created, which is not supposed to happen</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4509"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6300"/> <source>The transaction uses multiple or no inputs, which is not supposed to happen</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4586"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6377"/> <source>missing threshold amount</source> <translation>manca la soglia massima dell'ammontare</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4591"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6382"/> <source>invalid amount threshold</source> <translation>ammontare soglia invalido</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4601"/> - <source>donations are not enabled on the testnet</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4608"/> - <source>usage: donate [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <amount> [<payment_id>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4716"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6530"/> <source>Change goes to more than one address</source> <translation>Il cambiamento va a più di un indirizzo</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5077"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5188"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6969"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7079"/> <source>Good signature</source> <translation>Firma valida</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5104"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5190"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5293"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6996"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7081"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7181"/> <source>Bad signature</source> <translation>Firma invalida</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6046"/> - <source>usage: integrated_address [payment ID]</source> - <translation>utilizzo: integrated_address [ID pagamento]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6082"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8169"/> <source>Standard address: </source> <translation>Indirizzo standard: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6087"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8174"/> <source>failed to parse payment ID or address</source> <translation>impossibile fare il parsing di ID pagamento o indirizzo</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6098"/> - <source>usage: address_book [(add (<address> [pid <long or short payment id>])|<integrated address> [<description possibly with whitespaces>])|(delete <index>)]</source> - <translation>utilizzo: address_book [(add (<address> [pid <long or short payment id>])|<integrated address> [<description possibly with whitespaces>])|(delete <index>)]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6128"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8215"/> <source>failed to parse payment ID</source> <translation>impossibile fare il parsing di ID pagamento</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6146"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8233"/> <source>failed to parse index</source> <translation>impossibile fare il parsing dell'indice</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6154"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8241"/> <source>Address book is empty.</source> <translation>La rubrica è vuota.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6160"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8247"/> <source>Index: </source> <translation>Indice: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6161"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6287"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8248"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8378"/> <source>Address: </source> <translation>Indirizzo: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6162"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8249"/> <source>Payment ID: </source> <translation>ID Pagamento: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6163"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6286"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8250"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8377"/> <source>Description: </source> <translation>Descrizione: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6173"/> - <source>usage: set_tx_note [txid] free text note</source> - <translation>utilizzo: set_tx_note [txid] nota di testo libera</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6201"/> - <source>usage: get_tx_note [txid]</source> - <translation>utilizzo: get_tx_note [txid]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6304"/> - <source>usage: sign <filename></source> - <translation>utilizzo: sign <filename></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6309"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8407"/> <source>wallet is watch-only and cannot sign</source> <translation>il portafoglio è di tipo solo-visualizzazione e non può firmare</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="951"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6323"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6346"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6501"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1289"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8421"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8447"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8684"/> <source>failed to read file </source> <translation>impossibile leggere il file </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5039"/> - <source>usage: check_tx_proof <txid> <address> <signature_file> [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5066"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5181"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5278"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6958"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7072"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7166"/> <source>failed to load signature file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5117"/> - <source>usage: get_spend_proof <txid> [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5123"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7020"/> <source>wallet is watch-only and cannot generate the proof</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5161"/> - <source>usage: check_spend_proof <txid> <signature_file> [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5202"/> - <source>usage: get_reserve_proof (all|<amount>) [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5208"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7104"/> <source>The reserve proof can be generated only by a full wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5253"/> - <source>usage: check_reserve_proof <address> <signature_file> [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5271"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7159"/> <source>Address must not be a subaddress</source> - <translation type="unfinished"></translation> + <translation type="unfinished">L'indirizzo non può essere un sottoindirizzo</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5289"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7177"/> <source>Good signature -- total: %s, spent: %s, unspent: %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5353"/> - <source>usage: show_transfers [in|out|all|pending|failed] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5490"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7365"/> <source>[Double spend seen on the network: this transaction may or may not end up being mined] </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5526"/> - <source>usage: unspent_outputs [index=<N1>[,<N2>,...]] [<min_amount> [<max_amount>]]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5586"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7641"/> <source>There is no unspent output in the specified address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5699"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7799"/> <source> (no daemon)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5701"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7801"/> <source> (out of sync)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5758"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7852"/> <source>(Untitled account)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5771"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5789"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5814"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5837"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5990"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6013"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7865"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7883"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7908"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7931"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8077"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8100"/> <source>failed to parse index: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5776"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5995"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7870"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8082"/> <source>specify an index between 0 and </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5873"/> - <source>usage: - account - account new <label text with white spaces allowed> - account switch <index> - account label <index> <label text with white spaces allowed> - account tag <tag_name> <account_index_1> [<account_index_2> ...] - account untag <account_index_1> [<account_index_2> ...] - account tag_description <tag_name> <description></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5901"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7988"/> <source> Grand total: Balance: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5901"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7988"/> <source>, unlocked balance: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5909"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7996"/> <source>Untagged accounts:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5915"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8002"/> <source>Tag %s is unregistered.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5918"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8005"/> <source>Accounts with tag: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5919"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8006"/> <source>Tag's description: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5921"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8008"/> <source>Account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5927"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8014"/> <source> %c%8u %6s %21s %21s %21s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5937"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8024"/> <source>----------------------------------------------------------------------------------</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5938"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8025"/> <source>%15s %21s %21s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5961"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8048"/> <source>Primary address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5961"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8048"/> <source>(used)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5982"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8069"/> <source>(Untitled address)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6022"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8109"/> <source><index_min> is already out of bound</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6027"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8114"/> <source><index_max> exceeds the bound</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6035"/> - <source>usage: address [ new <label text with white spaces allowed> | all | <index_min> [<index_max>] | label <index> <label text with white spaces allowed> ]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6053"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6065"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8140"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8152"/> <source>Integrated addresses can only be created for account 0</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6077"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8164"/> <source>Integrated address: %s, payment ID: %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6082"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8169"/> <source>Subaddress: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6242"/> - <source>usage: get_description</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6248"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8335"/> <source>no description found</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6250"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8337"/> <source>description found: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6285"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8376"/> <source>Filename: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6290"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8381"/> <source>Watch only</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6292"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8383"/> <source>%u/%u multisig%s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6294"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8385"/> <source>Normal</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6295"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8386"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9180"/> <source>Type: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6296"/> - <source>Testnet: </source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6296"/> - <source>Yes</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6296"/> - <source>No</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6314"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8412"/> <source>This wallet is multisig and cannot sign</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6335"/> - <source>usage: verify <filename> <address> <signature></source> - <translation>utilizzo: verify <filename> <address> <signature></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6360"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8461"/> <source>Bad signature from </source> <translation>Firma non valida da </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6364"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8465"/> <source>Good signature from </source> <translation>Firma valida da </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6373"/> - <source>usage: export_key_images <filename></source> - <translation>utilizzo: export_key_images <filename></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6378"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8484"/> <source>wallet is watch-only and cannot export key images</source> <translation>il portafoglio è solo-vista e non può esportare immagini chiave</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="906"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6391"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6473"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1228"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8498"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8651"/> <source>failed to save file </source> <translation>impossibile salvare file </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6402"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8509"/> <source>Signed key images exported to </source> <translation>Chiave immagine firmata esportata in </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6416"/> - <source>usage: import_key_images <filename></source> - <translation>utilizzo: import_key_images <filename></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6447"/> - <source>usage: export_outputs <filename></source> - <translation>utilizzo: export_outputs <filename></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6484"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8662"/> <source>Outputs exported to </source> <translation>Outputs esportati in </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6492"/> - <source>usage: import_outputs <filename></source> - <translation>utilizzo: import_outputs <filename></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3819"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5219"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5545"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5354"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6417"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7115"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7600"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7608"/> <source>amount is wrong: </source> <translation>l'ammontare non è corretto: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3820"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5355"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6417"/> <source>expected number from 0 to </source> <translation>deve essere un numero da 0 a </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4079"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5721"/> <source>Sweeping </source> <translation>Eseguendo lo sweeping </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4559"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6350"/> <source>Money successfully sent, transaction: </source> <translation>Fondi inviati con successo, transazione: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4757"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6571"/> <source>%s change to %s</source> <translation>%s cambia in %s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4760"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6574"/> <source>no change</source> <translation>nessun cambiamento</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1044"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1057"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4826"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1435"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1448"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6646"/> <source>Transaction successfully signed to file </source> <translation>Transazione firmata con successo nel file </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4876"/> - <source>usage: get_tx_key <txid></source> - <translation>utilizzo: get_tx_key <txid></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4884"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4919"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4968"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5050"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5130"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5168"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6180"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6208"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6578"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6713"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6749"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6811"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6860"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6942"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7027"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7062"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8267"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8295"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8714"/> <source>failed to parse txid</source> <translation>parsing txid fallito</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4898"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6727"/> <source>Tx key: </source> <translation>Chiave Tx: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4903"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6732"/> <source>no tx keys found for this txid</source> <translation>nessuna chiave tx trovata per questo txid</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4912"/> - <source>usage: get_tx_proof <txid> <address> [<message>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4937"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5147"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5239"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6829"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7041"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7130"/> <source>signature file saved to: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4939"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5149"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5241"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6831"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7043"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7132"/> <source>failed to save signature file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4953"/> - <source>usage: check_tx_key <txid> <txkey> <address></source> - <translation>utilizzo: check_tx_key <txid> <txkey> <address></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4976"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4985"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6868"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6877"/> <source>failed to parse tx key</source> <translation>impossibile fare il parsing della chiave tx</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4943"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5031"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5109"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6835"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6923"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7001"/> <source>error: </source> <translation>errore: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5007"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5080"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6899"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6972"/> <source>received</source> <translation>ricevuto/i</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5007"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5080"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6899"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6972"/> <source>in txid</source> <translation>in txid</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5026"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5099"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6918"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6991"/> <source>received nothing in txid</source> <translation>nulla ricevuto in txid</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5010"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5083"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6902"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6975"/> <source>WARNING: this transaction is not yet included in the blockchain!</source> <translation>AVVISO: questa transazione non è ancora inclusa nella blockchain!</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5016"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5089"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6908"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6981"/> <source>This transaction has %u confirmations</source> <translation>Questa transazione ha %u conferme</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5020"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5093"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6912"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6985"/> <source>WARNING: failed to determine number of confirmations!</source> <translation>AVVISO: impossibile determinare il numero di conferme!</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5401"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7266"/> <source>bad min_height parameter:</source> <translation>parametro min_height non corretto:</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5413"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7278"/> <source>bad max_height parameter:</source> <translation>parametro max_height non corretto:</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5473"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7296"/> <source>in</source> <translation>in</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5473"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5514"/> - <source>out</source> - <translation>out</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5514"/> - <source>failed</source> - <translation>fallito</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5514"/> - <source>pending</source> - <translation>in attesa</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5560"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7615"/> <source><min_amount> should be smaller than <max_amount></source> <translation><min_amount> dovrebbe essere più piccolo di <max_amount></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5592"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7647"/> <source> Amount: </source> <translation> Ammontare: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5592"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7647"/> <source>, number of keys: </source> <translation>, numero di chiavi: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5597"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7652"/> <source> </source> <translation> </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5602"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7657"/> <source> Min block height: </source> <translation> Altezza minima blocco: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5603"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7658"/> <source> Max block height: </source> <translation> Altezza massima blocco: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5604"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7659"/> <source> Min amount found: </source> <translation> Ammontare minimo trovato: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5605"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7660"/> <source> Max amount found: </source> <translation> Ammontare massimo trovato: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5606"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7661"/> <source> Total count: </source> <translation> Conto totale: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5646"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7701"/> <source> Bin size: </source> <translation> Dimensione Bin: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5647"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7702"/> <source> Outputs per *: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5649"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7704"/> <source>count ^ </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5651"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7706"/> <source> |</source> <translation> |</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5653"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7708"/> <source> +</source> <translation> +</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5653"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7708"/> <source>+--> block height </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5654"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7709"/> <source> ^</source> <translation> ^</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5654"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7709"/> <source>^ </source> <translation>^ </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5655"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7710"/> <source> </source> <translation> </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5696"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7797"/> <source>wallet</source> <translation>portafoglio</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="666"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6057"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="870"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8144"/> <source>Random payment ID: </source> <translation>ID pagamento casuale: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6058"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8145"/> <source>Matching integrated address: </source> <translation>Indirizzo integrato corrispondente: </translation> </message> @@ -3553,11 +4531,6 @@ Outputs per *: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="72"/> - <source>How many participants wil share parts of the multisig wallet</source> - <translation type="unfinished"></translation> - </message> - <message> <location filename="../src/gen_multisig/gen_multisig.cpp" line="73"/> <source>How many signers are required to sign a valid transaction</source> <translation type="unfinished"></translation> @@ -3568,18 +4541,33 @@ Outputs per *: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="81"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="83"/> <source>Generating %u %u/%u multisig wallets</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="138"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="142"/> <source>Error verifying multisig extra info</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="146"/> - <source>Error finalizing multisig</source> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="72"/> + <source>How many participants will share parts of the multisig wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="75"/> + <source>Create stagenet multisig wallets</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="76"/> + <source>Create an address file for new wallets</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="107"/> + <source>Failed to verify multisig info</source> <translation type="unfinished"></translation> </message> <message> @@ -3593,132 +4581,495 @@ Outputs per *: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="176"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="182"/> <source>This program generates a set of multisig wallets - use this simpler scheme only if all the participants trust each other</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="194"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="201"/> + <source>Error: Can't specify more than one of --testnet and --stagenet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="208"/> <source>Error: expected N/M, but got: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="202"/> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="211"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="216"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="225"/> <source>Error: either --scheme or both of --threshold and --participants may be given</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="218"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="232"/> <source>Error: expected N > 1 and N <= M, but got N==%u and M==%d</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="227"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="241"/> <source>Error: --filename-base is required</source> <translation type="unfinished"></translation> </message> +</context> +<context> + <name>mms::message_store</name> + <message> + <location filename="../src/wallet/message_store.cpp" line="69"/> + <source>Use PyBitmessage instance at URL <arg></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="70"/> + <source>Specify <arg> as username:password for PyBitmessage API</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="832"/> + <source>Auto-config cannot proceed because auto config data from other signers is not complete</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="857"/> + <source>The signer config is not complete.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="909"/> + <source>Wallet can't go multisig because key sets from other signers are missing or not complete.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="951"/> + <source>Wallet can't start another key exchange round because key sets from other signers are missing or not complete.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1015"/> + <source>Syncing not done because multisig sync data from other signers are missing or not complete.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1129"/> + <source>There are waiting messages, but nothing is ready to process under normal circumstances</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1132"/> + <source> +Use "mms next sync" if you want to force processing of the waiting sync data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1136"/> + <source> +Use "mms note" to display the waiting notes</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1141"/> + <source>There are no messages waiting to be processed.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1359"/> + <source>key set</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1361"/> + <source>additional key set</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1363"/> + <source>multisig sync data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1365"/> + <source>partially signed tx</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1367"/> + <source>fully signed tx</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1369"/> + <source>note</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1371"/> + <source>signer config</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1373"/> + <source>auto-config data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1375"/> + <source>unknown message type</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1384"/> + <source>in</source> + <translation type="unfinished">in</translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1386"/> + <source>out</source> + <translation type="unfinished">out</translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1388"/> + <source>unknown message direction</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1397"/> + <source>ready to send</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="233"/> - <source>Error: unsupported scheme: only N/N and N-1/N are supported</source> + <location filename="../src/wallet/message_store.cpp" line="1399"/> + <source>sent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1401"/> + <source>waiting</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1403"/> + <source>processed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1405"/> + <source>cancelled</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1407"/> + <source>unknown message state</source> <translation type="unfinished"></translation> </message> </context> <context> <name>sw</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="115"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="125"/> <source>Generate new wallet and save it to <arg></source> <translation>Genera un nuovo portafoglio e salvalo in <arg></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="116"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="126"/> + <source>Generate new wallet from device and save it to <arg></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="127"/> <source>Generate incoming-only wallet from view key</source> <translation>Genera un portafoglio solo-ricezione da chiave di visualizzazione</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="117"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="128"/> <source>Generate deterministic wallet from spend key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="118"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="129"/> <source>Generate wallet from private keys</source> <translation>Genera portafoglio da chiavi private</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="119"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="130"/> <source>Generate a master wallet from multisig wallet keys</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="121"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="132"/> <source>Language for mnemonic</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="122"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="133"/> <source>Specify Electrum seed for wallet recovery/creation</source> <translation>Specifica il seed stile Electrum per recuperare/creare il portafoglio</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="123"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="134"/> <source>Recover wallet using Electrum-style mnemonic seed</source> <translation>Recupera portafoglio usando il seed mnemonico stile-Electrum</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="124"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="135"/> <source>Recover multisig wallet using Electrum-style mnemonic seed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="125"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="136"/> <source>Generate non-deterministic view and spend keys</source> <translation>Crea chiavi di visualizzione e chiavi di spesa non-deterministiche</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="126"/> - <source>Enable commands which rely on a trusted daemon</source> - <translation>Abilita comandi dipendenti da un daemon fidato</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="361"/> + <source>invalid argument: must be either 0/1, true/false, y/n, yes/no</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="127"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="417"/> + <source>DNSSEC validation passed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="421"/> + <source>WARNING: DNSSEC validation was unsuccessful, this address may not be correct!</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="424"/> + <source>For URL: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="426"/> + <source> Monero Address = </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="428"/> + <source>Is this OK? (Y/n) </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="438"/> + <source>you have cancelled the transfer request</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="459"/> + <source>failed to parse index: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="472"/> + <source>invalid format for subaddress lookahead; must be <major>:<minor></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="489"/> + <source>no connection to daemon. Please make sure daemon is running.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="494"/> + <source>RPC error: </source> + <translation type="unfinished">errore RPC: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="498"/> + <source>failed to get random outputs to mix: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="505"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="513"/> + <source>Not enough money in unlocked balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="523"/> + <source>Failed to find a way to create transactions. This is usually due to dust which is so small it cannot pay for itself in fees, or trying to send more money than the unlocked balance, or not leaving enough for fees</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="529"/> + <source>not enough outputs for specified ring size</source> + <translation type="unfinished">insufficiente numero di output per il ring size specificato</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="532"/> + <source>output amount</source> + <translation type="unfinished">ammontare output</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="532"/> + <source>found outputs to use</source> + <translation type="unfinished">trovati output che possono essere usati</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="534"/> + <source>Please use sweep_unmixable.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="538"/> + <source>transaction was not constructed</source> + <translation type="unfinished">transazione non costruita</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="543"/> + <source>transaction %s was rejected by daemon with status: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="546"/> + <source>Reason: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="555"/> + <source>one of destinations is zero</source> + <translation type="unfinished">una delle destinazioni è zero</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="560"/> + <source>failed to find a suitable way to split transactions</source> + <translation type="unfinished">impossibile trovare un modo per dividere le transazioni</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="566"/> + <source>unknown transfer error: </source> + <translation type="unfinished">errore trasferimento sconosciuto: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="571"/> + <source>Multisig error: </source> + <translation type="unfinished">Errore multisig: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="577"/> + <source>internal error: </source> + <translation type="unfinished">errore interno: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="582"/> + <source>unexpected error: </source> + <translation type="unfinished">errore inaspettato: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="586"/> + <source>There was an error, which could mean the node may be trying to get you to retry creating a transaction, and zero in on which outputs you own. Or it could be a bona fide error. It may be prudent to disconnect from this node, and not try to send a transaction immediately. Alternatively, connect to another node so the original node cannot correlate information.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="596"/> + <source>File %s likely stores wallet private keys! Use a different file name.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="599"/> + <source>File %s already exists. Are you sure to overwrite it? (Y/Yes/N/No): </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7195"/> + <source> seconds</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7197"/> + <source> minutes</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7199"/> + <source> hours</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7201"/> + <source> days</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7203"/> + <source> months</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7204"/> + <source>a long time</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8940"/> + <source>This is the command line monero wallet. It needs to connect to a monero +daemon to work correctly. +WARNING: Do not reuse your Monero keys on another fork, UNLESS this fork has key reuse mitigations built in. Doing so will harm your privacy.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8965"/> + <source>Unknown command: </source> + <translation type="unfinished">Comando sconosciuto: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="137"/> <source>Allow communicating with a daemon that uses a different RPC version</source> <translation>Permetti comunicazioni con un daemon che usa una versione RPC differente</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="128"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="138"/> <source>Restore from specific blockchain height</source> <translation>Ripristina da specifico blocco</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="129"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="139"/> <source>The newly created transaction will not be relayed to the monero network</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="171"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="140"/> + <source>Create an address file for new wallets</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="142"/> + <source>Display English language names</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="276"/> + <source>failed to read wallet password</source> + <translation type="unfinished">impossibile leggere la password del portafoglio</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="283"/> + <source>Enter a new password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="283"/> + <source>Wallet password</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="293"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="485"/> <source>daemon is busy. Please try again later.</source> <translation>il daemon è occupato. Prova più tardi.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="180"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="302"/> <source>possibly lost connection to daemon</source> <translation>possibile perdita di connessione con il daemon</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="197"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="319"/> <source>Error: </source> <translation>Errore: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6787"/> - <source>This is the command line monero wallet. It needs to connect to a monero -daemon to work correctly.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6801"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8959"/> <source>Failed to initialize wallet</source> <translation>Inizializzazione wallet fallita</translation> </message> @@ -3726,299 +5077,359 @@ daemon to work correctly.</source> <context> <name>tools::wallet2</name> <message> - <location filename="../src/wallet/wallet2.cpp" line="113"/> + <location filename="../src/wallet/wallet2.cpp" line="201"/> <source>Use daemon instance at <host>:<port></source> <translation>Usa instanza daemon in <host>:<port></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="114"/> + <location filename="../src/wallet/wallet2.cpp" line="202"/> <source>Use daemon instance at host <arg> instead of localhost</source> <translation>Usa istanza daemon all'host <arg> invece che localhost</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="116"/> + <location filename="../src/wallet/wallet2.cpp" line="206"/> <source>Wallet password file</source> <translation>File password portafoglio</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="117"/> + <location filename="../src/wallet/wallet2.cpp" line="207"/> <source>Use daemon instance at port <arg> instead of 18081</source> <translation>Usa istanza daemon alla porta <arg> invece che alla 18081</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="119"/> + <location filename="../src/wallet/wallet2.cpp" line="209"/> <source>For testnet. Daemon must also be launched with --testnet flag</source> <translation>Per testnet. Il daemon può anche essere lanciato con la flag --testnet</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="120"/> - <source>Restricts to view-only commands</source> - <translation>Restringi a comandi di tipo solo-vista</translation> - </message> - <message> - <location filename="../src/wallet/wallet2.cpp" line="168"/> + <location filename="../src/wallet/wallet2.cpp" line="282"/> <source>can't specify daemon host or port more than once</source> <translation>non puoi specificare la porta o l'host del daemon più di una volta</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="204"/> + <location filename="../src/wallet/wallet2.cpp" line="355"/> <source>can't specify more than one of --password and --password-file</source> <translation>non puoi specificare più di un --password e --password-file</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="217"/> + <location filename="../src/wallet/wallet2.cpp" line="368"/> <source>the password file specified could not be read</source> <translation>il file password specificato non può essere letto</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="240"/> + <location filename="../src/wallet/wallet2.cpp" line="394"/> <source>Failed to load file </source> <translation>Impossibile caricare file </translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="115"/> + <location filename="../src/wallet/wallet2.cpp" line="205"/> <source>Wallet password (escape/quote as needed)</source> <translation>Wallet password (escape/quote se necessario)</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="118"/> + <location filename="../src/wallet/wallet2.cpp" line="203"/> + <source>Enable commands which rely on a trusted daemon</source> + <translation type="unfinished">Abilita comandi dipendenti da un daemon fidato</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="204"/> + <source>Disable commands which rely on a trusted daemon</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="208"/> <source>Specify username[:password] for daemon RPC client</source> <translation>Specificare username[:password] per client del daemon RPC</translation> </message> <message> + <location filename="../src/wallet/wallet2.cpp" line="210"/> + <source>For stagenet. Daemon must also be launched with --stagenet flag</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="212"/> + <source>Set shared ring database path</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="223"/> + <source>Number of rounds for the key derivation function</source> + <translation type="unfinished"></translation> + </message> + <message> <location filename="../src/wallet/wallet2.cpp" line="224"/> + <source>HW device to use</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="225"/> + <source>HW device wallet derivation path (e.g., SLIP-10)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="313"/> + <source>--trusted-daemon and --untrusted-daemon are both seen, assuming untrusted</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="323"/> + <source>Daemon is local, assuming trusted</source> + <translation type="unfinished">Il daemon è locale, viene considerato fidato</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="375"/> <source>no password specified; use --prompt-for-password to prompt for a password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="246"/> + <location filename="../src/wallet/wallet2.cpp" line="377"/> + <source>Enter a new password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="377"/> + <source>Wallet password</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="400"/> <source>Failed to parse JSON</source> <translation>Impossibile fare il parsing di JSON</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="253"/> + <location filename="../src/wallet/wallet2.cpp" line="407"/> <source>Version %u too new, we can only grok up to %u</source> <translation>La versione %u è troppo recente, possiamo comprendere solo fino alla versione %u</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="269"/> + <location filename="../src/wallet/wallet2.cpp" line="423"/> <source>failed to parse view key secret key</source> <translation>impossibile fare il parsing di chiave di visualizzazione chiave segreta</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="274"/> - <location filename="../src/wallet/wallet2.cpp" line="339"/> - <location filename="../src/wallet/wallet2.cpp" line="380"/> + <location filename="../src/wallet/wallet2.cpp" line="428"/> + <location filename="../src/wallet/wallet2.cpp" line="496"/> + <location filename="../src/wallet/wallet2.cpp" line="539"/> <source>failed to verify view key secret key</source> <translation>impossibile verificare chiave di visualizzazione chiave segreta</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="285"/> + <location filename="../src/wallet/wallet2.cpp" line="439"/> <source>failed to parse spend key secret key</source> <translation>impossibile fare il parsing chiave di spesa chiave segreta</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="290"/> - <location filename="../src/wallet/wallet2.cpp" line="349"/> - <location filename="../src/wallet/wallet2.cpp" line="405"/> + <location filename="../src/wallet/wallet2.cpp" line="444"/> + <location filename="../src/wallet/wallet2.cpp" line="506"/> + <location filename="../src/wallet/wallet2.cpp" line="565"/> <source>failed to verify spend key secret key</source> <translation>impossibile verificare chiave di spesa chiave segreta</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="302"/> + <location filename="../src/wallet/wallet2.cpp" line="456"/> <source>Electrum-style word list failed verification</source> <translation>Verifica lista di parole stile-Electrum fallita</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="319"/> - <source>At least one of Electrum-style word list and private view key and private spend key must be specified</source> + <location filename="../src/wallet/wallet2.cpp" line="476"/> + <source>At least one of either an Electrum-style word list, private view key, or private spend key must be specified</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="323"/> + <location filename="../src/wallet/wallet2.cpp" line="480"/> <source>Both Electrum-style word list and private key(s) specified</source> <translation>Specificate entrambe lista parole stile-Electrum e chiave/i privata/e </translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="333"/> + <location filename="../src/wallet/wallet2.cpp" line="490"/> <source>invalid address</source> <translation>indirizzo invalido</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="342"/> + <location filename="../src/wallet/wallet2.cpp" line="499"/> <source>view key does not match standard address</source> <translation>la chiave di visualizzazione non corrisponde all'indirizzo standard</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="352"/> + <location filename="../src/wallet/wallet2.cpp" line="509"/> <source>spend key does not match standard address</source> <translation>la chiave di spesa non corrisponde all'indirizzo standard</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="360"/> + <location filename="../src/wallet/wallet2.cpp" line="517"/> <source>Cannot generate deprecated wallets from JSON</source> <translation>Impossibile creare portafogli disapprovati da JSON</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="392"/> + <location filename="../src/wallet/wallet2.cpp" line="551"/> <source>failed to parse address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="398"/> + <location filename="../src/wallet/wallet2.cpp" line="557"/> <source>Address must be specified in order to create watch-only wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="413"/> + <location filename="../src/wallet/wallet2.cpp" line="574"/> <source>failed to generate new wallet: </source> <translation>impossibile generare nuovo portafoglio: </translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="2813"/> - <location filename="../src/wallet/wallet2.cpp" line="2873"/> - <location filename="../src/wallet/wallet2.cpp" line="2952"/> - <location filename="../src/wallet/wallet2.cpp" line="2998"/> - <location filename="../src/wallet/wallet2.cpp" line="3089"/> - <location filename="../src/wallet/wallet2.cpp" line="3189"/> - <location filename="../src/wallet/wallet2.cpp" line="3599"/> - <location filename="../src/wallet/wallet2.cpp" line="3955"/> + <location filename="../src/wallet/wallet2.cpp" line="1382"/> + <source>Password is needed to compute key image for incoming monero</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="1383"/> + <source>Invalid password: password is needed to compute key image for incoming monero</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="3770"/> + <location filename="../src/wallet/wallet2.cpp" line="4374"/> + <location filename="../src/wallet/wallet2.cpp" line="4926"/> <source>Primary account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="7914"/> + <location filename="../src/wallet/wallet2.cpp" line="10157"/> <source>No funds received in this tx.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="8607"/> + <location filename="../src/wallet/wallet2.cpp" line="10899"/> <source>failed to read file </source> <translation>lettura file fallita</translation> </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="141"/> + <source>Set subaddress lookahead sizes to <major>:<minor></source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>tools::wallet_rpc_server</name> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="160"/> - <source>Daemon is local, assuming trusted</source> - <translation>Il daemon è locale, viene considerato fidato</translation> - </message> - <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="175"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="180"/> <source>Failed to create directory </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="177"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="182"/> <source>Failed to create directory %s: %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="188"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="193"/> <source>Cannot specify --</source> <translation>Impossibile specificare --</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="188"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="193"/> <source> and --</source> <translation> e --</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="207"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="212"/> <source>Failed to create file </source> <translation>Impossibile creare file </translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="207"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="212"/> <source>. Check permissions or remove file</source> <translation>. Controlla permessi o rimuovi il file</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="217"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="222"/> <source>Error writing to file </source> <translation>Errore durante scrittura su file </translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="220"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="225"/> <source>RPC username/password is stored in file </source> <translation>Username/password RPC conservato nel file </translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="443"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="479"/> <source>Tag %s is unregistered.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2435"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3081"/> <source>Transaction not possible. Available only %s, transaction amount %s = %s + %s (fee)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2870"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3947"/> <source>This is the RPC monero wallet. It needs to connect to a monero daemon to work correctly.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2893"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3788"/> <source>Can't specify more than one of --wallet-file and --generate-from-json</source> <translation>Non puoi specificare più di un --wallet-file e --generate-from-json</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2905"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3773"/> + <source>Can't specify more than one of --testnet and --stagenet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3800"/> <source>Must specify --wallet-file or --generate-from-json or --wallet-dir</source> <translation>Devi specificare --wallet-file o --generate-from-json o --wallet-dir</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2909"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3804"/> <source>Loading wallet...</source> <translation>Sto caricando il portafoglio...</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2942"/> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2975"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3838"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3870"/> <source>Saving wallet...</source> <translation>Sto salvando il portafoglio...</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2944"/> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2977"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3840"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3872"/> <source>Successfully saved</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2947"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3843"/> <source>Successfully loaded</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2951"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3847"/> <source>Wallet initialization failed: </source> <translation>Inizializzazione portafoglio fallita: </translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2958"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3853"/> <source>Failed to initialize wallet RPC server</source> <translation>Inizializzazione server RPC portafoglio fallita</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2962"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3857"/> <source>Starting wallet RPC server</source> <translation>Server RPC portafoglio in avvio</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2969"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3864"/> <source>Failed to run wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2972"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3867"/> <source>Stopped wallet RPC server</source> <translation>Server RPC portafoglio arrestato</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2981"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3876"/> <source>Failed to save wallet: </source> <translation>Impossibile salvare portafoglio: </translation> </message> @@ -4026,9 +5437,9 @@ daemon to work correctly.</source> <context> <name>wallet_args</name> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="166"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6760"/> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2856"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="168"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8908"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3928"/> <source>Wallet options</source> <translation>Opzioni portafoglio</translation> </message> @@ -4043,48 +5454,58 @@ daemon to work correctly.</source> <translation>Usa portafoglio <arg></translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="104"/> + <location filename="../src/wallet/wallet_args.cpp" line="105"/> <source>Max number of threads to use for a parallel job</source> <translation>Numero massimo di threads da utilizzare per un lavoro parallelo</translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="105"/> + <location filename="../src/wallet/wallet_args.cpp" line="106"/> <source>Specify log file</source> <translation>Specificare file di log</translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="106"/> + <location filename="../src/wallet/wallet_args.cpp" line="107"/> <source>Config file</source> <translation>File configurazione</translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="115"/> + <location filename="../src/wallet/wallet_args.cpp" line="119"/> <source>General options</source> <translation>Opzioni generali</translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="138"/> + <location filename="../src/wallet/wallet_args.cpp" line="144"/> <source>This is the command line monero wallet. It needs to connect to a monero daemon to work correctly.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="161"/> + <location filename="../src/wallet/wallet_args.cpp" line="169"/> <source>Can't find config file </source> <translation>Impossibile trovare file configurazione </translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="195"/> + <location filename="../src/wallet/wallet_args.cpp" line="210"/> <source>Logging to: </source> <translation>Sto salvando il Log in: </translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="197"/> + <location filename="../src/wallet/wallet_args.cpp" line="212"/> <source>Logging to %s</source> <translation>Sto salvando il Log in %s</translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="140"/> + <location filename="../src/wallet/wallet_args.cpp" line="216"/> + <source>WARNING: You may not have a high enough lockable memory limit</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="218"/> + <source>see ulimit -l</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="146"/> <source>Usage:</source> <translation>Uso:</translation> </message> diff --git a/translations/monero_ja.ts b/translations/monero_ja.ts index 7305b42f8..617186da3 100644 --- a/translations/monero_ja.ts +++ b/translations/monero_ja.ts @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> -<TS version="2.1" language="ja" sourcelanguage="en"> +<TS version="2.0" language="ja" sourcelanguage="en"> <context> <name>Monero::AddressBookImpl</name> <message> @@ -27,45 +27,55 @@ <context> <name>Monero::PendingTransactionImpl</name> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="90"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="91"/> <source>Attempting to save transaction to file, but specified file(s) exist. Exiting to not risk overwriting. File:</source> <translation>ファイルは既に存在するのでファイルに取引を書き出せなかった。上書きしないにエグジットしてます。ファイル:</translation> </message> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="97"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="98"/> <source>Failed to write transaction(s) to file</source> <translation>取引をファイルに書き込めませんでした</translation> </message> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="115"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="121"/> <source>daemon is busy. Please try again later.</source> <translation>デーモンは忙しいです。後でもう一度試してください。</translation> </message> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="118"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="124"/> <source>no connection to daemon. Please make sure daemon is running.</source> <translation>デーモンの接続が確立ありません。デーモンが実行中になっていることを確認してください。</translation> </message> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="122"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="128"/> <source>transaction %s was rejected by daemon with status: </source> <translation>取引 %s がデーモンによって拒否しました。ステータス: </translation> </message> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="127"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="133"/> <source>. Reason: </source> <translation>。 理由: </translation> </message> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="129"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="135"/> <source>Unknown exception: </source> <translation>未知の例外: </translation> </message> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="132"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="138"/> <source>Unhandled exception</source> <translation>未処理の例外</translation> </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="211"/> + <source>Couldn't multisig sign data: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="233"/> + <source>Couldn't sign multisig transaction: </source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Monero::UnsignedTransactionImpl</name> @@ -124,281 +134,407 @@ <context> <name>Monero::WalletImpl</name> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1111"/> + <location filename="../src/wallet/api/wallet.cpp" line="1383"/> <source>payment id has invalid format, expected 16 or 64 character hex string: </source> <translation>ペイメントIDのフォーマットは不正です。16文字または64文字の16進数の文字列が必要で: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1121"/> + <location filename="../src/wallet/api/wallet.cpp" line="1392"/> <source>Failed to add short payment id: </source> <translation>短いペイメントIDの追加に失敗しました: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1154"/> - <location filename="../src/wallet/api/wallet.cpp" line="1258"/> + <location filename="../src/wallet/api/wallet.cpp" line="1428"/> + <location filename="../src/wallet/api/wallet.cpp" line="1510"/> <source>daemon is busy. Please try again later.</source> <translation>デーモンは忙しいです。後でもう一度試してください。</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1157"/> - <location filename="../src/wallet/api/wallet.cpp" line="1261"/> + <location filename="../src/wallet/api/wallet.cpp" line="1430"/> + <location filename="../src/wallet/api/wallet.cpp" line="1512"/> <source>no connection to daemon. Please make sure daemon is running.</source> <translation>デーモンの接続が確立ありません。デーモンが実行中になっていることを確認してください。</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1160"/> - <location filename="../src/wallet/api/wallet.cpp" line="1264"/> + <location filename="../src/wallet/api/wallet.cpp" line="1432"/> + <location filename="../src/wallet/api/wallet.cpp" line="1514"/> <source>RPC error: </source> <translation>RPCエラー: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1197"/> - <location filename="../src/wallet/api/wallet.cpp" line="1301"/> + <location filename="../src/wallet/api/wallet.cpp" line="1460"/> + <location filename="../src/wallet/api/wallet.cpp" line="1545"/> <source>not enough outputs for specified ring size</source> <translation>指定したリングサイズのアウトプットが不十分です</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1199"/> - <location filename="../src/wallet/api/wallet.cpp" line="1303"/> + <location filename="../src/wallet/api/wallet.cpp" line="1462"/> + <location filename="../src/wallet/api/wallet.cpp" line="1547"/> <source>found outputs to use</source> <translation>使うためにアウトプットを見つかれました</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1201"/> + <location filename="../src/wallet/api/wallet.cpp" line="1464"/> <source>Please sweep unmixable outputs.</source> <translation>ミックス不能なアウトプットをスイープしてください。</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1267"/> - <source>failed to get random outputs to mix</source> - <translation>ランダムなアウトプットをミックスすることに失敗しました</translation> - </message> - <message> - <location filename="../src/wallet/api/wallet.cpp" line="1170"/> - <location filename="../src/wallet/api/wallet.cpp" line="1274"/> + <location filename="../src/wallet/api/wallet.cpp" line="1438"/> + <location filename="../src/wallet/api/wallet.cpp" line="1521"/> <source>not enough money to transfer, available only %s, sent amount %s</source> <translation>振替でMoneroを受け取ることできません。利用可能な金額: %s, 取引の金額: %s</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="474"/> + <location filename="../src/wallet/api/wallet.cpp" line="541"/> <source>failed to parse address</source> <translation>アドレスの解析に失敗しました</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="486"/> + <location filename="../src/wallet/api/wallet.cpp" line="552"/> <source>failed to parse secret spend key</source> <translation>秘密なスペンドキーの解析に失敗しました</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="496"/> - <source>No view key supplied, cancelled</source> - <translation>ビューキーをもらいませんでしたのでキャンセルしました</translation> - </message> - <message> - <location filename="../src/wallet/api/wallet.cpp" line="503"/> + <location filename="../src/wallet/api/wallet.cpp" line="575"/> <source>failed to parse secret view key</source> <translation>秘密なビューキーの解析に失敗しました</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="513"/> + <location filename="../src/wallet/api/wallet.cpp" line="584"/> <source>failed to verify secret spend key</source> <translation>秘密なスペンドキーの検証に失敗しました</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="518"/> + <location filename="../src/wallet/api/wallet.cpp" line="588"/> <source>spend key does not match address</source> <translation>スペンドキーがアドレスと一致しませんでした</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="524"/> + <location filename="../src/wallet/api/wallet.cpp" line="594"/> <source>failed to verify secret view key</source> <translation>秘密なビューキーの検証に失敗しました</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="529"/> + <location filename="../src/wallet/api/wallet.cpp" line="598"/> <source>view key does not match address</source> <translation>ビューキーがアドレスと一致しませんでした</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="548"/> + <location filename="../src/wallet/api/wallet.cpp" line="621"/> + <location filename="../src/wallet/api/wallet.cpp" line="638"/> <source>failed to generate new wallet: </source> <translation>新しいウォレットの生成に失敗しました: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="773"/> + <location filename="../src/wallet/api/wallet.cpp" line="885"/> <source>Failed to send import wallet request</source> <translation>インポートウォレットリクエストの送信に失敗しました</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="919"/> + <location filename="../src/wallet/api/wallet.cpp" line="1049"/> <source>Failed to load unsigned transactions</source> <translation>未署名の取引を読み込めませんでした</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="940"/> + <location filename="../src/wallet/api/wallet.cpp" line="1068"/> <source>Failed to load transaction from file</source> <translation>ファイルからの取引のロードに失敗しました</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="958"/> + <location filename="../src/wallet/api/wallet.cpp" line="1084"/> <source>Wallet is view only</source> <translation>閲覧専用ウォレットです</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="967"/> + <location filename="../src/wallet/api/wallet.cpp" line="1092"/> <source>failed to save file </source> <translation>ファイルを保存できませんでした </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="986"/> + <location filename="../src/wallet/api/wallet.cpp" line="1108"/> <source>Key images can only be imported with a trusted daemon</source> <translation>信頼できるデーモンしかでキーイメージをインポートしません</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="999"/> + <location filename="../src/wallet/api/wallet.cpp" line="1121"/> <source>Failed to import key images: </source> <translation>キーイメージをインポートできませんでした: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1032"/> + <location filename="../src/wallet/api/wallet.cpp" line="1153"/> <source>Failed to get subaddress label: </source> <translation>サブアドレスラベルを取得できませんでした: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1046"/> + <location filename="../src/wallet/api/wallet.cpp" line="1166"/> <source>Failed to set subaddress label: </source> <translation>サブアドレスラベルをセットできませんでした: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1163"/> - <source>failed to get random outputs to mix: %s</source> - <translation>ランダムなアウトプットをミックスすることに失敗しました: %s</translation> + <location filename="../src/wallet/api/wallet.cpp" line="567"/> + <source>Neither view key nor spend key supplied, cancelled</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1179"/> - <location filename="../src/wallet/api/wallet.cpp" line="1283"/> + <location filename="../src/wallet/api/wallet.cpp" line="686"/> + <source>Electrum seed is empty</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="695"/> + <source>Electrum-style word list failed verification</source> + <translation type="unfinished">Electrumな単語表の検証に失敗しました</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1183"/> + <source>Failed to get multisig info: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1200"/> + <location filename="../src/wallet/api/wallet.cpp" line="1214"/> + <source>Failed to make multisig: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1229"/> + <source>Failed to finalize multisig wallet creation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1232"/> + <source>Failed to finalize multisig wallet creation: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1248"/> + <source>Failed to export multisig images: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1266"/> + <source>Failed to parse imported multisig images</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1276"/> + <source>Failed to import multisig images: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1290"/> + <source>Failed to check for partial multisig key images: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1318"/> + <source>Failed to restore multisig transaction: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1358"/> + <source>Invalid destination address</source> + <translation type="unfinished">不正な宛先アドレス</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1434"/> + <source>failed to get outputs to mix: %s</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1445"/> + <location filename="../src/wallet/api/wallet.cpp" line="1529"/> <source>not enough money to transfer, overall balance only %s, sent amount %s</source> <translation>振替でMoneroを受け取ることできません。利用可能な金額: %s, 取引の金額: %s</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1188"/> - <location filename="../src/wallet/api/wallet.cpp" line="1292"/> + <location filename="../src/wallet/api/wallet.cpp" line="1452"/> + <location filename="../src/wallet/api/wallet.cpp" line="1537"/> <source>not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)</source> <translation>取引は無理です。利用可能な金額 %s、 取引の金額 %s = %s + %s (手数料)</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1199"/> - <location filename="../src/wallet/api/wallet.cpp" line="1303"/> + <location filename="../src/wallet/api/wallet.cpp" line="1462"/> + <location filename="../src/wallet/api/wallet.cpp" line="1547"/> <source>output amount</source> <translation>アウトプットの金額</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1205"/> - <location filename="../src/wallet/api/wallet.cpp" line="1308"/> + <location filename="../src/wallet/api/wallet.cpp" line="1467"/> + <location filename="../src/wallet/api/wallet.cpp" line="1551"/> <source>transaction was not constructed</source> <translation>取引を作りませんでした</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1209"/> - <location filename="../src/wallet/api/wallet.cpp" line="1312"/> + <location filename="../src/wallet/api/wallet.cpp" line="1470"/> + <location filename="../src/wallet/api/wallet.cpp" line="1554"/> <source>transaction %s was rejected by daemon with status: </source> <translation>取引 %s がデーモンによって拒否しました。ステータス: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1216"/> - <location filename="../src/wallet/api/wallet.cpp" line="1319"/> + <location filename="../src/wallet/api/wallet.cpp" line="1475"/> + <location filename="../src/wallet/api/wallet.cpp" line="1559"/> <source>one of destinations is zero</source> <translation>宛先の1つはゼロです</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1219"/> - <location filename="../src/wallet/api/wallet.cpp" line="1322"/> + <location filename="../src/wallet/api/wallet.cpp" line="1477"/> + <location filename="../src/wallet/api/wallet.cpp" line="1561"/> <source>failed to find a suitable way to split transactions</source> <translation>取引を分割する適切な方法を見つけることができませんでした</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1222"/> - <location filename="../src/wallet/api/wallet.cpp" line="1325"/> + <location filename="../src/wallet/api/wallet.cpp" line="1479"/> + <location filename="../src/wallet/api/wallet.cpp" line="1563"/> <source>unknown transfer error: </source> <translation>不明な転送エラー: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1225"/> - <location filename="../src/wallet/api/wallet.cpp" line="1328"/> + <location filename="../src/wallet/api/wallet.cpp" line="1481"/> + <location filename="../src/wallet/api/wallet.cpp" line="1565"/> <source>internal error: </source> <translation>内部エラー: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1228"/> - <location filename="../src/wallet/api/wallet.cpp" line="1331"/> + <location filename="../src/wallet/api/wallet.cpp" line="1483"/> + <location filename="../src/wallet/api/wallet.cpp" line="1567"/> <source>unexpected error: </source> <translation>予期せぬエラー: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1231"/> - <location filename="../src/wallet/api/wallet.cpp" line="1334"/> + <location filename="../src/wallet/api/wallet.cpp" line="1485"/> + <location filename="../src/wallet/api/wallet.cpp" line="1569"/> <source>unknown error</source> <translation>不明なエラー</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1412"/> - <location filename="../src/wallet/api/wallet.cpp" line="1441"/> - <location filename="../src/wallet/api/wallet.cpp" line="1494"/> - <location filename="../src/wallet/api/wallet.cpp" line="1525"/> - <location filename="../src/wallet/api/wallet.cpp" line="1556"/> - <location filename="../src/wallet/api/wallet.cpp" line="1579"/> + <location filename="../src/wallet/api/wallet.cpp" line="1516"/> + <source>failed to get outputs to mix</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1644"/> + <location filename="../src/wallet/api/wallet.cpp" line="1671"/> + <location filename="../src/wallet/api/wallet.cpp" line="1719"/> + <location filename="../src/wallet/api/wallet.cpp" line="1747"/> + <location filename="../src/wallet/api/wallet.cpp" line="1775"/> + <location filename="../src/wallet/api/wallet.cpp" line="1796"/> + <location filename="../src/wallet/api/wallet.cpp" line="2258"/> <source>Failed to parse txid</source> <translation>txidの解析に失敗しました</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1430"/> + <location filename="../src/wallet/api/wallet.cpp" line="1661"/> <source>no tx keys found for this txid</source> <translation>このtxidのためにtxキーを見つかれませんでした</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1450"/> - <location filename="../src/wallet/api/wallet.cpp" line="1460"/> + <location filename="../src/wallet/api/wallet.cpp" line="1679"/> + <location filename="../src/wallet/api/wallet.cpp" line="1688"/> <source>Failed to parse tx key</source> <translation>txキーの解析に失敗しました</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1470"/> - <location filename="../src/wallet/api/wallet.cpp" line="1502"/> - <location filename="../src/wallet/api/wallet.cpp" line="1533"/> - <location filename="../src/wallet/api/wallet.cpp" line="1621"/> + <location filename="../src/wallet/api/wallet.cpp" line="1697"/> + <location filename="../src/wallet/api/wallet.cpp" line="1726"/> + <location filename="../src/wallet/api/wallet.cpp" line="1754"/> + <location filename="../src/wallet/api/wallet.cpp" line="1835"/> <source>Failed to parse address</source> <translation>アドレスの解析に失敗しました</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1627"/> + <location filename="../src/wallet/api/wallet.cpp" line="1840"/> <source>Address must not be a subaddress</source> <translation>アドレスはサブアドレスであってはならないです</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1849"/> + <location filename="../src/wallet/api/wallet.cpp" line="1880"/> + <source>The wallet must be in multisig ready state</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1902"/> + <source>Given string is not a key</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2130"/> <source>Rescan spent can only be used with a trusted daemon</source> <translation>信頼できるデーモンしかで再スキャンしません</translation> </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2179"/> + <source>Invalid output: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2186"/> + <source>Failed to mark outputs as spent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2197"/> + <location filename="../src/wallet/api/wallet.cpp" line="2219"/> + <source>Failed to parse output amount</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2202"/> + <location filename="../src/wallet/api/wallet.cpp" line="2224"/> + <source>Failed to parse output offset</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2208"/> + <source>Failed to mark output as spent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2230"/> + <source>Failed to mark output as unspent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2241"/> + <location filename="../src/wallet/api/wallet.cpp" line="2280"/> + <source>Failed to parse key image</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2247"/> + <source>Failed to get ring</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2265"/> + <source>Failed to get rings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2286"/> + <source>Failed to set ring</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Wallet</name> <message> - <location filename="../src/wallet/api/wallet.cpp" line="246"/> + <location filename="../src/wallet/api/wallet.cpp" line="301"/> <source>Failed to parse address</source> <translation>アドレスの解析に失敗しました</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="253"/> + <location filename="../src/wallet/api/wallet.cpp" line="308"/> <source>Failed to parse key</source> <translation>キーの解析に失敗しました</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="261"/> + <location filename="../src/wallet/api/wallet.cpp" line="316"/> <source>failed to verify key</source> <translation>キーの検証に失敗しました</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="271"/> + <location filename="../src/wallet/api/wallet.cpp" line="326"/> <source>key does not match address</source> <translation>キーがアドレスと一致しませんでした</translation> </message> @@ -406,12 +542,12 @@ <context> <name>command_line</name> <message> - <location filename="../src/common/command_line.cpp" line="57"/> + <location filename="../src/common/command_line.cpp" line="54"/> <source>yes</source> <translation>はい</translation> </message> <message> - <location filename="../src/common/command_line.cpp" line="71"/> + <location filename="../src/common/command_line.cpp" line="68"/> <source>no</source> <translation>いいえ</translation> </message> @@ -449,18 +585,18 @@ <translation> は暗号化されていない外部接続をできますがSSHトンネルやSSLプロキシの方がいいです。これでオーバーライド --</translation> </message> <message> - <location filename="../src/rpc/rpc_args.cpp" line="95"/> + <location filename="../src/rpc/rpc_args.cpp" line="101"/> <source>Username specified with --</source> <translation>このRPCサーバのユーザー名につて --</translation> </message> <message> - <location filename="../src/rpc/rpc_args.cpp" line="95"/> - <location filename="../src/rpc/rpc_args.cpp" line="105"/> + <location filename="../src/rpc/rpc_args.cpp" line="101"/> + <location filename="../src/rpc/rpc_args.cpp" line="111"/> <source> cannot be empty</source> <translation> 入力する必要があります</translation> </message> <message> - <location filename="../src/rpc/rpc_args.cpp" line="105"/> + <location filename="../src/rpc/rpc_args.cpp" line="111"/> <source> requires RPC server password --</source> <translation> のRPCサーバのパスワードありません --</translation> </message> @@ -468,3057 +604,3908 @@ <context> <name>cryptonote::simple_wallet</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="479"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="645"/> <source>Commands: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3008"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4359"/> <source>failed to read wallet password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2699"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3954"/> <source>invalid password</source> <translation>不正なパスワード</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1905"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3073"/> <source>set seed: needs an argument. available options: language</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1933"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3108"/> <source>set: unrecognized argument(s)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2869"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4199"/> <source>wallet file path not valid: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1987"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3178"/> <source>Attempting to generate or restore wallet, but specified file(s) exist. Exiting to not risk overwriting.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="662"/> - <source>usage: payment_id</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1891"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3059"/> <source>needs an argument</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1914"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1915"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1916"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1918"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1921"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1922"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1926"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1927"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1929"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1931"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3082"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3083"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3084"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3086"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3089"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3094"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3095"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3097"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3099"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3100"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3101"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3104"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3105"/> <source>0 or 1</source> <translation>0や1</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1920"/> - <source>0, 1, 2, 3, or 4</source> - <translation>0、1、2、3、や 4</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1924"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1928"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3092"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3096"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3103"/> <source>unsigned integer</source> <translation>符号無しの整数</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2041"/> - <source>NOTE: the following 25 words can be used to recover access to your wallet. Write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control. -</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2092"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3312"/> <source>--restore-deterministic-wallet uses --generate-new-wallet, not --wallet-file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2121"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3341"/> <source>specify a recovery parameter with the --electrum-seed="words list here"</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2471"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3717"/> <source>specify a wallet path with --generate-new-wallet (not --wallet-file)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2635"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3887"/> <source>wallet failed to connect to daemon: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2643"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3895"/> <source>Daemon uses a different RPC major version (%u) than the wallet (%u): %s. Either update one of them, or use --allow-mismatched-daemon-version.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2662"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3916"/> <source>List of available languages for your wallet's seed:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2671"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3926"/> <source>Enter the number corresponding to the language of your choice: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2737"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4000"/> <source>You had been using a deprecated version of the wallet. Please use the new seed that we provide. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2751"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2809"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4016"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4088"/> <source>Generated new wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2757"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2814"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2858"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4025"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4093"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4135"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4188"/> <source>failed to generate new wallet: </source> <translation>新しいウォレットの生成に失敗しました: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2887"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4230"/> <source>Opened watch-only wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2891"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4234"/> <source>Opened wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2901"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4252"/> <source>You had been using a deprecated version of the wallet. Please proceed to upgrade your wallet. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2916"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4267"/> <source>You had been using a deprecated version of the wallet. Your wallet file format is being upgraded now. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2924"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4275"/> <source>failed to load wallet: </source> <translation>ウォレットをロードできませんでした: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2941"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4292"/> <source>Use the "help" command to see the list of available commands. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2986"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4337"/> <source>Wallet data saved</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3072"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4431"/> <source>Mining started in daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3074"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4433"/> <source>mining has NOT been started: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3093"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4453"/> <source>Mining stopped in daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3095"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4455"/> <source>mining has NOT been stopped: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3150"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4537"/> <source>Blockchain saved</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3165"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3183"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3196"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4552"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4589"/> <source>Height </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3197"/> - <source>transaction </source> - <translation>取引 </translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3185"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4591"/> <source>spent </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3198"/> - <source>unsupported transaction format</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3219"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4698"/> <source>Starting refresh...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3232"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4712"/> <source>Refresh done, blocks received: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3758"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4230"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5958"/> <source>payment id has invalid format, expected 16 or 64 character hex string: </source> - <translation type="unfinished"></translation> + <translation type="unfinished">ペイメントIDのフォーマットは不正です。16文字または64文字の16進数の文字列が必要で: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3773"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5307"/> <source>bad locked_blocks parameter:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3801"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4248"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4462"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5978"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6251"/> <source>a single transaction cannot use more than one payment id: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3810"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4257"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4430"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4470"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5405"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5987"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6219"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6259"/> <source>failed to set up payment id, though it was decoded correctly</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3835"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3916"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3987"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4096"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4271"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4329"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4484"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4527"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5251"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5870"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6173"/> + <source>ring size %u is too large, maximum is %u</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5276"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5395"/> + <source>Unencrypted payment IDs are bad for privacy: ask the recipient to use subaddresses instead</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5293"/> + <source>payment id failed to encode</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5312"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5894"/> + <source>Locked blocks too high, max 1000000 (Ë4 yrs)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5340"/> + <source>failed to parse short payment ID from URI</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5363"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5365"/> + <source>Invalid last argument: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5382"/> + <source>a single transaction cannot use more than one payment id</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5399"/> + <source>failed to parse payment id, though it was detected</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5422"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5502"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5590"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5738"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6001"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6059"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6273"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6318"/> <source>transaction cancelled.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3895"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3905"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5481"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5491"/> <source>Is this okay anyway? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3900"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5486"/> <source>There is currently a %u block backlog at that fee level. Is this okay? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3905"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5491"/> <source>Failed to check for backlog: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3946"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4302"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5532"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6032"/> <source> Transaction </source> <translation> 取引 </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3951"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4307"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5537"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6037"/> <source>Spending from address index %d </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3953"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4309"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5539"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6039"/> <source>WARNING: Outputs of multiple addresses are being used together, which might potentially compromise your privacy. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3955"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5541"/> <source>Sending %s. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3958"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5544"/> <source>Your transaction needs to be split into %llu transactions. This will result in a transaction fee being applied to each transaction, for a total fee of %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3964"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5550"/> <source>The transaction fee is %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3967"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5553"/> <source>, of which %s is dust from change</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3968"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5554"/> <source>.</source> <translation>。</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3968"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5554"/> <source>A total of %s from dust change will be sent to dust address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3973"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5559"/> <source>. This transaction will unlock on block %llu, in approximately %s days (assuming 2 minutes per block)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3999"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4011"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4107"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4119"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4340"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4352"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4537"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4549"/> - <source>Failed to write transaction(s) to file</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="5603"/> + <source>Unsigned transaction(s) successfully written to MMS</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4003"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4015"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4111"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4123"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4344"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4356"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4541"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5611"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5648"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5749"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5761"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6070"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6107"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6328"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6340"/> + <source>Failed to write transaction(s) to file</source> + <translation type="unfinished">取引をファイルに書き込めませんでした</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5616"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5653"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5753"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5765"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6074"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6111"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6332"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6344"/> <source>Unsigned transaction(s) successfully written to file: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4066"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5625"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6086"/> + <source>Failed to cold sign transaction with HW wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5708"/> <source>No unmixable outputs found</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4149"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5775"/> + <source>Not enough money in unlocked balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5776"/> + <source>Discarding %s of unmixable outputs that cannot be spent, which can be undone by "rescan_spent". Is this okay? (Y/Yes/N/No): </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5815"/> <source>No address given</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4424"/> - <source>failed to parse Payment ID</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="5879"/> + <source>missing lockedblocks parameter</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5889"/> + <source>bad locked_blocks parameter</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5914"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6182"/> + <source>Failed to parse number of outputs</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4440"/> - <source>usage: sweep_single [<priority>] [<ring_size>] <key_image> <address> [<payment_id>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="5919"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6187"/> + <source>Amount of outputs should be greater than 0</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6213"/> + <source>failed to parse Payment ID</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4447"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6236"/> <source>failed to parse key image</source> <translation>キーイメージの解析に失敗しました</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4499"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6290"/> <source>No outputs found</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4504"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6295"/> <source>Multiple transactions are created, which is not supposed to happen</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4509"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6300"/> <source>The transaction uses multiple or no inputs, which is not supposed to happen</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4586"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6377"/> <source>missing threshold amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4591"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6382"/> <source>invalid amount threshold</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4601"/> - <source>donations are not enabled on the testnet</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4608"/> - <source>usage: donate [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <amount> [<payment_id>]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4702"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6516"/> <source>Claimed change does not go to a paid address</source> - <translation type="unfinished"></translation> + <translation type="unfinished">請求したお釣りはもうお金に送ったアドレス送りません</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4707"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6521"/> <source>Claimed change is larger than payment to the change address</source> - <translation type="unfinished"></translation> + <translation type="unfinished">請求したお釣りはお釣りのアドレスに送ったペイメントより大きいです</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4738"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6552"/> <source>sending %s to %s</source> <translation>%s を %s に送ってます</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4748"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6562"/> <source> dummy output(s)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4751"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6565"/> <source>with no destinations</source> <translation>目的地なし</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4763"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6577"/> <source>Loaded %lu transactions, for %s, fee %s, %s, %s, with min ring size %lu, %s. %sIs this okay? (Y/Yes/N/No): </source> - <translation>取引は %lu ロードした、 %s に、%s のの手数料、 %s 、 %s 、最小リングサイズ %lu 、%s。これは大丈夫ですか? はい (Y) いいえ (N): </translation> + <translation>取引は %lu ロードした、 %s に、%s のの手数料、 %s 、 %s 、最小リングサイズ %lu 、%s。これは大丈夫ですか? はい (Y) いいえ (N): </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4787"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6606"/> <source>This is a multisig wallet, it can only sign with sign_multisig</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4797"/> - <source>usage: sign_transfer [export]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4809"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6629"/> <source>Failed to sign transaction</source> <translation>取引を署名できませんでした</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4815"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6635"/> <source>Failed to sign transaction: </source> <translation>取引を署名できませんでした: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4836"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6656"/> <source>Transaction raw hex data exported to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4852"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6677"/> <source>Failed to load transaction from file</source> <translation>ファイルからの取引のロードに失敗しました</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3248"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3551"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4729"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5051"/> <source>RPC error: </source> <translation>RPCエラー: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="522"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="695"/> <source>wallet is watch-only and has no spend key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="636"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="780"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="848"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="839"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1021"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1074"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1141"/> <source>Your original password was incorrect.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="650"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="854"/> <source>Error with wallet rewrite: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1289"/> - <source>priority must be 0, 1, 2, 3, or 4 </source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1301"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1316"/> - <source>priority must be 0, 1, 2, 3, or 4</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1404"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2284"/> <source>invalid unit</source> <translation>不正なユニット</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1422"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1484"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2302"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2364"/> <source>invalid count: must be an unsigned integer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1440"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2320"/> <source>invalid value</source> <translation>不正な金額</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1942"/> - <source>usage: set_log <log_level_number_0-4> | <categories></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2013"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3204"/> <source>(Y/Yes/N/No): </source> - <translation>(はい (Y) いいえ (N)): </translation> + <translation>(はい (Y) いいえ (N)): </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2509"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2536"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3761"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3788"/> <source>bad m_restore_height parameter: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2514"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3766"/> <source>date format must be YYYY-MM-DD</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2527"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3779"/> <source>Restore height is: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2528"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3980"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3705"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3780"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5583"/> <source>Is this okay? (Y/Yes/N/No): </source> - <translation>これは大丈夫ですか? (はい (Y) いいえ (N)): </translation> + <translation>これは大丈夫ですか? (はい (Y) いいえ (N)): </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2575"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4509"/> <source>Daemon is local, assuming trusted</source> <translation>デーモンはローカルです。信頼できるデーモン予期してます</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3004"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4355"/> <source>Password for new watch-only wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3063"/> - <source>invalid arguments. Please use start_mining [<number_of_threads>] [do_bg_mining] [ignore_battery], <number_of_threads> should be from 1 to </source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3258"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4739"/> <source>internal error: </source> <translation>内部エラー: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1185"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3263"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3556"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1608"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4744"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5056"/> <source>unexpected error: </source> <translation>予期せぬエラー: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1119"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1190"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3268"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3561"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4030"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4138"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4371"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4570"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4865"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1534"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1613"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4749"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5061"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5639"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5669"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5794"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6099"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6126"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6361"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6690"/> <source>unknown error</source> <translation>不明なエラー</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3273"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4754"/> <source>refresh failed: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3273"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4754"/> <source>Blocks received: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3304"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4787"/> <source>unlocked balance: </source> <translation>ロック解除された残高: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1925"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3093"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> <source>amount</source> <translation>金額</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="219"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="341"/> <source>false</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="493"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="659"/> <source>Unknown command: </source> <translation>未知のコマンド: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="500"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="666"/> <source>Command usage: </source> <translation>コマンドの使用: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="503"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="669"/> <source>Command description: </source> <translation>コマンドの記述: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="551"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="735"/> <source>wallet is multisig but not yet finalized</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="567"/> - <source>Enter optional seed encryption passphrase, empty to see raw seed</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="584"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="768"/> <source>Failed to retrieve seed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="603"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="792"/> <source>wallet is multisig and has no seed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="674"/> - <source>Cannot connect to daemon</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="679"/> - <source>Current fee is %s monero per kB</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="695"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="899"/> <source>Error: failed to estimate backlog array size: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="700"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="904"/> <source>Error: bad estimated backlog array size</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="712"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="916"/> <source> (current)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="715"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="919"/> <source>%u block (%u minutes) backlog at priority %u%s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="717"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="921"/> <source>%u to %u block (%u to %u minutes) backlog at priority %u</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="720"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="924"/> <source>No backlog at priority </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="729"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="762"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="944"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="989"/> <source>This wallet is already multisig</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="734"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="767"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="949"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="994"/> <source>wallet is watch-only and cannot be made multisig</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="740"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="773"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="955"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1000"/> <source>This wallet has been used before, please use a new wallet to create a multisig wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="747"/> - <source>Your password is incorrect.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="753"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="963"/> <source>Send this multisig info to all other participants, then use make_multisig <threshold> <info1> [<info2>...] with others' multisig info</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="754"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="964"/> <source>This includes the PRIVATE view key, so needs to be disclosed only to that multisig wallet's participants </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="786"/> - <source>usage: make_multisig <threshold> <multisiginfo1> [<multisiginfo2>...]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="794"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1014"/> <source>Invalid threshold</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="807"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1034"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1156"/> <source>Another step is needed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="809"/> - <source>Send this multisig info to all other participants, then use finalize_multisig <info1> [<info2>...] with others' multisig info</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="815"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1046"/> <source>Error creating multisig: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="822"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1053"/> <source>Error creating multisig: new wallet is not multisig</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="825"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1056"/> <source> multisig address: </source> <translation> マルチサインアドレス: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="836"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="880"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="927"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1080"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1129"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1195"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1261"/> <source>This wallet is not multisig</source> <translation>これはマルチシッグウォレットではありません</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="841"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1085"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1134"/> <source>This wallet is already finalized</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="854"/> - <source>usage: finalize_multisig <multisiginfo1> [<multisiginfo2>...]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="862"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1101"/> <source>Failed to finalize multisig</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="868"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1107"/> <source>Failed to finalize multisig: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="885"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="932"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1006"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1074"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1136"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1200"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1266"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1360"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1476"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1557"/> <source>This multisig wallet is not yet finalized</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="890"/> - <source>usage: export_multisig_info <filename></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="913"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1236"/> <source>Error exporting multisig info: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="917"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1240"/> <source>Multisig info exported to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="937"/> - <source>usage: import_multisig_info <filename1> [<filename2>...] - one for each other participant</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="965"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1306"/> <source>Multisig info imported</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="969"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1310"/> <source>Failed to import multisig info: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="980"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1321"/> <source>Failed to update spent status after importing multisig info: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="985"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1327"/> <source>Untrusted daemon, spent status may be incorrect. Use a trusted daemon and run "rescan_spent"</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1001"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1069"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1131"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1355"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1471"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1552"/> <source>This is not a multisig wallet</source> <translation>これはマルチシッグウォレットではありません</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1011"/> - <source>usage: sign_multisig <filename></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1024"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1405"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1414"/> <source>Failed to sign multisig transaction</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1030"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1421"/> <source>Multisig error: </source> <translation>マルチサインエラー: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1035"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1426"/> <source>Failed to sign multisig transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1058"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1449"/> <source>It may be relayed to the network with submit_multisig</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1079"/> - <source>usage: submit_multisig <filename></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1094"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1155"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1508"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1578"/> <source>Failed to load multisig transaction from file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1099"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1160"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1514"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1583"/> <source>Multisig transaction signed by only %u signers, needs %u more signatures</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1108"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6750"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1523"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8890"/> <source>Transaction successfully submitted, transaction </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1109"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6751"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1524"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8891"/> <source>You can check its status by using the `show_transfers` command.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1141"/> - <source>usage: export_raw_multisig <filename></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1176"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1599"/> <source>Failed to export multisig transaction to file </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1180"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1603"/> <source>Saved exported multisig transaction file(s): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1252"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1258"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1272"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2095"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2101"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2120"/> <source>ring size must be an integer >= </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1277"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2125"/> <source>could not change default ring size</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1518"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2398"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2469"/> <source>Invalid height</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1564"/> - <source>start_mining [<number_of_threads>] [bg_mining] [ignore_battery]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2562"/> + <source>Start mining in the daemon (bg_mining and ignore_battery are optional booleans).</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1565"/> - <source>Start mining in the daemon (bg_mining and ignore_battery are optional booleans).</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2565"/> + <source>Stop mining in the daemon.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1568"/> - <source>Stop mining in the daemon.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2569"/> + <source>Set another daemon to connect to.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1571"/> - <source>set_daemon <host>[:<port>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2572"/> + <source>Save the current blockchain data.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1572"/> - <source>Set another daemon to connect to.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2575"/> + <source>Synchronize the transactions and balance.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1575"/> - <source>Save the current blockchain data.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2579"/> + <source>Show the wallet's balance of the currently selected account.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1578"/> - <source>Synchronize the transactions and balance.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2589"/> + <source>Show the payments for the given payment IDs.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1581"/> - <source>balance [detail]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2592"/> + <source>Show the blockchain height.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1582"/> - <source>Show the wallet's balance of the currently selected account.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2606"/> + <source>Send all unmixable outputs to yourself with ring_size 1</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1585"/> - <source>incoming_transfers [available|unavailable] [verbose] [index=<N1>[,<N2>[,...]]]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2613"/> + <source>Send all unlocked outputs below the threshold to an address.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1586"/> - <source>Show the incoming transfers, all or filtered by availability and address index. - -Output format: -Amount, Spent("T"|"F"), "locked"|"unlocked", RingCT, Global Index, Transaction Hash, Address Index, [Public Key, Key Image]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2617"/> + <source>Send a single output of the given key image to an address without change.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1589"/> - <source>payments <PID_1> [<PID_2> ... <PID_N>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2621"/> + <source>Donate <amount> to the development team (donate.getmonero.org).</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1590"/> - <source>Show the payments for the given payment IDs.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2628"/> + <source>Submit a signed transaction from a file.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1593"/> - <source>Show the blockchain height.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2632"/> + <source>Change the current log detail (level must be <0-4>).</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1596"/> - <source>transfer_original [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> <amount> [<payment_id>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2636"/> + <source>If no arguments are specified, the wallet shows all the existing accounts along with their balances. +If the "new" argument is specified, the wallet creates a new account with its label initialized by the provided label text (which can be empty). +If the "switch" argument is specified, the wallet switches to the account specified by <index>. +If the "label" argument is specified, the wallet sets the label of the account specified by <index> to the provided label text. +If the "tag" argument is specified, a tag <tag_name> is assigned to the specified accounts <account_index_1>, <account_index_2>, .... +If the "untag" argument is specified, the tags assigned to the specified accounts <account_index_1>, <account_index_2> ..., are removed. +If the "tag_description" argument is specified, the tag <tag_name> is assigned an arbitrary text <description>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1597"/> - <source>Transfer <amount> to <address> using an older transaction building algorithm. If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2646"/> + <source>If no arguments are specified or <index> is specified, the wallet shows the default or specified address. If "all" is specified, the wallet shows all the existing addresses in the currently selected account. If "new " is specified, the wallet creates a new address with the provided label text (which can be empty). If "label" is specified, the wallet sets the label of the address specified by <index> to the provided label text.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1599"/> - <source>transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> <amount> [<payment_id>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2650"/> + <source>Encode a payment ID into an integrated address for the current wallet public address (no argument uses a random payment ID), or decode an integrated address to standard address and payment ID</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1600"/> - <source>Transfer <amount> to <address>. If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2654"/> + <source>Print all entries in the address book, optionally adding/deleting an entry to/from it.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1603"/> - <source>locked_transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <addr> <amount> <lockblocks> [<payment_id>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2657"/> + <source>Save the wallet data.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1604"/> - <source>Transfer <amount> to <address> and lock it for <lockblocks> (max. 1000000). If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2660"/> + <source>Save a watch-only keys file.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1607"/> - <source>Send all unmixable outputs to yourself with ring_size 1</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2663"/> + <source>Display the private view key.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1609"/> - <source>sweep_all [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> [<payment_id>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2666"/> + <source>Display the private spend key.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1610"/> - <source>Send all unlocked balance to an address. If the parameter "index<N1>[,<N2>,...]" is specified, the wallet sweeps outputs received by those address indices. If omitted, the wallet randomly chooses an address index to be used.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2669"/> + <source>Display the Electrum-style mnemonic seed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1613"/> - <source>sweep_below <amount_threshold> [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> [<payment_id>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2719"/> + <source>Display the encrypted Electrum-style mnemonic seed.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1614"/> - <source>Send all unlocked outputs below the threshold to an address.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2722"/> + <source>Rescan the blockchain for spent outputs.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1617"/> - <source>sweep_single [<priority>] [<ring_size>] <key_image> <address> [<payment_id>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2726"/> + <source>Get the transaction key (r) for a given <txid>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1618"/> - <source>Send a single output of the given key image to an address without change.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2734"/> + <source>Check the amount going to <address> in <txid>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1621"/> - <source>donate [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <amount> [<payment_id>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2738"/> + <source>Generate a signature proving funds sent to <address> in <txid>, optionally with a challenge string <message>, using either the transaction secret key (when <address> is not your wallet's address) or the view secret key (otherwise), which does not disclose the secret key.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1622"/> - <source>Donate <amount> to the development team (donate.getmonero.org).</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2742"/> + <source>Check the proof for funds going to <address> in <txid> with the challenge string <message> if any.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1625"/> - <source>sign_transfer <file></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2746"/> + <source>Generate a signature proving that you generated <txid> using the spend secret key, optionally with a challenge string <message>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1626"/> - <source>Sign a transaction from a <file>.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2750"/> + <source>Check a signature proving that the signer generated <txid>, optionally with a challenge string <message>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1629"/> - <source>Submit a signed transaction from a file.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2754"/> + <source>Generate a signature proving that you own at least this much, optionally with a challenge string <message>. +If 'all' is specified, you prove the entire sum of all of your existing accounts' balances. +Otherwise, you prove the reserve of the smallest possible amount above <amount> available in your current account.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1632"/> - <source>set_log <level>|{+,-,}<categories></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2760"/> + <source>Check a signature proving that the owner of <address> holds at least this much, optionally with a challenge string <message>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1633"/> - <source>Change the current log detail (level must be <0-4>).</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2780"/> + <source>Show the unspent outputs of a specified address within an optional amount range.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1636"/> - <source>account - account new <label text with white spaces allowed> - account switch <index> - account label <index> <label text with white spaces allowed> - account tag <tag_name> <account_index_1> [<account_index_2> ...] - account untag <account_index_1> [<account_index_2> ...] - account tag_description <tag_name> <description></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2788"/> + <source>Set an arbitrary string note for a <txid>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1643"/> - <source>If no arguments are specified, the wallet shows all the existing accounts along with their balances. -If the "new" argument is specified, the wallet creates a new account with its label initialized by the provided label text (which can be empty). -If the "switch" argument is specified, the wallet switches to the account specified by <index>. -If the "label" argument is specified, the wallet sets the label of the account specified by <index> to the provided label text. -If the "tag" argument is specified, a tag <tag_name> is assigned to the specified accounts <account_index_1>, <account_index_2>, .... -If the "untag" argument is specified, the tags assigned to the specified accounts <account_index_1>, <account_index_2> ..., are removed. -If the "tag_description" argument is specified, the tag <tag_name> is assigned an arbitrary text <description>.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2792"/> + <source>Get a string note for a txid.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1652"/> - <source>address [ new <label text with white spaces allowed> | all | <index_min> [<index_max>] | label <index> <label text with white spaces allowed>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2796"/> + <source>Set an arbitrary description for the wallet.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1653"/> - <source>If no arguments are specified or <index> is specified, the wallet shows the default or specified address. If "all" is specified, the wallet shows all the existing addresses in the currently selected account. If "new " is specified, the wallet creates a new address with the provided label text (which can be empty). If "label" is specified, the wallet sets the label of the address specified by <index> to the provided label text.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2800"/> + <source>Get the description of the wallet.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1656"/> - <source>integrated_address [<payment_id> | <address>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2803"/> + <source>Show the wallet's status.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1657"/> - <source>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> + <location filename="../src/simplewallet/simplewallet.cpp" line="2806"/> + <source>Show the wallet's information.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1660"/> - <source>address_book [(add ((<address> [pid <id>])|<integrated address>) [<description possibly with whitespaces>])|(delete <index>)]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2810"/> + <source>Sign the contents of a file.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1661"/> - <source>Print all entries in the address book, optionally adding/deleting an entry to/from it.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2814"/> + <source>Verify a signature on the contents of a file.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1664"/> - <source>Save the wallet data.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2822"/> + <source>Import a signed key images list and verify their spent status.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1667"/> - <source>Save a watch-only keys file.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2834"/> + <source>Export a set of outputs owned by this wallet.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1670"/> - <source>Display the private view key.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2838"/> + <source>Import a set of outputs owned by this wallet.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1673"/> - <source>Display the private spend key.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2842"/> + <source>Show information about a transfer to/from this address.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1676"/> - <source>Display the Electrum-style mnemonic seed</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2845"/> + <source>Change the wallet's password.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1679"/> - <source>set <option> [<value>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2849"/> + <source>Generate a new random full size payment id. These will be unencrypted on the blockchain, see integrated_address for encrypted short payment ids.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1680"/> - <source>Available options: - seed language - Set the wallet's 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 the default ring size (default and minimum is 5). - auto-refresh <1|0> - Whether to automatically synchronize new blocks from the daemon. - refresh-type <full|optimize-coinbase|no-coinbase|default> - Set the wallet's refresh behaviour. - priority [0|1|2|3|4] - Set the fee to default/unimportant/normal/elevated/priority. - confirm-missing-payment-id <1|0> - ask-password <1|0> - unit <monero|millinero|micronero|nanonero|piconero> - Set the 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] - Set a threshold for confirm-backlog to only warn if the transaction backlog is greater than n blocks. - refresh-from-block-height [n] - Set the height before which to ignore blocks. - auto-low-priority <1|0> - Whether to automatically use the low priority fee level when it's safe to do so.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2852"/> + <source>Print the information about the current fee and transaction backlog.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1717"/> - <source>Display the encrypted Electrum-style mnemonic seed.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2854"/> + <source>Export data needed to create a multisig wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1720"/> - <source>Rescan the blockchain for spent outputs.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2857"/> + <source>Turn this wallet into a multisig wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1723"/> - <source>get_tx_key <txid></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2861"/> + <source>Turn this wallet into a multisig wallet, extra step for N-1/N wallets</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1724"/> - <source>Get the transaction key (r) for a given <txid>.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2869"/> + <source>Export multisig info for other participants</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1727"/> - <source>check_tx_key <txid> <txkey> <address></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2873"/> + <source>Import multisig info from other participants</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1728"/> - <source>Check the amount going to <address> in <txid>.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2877"/> + <source>Sign a multisig transaction from a file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1731"/> - <source>get_tx_proof <txid> <address> [<message>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2881"/> + <source>Submit a signed multisig transaction from a file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1732"/> - <source>Generate a signature proving funds sent to <address> in <txid>, optionally with a challenge string <message>, using either the transaction secret key (when <address> is not your wallet's address) or the view secret key (otherwise), which does not disclose the secret key.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2885"/> + <source>Export a signed multisig transaction to a file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1735"/> - <source>check_tx_proof <txid> <address> <signature_file> [<message>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3002"/> + <source>Show the help section or the documentation about a <command>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1736"/> - <source>Check the proof for funds going to <address> in <txid> with the challenge string <message> if any.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3085"/> + <source>integer >= </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1739"/> - <source>get_spend_proof <txid> [<message>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3098"/> + <source>block height</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1740"/> - <source>Generate a signature proving that you generated <txid> using the spend secret key, optionally with a challenge string <message>.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3203"/> + <source>No wallet found with that name. Confirm creation of new wallet named: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1743"/> - <source>check_spend_proof <txid> <signature_file> [<message>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3304"/> + <source>can't specify both --restore-deterministic-wallet or --restore-multisig-wallet and --non-deterministic</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1744"/> - <source>Check a signature proving that the signer generated <txid>, optionally with a challenge string <message>.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> + <source>--restore-multisig-wallet uses --generate-new-wallet, not --wallet-file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1747"/> - <source>get_reserve_proof (all|<amount>) [<message>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3326"/> + <source>specify a recovery parameter with the --electrum-seed="multisig seed here"</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1748"/> - <source>Generate a signature proving that you own at least this much, optionally with a challenge string <message>. -If 'all' is specified, you prove the entire sum of all of your existing accounts' balances. -Otherwise, you prove the reserve of the smallest possible amount above <amount> available in your current account.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3355"/> + <source>Multisig seed failed verification</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1753"/> - <source>check_reserve_proof <address> <signature_file> [<message>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3406"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3481"/> + <source>This address is a subaddress which cannot be used here.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1754"/> - <source>Check a signature proving that the owner of <address> holds at least this much, optionally with a challenge string <message>.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3558"/> + <source>Error: expected M/N, but got: </source> + <translation>エラー: N/Mを欲しかったでもこれを貰いました: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3563"/> + <source>Error: expected N > 1 and N <= M, but got: </source> + <translation>エラー: N > 1 と N <= M のこと欲しかったでもこれを貰いました: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3568"/> + <source>Error: M/N is currently unsupported. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1757"/> - <source>show_transfers [in|out|pending|failed|pool] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3571"/> + <source>Generating master wallet from %u of %u multisig wallet keys</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1758"/> - <source>Show the incoming/outgoing transfers within an optional height range.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3600"/> + <source>failed to parse secret view key</source> + <translation>秘密なビューキーの解析に失敗しました</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3608"/> + <source>failed to verify secret view key</source> + <translation>秘密なビューキーの検証に失敗しました</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3628"/> + <source>Secret spend key (%u of %u):</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1761"/> - <source>unspent_outputs [index=<N1>[,<N2>,...]] [<min_amount> [<max_amount>]]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3651"/> + <source>Error: M/N is currently unsupported</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1762"/> - <source>Show the unspent outputs of a specified address within an optional amount range.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3802"/> + <source>Restore height </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1765"/> - <source>Rescan the blockchain from scratch.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3803"/> + <source>Still apply restore height? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1768"/> - <source>set_tx_note <txid> [free text note]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3829"/> + <source>Warning: using an untrusted daemon at %s, privacy will be lessened</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1769"/> - <source>Set an arbitrary string note for a <txid>.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3888"/> + <source>Daemon either is not started or wrong port was passed. Please make sure daemon is running or change the daemon address using the 'set_daemon' command.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1772"/> - <source>get_tx_note <txid></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="4036"/> + <source>Your wallet has been generated! +To start synchronizing with the daemon, use the "refresh" command. +Use the "help" command to see the list of available commands. +Use "help <command>" to see a command's documentation. +Always use the "exit" command when closing monero-wallet-cli to save +your current session's state. Otherwise, you might need to synchronize +your wallet again (your wallet keys are NOT at risk in any case). +</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1773"/> - <source>Get a string note for a txid.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="4180"/> + <source>failed to generate new mutlisig wallet</source> + <translation>新しいマルチシッグウォレットの生成に失敗しました</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4183"/> + <source>Generated new %u/%u multisig wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1776"/> - <source>set_description [free text note]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="4232"/> + <source>Opened %u/%u multisig wallet%s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1777"/> - <source>Set an arbitrary description for the wallet.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="4293"/> + <source>Use "help <command>" to see a command's documentation. +</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1780"/> - <source>Get the description of the wallet.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="4351"/> + <source>wallet is multisig and cannot save a watch-only version</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1783"/> - <source>Show the wallet's status.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="4476"/> + <source>Unexpected array length - Exited simple_wallet::set_daemon()</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1786"/> - <source>Show the wallet's information.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="4517"/> + <source>This does not seem to be a valid daemon URL.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1789"/> - <source>sign <file></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="4553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4590"/> + <source>txid </source> + <translation>txid </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4555"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4592"/> + <source>idx </source> + <translation>idx </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4780"/> + <source> (Some owned outputs have partial key images - import_multisig_info needed)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1790"/> - <source>Sign the contents of a file.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="4783"/> + <source>Currently selected account: [</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1793"/> - <source>verify <filename> <address> <signature></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="4783"/> + <source>] </source> + <translation>] </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4785"/> + <source>Tag: </source> + <translation>タグ: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4785"/> + <source>(No tag assigned)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1794"/> - <source>Verify a signature on the contents of a file.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="4792"/> + <source>Balance per address:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1797"/> - <source>export_key_images <file></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> + <source>Address</source> + <translation>アドレス</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8008"/> + <source>Balance</source> + <translation>残高</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8008"/> + <source>Unlocked balance</source> + <translation>ロック解除された残高</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> + <source>Outputs</source> + <translation>アウトプット</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8008"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9122"/> + <source>Label</source> + <translation>ラベル</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4801"/> + <source>%8u %6s %21s %21s %7u %21s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1798"/> - <source>Export a signed set of key images to a <file>.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> + <source>spent</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1801"/> - <source>import_key_images <file></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> + <source>global index</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1802"/> - <source>Import a signed key images list and verify their spent status.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> + <source>tx id</source> + <translation>tx id</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> + <source>addr index</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1805"/> - <source>export_outputs <file></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="4924"/> + <source>No incoming transfers</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1806"/> - <source>Export a set of outputs owned by this wallet.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="4928"/> + <source>No incoming available transfers</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1809"/> - <source>import_outputs <file></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="4932"/> + <source>No incoming unavailable transfers</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1810"/> - <source>Import a set of outputs owned by this wallet.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> + <source>payment</source> + <translation>ペイメント</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> + <source>transaction</source> + <translation>取引</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> + <source>height</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1813"/> - <source>show_transfer <txid></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> + <source>unlock time</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1814"/> - <source>Show information about a transfer to/from this address.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="4968"/> + <source>No payments with id </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1817"/> - <source>Change the wallet's password.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="5016"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5106"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5442"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5901"/> + <source>failed to get blockchain height: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1820"/> - <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> + <location filename="../src/simplewallet/simplewallet.cpp" line="5114"/> + <source> +Transaction %llu/%llu: txid=%s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1823"/> - <source>Print the information about the current fee and transaction backlog.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="5135"/> + <source> +Input %llu/%llu: amount=%s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1825"/> - <source>Export data needed to create a multisig wallet</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="5151"/> + <source>failed to get output: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1827"/> - <source>make_multisig <threshold> <string1> [<string>...]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="5159"/> + <source>output key's originating block height shouldn't be higher than the blockchain height</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1828"/> - <source>Turn this wallet into a multisig wallet</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="5163"/> + <source> +Originating block heights: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1831"/> - <source>finalize_multisig <string> [<string>...]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="5175"/> + <source> +|</source> + <translation> +|</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5175"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7706"/> + <source>| +</source> + <translation>| +</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5192"/> + <source> +Warning: Some input keys being spent are from </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1832"/> - <source>Turn this wallet into a multisig wallet, extra step for N-1/N wallets</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="5194"/> + <source>, which can break the anonymity of ring signature. Make sure this is intentional!</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1835"/> - <source>export_multisig_info <filename></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="5234"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5853"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6156"/> + <source>Ring size must not be 0</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1836"/> - <source>Export multisig info for other participants</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="5246"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5865"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6168"/> + <source>ring size %u is too small, minimum is %u</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1839"/> - <source>import_multisig_info <filename> [<filename>...]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="5258"/> + <source>wrong number of arguments</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1840"/> - <source>Import multisig info from other participants</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="5417"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5996"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6268"/> + <source>No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1843"/> - <source>sign_multisig <filename></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="5458"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6016"/> + <source>No outputs found, or daemon is not ready</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1844"/> - <source>Sign a multisig transaction from a file</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="6428"/> + <source>Failed to parse donation address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1847"/> - <source>submit_multisig <filename></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="6442"/> + <source>Donating %s %s to The Monero Project (donate.getmonero.org or %s).</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1848"/> - <source>Submit a signed multisig transaction from a file</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="6444"/> + <source>Donating %s %s to %s.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1851"/> - <source>export_raw_multisig_tx <filename></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="6759"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6770"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6777"/> + <source>failed to parse tx_key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1852"/> - <source>Export a signed multisig transaction to a file</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="6786"/> + <source>Tx key successfully stored.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1855"/> - <source>help [<command>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="6790"/> + <source>Failed to store tx key: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1856"/> - <source>Show the help section or the documentation about a <command>.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="7296"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>block</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1917"/> - <source>integer >= </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="7440"/> + <source>usage: show_transfers [in|out|all|pending|failed|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1930"/> - <source>block height</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="7493"/> + <source>usage: export_transfers [in|out|all|pending|failed|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]] [output=<path>]</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2012"/> - <source>No wallet found with that name. Confirm creation of new wallet named: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>direction</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2068"/> - <source>can't specify more than one of --generate-new-wallet="wallet_name", --wallet-file="wallet_name", --generate-from-view-key="wallet_name", --generate-from-spend-key="wallet_name", --generate-from-keys="wallet_name", --generate-from-multisig-keys="wallet_name" and --generate-from-json="jsonfilename"</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>timestamp</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2084"/> - <source>can't specify both --restore-deterministic-wallet or --restore-multisig-wallet and --non-deterministic</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>running balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2090"/> - <source>--restore-multisig-wallet uses --generate-new-wallet, not --wallet-file</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>hash</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2106"/> - <source>specify a recovery parameter with the --electrum-seed="multisig seed here"</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>payment ID</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2133"/> - <source>Multisig seed failed verification</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>fee</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2149"/> - <source>Enter seed encryption passphrase, empty if none</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>destination</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2185"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2259"/> - <source>This address is a subaddress which cannot be used here.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>index</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2337"/> - <source>Error: expected M/N, but got: </source> - <translation>エラー: N/Mを欲しかったでもこれを貰いました: </translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>note</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2342"/> - <source>Error: expected N > 1 and N <= M, but got: </source> - <translation>エラー: N > 1 と N <= M のこと欲しかったでもこれを貰いました: </translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="7572"/> + <source>CSV exported to </source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2347"/> - <source>Error: M/N is currently unsupported. </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="7730"/> + <source>Warning: this will lose any information which can not be recovered from the blockchain.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2350"/> - <source>Generating master wallet from %u of %u multisig wallet keys</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="7731"/> + <source>This includes destination addresses, tx secret keys, tx notes, etc</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2379"/> - <source>failed to parse secret view key</source> - <translation>秘密なビューキーの解析に失敗しました</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="7732"/> + <source>Rescan anyway ? (Y/Yes/N/No): </source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2388"/> - <source>failed to verify secret view key</source> - <translation>秘密なビューキーの検証に失敗しました</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="7750"/> + <source>MMS received new message</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2408"/> - <source>Secret spend key (%u of %u):</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8387"/> + <source>Network type: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2432"/> - <source>Error: M/N is currently unsupported</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8388"/> + <source>Testnet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2550"/> - <source>Restore height </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8389"/> + <source>Stagenet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2551"/> - <source>Still apply restore height? (Y/Yes/N/No): </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8389"/> + <source>Mainnet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2582"/> - <source>Warning: using an untrusted daemon at %s, privacy will be lessened</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8559"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8605"/> + <source>command only supported by HW wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2636"/> - <source>Daemon either is not started or wrong port was passed. Please make sure daemon is running or change the daemon address using the 'set_daemon' command.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8564"/> + <source>hw wallet does not support cold KI sync</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2768"/> - <source>Your wallet has been generated! -To start synchronizing with the daemon, use the "refresh" command. -Use the "help" command to see the list of available commands. -Use "help <command>" to see a command's documentation. -Always use the "exit" command when closing monero-wallet-cli to save -your current session's state. Otherwise, you might need to synchronize -your wallet again (your wallet keys are NOT at risk in any case). -</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8576"/> + <source>Please confirm the key image sync on the device</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2850"/> - <source>failed to generate new mutlisig wallet</source> - <translation>新しいマルチシッグウォレットの生成に失敗しました</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="8582"/> + <source>Key images synchronized to height </source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2853"/> - <source>Generated new %u/%u multisig wallet: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8585"/> + <source>Running untrusted daemon, cannot determine which transaction output is spent. Use a trusted daemon with --trusted-daemon and run rescan_spent</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2889"/> - <source>Opened %u/%u multisig wallet%s</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8588"/> + <source> spent, </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2942"/> - <source>Use "help <command>" to see a command's documentation. -</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8588"/> + <source> unspent</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3000"/> - <source>wallet is multisig and cannot save a watch-only version</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8592"/> + <source>Failed to import key images</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3105"/> - <source>missing daemon URL argument</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8597"/> + <source>Failed to import key images: </source> + <translation type="unfinished">キーイメージをインポートできませんでした: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8614"/> + <source>Failed to reconnect device</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3116"/> - <source>Unexpected array length - Exited simple_wallet::set_daemon()</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8619"/> + <source>Failed to reconnect device: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3130"/> - <source>This does not seem to be a valid daemon URL.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8883"/> + <source>Transaction successfully saved to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3166"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3184"/> - <source>txid </source> - <translation>txid </translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="8883"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8885"/> + <source>, txid </source> + <translation>、txid </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3168"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3186"/> - <source>idx </source> - <translation>idx </translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="8885"/> + <source>Failed to save transaction to </source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3299"/> - <source> (Some owned outputs have partial key images - import_multisig_info needed)</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="5723"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6044"/> + <source>Sweeping %s in %llu transactions for a total fee of %s. Is this okay? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3300"/> - <source>Currently selected account: [</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="5729"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6050"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6310"/> + <source>Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3300"/> - <source>] </source> - <translation>] </translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="6611"/> + <source>This is a watch only wallet</source> + <translation>これは閲覧専用ウォレットです</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3302"/> - <source>Tag: </source> - <translation>タグ: </translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="8813"/> + <source>Double spend seen on the network: this transaction may or may not end up being mined</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3302"/> - <source>(No tag assigned)</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="8848"/> + <source>Transaction ID not found</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3309"/> - <source>Balance per address:</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="336"/> + <source>true</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> - <source>Address</source> - <translation>アドレス</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="389"/> + <source>failed to parse refresh type</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5921"/> - <source>Balance</source> - <translation>残高</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="721"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="787"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="939"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="984"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1067"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1124"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1190"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1256"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1350"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1466"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1547"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6601"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6665"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6702"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6799"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7010"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7094"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8397"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8474"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8517"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8630"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8670"/> + <source>command not supported by HW wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="726"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="797"/> + <source>wallet is watch-only and has no seed</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5921"/> - <source>Unlocked balance</source> - <translation>ロック解除された残高</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="744"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="807"/> + <source>wallet is non-deterministic and has no seed</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> - <source>Outputs</source> - <translation>アウトプット</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="751"/> + <source>Enter optional seed offset passphrase, empty to see raw seed</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5921"/> - <source>Label</source> - <translation>ラベル</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="817"/> + <source>Incorrect password</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3318"/> - <source>%8u %6s %21s %21s %7u %21s</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="883"/> + <source>Current fee is %s %s per %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3327"/> - <source>usage: balance [detail]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1036"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1158"/> + <source>Send this multisig info to all other participants, then use exchange_multisig_keys <info1> [<info2>...] with others' multisig info</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3339"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3381"/> - <source>usage: incoming_transfers [available|unavailable] [verbose] [index=<N1>[,<N2>[,...]]]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1167"/> + <source>Multisig wallet has been successfully created. Current wallet type: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> - <source>spent</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1172"/> + <source>Failed to perform multisig keys exchange: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> - <source>global index</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1499"/> + <source>Failed to load multisig transaction from MMS</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> - <source>tx id</source> - <translation>tx id</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="1631"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1788"/> + <source>Invalid key image</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> - <source>addr index</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1637"/> + <source>Invalid txid</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3423"/> - <source>No incoming transfers</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1649"/> + <source>Key image either not spent, or spent with mixin 0</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3427"/> - <source>No incoming available transfers</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1664"/> + <source>Failed to get key image ring: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3431"/> - <source>No incoming unavailable transfers</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1679"/> + <source>File doesn't exist</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3442"/> - <source>expected at least one payment ID</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1701"/> + <source>Invalid ring specification: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> - <source>payment</source> - <translation>ペイメント</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="1709"/> + <source>Invalid key image: </source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> - <source>transaction</source> - <translation>取引</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="1714"/> + <source>Invalid ring type, expected relative or abosolute: </source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> - <source>height</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1720"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1732"/> + <source>Error reading line: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> - <source>unlock time</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1743"/> + <source>Invalid ring: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3463"/> - <source>No payments with id </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1752"/> + <source>Invalid relative ring: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3516"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3582"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3853"/> - <source>failed to get blockchain height: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1764"/> + <source>Invalid absolute ring: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3572"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5136"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5174"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5226"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5259"/> - <source>failed to connect to the daemon</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1773"/> + <source>Failed to set ring for key image: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3590"/> - <source> -Transaction %llu/%llu: txid=%s</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1773"/> + <source>Continuing.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3600"/> - <source> -Input %llu/%llu: amount=%s</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1803"/> + <source>Missing absolute or relative keyword</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3616"/> - <source>failed to get output: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1813"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1820"/> + <source>invalid index: must be a strictly positive unsigned integer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3624"/> - <source>output key's originating block height shouldn't be higher than the blockchain height</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1828"/> + <source>invalid index: indices wrap</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3628"/> - <source> -Originating block heights: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1838"/> + <source>invalid index: indices should be in strictly ascending order</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3643"/> - <source> -|</source> - <translation> -|</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="1845"/> + <source>failed to set ring</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3643"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5651"/> - <source>| -</source> - <translation>| -</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="1890"/> + <source>First line is not an amount</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3660"/> - <source> -Warning: Some input keys being spent are from </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1904"/> + <source>Invalid output: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3662"/> - <source>, which can break the anonymity of ring signature. Make sure this is intentional!</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1914"/> + <source>Bad argument: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3705"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4184"/> - <source>Ring size must not be 0</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1914"/> + <source>should be "add"</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3717"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4196"/> - <source>ring size %u is too small, minimum is %u</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1923"/> + <source>Failed to open file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3724"/> - <source>wrong number of arguments</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1929"/> + <source>Invalid output key, and file doesn't exist</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3830"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4266"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4479"/> - <source>No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1935"/> + <source>Failed to mark output spent: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3872"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4286"/> - <source>No outputs found, or daemon is not ready</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1952"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1979"/> + <source>Invalid output</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6743"/> - <source>Transaction successfully saved to </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1962"/> + <source>Failed to mark output unspent: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6743"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6745"/> - <source>, txid </source> - <translation>、txid </translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="1986"/> + <source>Spent: </source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6745"/> - <source>Failed to save transaction to </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1988"/> + <source>Not spent: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4081"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4314"/> - <source>Sweeping %s in %llu transactions for a total fee of %s. Is this okay? (Y/Yes/N/No): </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1992"/> + <source>Failed to check whether output is spent: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4087"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4320"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4519"/> - <source>Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No): </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2007"/> + <source>Failed to save known rings: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4630"/> - <source>Donating </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2022"/> + <source>Please confirm the transaction on the device</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4792"/> - <source>This is a watch only wallet</source> - <translation>これは閲覧専用ウォレットです</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="2069"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2088"/> + <source>wallet is watch-only and cannot transfer</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6571"/> - <source>usage: show_transfer <txid></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2106"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5581"/> + <source>WARNING: this is a non default ring size, which may harm your privacy. Default is recommended.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6673"/> - <source>Double spend seen on the network: this transaction may or may not end up being mined</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2108"/> + <source>WARNING: from v8, ring size will be fixed and this setting will be ignored.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6708"/> - <source>Transaction ID not found</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2137"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2160"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2176"/> + <source>priority must be either 0, 1, 2, 3, or 4, or one of: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="214"/> - <source>true</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2181"/> + <source>could not change default priority</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="267"/> - <source>failed to parse refresh type</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2249"/> + <source>invalid argument: must be either 0/never, 1/action, or 2/encrypt/decrypt</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="541"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="608"/> - <source>wallet is watch-only and has no seed</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2510"/> + <source>Device name not specified</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="557"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="613"/> - <source>wallet is non-deterministic and has no seed</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2519"/> + <source>Device reconnect failed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1226"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1245"/> - <source>wallet is watch-only and cannot transfer</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2524"/> + <source>Device reconnect failed: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1321"/> - <source>could not change default priority</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2583"/> + <source>Show the incoming transfers, all or filtered by availability and address index. + +Output format: +Amount, Spent("T"|"F"), "locked"|"unlocked", RingCT, Global Index, Transaction Hash, Address Index, [Public Key, Key Image] </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2595"/> + <source>Transfer <amount> to <address>. If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding URI_2 or <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2599"/> + <source>Transfer <amount> to <address> and lock it for <lockblocks> (max. 1000000). If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding URI_2 or <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2603"/> + <source>Send all unlocked balance to an address and lock it for <lockblocks> (max. 1000000). If the parameter "index<N1>[,<N2>,...]" is specified, the wallet sweeps outputs received by those address indices. If omitted, the wallet randomly chooses an address index to be used. <priority> is the priority of the sweep. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2609"/> + <source>Send all unlocked balance to an address. If the parameter "index<N1>[,<N2>,...]" is specified, the wallet sweeps outputs received by those address indices. If omitted, the wallet randomly chooses an address index to be used. If the parameter "outputs=<N>" is specified and N > 0, wallet splits the transaction into N even outputs.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2625"/> + <source>Sign a transaction from a file. If the parameter "export_raw" is specified, transaction raw hex data suitable for the daemon RPC /sendrawtransaction is exported.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2673"/> + <source>Available options: + seed language + Set the wallet's 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 the default ring size (obsolete). + auto-refresh <1|0> + Whether to automatically synchronize new blocks from the daemon. + refresh-type <full|optimize-coinbase|no-coinbase|default> + Set the wallet's refresh behaviour. + priority [0|1|2|3|4] + Set the fee to default/unimportant/normal/elevated/priority. + confirm-missing-payment-id <1|0> + ask-password <0|1|2 (or never|action|decrypt)> + unit <monero|millinero|micronero|nanonero|piconero> + Set the 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] + Set a threshold for confirm-backlog to only warn if the transaction backlog is greater than n blocks. + refresh-from-block-height [n] + Set the height before which to ignore blocks. + auto-low-priority <1|0> + Whether to automatically use the low priority fee level when it's safe to do so. + segregate-pre-fork-outputs <1|0> + Set this if you intend to spend outputs on both Monero AND a key reusing fork. + key-reuse-mitigation2 <1|0> + Set this if you are not sure whether you will spend on a key reusing Monero fork later. +subaddress-lookahead <major>:<minor> + Set the lookahead sizes for the subaddress hash table. + Set this if you are not sure whether you will spend on a key reusing Monero fork later. + segregation-height <n> + Set to the height of a key reusing fork you want to use, 0 to use default.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2730"/> + <source>Set the transaction key (r) for a given <txid> in case the tx was made by some other device or 3rd party wallet.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2765"/> + <source>Show the incoming/outgoing transfers within an optional height range. + +Output format: +In or Coinbase: Block Number, "block"|"in", Time, Amount, Transaction Hash, Payment ID, Subaddress Index, "-", Note +Out: Block Number, "out", Time, Amount*, Transaction Hash, Payment ID, Fee, Destinations, Input addresses**, "-", Note +Pool: "pool", "in", Time, Amount, Transaction Hash, Payment Id, Subaddress Index, "-", Note, Double Spend Note +Pending or Failed: "failed"|"pending", "out", Time, Amount*, Transaction Hash, Payment ID, Fee, Input addresses**, "-", Note + +* Excluding change and fee. +** Set of address indices used as inputs in this transfer.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2775"/> + <source>export_transfers [in|out|all|pending|failed|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]] [output=<filepath>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2776"/> + <source>Export to CSV the incoming/outgoing transfers within an optional height range.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2784"/> + <source>Rescan the blockchain from scratch, losing any information which can not be recovered from the blockchain itself.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1919"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2818"/> + <source>Export a signed set of key images to a <filename>.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2826"/> + <source>Synchronizes key images with the hw wallet.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2830"/> + <source>Attempts to reconnect HW wallet.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2865"/> + <source>Performs extra multisig keys exchange rounds. Needed for arbitrary M/N multisig wallets</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2889"/> + <source>Interface with the MMS (Multisig Messaging System) +<subcommand> is one of: + init, info, signer, list, next, sync, transfer, delete, send, receive, export, note, show, set, help + send_signer_config, start_auto_config, stop_auto_config, auto_config +Get help about a subcommand with: help mms <subcommand>, or mms help <subcommand></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2897"/> + <source>Initialize and configure the MMS for M/N = number of required signers/number of authorized signers multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2901"/> + <source>Display current MMS configuration</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2905"/> + <source>Set or modify authorized signer info (single-word label, transport address, Monero address), or list all signers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2909"/> + <source>List all messages</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2913"/> + <source>Evaluate the next possible multisig-related action(s) according to wallet state, and execute or offer for choice +By using 'sync' processing of waiting messages with multisig sync info can be forced regardless of wallet state</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2918"/> + <source>Force generation of multisig sync info regardless of wallet state, to recover from special situations like "stale data" errors</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2922"/> + <source>Initiate transfer with MMS support; arguments identical to normal 'transfer' command arguments, for info see there</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2926"/> + <source>Delete a single message by giving its id, or delete all messages by using 'all'</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2930"/> + <source>Send a single message by giving its id, or send all waiting messages</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2934"/> + <source>Check right away for new messages to receive</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2938"/> + <source>Write the content of a message to a file "mms_message_content"</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2942"/> + <source>Send a one-line message to an authorized signer, identified by its label, or show any waiting unread notes</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2946"/> + <source>Show detailed info about a single message</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2950"/> + <source>Available options: + auto-send <1|0> + Whether to automatically send newly generated messages right away. + </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2956"/> + <source>Send completed signer config to all other authorized signers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2960"/> + <source>Start auto-config at the auto-config manager's wallet by issuing auto-config tokens and optionally set others' labels</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2964"/> + <source>Delete any auto-config tokens and abort a auto-config process</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2968"/> + <source>Start auto-config by using the token received from the auto-config manager</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2972"/> + <source>Print the ring(s) used to spend a given key image or transaction (if the ring size is > 1) + +Output format: +Key Image, "absolute", list of rings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2978"/> + <source>Set the ring used for a given key image, so it can be reused in a fork</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2982"/> + <source>Save known rings to the shared rings database</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2986"/> + <source>Mark output(s) as spent so they never get selected as fake outputs in a ring</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2990"/> + <source>Marks an output as unspent so it may get selected as a fake output in a ring</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2994"/> + <source>Checks whether an output is marked as spent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2998"/> + <source>Returns version information</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3087"/> <source>full (slowest, no assumptions); optimize-coinbase (fast, assumes the whole coinbase is paid to a single address); no-coinbase (fastest, assumes we receive no coinbase transaction), default (same as optimize-coinbase)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1923"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3088"/> + <source>0, 1, 2, 3, or 4, or one of </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3090"/> + <source>0|1|2 (or never|action|decrypt)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3091"/> <source>monero, millinero, micronero, nanonero, piconero</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1975"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3102"/> + <source><major>:<minor></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3106"/> + <source><device_name[:device_spec]></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3127"/> + <source>wrong number range, use: %s</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3166"/> <source>Wallet name not valid. Please try again or use Ctrl-C to quit.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1992"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3183"/> <source>Wallet and key files found, loading...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1998"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3189"/> <source>Key file found but not wallet file. Regenerating...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2004"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3195"/> <source>Key file not found. Failed to open wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2023"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3214"/> <source>Generating new wallet...</source> <translation>新しいウォレットを生じてます...</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2141"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3232"/> + <source>NOTE: the following %s can be used to recover access to your wallet. Write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3234"/> + <source>string</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3234"/> + <source>25 words</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3273"/> + <source>Can't specify more than one of --testnet and --stagenet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3285"/> + <source>can't specify more than one of --generate-new-wallet="wallet_name", --wallet-file="wallet_name", --generate-from-view-key="wallet_name", --generate-from-spend-key="wallet_name", --generate-from-keys="wallet_name", --generate-from-multisig-keys="wallet_name", --generate-from-json="jsonfilename" and --generate-from-device="wallet_name"</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3364"/> <source>Electrum-style word list failed verification</source> <translation>Electrumな単語表の検証に失敗しました</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2174"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2194"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2229"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2248"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2268"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2284"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2332"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2357"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2373"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2413"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3369"/> + <source>Enter seed offset passphrase, empty if none</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3395"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3415"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3450"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3470"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3490"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3505"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3578"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3594"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3633"/> <source>No data supplied, cancelled</source> <translation>データをもらいませんでしたのでキャンセルしました</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2180"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2254"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2363"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3791"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4240"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4454"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4926"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4994"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5058"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5266"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6106"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6353"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3401"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3476"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3584"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5371"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5969"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6243"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6818"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6886"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6950"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7154"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8193"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8454"/> <source>failed to parse address</source> <translation>アドレスの解析に失敗しました</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2200"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2290"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3421"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3511"/> <source>failed to parse view key secret key</source> <translation>秘密なビューキーの解析に失敗しました</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2210"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2308"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3430"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3528"/> <source>failed to verify view key secret key</source> <translation>秘密なビューキーの検証に失敗しました</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2214"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2312"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2393"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3434"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3532"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3613"/> <source>view key does not match standard address</source> <translation>ビューキーが一般的なアドレスと一致しませんでした</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2219"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2238"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2316"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2450"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2480"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3439"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3459"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3536"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3669"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3695"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3726"/> <source>account creation failed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2234"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2274"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2418"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3455"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3496"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3638"/> <source>failed to parse spend key secret key</source> <translation>秘密なスペンドキーの解析に失敗しました</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2300"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2439"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3520"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3658"/> <source>failed to verify spend key secret key</source> <translation>秘密なスペンドキーの検証に失敗しました</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2304"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2444"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3524"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3663"/> <source>spend key does not match standard address</source> <translation>スペンドキーが一般的なアドレスと一致しませんでした</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2562"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3701"/> + <source>No restore height is specified.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3702"/> + <source>Assumed you are creating a new account, restore will be done from current estimated blockchain height.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3703"/> + <source>Use --restore-height if you want to restore an already setup account from a specific height</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3707"/> + <source>account creation aborted</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3816"/> + <source>can't specify --subaddress-lookahead and --wallet-file at the same time</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3820"/> <source>failed to open account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2566"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3030"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3085"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3142"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4962"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3824"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4391"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4444"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4529"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6854"/> <source>wallet is null</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2680"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2685"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3832"/> + <source>Failed to initialize ring database: privacy enhancing features will be inactive</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3917"/> + <source>If your display freezes, exit blind with ^C, then run again with --use-english-language-names</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3935"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3940"/> <source>invalid language choice entered. Please try again. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2753"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4019"/> <source>View key: </source> <translation>ビューキー: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2935"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4130"/> + <source>Generated new wallet on hw device: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4209"/> + <source>Key file not found. Failed to open wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4286"/> <source>You may want to remove the file "%s" and try again</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2963"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4314"/> <source>failed to deinitialize wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3021"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3524"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6410"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4367"/> + <source>Watch only wallet saved as: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4371"/> + <source>Failed to save watch only wallet: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4382"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5024"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8522"/> <source>this command requires a trusted daemon. Enable with --trusted-daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3152"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4498"/> + <source>Expected trusted or untrusted, got </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4515"/> + <source>trusted</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4515"/> + <source>untrusted</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4539"/> <source>blockchain can't be saved: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3239"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3538"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4569"/> + <source>NOTE: this transaction uses an encrypted payment ID: consider using subaddresses instead</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4572"/> + <source>WARNING: this transaction uses an unencrypted payment ID: consider using subaddresses instead</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4608"/> + <source>Password needed (%s) - use the refresh command</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4616"/> + <source>Enter password</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4631"/> + <source>Device requires attention</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4639"/> + <source>Enter device PIN</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4641"/> + <source>Failed to read device PIN</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4648"/> + <source>Please enter the device passphrase on the device</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4655"/> + <source>Enter device passphrase</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4657"/> + <source>Failed to read device passphrase</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4673"/> + <source>The first refresh has finished for the HW-based wallet with received money. hw_key_images_sync is needed. </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4675"/> + <source>Do you want to do it now? (Y/Yes/N/No): </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4677"/> + <source>hw_key_images_sync skipped. Run command manually before a transfer.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4720"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5038"/> <source>daemon is busy. Please try again later.</source> <translation>デーモンは忙しいです。後でもう一度試してください。</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3243"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3542"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4724"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5042"/> <source>no connection to daemon. Please make sure daemon is running.</source> <translation>デーモンの接続が確立ありません。デーモンが実行中になっていることを確認してください。</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3253"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4734"/> <source>refresh error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3303"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4782"/> + <source> (Some owned outputs have missing key images - import_key_images needed)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4786"/> <source>Balance: </source> <translation>残高: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3399"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4855"/> + <source>Invalid keyword: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4893"/> <source>pubkey</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3399"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4893"/> <source>key image</source> <translation>キーイメージ</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3410"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4910"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> <source>unlocked</source> <translation></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> <source>ringct</source> <translation>ringct</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3409"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4904"/> + <source>Heights: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4909"/> <source>T</source> <translation>T</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3409"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4909"/> <source>F</source> <translation>F</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3410"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4910"/> <source>locked</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3411"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4911"/> <source>RingCT</source> <translation>RingCT</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3411"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4911"/> <source>-</source> <translation>-</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3485"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4990"/> <source>payment ID has invalid format, expected 16 or 64 character hex string: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3546"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5046"/> <source>failed to get spent status</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3661"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5130"/> + <source>failed to find construction data for tx input</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5193"/> <source>the same transaction</source> <translation>同じ取引</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3661"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5193"/> <source>blocks that are temporally very close</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3778"/> - <source>Locked blocks too high, max 1000000 (˜4 yrs)</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9015"/> + <source> (Y/Yes/N/No): </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5077"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5188"/> - <source>Good signature</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9042"/> + <source>Choose processing:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5104"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5190"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5293"/> - <source>Bad signature</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9051"/> + <source>Sign tx</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6046"/> - <source>usage: integrated_address [payment ID]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9059"/> + <source>Send the tx for submission to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6082"/> - <source>Standard address: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9063"/> + <source>Send the tx for signing to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6087"/> - <source>failed to parse payment ID or address</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9070"/> + <source>Submit tx</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6098"/> - <source>usage: address_book [(add (<address> [pid <long or short payment id>])|<integrated address> [<description possibly with whitespaces>])|(delete <index>)]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9073"/> + <source>unknown</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6128"/> - <source>failed to parse payment ID</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9079"/> + <source>Choice: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6146"/> - <source>failed to parse index</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9091"/> + <source>Wrong choice</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6154"/> - <source>Address book is empty.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9098"/> + <source>Id</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6160"/> - <source>Index: </source> - <translation>インデックス: </translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="9098"/> + <source>I/O</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6161"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6287"/> - <source>Address: </source> - <translation>アドレス: </translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="9098"/> + <source>Authorized Signer</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6162"/> - <source>Payment ID: </source> - <translation>ペイメントID: </translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>Message Type</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6163"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6286"/> - <source>Description: </source> - <translation>記述: </translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>Height</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6173"/> - <source>usage: set_tx_note [txid] free text note</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>R</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6201"/> - <source>usage: get_tx_note [txid]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>Message State</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6304"/> - <source>usage: sign <filename></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>Since</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6309"/> - <source>wallet is watch-only and cannot sign</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9116"/> + <source> ago</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="951"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6323"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6346"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6501"/> - <source>failed to read file </source> - <translation>ファイルの読み込みに失敗しました </translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="9122"/> + <source>#</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5039"/> - <source>usage: check_tx_proof <txid> <address> <signature_file> [<message>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9122"/> + <source>Transport Address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5066"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5181"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5278"/> - <source>failed to load signature file</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9123"/> + <source>Auto-Config Token</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5117"/> - <source>usage: get_spend_proof <txid> [<message>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9123"/> + <source>Monero Address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5123"/> - <source>wallet is watch-only and cannot generate the proof</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9127"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9135"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9137"/> + <source><not set></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5161"/> - <source>usage: check_spend_proof <txid> <signature_file> [<message>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9178"/> + <source>Message </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5202"/> - <source>usage: get_reserve_proof (all|<amount>) [<message>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9179"/> + <source>In/out: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5208"/> - <source>The reserve proof can be generated only by a full wallet</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9181"/> + <source>State: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5253"/> - <source>usage: check_reserve_proof <address> <signature_file> [<message>]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9181"/> + <source>%s since %s, %s ago</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5271"/> - <source>Address must not be a subaddress</source> - <translation>アドレスはサブアドレスであってはならないです</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="9185"/> + <source>Sent: Never</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5289"/> - <source>Good signature -- total: %s, spent: %s, unspent: %s</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9189"/> + <source>Sent: %s, %s ago</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5353"/> - <source>usage: show_transfers [in|out|all|pending|failed] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9192"/> + <source>Authorized signer: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5490"/> - <source>[Double spend seen on the network: this transaction may or may not end up being mined] </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9193"/> + <source>Content size: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9193"/> + <source> bytes</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9194"/> + <source>Content: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9194"/> + <source>(binary data)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9224"/> + <source>Send these messages now?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9234"/> + <source>Queued for sending.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9254"/> + <source>Invalid message id</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9263"/> + <source>usage: mms init <required_signers>/<authorized_signers> <own_label> <own_transport_address></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9269"/> + <source>The MMS is already initialized. Re-initialize by deleting all signer info and messages?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9284"/> + <source>Error in the number of required signers and/or authorized signers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9301"/> + <source>The MMS is not active.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9324"/> + <source>Invalid signer number </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9329"/> + <source>mms signer [<number> <label> [<transport_address> [<monero_address>]]]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9348"/> + <source>Invalid Monero address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9355"/> + <source>Wallet state does not allow changing Monero addresses anymore</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9367"/> + <source>Usage: mms list</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9380"/> + <source>Usage: mms next [sync]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9405"/> + <source>No next step: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9415"/> + <source>prepare_multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9421"/> + <source>make_multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9436"/> + <source>exchange_multisig_keys</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9451"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9571"/> + <source>export_multisig_info</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9460"/> + <source>import_multisig_info</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9473"/> + <source>sign_multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9483"/> + <source>submit_multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9493"/> + <source>Send tx</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9504"/> + <source>Process signer config</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5526"/> - <source>usage: unspent_outputs [index=<N1>[,<N2>,...]] [<min_amount> [<max_amount>]]</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="9516"/> + <source>Replace current signer config with the one displayed above?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9530"/> + <source>Process auto config data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9544"/> + <source>Nothing ready to process</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9564"/> + <source>Usage: mms sync</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9588"/> + <source>Usage: mms delete (<message_id> | all)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9595"/> + <source>Delete all messages?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9621"/> + <source>Usage: mms send [<message_id>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9638"/> + <source>Usage: mms receive</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9655"/> + <source>Usage: mms export <message_id></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9667"/> + <source>Message content saved to: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9671"/> + <source>Failed to to save message content</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9695"/> + <source>Usage: mms note [<label> <text>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9702"/> + <source>No signer found with label </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9724"/> + <source>Usage: mms show <message_id></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9743"/> + <source>Usage: mms set <option_name> [<option_value>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9760"/> + <source>Wrong option value</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9765"/> + <source>Auto-send is on</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9765"/> + <source>Auto-send is off</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9770"/> + <source>Unknown option</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9778"/> + <source>Usage: mms help [<subcommand>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9794"/> + <source>Usage: mms send_signer_config</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9800"/> + <source>Signer config not yet complete</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9815"/> + <source>Usage: mms start_auto_config [<label> <label> ...]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9820"/> + <source>There are signers without a label set. Complete labels before auto-config or specify them as parameters here.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9826"/> + <source>Auto-config is already running. Cancel and restart?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9850"/> + <source>Usage: mms stop_auto_config</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9853"/> + <source>Delete any auto-config tokens and stop auto-config?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9866"/> + <source>Usage: mms auto_config <auto_config_token></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9873"/> + <source>Invalid auto-config token</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9879"/> + <source>Auto-config already running. Cancel and restart?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9911"/> + <source>The MMS is not active. Activate using the "mms init" command</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9988"/> + <source>Invalid MMS subcommand</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9993"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9997"/> + <source>Error in MMS command: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6969"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7079"/> + <source>Good signature</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6996"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7081"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7181"/> + <source>Bad signature</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8169"/> + <source>Standard address: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8174"/> + <source>failed to parse payment ID or address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5586"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8215"/> + <source>failed to parse payment ID</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8233"/> + <source>failed to parse index</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8241"/> + <source>Address book is empty.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8247"/> + <source>Index: </source> + <translation>インデックス: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8248"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8378"/> + <source>Address: </source> + <translation>アドレス: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8249"/> + <source>Payment ID: </source> + <translation>ペイメントID: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8250"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8377"/> + <source>Description: </source> + <translation>記述: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8407"/> + <source>wallet is watch-only and cannot sign</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1289"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8421"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8447"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8684"/> + <source>failed to read file </source> + <translation>ファイルの読み込みに失敗しました </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6958"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7072"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7166"/> + <source>failed to load signature file</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7020"/> + <source>wallet is watch-only and cannot generate the proof</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7104"/> + <source>The reserve proof can be generated only by a full wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7159"/> + <source>Address must not be a subaddress</source> + <translation>アドレスはサブアドレスであってはならないです</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7177"/> + <source>Good signature -- total: %s, spent: %s, unspent: %s</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7365"/> + <source>[Double spend seen on the network: this transaction may or may not end up being mined] </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7641"/> <source>There is no unspent output in the specified address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5699"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7799"/> <source> (no daemon)</source> <translation> (デーモンありません)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5701"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7801"/> <source> (out of sync)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5758"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7852"/> <source>(Untitled account)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5771"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5789"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5814"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5837"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5990"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6013"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7865"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7883"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7908"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7931"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8077"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8100"/> <source>failed to parse index: </source> <translation>インデックスの解析に失敗しました: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5776"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5995"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7870"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8082"/> <source>specify an index between 0 and </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5873"/> - <source>usage: - account - account new <label text with white spaces allowed> - account switch <index> - account label <index> <label text with white spaces allowed> - account tag <tag_name> <account_index_1> [<account_index_2> ...] - account untag <account_index_1> [<account_index_2> ...] - account tag_description <tag_name> <description></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5901"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7988"/> <source> Grand total: Balance: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5901"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7988"/> <source>, unlocked balance: </source> <translation>、ロック解除された残高: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5909"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7996"/> <source>Untagged accounts:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5915"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8002"/> <source>Tag %s is unregistered.</source> - <translation type="unfinished"></translation> + <translation type="unfinished">タグ %s を登録してません。</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5918"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8005"/> <source>Accounts with tag: </source> <translation>タグを持ってるアカウント: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5919"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8006"/> <source>Tag's description: </source> <translation>タグの記述: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5921"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8008"/> <source>Account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5927"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8014"/> <source> %c%8u %6s %21s %21s %21s</source> <translation> %c%8u %6s %21s %21s %21s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5937"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8024"/> <source>----------------------------------------------------------------------------------</source> <translation>----------------------------------------------------------------------------------</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5938"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8025"/> <source>%15s %21s %21s</source> <translation>%15s %21s %21s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5961"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8048"/> <source>Primary address</source> <translation>プライマリアドレス</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5961"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8048"/> <source>(used)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5982"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8069"/> <source>(Untitled address)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6022"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8109"/> <source><index_min> is already out of bound</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6027"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8114"/> <source><index_max> exceeds the bound</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6035"/> - <source>usage: address [ new <label text with white spaces allowed> | all | <index_min> [<index_max>] | label <index> <label text with white spaces allowed> ]</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6053"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6065"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8140"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8152"/> <source>Integrated addresses can only be created for account 0</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6077"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8164"/> <source>Integrated address: %s, payment ID: %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6082"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8169"/> <source>Subaddress: </source> <translation>サブアドレス: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6242"/> - <source>usage: get_description</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6248"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8335"/> <source>no description found</source> <translation>記述を見つかれませんでした</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6250"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8337"/> <source>description found: </source> <translation>記述を見つかれました: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6285"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8376"/> <source>Filename: </source> <translation>ファイル名: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6290"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8381"/> <source>Watch only</source> <translation>閲覧専用</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6292"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8383"/> <source>%u/%u multisig%s</source> <translation>%u/%u マルチサイン%s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6294"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8385"/> <source>Normal</source> <translation>ノーマル</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6295"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8386"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9180"/> <source>Type: </source> <translation>タイプ: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6296"/> - <source>Testnet: </source> - <translation>テストネット: </translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6296"/> - <source>Yes</source> - <translation>はい</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6296"/> - <source>No</source> - <translation>いいえ</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6314"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8412"/> <source>This wallet is multisig and cannot sign</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6335"/> - <source>usage: verify <filename> <address> <signature></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6360"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8461"/> <source>Bad signature from </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6364"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8465"/> <source>Good signature from </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6373"/> - <source>usage: export_key_images <filename></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6378"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8484"/> <source>wallet is watch-only and cannot export key images</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="906"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6391"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6473"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1228"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8498"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8651"/> <source>failed to save file </source> <translation>ファイルを保存できませんでした </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6402"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8509"/> <source>Signed key images exported to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6416"/> - <source>usage: import_key_images <filename></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6447"/> - <source>usage: export_outputs <filename></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6484"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8662"/> <source>Outputs exported to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6492"/> - <source>usage: import_outputs <filename></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3819"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5219"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5545"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5354"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6417"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7115"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7600"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7608"/> <source>amount is wrong: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3820"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5355"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6417"/> <source>expected number from 0 to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4079"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5721"/> <source>Sweeping </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4559"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6350"/> <source>Money successfully sent, transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4716"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6530"/> <source>Change goes to more than one address</source> - <translation type="unfinished"></translation> + <translation type="unfinished">お釣りは複数のアドレスに送ります</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4757"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6571"/> <source>%s change to %s</source> <translation>%s のお釣り %s に</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4760"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6574"/> <source>no change</source> <translation>お釣りありません</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1044"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1057"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4826"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1435"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1448"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6646"/> <source>Transaction successfully signed to file </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4876"/> - <source>usage: get_tx_key <txid></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4884"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4919"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4968"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5050"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5130"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5168"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6180"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6208"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6578"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6713"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6749"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6811"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6860"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6942"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7027"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7062"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8267"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8295"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8714"/> <source>failed to parse txid</source> <translation>txidの解析に失敗しました</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4898"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6727"/> <source>Tx key: </source> <translation>txキー: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4903"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6732"/> <source>no tx keys found for this txid</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4912"/> - <source>usage: get_tx_proof <txid> <address> [<message>]</source> - <translation type="unfinished"></translation> + <translation type="unfinished">このtxidのためにtxキーを見つかれませんでした</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4937"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5147"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5239"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6829"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7041"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7130"/> <source>signature file saved to: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4939"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5149"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5241"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6831"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7043"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7132"/> <source>failed to save signature file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4953"/> - <source>usage: check_tx_key <txid> <txkey> <address></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4976"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4985"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6868"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6877"/> <source>failed to parse tx key</source> <translation>txキーの解析に失敗しました</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4943"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5031"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5109"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6835"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6923"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7001"/> <source>error: </source> <translation>エラー: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5007"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5080"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6899"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6972"/> <source>received</source> <translation>貰いました</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5007"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5080"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6899"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6972"/> <source>in txid</source> <translation>txidに</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5026"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5099"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6918"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6991"/> <source>received nothing in txid</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5010"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5083"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6902"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6975"/> <source>WARNING: this transaction is not yet included in the blockchain!</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5016"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5089"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6908"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6981"/> <source>This transaction has %u confirmations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5020"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5093"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6912"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6985"/> <source>WARNING: failed to determine number of confirmations!</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5401"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7266"/> <source>bad min_height parameter:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5413"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7278"/> <source>bad max_height parameter:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5473"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7296"/> <source>in</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5473"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5514"/> - <source>out</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5514"/> - <source>failed</source> - <translation>失敗</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5514"/> - <source>pending</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5560"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7615"/> <source><min_amount> should be smaller than <max_amount></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5592"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7647"/> <source> Amount: </source> <translation> 金額: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5592"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7647"/> <source>, number of keys: </source> <translation>、キーの数: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5597"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7652"/> <source> </source> <translation> </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5602"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7657"/> <source> Min block height: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5603"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7658"/> <source> Max block height: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5604"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7659"/> <source> Min amount found: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5605"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7660"/> <source> Max amount found: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5606"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7661"/> <source> Total count: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5646"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7701"/> <source> Bin size: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5647"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7702"/> <source> Outputs per *: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5649"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7704"/> <source>count ^ </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5651"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7706"/> <source> |</source> <translation> |</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5653"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7708"/> <source> +</source> <translation> +</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5653"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7708"/> <source>+--> block height </source> <translation>+--> ブロック高 </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5654"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7709"/> <source> ^</source> <translation> ^</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5654"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7709"/> <source>^ </source> <translation>^ </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5655"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7710"/> <source> </source> <translation> </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5696"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7797"/> <source>wallet</source> <translation>ウォレット</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="666"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6057"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="870"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8144"/> <source>Random payment ID: </source> <translation>ランダムなペイメントID: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6058"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8145"/> <source>Matching integrated address: </source> <translation type="unfinished"></translation> </message> @@ -3551,19 +4538,29 @@ Outputs per *: </source> <translation>テストネットのマルチサインウォレットを作る</translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="81"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="75"/> + <source>Create stagenet multisig wallets</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="76"/> + <source>Create an address file for new wallets</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="83"/> <source>Generating %u %u/%u multisig wallets</source> <translation>%u %u/%u マルチサインウォレットを生じてます</translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="138"/> - <source>Error verifying multisig extra info</source> - <translation>マルチサインの追加情報を検証中にエラーありました</translation> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="107"/> + <source>Failed to verify multisig info</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="146"/> - <source>Error finalizing multisig</source> - <translation>マルチサイン締結中にエラーありました</translation> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="142"/> + <source>Error verifying multisig extra info</source> + <translation>マルチサインの追加情報を検証中にエラーありました</translation> </message> <message> <location filename="../src/gen_multisig/gen_multisig.cpp" line="153"/> @@ -3576,132 +4573,495 @@ Outputs per *: </source> <translation>マルチサインウォレットを樹立中にエラーありました: </translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="176"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="182"/> <source>This program generates a set of multisig wallets - use this simpler scheme only if all the participants trust each other</source> - <translation>このプログラムはマルチサインウォレットのセットを生じます - みんながみんなを信用する場合にだけこの単純なスキームを使ってください</translation> + <translation>このプログラムはマルチサインウォレットのセットを生じます - みんながみんなを信用する場合にだけこの単純なスキームを使ってください</translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="194"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="201"/> + <source>Error: Can't specify more than one of --testnet and --stagenet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="208"/> <source>Error: expected N/M, but got: </source> <translation>エラー: N/Mを欲しかったでもこれを貰いました: </translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="202"/> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="211"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="216"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="225"/> <source>Error: either --scheme or both of --threshold and --participants may be given</source> <translation>エラー: --scheme あるいは--threshold と --participants を上げられる</translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="218"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="232"/> <source>Error: expected N > 1 and N <= M, but got N==%u and M==%d</source> <translation>エラー: N > 1 と N <= M のこと欲しかったでも N==%u と M==%d を貰いました</translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="227"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="241"/> <source>Error: --filename-base is required</source> <translation>エラー: --filename-baseを使う必要だがあります</translation> </message> +</context> +<context> + <name>mms::message_store</name> + <message> + <location filename="../src/wallet/message_store.cpp" line="69"/> + <source>Use PyBitmessage instance at URL <arg></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="70"/> + <source>Specify <arg> as username:password for PyBitmessage API</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="832"/> + <source>Auto-config cannot proceed because auto config data from other signers is not complete</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="857"/> + <source>The signer config is not complete.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="909"/> + <source>Wallet can't go multisig because key sets from other signers are missing or not complete.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="951"/> + <source>Wallet can't start another key exchange round because key sets from other signers are missing or not complete.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1015"/> + <source>Syncing not done because multisig sync data from other signers are missing or not complete.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1129"/> + <source>There are waiting messages, but nothing is ready to process under normal circumstances</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1132"/> + <source> +Use "mms next sync" if you want to force processing of the waiting sync data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1136"/> + <source> +Use "mms note" to display the waiting notes</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1141"/> + <source>There are no messages waiting to be processed.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1359"/> + <source>key set</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1361"/> + <source>additional key set</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1363"/> + <source>multisig sync data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1365"/> + <source>partially signed tx</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1367"/> + <source>fully signed tx</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1369"/> + <source>note</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1371"/> + <source>signer config</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1373"/> + <source>auto-config data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1375"/> + <source>unknown message type</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1384"/> + <source>in</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1386"/> + <source>out</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1388"/> + <source>unknown message direction</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="233"/> - <source>Error: unsupported scheme: only N/N and N-1/N are supported</source> - <translation>エラー: 不正なスキーム: N/N や N-1/N`のことをできます</translation> + <location filename="../src/wallet/message_store.cpp" line="1397"/> + <source>ready to send</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1399"/> + <source>sent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1401"/> + <source>waiting</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1403"/> + <source>processed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1405"/> + <source>cancelled</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1407"/> + <source>unknown message state</source> + <translation type="unfinished"></translation> </message> </context> <context> <name>sw</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="115"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="125"/> <source>Generate new wallet and save it to <arg></source> <translation>新しいウォレットを生じろ <arg> をこっちにセーブしてください</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="116"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="126"/> + <source>Generate new wallet from device and save it to <arg></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="127"/> <source>Generate incoming-only wallet from view key</source> <translation>ビューキーで閲覧専用ウォレットを生じろください</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="117"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="128"/> <source>Generate deterministic wallet from spend key</source> <translation>スペンドキーで決定論的なウォレットを生じろください</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="118"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="129"/> <source>Generate wallet from private keys</source> <translation>秘密なキーでウォレットを生じろください</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="119"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="130"/> <source>Generate a master wallet from multisig wallet keys</source> <translation>マルチシガーウォレットキーでマスターウォレットを生じろください</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="121"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="132"/> <source>Language for mnemonic</source> <translation>ニーモニックのための言語</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="122"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="133"/> <source>Specify Electrum seed for wallet recovery/creation</source> <translation>ウォレットの回収や作成のためにElectrumなニーモニックシードを指定してください</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="123"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="134"/> <source>Recover wallet using Electrum-style mnemonic seed</source> <translation>Electrumなニーモニックシードでウォレットを復元してください</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="124"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="135"/> <source>Recover multisig wallet using Electrum-style mnemonic seed</source> <translation>Electrumなニーモニックシードでマルチシガーウォレットを復元してください</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="125"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="136"/> <source>Generate non-deterministic view and spend keys</source> <translation>非決定論的のビューとスペンドキーを生じろください</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="126"/> - <source>Enable commands which rely on a trusted daemon</source> - <translation>必要な信用できるデーモンのコマンドをエネーブルしてください</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="361"/> + <source>invalid argument: must be either 0/1, true/false, y/n, yes/no</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="127"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="417"/> + <source>DNSSEC validation passed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="421"/> + <source>WARNING: DNSSEC validation was unsuccessful, this address may not be correct!</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="424"/> + <source>For URL: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="426"/> + <source> Monero Address = </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="428"/> + <source>Is this OK? (Y/n) </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="438"/> + <source>you have cancelled the transfer request</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="459"/> + <source>failed to parse index: </source> + <translation type="unfinished">インデックスの解析に失敗しました: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="472"/> + <source>invalid format for subaddress lookahead; must be <major>:<minor></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="489"/> + <source>no connection to daemon. Please make sure daemon is running.</source> + <translation type="unfinished">デーモンの接続が確立ありません。デーモンが実行中になっていることを確認してください。</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="494"/> + <source>RPC error: </source> + <translation type="unfinished">RPCエラー: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="498"/> + <source>failed to get random outputs to mix: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="505"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="513"/> + <source>Not enough money in unlocked balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="523"/> + <source>Failed to find a way to create transactions. This is usually due to dust which is so small it cannot pay for itself in fees, or trying to send more money than the unlocked balance, or not leaving enough for fees</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="529"/> + <source>not enough outputs for specified ring size</source> + <translation type="unfinished">指定したリングサイズのアウトプットが不十分です</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="532"/> + <source>output amount</source> + <translation type="unfinished">アウトプットの金額</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="532"/> + <source>found outputs to use</source> + <translation type="unfinished">使うためにアウトプットを見つかれました</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="534"/> + <source>Please use sweep_unmixable.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="538"/> + <source>transaction was not constructed</source> + <translation type="unfinished">取引を作りませんでした</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="543"/> + <source>transaction %s was rejected by daemon with status: </source> + <translation type="unfinished">取引 %s がデーモンによって拒否しました。ステータス: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="546"/> + <source>Reason: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="555"/> + <source>one of destinations is zero</source> + <translation type="unfinished">宛先の1つはゼロです</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="560"/> + <source>failed to find a suitable way to split transactions</source> + <translation type="unfinished">取引を分割する適切な方法を見つけることができませんでした</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="566"/> + <source>unknown transfer error: </source> + <translation type="unfinished">不明な転送エラー: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="571"/> + <source>Multisig error: </source> + <translation type="unfinished">マルチサインエラー: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="577"/> + <source>internal error: </source> + <translation type="unfinished">内部エラー: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="582"/> + <source>unexpected error: </source> + <translation type="unfinished">予期せぬエラー: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="586"/> + <source>There was an error, which could mean the node may be trying to get you to retry creating a transaction, and zero in on which outputs you own. Or it could be a bona fide error. It may be prudent to disconnect from this node, and not try to send a transaction immediately. Alternatively, connect to another node so the original node cannot correlate information.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="596"/> + <source>File %s likely stores wallet private keys! Use a different file name.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="599"/> + <source>File %s already exists. Are you sure to overwrite it? (Y/Yes/N/No): </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7195"/> + <source> seconds</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7197"/> + <source> minutes</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7199"/> + <source> hours</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7201"/> + <source> days</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7203"/> + <source> months</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7204"/> + <source>a long time</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8940"/> + <source>This is the command line monero wallet. It needs to connect to a monero +daemon to work correctly. +WARNING: Do not reuse your Monero keys on another fork, UNLESS this fork has key reuse mitigations built in. Doing so will harm your privacy.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8965"/> + <source>Unknown command: </source> + <translation type="unfinished">未知のコマンド: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="137"/> <source>Allow communicating with a daemon that uses a different RPC version</source> <translation>別のRPCバージョンを使用してるデーモンとの通信を許可してください</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="128"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="138"/> <source>Restore from specific blockchain height</source> <translation>特定ブロックチェイン高で復元してください</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="129"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="139"/> <source>The newly created transaction will not be relayed to the monero network</source> <translation>新しい取引をネットワークに中継しません</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="171"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="140"/> + <source>Create an address file for new wallets</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="142"/> + <source>Display English language names</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="276"/> + <source>failed to read wallet password</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="283"/> + <source>Enter a new password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="283"/> + <source>Wallet password</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="293"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="485"/> <source>daemon is busy. Please try again later.</source> <translation>デーモンは忙しいです。後でもう一度試してください。</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="180"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="302"/> <source>possibly lost connection to daemon</source> <translation>デモンの接続が切れましたかもしりません</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="197"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="319"/> <source>Error: </source> <translation>エラー: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6787"/> - <source>This is the command line monero wallet. It needs to connect to a monero -daemon to work correctly.</source> - <translation>これはMoneroのコマンドラインウォレットです。別のMoneroデモンと接続する必要があります。</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6801"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8959"/> <source>Failed to initialize wallet</source> <translation>ウォレットを初期化できませんでした</translation> </message> @@ -3709,299 +5069,359 @@ daemon to work correctly.</source> <context> <name>tools::wallet2</name> <message> - <location filename="../src/wallet/wallet2.cpp" line="113"/> + <location filename="../src/wallet/wallet2.cpp" line="201"/> <source>Use daemon instance at <host>:<port></source> <translation><host>:<port>でデーモンインスタンスを使ってください</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="114"/> + <location filename="../src/wallet/wallet2.cpp" line="202"/> <source>Use daemon instance at host <arg> instead of localhost</source> <translation>localhostの代わりにホスト <arg>でデーモンインスタンスを使ってください</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="116"/> + <location filename="../src/wallet/wallet2.cpp" line="206"/> <source>Wallet password file</source> <translation>ウォレットのパスワードファイル</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="117"/> + <location filename="../src/wallet/wallet2.cpp" line="207"/> <source>Use daemon instance at port <arg> instead of 18081</source> <translation>18081の代わりにポート <arg>でデーモンインスタンスを使ってください</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="119"/> + <location filename="../src/wallet/wallet2.cpp" line="209"/> <source>For testnet. Daemon must also be launched with --testnet flag</source> <translation>テストネットのためにデーモンは --testnet のフラグで開始する必要があります</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="120"/> - <source>Restricts to view-only commands</source> - <translation>閲覧専用コマンドに限ります</translation> - </message> - <message> - <location filename="../src/wallet/wallet2.cpp" line="168"/> + <location filename="../src/wallet/wallet2.cpp" line="282"/> <source>can't specify daemon host or port more than once</source> <translation>デーモンのホストやポートを複数回指定することはできません</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="204"/> + <location filename="../src/wallet/wallet2.cpp" line="355"/> <source>can't specify more than one of --password and --password-file</source> <translation>--password と --passwordfile を1つしか指定しません</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="217"/> + <location filename="../src/wallet/wallet2.cpp" line="368"/> <source>the password file specified could not be read</source> <translation>指定されたパスワードファイルを読み取れません</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="240"/> + <location filename="../src/wallet/wallet2.cpp" line="394"/> <source>Failed to load file </source> <translation>ファイルのロードに失敗しました </translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="115"/> + <location filename="../src/wallet/wallet2.cpp" line="205"/> <source>Wallet password (escape/quote as needed)</source> <translation>ウォレットのパスワード(随時にエスケープ文字を使ってください)</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="118"/> + <location filename="../src/wallet/wallet2.cpp" line="203"/> + <source>Enable commands which rely on a trusted daemon</source> + <translation type="unfinished">必要な信用できるデーモンのコマンドをエネーブルしてください</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="204"/> + <source>Disable commands which rely on a trusted daemon</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="208"/> <source>Specify username[:password] for daemon RPC client</source> <translation>デーモンのRPCクライアントを使うためにユーザー名[:パスワード]を指定してください</translation> </message> <message> + <location filename="../src/wallet/wallet2.cpp" line="210"/> + <source>For stagenet. Daemon must also be launched with --stagenet flag</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="212"/> + <source>Set shared ring database path</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="223"/> + <source>Number of rounds for the key derivation function</source> + <translation type="unfinished"></translation> + </message> + <message> <location filename="../src/wallet/wallet2.cpp" line="224"/> + <source>HW device to use</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="225"/> + <source>HW device wallet derivation path (e.g., SLIP-10)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="313"/> + <source>--trusted-daemon and --untrusted-daemon are both seen, assuming untrusted</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="323"/> + <source>Daemon is local, assuming trusted</source> + <translation type="unfinished">デーモンはローカルです。信頼できるデーモン予期してます</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="375"/> <source>no password specified; use --prompt-for-password to prompt for a password</source> <translation>パスワードを指定しませんでした。パスワードプロンプトを見るために--prompt-for-password を使ってください</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="246"/> + <location filename="../src/wallet/wallet2.cpp" line="377"/> + <source>Enter a new password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="377"/> + <source>Wallet password</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="400"/> <source>Failed to parse JSON</source> <translation>JSONを解析に失敗しました</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="253"/> + <location filename="../src/wallet/wallet2.cpp" line="407"/> <source>Version %u too new, we can only grok up to %u</source> <translation>バージョン %u 新しすぎるです。%u までグロークできます</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="269"/> + <location filename="../src/wallet/wallet2.cpp" line="423"/> <source>failed to parse view key secret key</source> <translation>秘密なビューキーの解析に失敗しました</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="274"/> - <location filename="../src/wallet/wallet2.cpp" line="339"/> - <location filename="../src/wallet/wallet2.cpp" line="380"/> + <location filename="../src/wallet/wallet2.cpp" line="428"/> + <location filename="../src/wallet/wallet2.cpp" line="496"/> + <location filename="../src/wallet/wallet2.cpp" line="539"/> <source>failed to verify view key secret key</source> <translation>秘密なビューキーの検証に失敗しました</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="285"/> + <location filename="../src/wallet/wallet2.cpp" line="439"/> <source>failed to parse spend key secret key</source> <translation>秘密なスペンドキーの解析に失敗しました</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="290"/> - <location filename="../src/wallet/wallet2.cpp" line="349"/> - <location filename="../src/wallet/wallet2.cpp" line="405"/> + <location filename="../src/wallet/wallet2.cpp" line="444"/> + <location filename="../src/wallet/wallet2.cpp" line="506"/> + <location filename="../src/wallet/wallet2.cpp" line="565"/> <source>failed to verify spend key secret key</source> <translation>秘密なスペンドキーの検証に失敗しました</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="302"/> + <location filename="../src/wallet/wallet2.cpp" line="456"/> <source>Electrum-style word list failed verification</source> <translation>Electrumな単語表の検証に失敗しました</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="319"/> - <source>At least one of Electrum-style word list and private view key and private spend key must be specified</source> - <translation>Electrumな単語表と秘密なビューキーと秘密なスペンドキーの少なくとも1つを指定する必要があります</translation> + <location filename="../src/wallet/wallet2.cpp" line="476"/> + <source>At least one of either an Electrum-style word list, private view key, or private spend key must be specified</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="323"/> + <location filename="../src/wallet/wallet2.cpp" line="480"/> <source>Both Electrum-style word list and private key(s) specified</source> <translation>Electrumな単語表と秘密なキーを指定しました</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="333"/> + <location filename="../src/wallet/wallet2.cpp" line="490"/> <source>invalid address</source> <translation>不正なアドレス</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="342"/> + <location filename="../src/wallet/wallet2.cpp" line="499"/> <source>view key does not match standard address</source> <translation>ビューキーが一般的なアドレスと一致しませんでした</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="352"/> + <location filename="../src/wallet/wallet2.cpp" line="509"/> <source>spend key does not match standard address</source> <translation>スペンドキーが一般的なアドレスと一致しませんでした</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="360"/> + <location filename="../src/wallet/wallet2.cpp" line="517"/> <source>Cannot generate deprecated wallets from JSON</source> <translation>JSONで非推奨のウォレットを生成することはできません</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="392"/> + <location filename="../src/wallet/wallet2.cpp" line="551"/> <source>failed to parse address: </source> <translation>アドレスの解析に失敗しました: </translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="398"/> + <location filename="../src/wallet/wallet2.cpp" line="557"/> <source>Address must be specified in order to create watch-only wallet</source> <translation>閲覧専用ウォレットを作るためにアドレスを指定する必要があります</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="413"/> + <location filename="../src/wallet/wallet2.cpp" line="574"/> <source>failed to generate new wallet: </source> <translation>新しいウォレットの生成に失敗しました: </translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="2813"/> - <location filename="../src/wallet/wallet2.cpp" line="2873"/> - <location filename="../src/wallet/wallet2.cpp" line="2952"/> - <location filename="../src/wallet/wallet2.cpp" line="2998"/> - <location filename="../src/wallet/wallet2.cpp" line="3089"/> - <location filename="../src/wallet/wallet2.cpp" line="3189"/> - <location filename="../src/wallet/wallet2.cpp" line="3599"/> - <location filename="../src/wallet/wallet2.cpp" line="3955"/> + <location filename="../src/wallet/wallet2.cpp" line="1382"/> + <source>Password is needed to compute key image for incoming monero</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="1383"/> + <source>Invalid password: password is needed to compute key image for incoming monero</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="3770"/> + <location filename="../src/wallet/wallet2.cpp" line="4374"/> + <location filename="../src/wallet/wallet2.cpp" line="4926"/> <source>Primary account</source> <translation>プライマリア カウント</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="7914"/> + <location filename="../src/wallet/wallet2.cpp" line="10157"/> <source>No funds received in this tx.</source> <translation>この取引から資金貰いませんでした。</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="8607"/> + <location filename="../src/wallet/wallet2.cpp" line="10899"/> <source>failed to read file </source> <translation>ファイルの読み込みに失敗しました </translation> </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="141"/> + <source>Set subaddress lookahead sizes to <major>:<minor></source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>tools::wallet_rpc_server</name> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="160"/> - <source>Daemon is local, assuming trusted</source> - <translation>デーモンはローカルです。信頼できるデーモン予期してます</translation> - </message> - <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="175"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="180"/> <source>Failed to create directory </source> <translation>ディレクトリの作成に失敗しました </translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="177"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="182"/> <source>Failed to create directory %s: %s</source> <translation>%s %s ディレクトリの作成に失敗しました</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="188"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="193"/> <source>Cannot specify --</source> <translation>これを指定しません: --</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="188"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="193"/> <source> and --</source> <translation> と --</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="207"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="212"/> <source>Failed to create file </source> <translation>ファイルの作成に失敗しました </translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="207"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="212"/> <source>. Check permissions or remove file</source> <translation>。 パーミッションを確認するか、ファイルを削除してください</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="217"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="222"/> <source>Error writing to file </source> <translation>ファイルへの書き込みエラー </translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="220"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="225"/> <source>RPC username/password is stored in file </source> <translation>RPCユーザー名/パスワードはファイルに保存しました </translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="443"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="479"/> <source>Tag %s is unregistered.</source> <translation>タグ %s を登録してません。</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2435"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3081"/> <source>Transaction not possible. Available only %s, transaction amount %s = %s + %s (fee)</source> <translation>取引は無理です。利用可能な金額 %s、 取引の金額 %s = %s + %s (手数料)</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2870"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3947"/> <source>This is the RPC monero wallet. It needs to connect to a monero daemon to work correctly.</source> <translation>これはMoneroのコマンドラインウォレットです。別のMoneroデモンと接続する必要があります。</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2893"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3788"/> <source>Can't specify more than one of --wallet-file and --generate-from-json</source> <translation>--wallet-file と --generate-from-json を1つしか指定しません</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2905"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3773"/> + <source>Can't specify more than one of --testnet and --stagenet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3800"/> <source>Must specify --wallet-file or --generate-from-json or --wallet-dir</source> <translation>--wallet-file や --generate-from-json や --wallet-dir を指定する必要があります</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2909"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3804"/> <source>Loading wallet...</source> <translation>ウォレットをロードしてます...</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2942"/> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2975"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3838"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3870"/> <source>Saving wallet...</source> <translation>ウォレットを保存してます...</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2944"/> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2977"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3840"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3872"/> <source>Successfully saved</source> <translation>保存しました</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2947"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3843"/> <source>Successfully loaded</source> <translation>ロードしました</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2951"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3847"/> <source>Wallet initialization failed: </source> <translation>ウォレットを初期化できませんでした: </translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2958"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3853"/> <source>Failed to initialize wallet RPC server</source> <translation>ウォレットのRPCサーバを初期化できませんでした</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2962"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3857"/> <source>Starting wallet RPC server</source> <translation>ウォレットのRPCサーバを開始してます</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2969"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3864"/> <source>Failed to run wallet: </source> <translation>ウォレットを起動することできませんでした: </translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2972"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3867"/> <source>Stopped wallet RPC server</source> <translation>ウォレットのRPCサーバを停止しました</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2981"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3876"/> <source>Failed to save wallet: </source> <translation>ウォレットを保存することできませんでした: </translation> </message> @@ -4009,9 +5429,9 @@ daemon to work correctly.</source> <context> <name>wallet_args</name> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="166"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6760"/> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2856"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="168"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8908"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3928"/> <source>Wallet options</source> <translation>ウォレットのオプション</translation> </message> @@ -4026,48 +5446,58 @@ daemon to work correctly.</source> <translation>ウォレットの <arg> を使てください</translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="104"/> + <location filename="../src/wallet/wallet_args.cpp" line="105"/> <source>Max number of threads to use for a parallel job</source> <translation>並列ジョブのために最大スレッドの数</translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="105"/> + <location filename="../src/wallet/wallet_args.cpp" line="106"/> <source>Specify log file</source> <translation>ログファイルを指定してください</translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="106"/> + <location filename="../src/wallet/wallet_args.cpp" line="107"/> <source>Config file</source> <translation>設定ファイル</translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="115"/> + <location filename="../src/wallet/wallet_args.cpp" line="119"/> <source>General options</source> <translation>ジェネラルオプション</translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="138"/> + <location filename="../src/wallet/wallet_args.cpp" line="144"/> <source>This is the command line monero wallet. It needs to connect to a monero daemon to work correctly.</source> <translation>これはMoneroのコマンドラインウォレットです。別のMoneroデモンと接続する必要があります。</translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="161"/> + <location filename="../src/wallet/wallet_args.cpp" line="169"/> <source>Can't find config file </source> <translation>設定ファイルを見つかりませんでした </translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="195"/> + <location filename="../src/wallet/wallet_args.cpp" line="210"/> <source>Logging to: </source> <translation>こっちにログをしてます: </translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="197"/> + <location filename="../src/wallet/wallet_args.cpp" line="212"/> <source>Logging to %s</source> <translation>%s にログをしてます</translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="140"/> + <location filename="../src/wallet/wallet_args.cpp" line="216"/> + <source>WARNING: You may not have a high enough lockable memory limit</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="218"/> + <source>see ulimit -l</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="146"/> <source>Usage:</source> <translation>使用:</translation> </message> diff --git a/translations/monero_sv.ts b/translations/monero_sv.ts index 26ad43f7b..f4704fdd6 100644 --- a/translations/monero_sv.ts +++ b/translations/monero_sv.ts @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> -<TS version="2.1"> +<TS version="2.0"> <context> <name>Monero::AddressBookImpl</name> <message> @@ -27,45 +27,55 @@ <context> <name>Monero::PendingTransactionImpl</name> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="90"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="91"/> <source>Attempting to save transaction to file, but specified file(s) exist. Exiting to not risk overwriting. File:</source> <translation>Försöker spara transaktion till fil, men angiven fil finns redan. Avslutar för att inte riskera att skriva över någonting. Fil:</translation> </message> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="97"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="98"/> <source>Failed to write transaction(s) to file</source> <translation>Det gick inte att skriva transaktioner till fil</translation> </message> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="115"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="121"/> <source>daemon is busy. Please try again later.</source> <translation>daemonen är upptagen. Försök igen senare.</translation> </message> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="118"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="124"/> <source>no connection to daemon. Please make sure daemon is running.</source> <translation>ingen anslutning till daemonen. Se till att daemonen körs.</translation> </message> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="122"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="128"/> <source>transaction %s was rejected by daemon with status: </source> <translation>transaktionen %s avvisades av daemonen med status: </translation> </message> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="127"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="133"/> <source>. Reason: </source> <translation>. Orsak: </translation> </message> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="129"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="135"/> <source>Unknown exception: </source> <translation>Okänt undantag: </translation> </message> <message> - <location filename="../src/wallet/api/pending_transaction.cpp" line="132"/> + <location filename="../src/wallet/api/pending_transaction.cpp" line="138"/> <source>Unhandled exception</source> <translation>Ohanterat undantag</translation> </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="211"/> + <source>Couldn't multisig sign data: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="233"/> + <source>Couldn't sign multisig transaction: </source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Monero::UnsignedTransactionImpl</name> @@ -124,281 +134,407 @@ <context> <name>Monero::WalletImpl</name> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1111"/> + <location filename="../src/wallet/api/wallet.cpp" line="1383"/> <source>payment id has invalid format, expected 16 or 64 character hex string: </source> <translation>betalnings-ID har ogiltigt format. En hexadecimal sträng med 16 eller 64 tecken förväntades: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1121"/> + <location filename="../src/wallet/api/wallet.cpp" line="1392"/> <source>Failed to add short payment id: </source> <translation>Det gick inte att lägga till kort betalnings-ID: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1154"/> - <location filename="../src/wallet/api/wallet.cpp" line="1258"/> + <location filename="../src/wallet/api/wallet.cpp" line="1428"/> + <location filename="../src/wallet/api/wallet.cpp" line="1510"/> <source>daemon is busy. Please try again later.</source> <translation>daemonen är upptagen. Försök igen senare.</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1157"/> - <location filename="../src/wallet/api/wallet.cpp" line="1261"/> + <location filename="../src/wallet/api/wallet.cpp" line="1430"/> + <location filename="../src/wallet/api/wallet.cpp" line="1512"/> <source>no connection to daemon. Please make sure daemon is running.</source> <translation>ingen anslutning till daemonen. Se till att daemonen körs.</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1160"/> - <location filename="../src/wallet/api/wallet.cpp" line="1264"/> + <location filename="../src/wallet/api/wallet.cpp" line="1432"/> + <location filename="../src/wallet/api/wallet.cpp" line="1514"/> <source>RPC error: </source> <translation>RPC-fel: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1197"/> - <location filename="../src/wallet/api/wallet.cpp" line="1301"/> + <location filename="../src/wallet/api/wallet.cpp" line="1460"/> + <location filename="../src/wallet/api/wallet.cpp" line="1545"/> <source>not enough outputs for specified ring size</source> <translation>inte tillräckligt med utgångar för angiven ringstorlek</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1199"/> - <location filename="../src/wallet/api/wallet.cpp" line="1303"/> + <location filename="../src/wallet/api/wallet.cpp" line="1462"/> + <location filename="../src/wallet/api/wallet.cpp" line="1547"/> <source>found outputs to use</source> <translation>hittade utgångar att använda</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1201"/> + <location filename="../src/wallet/api/wallet.cpp" line="1464"/> <source>Please sweep unmixable outputs.</source> <translation>Svep upp omixbara utgångar.</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1267"/> - <source>failed to get random outputs to mix</source> - <translation>det gick inte att hämta slumpmässiga utgångar att mixa</translation> - </message> - <message> - <location filename="../src/wallet/api/wallet.cpp" line="1170"/> - <location filename="../src/wallet/api/wallet.cpp" line="1274"/> + <location filename="../src/wallet/api/wallet.cpp" line="1438"/> + <location filename="../src/wallet/api/wallet.cpp" line="1521"/> <source>not enough money to transfer, available only %s, sent amount %s</source> <translation>inte tillräckligt med pengar för överföring, endast tillgängligt %s, skickat belopp %s</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="474"/> + <location filename="../src/wallet/api/wallet.cpp" line="541"/> <source>failed to parse address</source> <translation>det gick inte att parsa adressen</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="486"/> + <location filename="../src/wallet/api/wallet.cpp" line="552"/> <source>failed to parse secret spend key</source> <translation>det gick inte att parsa hemlig spendernyckel</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="496"/> - <source>No view key supplied, cancelled</source> - <translation>Ingen granskningsnyckel angiven, avbruten</translation> - </message> - <message> - <location filename="../src/wallet/api/wallet.cpp" line="503"/> + <location filename="../src/wallet/api/wallet.cpp" line="575"/> <source>failed to parse secret view key</source> <translation>det gick inte att parsa hemlig granskningsnyckel</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="513"/> + <location filename="../src/wallet/api/wallet.cpp" line="584"/> <source>failed to verify secret spend key</source> <translation>det gick inte att verifiera hemlig spendernyckel</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="518"/> + <location filename="../src/wallet/api/wallet.cpp" line="588"/> <source>spend key does not match address</source> <translation>spendernyckel matchar inte adress</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="524"/> + <location filename="../src/wallet/api/wallet.cpp" line="594"/> <source>failed to verify secret view key</source> <translation>det gick inte att verifiera hemlig granskningsnyckel</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="529"/> + <location filename="../src/wallet/api/wallet.cpp" line="598"/> <source>view key does not match address</source> <translation>granskningsnyckel matchar inte adress</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="548"/> + <location filename="../src/wallet/api/wallet.cpp" line="621"/> + <location filename="../src/wallet/api/wallet.cpp" line="638"/> <source>failed to generate new wallet: </source> <translation>det gick inte att skapa ny plånbok: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="773"/> + <location filename="../src/wallet/api/wallet.cpp" line="885"/> <source>Failed to send import wallet request</source> <translation>Det gick inte att skicka begäran om att importera plånbok</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="919"/> + <location filename="../src/wallet/api/wallet.cpp" line="1049"/> <source>Failed to load unsigned transactions</source> <translation>Det gick inte att läsa in osignerade transaktioner</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="940"/> + <location filename="../src/wallet/api/wallet.cpp" line="1068"/> <source>Failed to load transaction from file</source> <translation>Det gick inte att läsa in transaktion från fil</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="958"/> + <location filename="../src/wallet/api/wallet.cpp" line="1084"/> <source>Wallet is view only</source> <translation>Plånboken är endast för granskning</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="967"/> + <location filename="../src/wallet/api/wallet.cpp" line="1092"/> <source>failed to save file </source> <translation>det gick inte att spara fil </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="986"/> + <location filename="../src/wallet/api/wallet.cpp" line="1108"/> <source>Key images can only be imported with a trusted daemon</source> <translation>Nyckelavbildningar kan bara importeras med en betrodd daemon</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="999"/> + <location filename="../src/wallet/api/wallet.cpp" line="1121"/> <source>Failed to import key images: </source> <translation>Det gick inte att importera nyckelavbildningar: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1032"/> + <location filename="../src/wallet/api/wallet.cpp" line="1153"/> <source>Failed to get subaddress label: </source> <translation>Det gick inte att hämta etikett för underadress: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1046"/> + <location filename="../src/wallet/api/wallet.cpp" line="1166"/> <source>Failed to set subaddress label: </source> <translation>Det gick inte att ange etikett för underadress: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1163"/> - <source>failed to get random outputs to mix: %s</source> - <translation>det gick inte att hitta slumpmässiga utgångar att mixa: %s</translation> + <location filename="../src/wallet/api/wallet.cpp" line="567"/> + <source>Neither view key nor spend key supplied, cancelled</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="686"/> + <source>Electrum seed is empty</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="695"/> + <source>Electrum-style word list failed verification</source> + <translation type="unfinished">Det gick inte att verifiera ordlista av Electrum-typ</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1183"/> + <source>Failed to get multisig info: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1200"/> + <location filename="../src/wallet/api/wallet.cpp" line="1214"/> + <source>Failed to make multisig: </source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1179"/> - <location filename="../src/wallet/api/wallet.cpp" line="1283"/> + <location filename="../src/wallet/api/wallet.cpp" line="1229"/> + <source>Failed to finalize multisig wallet creation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1232"/> + <source>Failed to finalize multisig wallet creation: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1248"/> + <source>Failed to export multisig images: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1266"/> + <source>Failed to parse imported multisig images</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1276"/> + <source>Failed to import multisig images: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1290"/> + <source>Failed to check for partial multisig key images: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1318"/> + <source>Failed to restore multisig transaction: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1358"/> + <source>Invalid destination address</source> + <translation type="unfinished">Ogiltig måladress</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1434"/> + <source>failed to get outputs to mix: %s</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1445"/> + <location filename="../src/wallet/api/wallet.cpp" line="1529"/> <source>not enough money to transfer, overall balance only %s, sent amount %s</source> <translation>inte tillräckligt med pengar för överföring, totalt saldo är bara %s, skickat belopp %s</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1188"/> - <location filename="../src/wallet/api/wallet.cpp" line="1292"/> + <location filename="../src/wallet/api/wallet.cpp" line="1452"/> + <location filename="../src/wallet/api/wallet.cpp" line="1537"/> <source>not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)</source> <translation>ej tillräckligt med pengar för överföring, endast tillgängligt %s, transaktionsbelopp %s = %s + %s (avgift)</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1199"/> - <location filename="../src/wallet/api/wallet.cpp" line="1303"/> + <location filename="../src/wallet/api/wallet.cpp" line="1462"/> + <location filename="../src/wallet/api/wallet.cpp" line="1547"/> <source>output amount</source> <translation>utgångens belopp</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1205"/> - <location filename="../src/wallet/api/wallet.cpp" line="1308"/> + <location filename="../src/wallet/api/wallet.cpp" line="1467"/> + <location filename="../src/wallet/api/wallet.cpp" line="1551"/> <source>transaction was not constructed</source> <translation>transaktionen konstruerades inte</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1209"/> - <location filename="../src/wallet/api/wallet.cpp" line="1312"/> + <location filename="../src/wallet/api/wallet.cpp" line="1470"/> + <location filename="../src/wallet/api/wallet.cpp" line="1554"/> <source>transaction %s was rejected by daemon with status: </source> <translation>transaktionen %s avvisades av daemonen med status: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1216"/> - <location filename="../src/wallet/api/wallet.cpp" line="1319"/> + <location filename="../src/wallet/api/wallet.cpp" line="1475"/> + <location filename="../src/wallet/api/wallet.cpp" line="1559"/> <source>one of destinations is zero</source> <translation>ett av målen är noll</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1219"/> - <location filename="../src/wallet/api/wallet.cpp" line="1322"/> + <location filename="../src/wallet/api/wallet.cpp" line="1477"/> + <location filename="../src/wallet/api/wallet.cpp" line="1561"/> <source>failed to find a suitable way to split transactions</source> <translation>det gick inte att hitta ett lämpligt sätt att dela upp transaktioner</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1222"/> - <location filename="../src/wallet/api/wallet.cpp" line="1325"/> + <location filename="../src/wallet/api/wallet.cpp" line="1479"/> + <location filename="../src/wallet/api/wallet.cpp" line="1563"/> <source>unknown transfer error: </source> <translation>okänt överföringsfel: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1225"/> - <location filename="../src/wallet/api/wallet.cpp" line="1328"/> + <location filename="../src/wallet/api/wallet.cpp" line="1481"/> + <location filename="../src/wallet/api/wallet.cpp" line="1565"/> <source>internal error: </source> <translation>internt fel: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1228"/> - <location filename="../src/wallet/api/wallet.cpp" line="1331"/> + <location filename="../src/wallet/api/wallet.cpp" line="1483"/> + <location filename="../src/wallet/api/wallet.cpp" line="1567"/> <source>unexpected error: </source> <translation>oväntat fel: </translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1231"/> - <location filename="../src/wallet/api/wallet.cpp" line="1334"/> + <location filename="../src/wallet/api/wallet.cpp" line="1485"/> + <location filename="../src/wallet/api/wallet.cpp" line="1569"/> <source>unknown error</source> <translation>okänt fel</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1412"/> - <location filename="../src/wallet/api/wallet.cpp" line="1441"/> - <location filename="../src/wallet/api/wallet.cpp" line="1494"/> - <location filename="../src/wallet/api/wallet.cpp" line="1525"/> - <location filename="../src/wallet/api/wallet.cpp" line="1556"/> - <location filename="../src/wallet/api/wallet.cpp" line="1579"/> + <location filename="../src/wallet/api/wallet.cpp" line="1516"/> + <source>failed to get outputs to mix</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1644"/> + <location filename="../src/wallet/api/wallet.cpp" line="1671"/> + <location filename="../src/wallet/api/wallet.cpp" line="1719"/> + <location filename="../src/wallet/api/wallet.cpp" line="1747"/> + <location filename="../src/wallet/api/wallet.cpp" line="1775"/> + <location filename="../src/wallet/api/wallet.cpp" line="1796"/> + <location filename="../src/wallet/api/wallet.cpp" line="2258"/> <source>Failed to parse txid</source> <translation>Det gick inte att parsa txid</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1430"/> + <location filename="../src/wallet/api/wallet.cpp" line="1661"/> <source>no tx keys found for this txid</source> <translation>inga tx-nycklar kunde hittas för detta txid</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1450"/> - <location filename="../src/wallet/api/wallet.cpp" line="1460"/> + <location filename="../src/wallet/api/wallet.cpp" line="1679"/> + <location filename="../src/wallet/api/wallet.cpp" line="1688"/> <source>Failed to parse tx key</source> <translation>Det gick inte att parsa txnyckel</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1470"/> - <location filename="../src/wallet/api/wallet.cpp" line="1502"/> - <location filename="../src/wallet/api/wallet.cpp" line="1533"/> - <location filename="../src/wallet/api/wallet.cpp" line="1621"/> + <location filename="../src/wallet/api/wallet.cpp" line="1697"/> + <location filename="../src/wallet/api/wallet.cpp" line="1726"/> + <location filename="../src/wallet/api/wallet.cpp" line="1754"/> + <location filename="../src/wallet/api/wallet.cpp" line="1835"/> <source>Failed to parse address</source> <translation>Det gick inte att parsa adressen</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1627"/> + <location filename="../src/wallet/api/wallet.cpp" line="1840"/> <source>Address must not be a subaddress</source> <translation>Adressen får inte vara en underadress</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="1849"/> + <location filename="../src/wallet/api/wallet.cpp" line="1880"/> + <source>The wallet must be in multisig ready state</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1902"/> + <source>Given string is not a key</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2130"/> <source>Rescan spent can only be used with a trusted daemon</source> <translation>Genomsök efter spenderade kan endast användas med en betrodd daemon</translation> </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2179"/> + <source>Invalid output: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2186"/> + <source>Failed to mark outputs as spent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2197"/> + <location filename="../src/wallet/api/wallet.cpp" line="2219"/> + <source>Failed to parse output amount</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2202"/> + <location filename="../src/wallet/api/wallet.cpp" line="2224"/> + <source>Failed to parse output offset</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2208"/> + <source>Failed to mark output as spent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2230"/> + <source>Failed to mark output as unspent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2241"/> + <location filename="../src/wallet/api/wallet.cpp" line="2280"/> + <source>Failed to parse key image</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2247"/> + <source>Failed to get ring</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2265"/> + <source>Failed to get rings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="2286"/> + <source>Failed to set ring</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Wallet</name> <message> - <location filename="../src/wallet/api/wallet.cpp" line="246"/> + <location filename="../src/wallet/api/wallet.cpp" line="301"/> <source>Failed to parse address</source> <translation>Det gick inte att parsa adressen</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="253"/> + <location filename="../src/wallet/api/wallet.cpp" line="308"/> <source>Failed to parse key</source> <translation>Det gick inte att parsa nyckeln</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="261"/> + <location filename="../src/wallet/api/wallet.cpp" line="316"/> <source>failed to verify key</source> <translation>det gick inte att verifiera nyckeln</translation> </message> <message> - <location filename="../src/wallet/api/wallet.cpp" line="271"/> + <location filename="../src/wallet/api/wallet.cpp" line="326"/> <source>key does not match address</source> <translation>nyckeln matchar inte adressen</translation> </message> @@ -406,12 +542,12 @@ <context> <name>command_line</name> <message> - <location filename="../src/common/command_line.cpp" line="57"/> + <location filename="../src/common/command_line.cpp" line="54"/> <source>yes</source> <translation>ja</translation> </message> <message> - <location filename="../src/common/command_line.cpp" line="71"/> + <location filename="../src/common/command_line.cpp" line="68"/> <source>no</source> <translation>nej</translation> </message> @@ -449,18 +585,18 @@ <translation> tillåter inkommande okrypterade externa anslutningar. Överväg att använda SSH-tunnel eller SSL-proxy istället. Åsidosätt med --</translation> </message> <message> - <location filename="../src/rpc/rpc_args.cpp" line="95"/> + <location filename="../src/rpc/rpc_args.cpp" line="101"/> <source>Username specified with --</source> <translation>Användarnamn angivet med --</translation> </message> <message> - <location filename="../src/rpc/rpc_args.cpp" line="95"/> - <location filename="../src/rpc/rpc_args.cpp" line="105"/> + <location filename="../src/rpc/rpc_args.cpp" line="101"/> + <location filename="../src/rpc/rpc_args.cpp" line="111"/> <source> cannot be empty</source> <translation> får inte vara tomt</translation> </message> <message> - <location filename="../src/rpc/rpc_args.cpp" line="105"/> + <location filename="../src/rpc/rpc_args.cpp" line="111"/> <source> requires RPC server password --</source> <translation> kräver lösenord till RPC-server --</translation> </message> @@ -468,1372 +604,1091 @@ <context> <name>cryptonote::simple_wallet</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="479"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="645"/> <source>Commands: </source> <translation>Kommandon: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3008"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4359"/> <source>failed to read wallet password</source> <translation>det gick inte att läsa lösenord för plånboken</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2699"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3954"/> <source>invalid password</source> <translation>ogiltigt lösenord</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1905"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3073"/> <source>set seed: needs an argument. available options: language</source> <translation>set seed: kräver ett argument. tillgängliga alternativ: språk</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1933"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3108"/> <source>set: unrecognized argument(s)</source> <translation>set: okända argument</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2869"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4199"/> <source>wallet file path not valid: </source> <translation>ogiltig sökväg till plånbok: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1987"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3178"/> <source>Attempting to generate or restore wallet, but specified file(s) exist. Exiting to not risk overwriting.</source> <translation>Försöker skapa eller återställa plånbok, men angivna filer finns redan. Avslutar för att inte riskera att skriva över någonting.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="662"/> - <source>usage: payment_id</source> - <translation>användning: payment_id</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1891"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3059"/> <source>needs an argument</source> <translation>kräver ett argument</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1914"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1915"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1916"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1918"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1921"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1922"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1926"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1927"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1929"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1931"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3082"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3083"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3084"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3086"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3089"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3094"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3095"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3097"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3099"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3100"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3101"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3104"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3105"/> <source>0 or 1</source> <translation>0 eller 1</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1920"/> - <source>0, 1, 2, 3, or 4</source> - <translation>0, 1, 2, 3 eller 4</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1924"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1928"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3092"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3096"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3103"/> <source>unsigned integer</source> <translation>positivt heltal</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2041"/> - <source>NOTE: the following 25 words can be used to recover access to your wallet. Write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control. -</source> - <translation>OBS: följande 25 ord kan användas för att återställa åtkomst till din plånbok. Skriv ner och spara dem på ett säkert ställe. Spara dem inte i din e-post eller på något lagringsutrymme som du inte har direkt kontroll över. -</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2092"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3312"/> <source>--restore-deterministic-wallet uses --generate-new-wallet, not --wallet-file</source> <translation>--restore-deterministic-wallet använder --generate-new-wallet, inte --wallet-file</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2121"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3341"/> <source>specify a recovery parameter with the --electrum-seed="words list here"</source> <translation>ange en återställningsparameter med --electrum-seed="ordlista här"</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2471"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3717"/> <source>specify a wallet path with --generate-new-wallet (not --wallet-file)</source> <translation>ange sökväg till en plånbok med --generate-new-wallet (inte --wallet-file)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2635"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3887"/> <source>wallet failed to connect to daemon: </source> <translation>plånboken kunde inte ansluta till daemonen: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2643"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3895"/> <source>Daemon uses a different RPC major version (%u) than the wallet (%u): %s. Either update one of them, or use --allow-mismatched-daemon-version.</source> <translation>Daemonen använder en högre version av RPC (%u) än plånboken (%u): %s. Antingen uppdatera en av dem, eller använd --allow-mismatched-daemon-version.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2662"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3916"/> <source>List of available languages for your wallet's seed:</source> <translation>Lista över tillgängliga språk för din plånboks startvärde:</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2671"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3926"/> <source>Enter the number corresponding to the language of your choice: </source> <translation>Ange det tal som motsvarar det språk du vill använda: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2737"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4000"/> <source>You had been using a deprecated version of the wallet. Please use the new seed that we provide. </source> <translation>Du hade använt en inaktuell version av plånboken. Använd det nya startvärde som tillhandahålls. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2751"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2809"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4016"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4088"/> <source>Generated new wallet: </source> <translation>Ny plånbok skapad: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2757"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2814"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2858"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4025"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4093"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4135"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4188"/> <source>failed to generate new wallet: </source> <translation>det gick inte att skapa ny plånbok: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2887"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4230"/> <source>Opened watch-only wallet</source> <translation>Öppnade plånbok för granskning</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2891"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4234"/> <source>Opened wallet</source> <translation>Öppnade plånbok</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2901"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4252"/> <source>You had been using a deprecated version of the wallet. Please proceed to upgrade your wallet. </source> <translation>Du hade använt en inaktuell version av plånboken. Fortsätt för att uppgradera din plånbok. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2916"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4267"/> <source>You had been using a deprecated version of the wallet. Your wallet file format is being upgraded now. </source> <translation>Du hade använt en inaktuell version av plånboken. Plånbokens filformat kommer nu att uppgraderas. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2924"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4275"/> <source>failed to load wallet: </source> <translation>det gick inte att läsa in plånboken: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2941"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4292"/> <source>Use the "help" command to see the list of available commands. </source> <translation>Använd kommandot "help" för att visa en lista över tillgängliga kommandon. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2986"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4337"/> <source>Wallet data saved</source> <translation>Plånboksdata sparades</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3072"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4431"/> <source>Mining started in daemon</source> <translation>Brytning startad i daemonen</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3074"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4433"/> <source>mining has NOT been started: </source> <translation>brytning har INTE startats: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3093"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4453"/> <source>Mining stopped in daemon</source> <translation>Brytning stoppad i daemonen</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3095"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4455"/> <source>mining has NOT been stopped: </source> <translation>brytning har INTE stoppats: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3150"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4537"/> <source>Blockchain saved</source> <translation>Blockkedjan sparades</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3165"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3183"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3196"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4552"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4589"/> <source>Height </source> <translation>Höjd </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3197"/> - <source>transaction </source> - <translation>transaktion </translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3185"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4591"/> <source>spent </source> <translation>spenderat </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3198"/> - <source>unsupported transaction format</source> - <translation>transaktionsformatet stöds inte</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3219"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4698"/> <source>Starting refresh...</source> <translation>Startar uppdatering …</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3232"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4712"/> <source>Refresh done, blocks received: </source> <translation>Uppdatering färdig, mottagna block: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3758"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4230"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5958"/> <source>payment id has invalid format, expected 16 or 64 character hex string: </source> <translation>betalnings-ID har ogiltigt format. En hexadecimal sträng med 16 eller 64 tecken förväntades: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3773"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5307"/> <source>bad locked_blocks parameter:</source> <translation>felaktig parameter för locked_blocks:</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3801"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4248"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4462"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5978"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6251"/> <source>a single transaction cannot use more than one payment id: </source> <translation>en enda transaktion kan inte använda fler än ett betalnings-ID: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3810"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4257"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4430"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4470"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5405"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5987"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6219"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6259"/> <source>failed to set up payment id, though it was decoded correctly</source> <translation>det gick inte att upprätta betalnings-ID, trots att det avkodades korrekt</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3835"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3916"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3987"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4096"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4271"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4329"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4484"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4527"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5251"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5870"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6173"/> + <source>ring size %u is too large, maximum is %u</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5276"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5395"/> + <source>Unencrypted payment IDs are bad for privacy: ask the recipient to use subaddresses instead</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5293"/> + <source>payment id failed to encode</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5312"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5894"/> + <source>Locked blocks too high, max 1000000 (Ë4 yrs)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5340"/> + <source>failed to parse short payment ID from URI</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5363"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5365"/> + <source>Invalid last argument: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5382"/> + <source>a single transaction cannot use more than one payment id</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5399"/> + <source>failed to parse payment id, though it was detected</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5422"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5502"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5590"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5738"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6001"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6059"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6273"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6318"/> <source>transaction cancelled.</source> <translation>transaktion avbruten.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3895"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3905"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5481"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5491"/> <source>Is this okay anyway? (Y/Yes/N/No): </source> <translation>Är detta okej ändå? (J/Ja/N/Nej): </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3900"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5486"/> <source>There is currently a %u block backlog at that fee level. Is this okay? (Y/Yes/N/No): </source> <translation>Det finns för närvarande en %u blocks eftersläpning på den avgiftsnivån. Är detta okej? (J/Ja/N/Nej): </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3905"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5491"/> <source>Failed to check for backlog: </source> <translation>Det gick inte att kontrollera eftersläpning: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3946"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4302"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5532"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6032"/> <source> Transaction </source> <translation> Transaktion </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3951"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4307"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5537"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6037"/> <source>Spending from address index %d </source> <translation>Spendera från adressindex %d </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3953"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4309"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5539"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6039"/> <source>WARNING: Outputs of multiple addresses are being used together, which might potentially compromise your privacy. </source> <translation>VARNING: Utgångar från flera adresser används tillsammans, vilket möjligen kan kompromettera din sekretess. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3955"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5541"/> <source>Sending %s. </source> <translation>Skickar %s. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3958"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5544"/> <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>Transaktionen behöver delas upp i %llu transaktioner. Detta gör att en transaktionsavgift läggs till varje transaktion, med ett totalbelopp på %s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3964"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5550"/> <source>The transaction fee is %s</source> <translation>Transaktionsavgiften är %s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3967"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5553"/> <source>, of which %s is dust from change</source> <translation>, varav %s är damm från växel</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3968"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5554"/> <source>.</source> <translation>.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3968"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5554"/> <source>A total of %s from dust change will be sent to dust address</source> <translation>Ett totalt belopp på %s från växeldamm skickas till damm-adressen</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3973"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5559"/> <source>. This transaction will unlock on block %llu, in approximately %s days (assuming 2 minutes per block)</source> <translation>. Denna transaktion låses upp vid block %llu, om ungefär %s dagar (förutsatt en blocktid på 2 minuter)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3999"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4011"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4107"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4119"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4340"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4352"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4537"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4549"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5603"/> + <source>Unsigned transaction(s) successfully written to MMS</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5611"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5648"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5749"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5761"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6070"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6107"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6328"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6340"/> <source>Failed to write transaction(s) to file</source> <translation>Det gick inte att skriva transaktioner till fil</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4003"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4015"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4111"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4123"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4344"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4356"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4541"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5616"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5653"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5753"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5765"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6074"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6111"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6332"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6344"/> <source>Unsigned transaction(s) successfully written to file: </source> <translation>Osignerade transaktioner skrevs till fil: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4066"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5625"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6086"/> + <source>Failed to cold sign transaction with HW wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5708"/> <source>No unmixable outputs found</source> <translation>Inga omixbara utgångar kunde hittas</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4149"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5775"/> + <source>Not enough money in unlocked balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5776"/> + <source>Discarding %s of unmixable outputs that cannot be spent, which can be undone by "rescan_spent". Is this okay? (Y/Yes/N/No): </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5815"/> <source>No address given</source> <translation>Ingen adress har angivits</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4424"/> - <source>failed to parse Payment ID</source> - <translation>det gick inte att parsa betalnings-ID</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="5879"/> + <source>missing lockedblocks parameter</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5889"/> + <source>bad locked_blocks parameter</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4440"/> - <source>usage: sweep_single [<priority>] [<ring_size>] <key_image> <address> [<payment_id>]</source> - <translation>användning: sweep_single [<prioritet>] [<ringstorlek>] <nyckelavbildning> <adress> [<betalnings_id>]</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="5914"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6182"/> + <source>Failed to parse number of outputs</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4447"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5919"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6187"/> + <source>Amount of outputs should be greater than 0</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6213"/> + <source>failed to parse Payment ID</source> + <translation>det gick inte att parsa betalnings-ID</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6236"/> <source>failed to parse key image</source> <translation>det gick inte att parsa nyckelavbildning</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4499"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6290"/> <source>No outputs found</source> <translation>Inga utgångar kunde hittas</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4504"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6295"/> <source>Multiple transactions are created, which is not supposed to happen</source> <translation>Flera transaktioner skapas, vilket inte ska kunna inträffa</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4509"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6300"/> <source>The transaction uses multiple or no inputs, which is not supposed to happen</source> <translation>Transaktionen använder flera eller inga ingångar, vilket inte ska kunna inträffa</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4586"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6377"/> <source>missing threshold amount</source> <translation>tröskelbelopp saknas</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4591"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6382"/> <source>invalid amount threshold</source> <translation>ogiltigt tröskelbelopp</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4601"/> - <source>donations are not enabled on the testnet</source> - <translation>donationer är inte aktiverade på testnet</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4608"/> - <source>usage: donate [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <amount> [<payment_id>]</source> - <translation>användning: donate [index=<N1>[, <N2>, …]] [<prioritet>] [<ringstorlek>] <belopp> [<betalnings_id>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4702"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6516"/> <source>Claimed change does not go to a paid address</source> <translation>Begärd växel går inte till en betald adress</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4707"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6521"/> <source>Claimed change is larger than payment to the change address</source> <translation>Begärd växel är större än betalning till växeladressen</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4738"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6552"/> <source>sending %s to %s</source> <translation>skickar %s till %s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4748"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6562"/> <source> dummy output(s)</source> <translation> dummy-utgångar</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4751"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6565"/> <source>with no destinations</source> <translation>utan några mål</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4763"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6577"/> <source>Loaded %lu transactions, for %s, fee %s, %s, %s, with min ring size %lu, %s. %sIs this okay? (Y/Yes/N/No): </source> <translation>Läste in %lu transaktioner, för %s, avgift %s, %s, %s, med minsta ringstorlek %lu, %s. %sÄr detta okej? (J/Ja/N/Nej): </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4787"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6606"/> <source>This is a multisig wallet, it can only sign with sign_multisig</source> <translation>Detta är en multisig-plånbok, som endast kan signera med sign_multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4797"/> - <source>usage: sign_transfer [export]</source> - <translation>användning: sign_transfer [export]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4809"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6629"/> <source>Failed to sign transaction</source> <translation>Det gick inte att signera transaktionen</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4815"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6635"/> <source>Failed to sign transaction: </source> <translation>Det gick inte att signera transaktionen: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4836"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6656"/> <source>Transaction raw hex data exported to </source> <translation>Hexadecimala rådata för transaktionen exporterades till </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4852"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6677"/> <source>Failed to load transaction from file</source> <translation>Det gick inte att läsa in transaktion från fil</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3248"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3551"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4729"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5051"/> <source>RPC error: </source> <translation>RPC-fel: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="522"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="695"/> <source>wallet is watch-only and has no spend key</source> <translation>plånboken är enbart för granskning och har ingen spendernyckel</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="636"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="780"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="848"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="839"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1021"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1074"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1141"/> <source>Your original password was incorrect.</source> <translation>Ditt ursprungliga lösenord var fel.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="650"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="854"/> <source>Error with wallet rewrite: </source> <translation>Ett fel uppstod vid återskrivning av plånbok: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1289"/> - <source>priority must be 0, 1, 2, 3, or 4 </source> - <translation>prioritet måste vara 0, 1, 2, 3 eller 4 </translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1301"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1316"/> - <source>priority must be 0, 1, 2, 3, or 4</source> - <translation>prioritet måste vara 0, 1, 2, 3 eller 4</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1404"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2284"/> <source>invalid unit</source> <translation>ogiltig enhet</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1422"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1484"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2302"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2364"/> <source>invalid count: must be an unsigned integer</source> <translation>ogiltigt värde för count: måste vara ett heltal utan tecken</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1440"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2320"/> <source>invalid value</source> <translation>ogiltigt värde</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1942"/> - <source>usage: set_log <log_level_number_0-4> | <categories></source> - <translation>användning: set_log <loggnivå_nummer_0-4> | <kategorier></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2013"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3204"/> <source>(Y/Yes/N/No): </source> <translation>(J/Ja/N/Nej): </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2509"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2536"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3761"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3788"/> <source>bad m_restore_height parameter: </source> <translation>felaktig parameter för m_restore_height: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2514"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3766"/> <source>date format must be YYYY-MM-DD</source> <translation>datumformat måste vara ÅÅÅÅ-MM-DD</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2527"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3779"/> <source>Restore height is: </source> <translation>Återställningshöjd är: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2528"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3980"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3705"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3780"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5583"/> <source>Is this okay? (Y/Yes/N/No): </source> <translation>Är detta okej? (J/Ja/N/Nej): </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2575"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4509"/> <source>Daemon is local, assuming trusted</source> <translation>Daemonen är lokal, utgår från att den är betrodd</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3004"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4355"/> <source>Password for new watch-only wallet</source> <translation>Lösenord för ny granskningsplånbok</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3063"/> - <source>invalid arguments. Please use start_mining [<number_of_threads>] [do_bg_mining] [ignore_battery], <number_of_threads> should be from 1 to </source> - <translation>ogiltiga argument. Använd start_mining [<antal_trådar>] [do_bg_mining] [ignore_battery], <antal_trådar> ska vara från 1 till </translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3258"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4739"/> <source>internal error: </source> <translation>internt fel: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1185"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3263"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3556"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1608"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4744"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5056"/> <source>unexpected error: </source> <translation>oväntat fel: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1119"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1190"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3268"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3561"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4030"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4138"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4371"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4570"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4865"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1534"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1613"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4749"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5061"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5639"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5669"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5794"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6099"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6126"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6361"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6690"/> <source>unknown error</source> <translation>okänt fel</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3273"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4754"/> <source>refresh failed: </source> <translation>det gick inte att uppdatera: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3273"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4754"/> <source>Blocks received: </source> <translation>Mottagna block: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3304"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4787"/> <source>unlocked balance: </source> <translation>upplåst saldo: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1925"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3093"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> <source>amount</source> <translation>belopp</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="219"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="341"/> <source>false</source> <translation>falskt</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="493"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="659"/> <source>Unknown command: </source> <translation>Okänt kommando: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="500"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="666"/> <source>Command usage: </source> <translation>Användning av kommando: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="503"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="669"/> <source>Command description: </source> <translation>Beskrivning av kommando: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="551"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="735"/> <source>wallet is multisig but not yet finalized</source> <translation>plånboken är multisig men är ännu inte slutförd</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="567"/> - <source>Enter optional seed encryption passphrase, empty to see raw seed</source> - <translation>Ange valfri lösenfras för kryptering av startvärdet, lämna tomt för att se rådata för startvärdet</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="584"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="768"/> <source>Failed to retrieve seed</source> <translation>Det gick inte att hämta startvärde</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="603"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="792"/> <source>wallet is multisig and has no seed</source> <translation>plånboken är multisig och har inget startvärde</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="674"/> - <source>Cannot connect to daemon</source> - <translation>Det går inte att ansluta till daemonen</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="679"/> - <source>Current fee is %s monero per kB</source> - <translation>Aktuell avgift är %s monero per kB</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="695"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="899"/> <source>Error: failed to estimate backlog array size: </source> <translation>Fel: det gick inte att uppskatta eftersläpningsmatrisens storlek: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="700"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="904"/> <source>Error: bad estimated backlog array size</source> <translation>Fel: felaktigt uppskattat värde för eftersläpningsmatrisens storlek</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="712"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="916"/> <source> (current)</source> <translation> (aktuellt)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="715"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="919"/> <source>%u block (%u minutes) backlog at priority %u%s</source> <translation>%u blocks (%u minuters) eftersläpning vid prioritet %u%s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="717"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="921"/> <source>%u to %u block (%u to %u minutes) backlog at priority %u</source> <translation>%u till %u blocks (%u till %u minuters) eftersläpning vid prioritet %u</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="720"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="924"/> <source>No backlog at priority </source> <translation>Ingen eftersläpning vid prioritet </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="729"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="762"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="944"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="989"/> <source>This wallet is already multisig</source> <translation>Denna plånbok är redan multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="734"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="767"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="949"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="994"/> <source>wallet is watch-only and cannot be made multisig</source> <translation>plånboken är enbart för granskning och kan inte göras om till multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="740"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="773"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="955"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1000"/> <source>This wallet has been used before, please use a new wallet to create a multisig wallet</source> <translation>Denna plånbok har använts tidigare. Använd en ny plånbok för att skapa en multisig-plånbok</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="747"/> - <source>Your password is incorrect.</source> - <translation>Ditt lösenord är fel.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="753"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="963"/> <source>Send this multisig info to all other participants, then use make_multisig <threshold> <info1> [<info2>...] with others' multisig info</source> <translation>Skicka denna multisig-info till alla andra deltagare och använd sedan make_multisig <tröskelvärde> <info1> [<info2>…] med de andras multisig-info</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="754"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="964"/> <source>This includes the PRIVATE view key, so needs to be disclosed only to that multisig wallet's participants </source> <translation>Detta innefattar den PRIVATA granskningsnyckeln, så den behöver endast lämnas ut till den multisig-plånbokens deltagare </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="786"/> - <source>usage: make_multisig <threshold> <multisiginfo1> [<multisiginfo2>...]</source> - <translation>användning: make_multisig <tröskelvärde> <multisiginfo1> [<multisiginfo2>…]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="794"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1014"/> <source>Invalid threshold</source> <translation>Ogiltigt tröskelvärde</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="807"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1034"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1156"/> <source>Another step is needed</source> <translation>Ytterligare ett steg krävs</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="809"/> - <source>Send this multisig info to all other participants, then use finalize_multisig <info1> [<info2>...] with others' multisig info</source> - <translation>Skicka denna multisig-info till alla andra deltagare, använd sedan finalize_multisig <info1> [<info2>…] med de andras multisig-info</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="815"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1046"/> <source>Error creating multisig: </source> <translation>Ett fel uppstod när multisig skapades: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="822"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1053"/> <source>Error creating multisig: new wallet is not multisig</source> <translation>Ett fel uppstod när multisig skapades: den nya plånboken är inte multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="825"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1056"/> <source> multisig address: </source> <translation> multisig-adress: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="836"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="880"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="927"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1080"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1129"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1195"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1261"/> <source>This wallet is not multisig</source> <translation>Denna plånbok är inte multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="841"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1085"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1134"/> <source>This wallet is already finalized</source> <translation>Denna plånbok är redan slutförd</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="854"/> - <source>usage: finalize_multisig <multisiginfo1> [<multisiginfo2>...]</source> - <translation>användning: finalize_multisig <multisiginfo1> [<multisiginfo2>…]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="862"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1101"/> <source>Failed to finalize multisig</source> <translation>Det gick inte att slutföra multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="868"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1107"/> <source>Failed to finalize multisig: </source> <translation>Det gick inte att slutföra multisig: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="885"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="932"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1006"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1074"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1136"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1200"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1266"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1360"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1476"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1557"/> <source>This multisig wallet is not yet finalized</source> <translation>Denna multisig-plånbok är inte slutförd ännu</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="890"/> - <source>usage: export_multisig_info <filename></source> - <translation>användning: export_multisig_info <filnamn></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="913"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1236"/> <source>Error exporting multisig info: </source> <translation>Ett fel uppstod när multisig-info exporterades: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="917"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1240"/> <source>Multisig info exported to </source> <translation>Multisig-info exporterades till </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="937"/> - <source>usage: import_multisig_info <filename1> [<filename2>...] - one for each other participant</source> - <translation>användning: import_multisig_info <filename1> [<filename2>…] - en för varje annan deltagare</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="965"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1306"/> <source>Multisig info imported</source> <translation>Multisig-info importerades</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="969"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1310"/> <source>Failed to import multisig info: </source> <translation>Det gick inte att importera multisig-info: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="980"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1321"/> <source>Failed to update spent status after importing multisig info: </source> <translation>Det gick inte att uppdatera spenderstatus efter import av multisig-info: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="985"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1327"/> <source>Untrusted daemon, spent status may be incorrect. Use a trusted daemon and run "rescan_spent"</source> <translation>Ej betrodd daemon. Spenderstatus kan vara felaktig. Använd en betrodd daemon och kör "rescan_spent"</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1001"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1069"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1131"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1355"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1471"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1552"/> <source>This is not a multisig wallet</source> <translation>Detta är inte en multisig-plånbok</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1011"/> - <source>usage: sign_multisig <filename></source> - <translation>användning: sign_multisig <filnamn></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1024"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1405"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1414"/> <source>Failed to sign multisig transaction</source> <translation>Det gick inte att signera multisig-transaktion</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1030"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1421"/> <source>Multisig error: </source> <translation>Multisig-fel: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1035"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1426"/> <source>Failed to sign multisig transaction: </source> <translation>Det gick inte att signera multisig-transaktion: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1058"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1449"/> <source>It may be relayed to the network with submit_multisig</source> <translation>Den kan skickas vidare till nätverket med submit_multisig</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1079"/> - <source>usage: submit_multisig <filename></source> - <translation>användning: submit_multisig <filnamn></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1094"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1155"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1508"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1578"/> <source>Failed to load multisig transaction from file</source> <translation>Det gick inte att läsa in multisig-transaktion från fil</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1099"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1160"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1514"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1583"/> <source>Multisig transaction signed by only %u signers, needs %u more signatures</source> <translation>Multisig-transaktion har signerats av bara %u signerare. Den behöver %u ytterligare signaturer</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1108"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6750"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1523"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8890"/> <source>Transaction successfully submitted, transaction </source> <translation>Transaktionen skickades, transaktion </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1109"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6751"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1524"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8891"/> <source>You can check its status by using the `show_transfers` command.</source> <translation>Du kan kontrollera dess status genom att använda kommandot 'show_transfers'.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1141"/> - <source>usage: export_raw_multisig <filename></source> - <translation>användning: export_raw_multisig <filnamn></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1176"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1599"/> <source>Failed to export multisig transaction to file </source> <translation>Det gick inte att exportera multisig-transaktion till fil </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1180"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1603"/> <source>Saved exported multisig transaction file(s): </source> <translation>Sparade filer med exporterade multisig-transaktioner: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1252"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1258"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1272"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2095"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2101"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2120"/> <source>ring size must be an integer >= </source> <translation>ringstorlek måste vara ett heltal >= </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1277"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2125"/> <source>could not change default ring size</source> <translation>det gick inte att ändra standardinställning för ringstorlek</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1518"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2398"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2469"/> <source>Invalid height</source> <translation>Ogiltig höjd</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1564"/> - <source>start_mining [<number_of_threads>] [bg_mining] [ignore_battery]</source> - <translation>start_mining [<antal_trådar>] [<bgbrytning>] [<ignorera_batteri>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1565"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2562"/> <source>Start mining in the daemon (bg_mining and ignore_battery are optional booleans).</source> <translation>Starta brytning i daemonen (bgbrytning och ignorera_batteri är valfri booleska värden).</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1568"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2565"/> <source>Stop mining in the daemon.</source> <translation>Stoppa brytning i daemonen.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1571"/> - <source>set_daemon <host>[:<port>]</source> - <translation>set_daemon <värddator>[:<port>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1572"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2569"/> <source>Set another daemon to connect to.</source> <translation>Ange en annan daemon att ansluta till.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1575"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2572"/> <source>Save the current blockchain data.</source> <translation>Spara aktuella blockkedjedata.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1578"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2575"/> <source>Synchronize the transactions and balance.</source> <translation>Synkronisera transaktionerna och saldot.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1581"/> - <source>balance [detail]</source> - <translation>balance [detail]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1582"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2579"/> <source>Show the wallet's balance of the currently selected account.</source> <translation>Visa plånbokens saldo för det aktiva kontot.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1585"/> - <source>incoming_transfers [available|unavailable] [verbose] [index=<N1>[,<N2>[,...]]]</source> - <translation>incoming_transfers [available|unavailable] [verbose] [index=<N1>[, <N2>[, …]]]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1586"/> - <source>Show the incoming transfers, all or filtered by availability and address index. - -Output format: -Amount, Spent("T"|"F"), "locked"|"unlocked", RingCT, Global Index, Transaction Hash, Address Index, [Public Key, Key Image]</source> - <translation type="unfinished">Visa inkommande överföringar: alla eller filtrerade efter tillgänglighet och adressindex.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1589"/> - <source>payments <PID_1> [<PID_2> ... <PID_N>]</source> - <translation>payments <BID_1> [<BID_2> … <BID_N>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1590"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2589"/> <source>Show the payments for the given payment IDs.</source> <translation>Visa betalningar för givna betalnings-ID.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1593"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2592"/> <source>Show the blockchain height.</source> <translation>Visa blockkedjans höjd.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1596"/> - <source>transfer_original [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> <amount> [<payment_id>]</source> - <translation>transfer_original [index=<N1>[, <N2>, …]] [<prioritet>] [<ringstorlek>] <adress> <belopp> [<betalnings_id>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1597"/> - <source>Transfer <amount> to <address> using an older transaction building algorithm. If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> - <translation>Överför <belopp> till <adress> genom att använda en äldre algoritm för att bygga transaktioner. Om parametern "index=<N1>[, <N2>, …]" anges använder plånboken utgångar som tagits emot av adresser vid dessa index. Om parametern utelämnas väljer plånboken slumpmässigt adressindex att använda. Oavsett vilket kommer den att göra sitt bästa för att inte kombinera utgångar från flera adresser. <prioritet> är transaktionens prioritet. Ju högre prioritet, desto högre transaktionsavgift. Giltiga värden i prioritetsordning (från lägsta till högsta) är: unimportant, normal, elevated, priority. Om värdet utelämnas kommer standardvärdet att användas (se kommandot "set priority"). <ringstorlek> är det antal ingångar som ska inkluderas för att uppnå ospårbarhet. Flera betalningar kan göras på en gång genom att lägga till <adress_2> <belopp_2> osv (före betalnings-ID, om det inkluderas)</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1599"/> - <source>transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> <amount> [<payment_id>]</source> - <translation>transfer [index=<N1>[, <N2>, …]] [<prioritet>] [<ringstorlek>] <adress> <belopp> [<betalnings_id>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1600"/> - <source>Transfer <amount> to <address>. If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> - <translation>Överför <belopp> till <adress>. Om parametern "index=<N1>[, <N2>, …]" anges använder plånboken utgångar som tagits emot av adresser vid dessa index. Om parametern utelämnas väljer plånboken slumpmässigt adressindex att använda. Oavsett vilket kommer den att göra sitt bästa för att inte kombinera utgångar från flera adresser. <prioritet> är transaktionens prioritet. Ju högre prioritet, desto högre transaktionsavgift. Giltiga värden i prioritetsordning (från lägsta till högsta) är: unimportant, normal, elevated, priority. Om värdet utelämnas kommer standardvärdet att användas (se kommandot "set priority"). <ringstorlek> är det antal ingångar som ska inkluderas för att uppnå ospårbarhet. Flera betalningar kan göras på en gång genom att lägga till <adress_2> <belopp_2> osv (före betalnings-ID, om det inkluderas)</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1603"/> - <source>locked_transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <addr> <amount> <lockblocks> [<payment_id>]</source> - <translation>locked_transfer [index=<N1>[, <N2>, …]] [<prioritet>] [<ringstorlek>] <adress> <belopp> <låsblock> [<betalnings_id>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1604"/> - <source>Transfer <amount> to <address> and lock it for <lockblocks> (max. 1000000). If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> - <translation>Överför <belopp> till <adress> och lås det i <låsblock> (max. 1000000). Om parametern "index=<N1>[, <N2>, …]" anges använder plånboken utgångar som tagits emot av adresser vid dessa index. Om parametern utelämnas väljer plånboken slumpmässigt adressindex att använda. Oavsett vilket kommer den att göra sitt bästa för att inte kombinera utgångar från flera adresser. <prioritet> är transaktionens prioritet. Ju högre prioritet, desto högre transaktionsavgift. Giltiga värden i prioritetsordning (från lägsta till högsta) är: unimportant, normal, elevated, priority. Om värdet utelämnas kommer standardvärdet att användas (se kommandot "set priority"). <ringstorlek> är det antal ingångar som ska inkluderas för att uppnå ospårbarhet. Flera betalningar kan göras på en gång genom att lägga till <adress_2> <belopp_2> osv (före betalnings-ID, om det inkluderas)</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1607"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2606"/> <source>Send all unmixable outputs to yourself with ring_size 1</source> <translation>Skicka alla omixbara utgångar till dig själv med ringstorlek 1</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1609"/> - <source>sweep_all [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> [<payment_id>]</source> - <translation>sweep_all [index=<N1>[, <N2>, …]] [<prioritet>] [<ringstorlek>] <adress> [<betalnings_id>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1610"/> - <source>Send all unlocked balance to an address. If the parameter "index<N1>[,<N2>,...]" is specified, the wallet sweeps outputs received by those address indices. If omitted, the wallet randomly chooses an address index to be used.</source> - <translation>Skicka allt upplåst saldo till en adress. Om parametern "index<N1>[, <N2>, …]" anges sveper plånboken upp utgångar som tagits emot av adresserna vid dessa index. Om parametern utelämnas väljer plånboken slumpmässigt ett adressindex att använda.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1613"/> - <source>sweep_below <amount_threshold> [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> [<payment_id>]</source> - <translation>sweep_below <tröskelbelopp> [index=<N1>[, <N2>, …]] [<prioritet>] [<ringstorlek>] <adress> [<betalnings_id>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1614"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2613"/> <source>Send all unlocked outputs below the threshold to an address.</source> <translation>Skicka alla upplåsta utgångar under tröskelvärdet till en adress.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1617"/> - <source>sweep_single [<priority>] [<ring_size>] <key_image> <address> [<payment_id>]</source> - <translation>sweep_single [<prioritet>] [<ringstorlek>] <nyckelavbildning> <adress> [<betalnings_id>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1618"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2617"/> <source>Send a single output of the given key image to an address without change.</source> <translation>Skicka en enda utgång hos den givna nyckelavbildningen till en adress utan växel.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1621"/> - <source>donate [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <amount> [<payment_id>]</source> - <translation>donate [index=<N1>[, <N2>, …]] [<prioritet>] [<ringstorlek>] <belopp> [<betalnings_id>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1622"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2621"/> <source>Donate <amount> to the development team (donate.getmonero.org).</source> <translation>Donera <belopp> till utvecklingsteamet (donate.getmonero.org).</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1625"/> - <source>sign_transfer <file></source> - <translation>sign_transfer <fil></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1626"/> - <source>Sign a transaction from a <file>.</source> - <translation>Signera en transaktion från <fil>.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1629"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2628"/> <source>Submit a signed transaction from a file.</source> <translation>Skicka en signerad transaktion från en fil.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1632"/> - <source>set_log <level>|{+,-,}<categories></source> - <translation>set_log <nivå>|{+,-,}<kategorier></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1633"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2632"/> <source>Change the current log detail (level must be <0-4>).</source> <translation>Ändra detaljnivån för aktuell logg (nivå måste vara 0-4).</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1636"/> - <source>account - account new <label text with white spaces allowed> - account switch <index> - account label <index> <label text with white spaces allowed> - account tag <tag_name> <account_index_1> [<account_index_2> ...] - account untag <account_index_1> [<account_index_2> ...] - account tag_description <tag_name> <description></source> - <translation>account - account new <etikettext med blanktecken tillåtna> - account switch <index> - account label <index> <etikettext med blanktecken tillåtna> - account tag <taggnamn> <kontoindex_1> [<kontoindex_2> …] - account untag <kontoindex_1> [<kontoindex_2> …] - account tag_description <taggnamn> <beskrivning></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1643"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2636"/> <source>If no arguments are specified, the wallet shows all the existing accounts along with their balances. If the "new" argument is specified, the wallet creates a new account with its label initialized by the provided label text (which can be empty). -If the "switch" argument is specified, the wallet switches to the account specified by <index>. -If the "label" argument is specified, the wallet sets the label of the account specified by <index> to the provided label text. -If the "tag" argument is specified, a tag <tag_name> is assigned to the specified accounts <account_index_1>, <account_index_2>, .... -If the "untag" argument is specified, the tags assigned to the specified accounts <account_index_1>, <account_index_2> ..., are removed. -If the "tag_description" argument is specified, the tag <tag_name> is assigned an arbitrary text <description>.</source> +If the "switch" argument is specified, the wallet switches to the account specified by <index>. +If the "label" argument is specified, the wallet sets the label of the account specified by <index> to the provided label text. +If the "tag" argument is specified, a tag <tag_name> is assigned to the specified accounts <account_index_1>, <account_index_2>, .... +If the "untag" argument is specified, the tags assigned to the specified accounts <account_index_1>, <account_index_2> ..., are removed. +If the "tag_description" argument is specified, the tag <tag_name> is assigned an arbitrary text <description>.</source> <translation>Om inga argument anges visas plånbokens samtliga befintliga konton, tillsammans med deras respektive saldo. Om argumentet "new" anges, skapar plånboken ett nytt konto med etiketten satt till med den angivna etikettexten (som kan vara tom). -Om argumentet "switch" anges, växlar plånboken till det konto som anges av <index>. -Om argumentet "label" anges, sätter plånboken etiketten för kontot som anges av <index> till den angivna etikettexten. -Om argumentet "tag" anges, så tilldelas taggen <taggnamn> till det angivna kontona <kontoindex_1>, <kontoindex_2>, … -Om argumentet "untag" anges, tas tilldelade taggar bort från de angivna kontona <kontoindex_1>, <kontoindex_2> … -Om argumentet "tag_description" anges, så tilldelas taggen <taggnamn> den godtyckliga texten <beskrivning>.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1652"/> - <source>address [ new <label text with white spaces allowed> | all | <index_min> [<index_max>] | label <index> <label text with white spaces allowed>]</source> - <translation>address [new <etikettext med blanktecken tillåtna> | all | <index_min> [<index_max>] | label <index> <etikettext med blanktecken tillåtna>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1653"/> - <source>If no arguments are specified or <index> is specified, the wallet shows the default or specified address. If "all" is specified, the walllet shows all the existing addresses in the currently selected account. If "new " is specified, the wallet creates a new address with the provided label text (which can be empty). If "label" is specified, the wallet sets the label of the address specified by <index> to the provided label text.</source> - <translation>Om inga argument anges, eller om <index> anges, visar plånboken standardadressen eller den angivna adressen. Om argumentet "all" anges visar plånboken samtliga befintliga adresser i det aktiva kontot. Om argumentet "new " anges skapar plånboken en ny adress med den angivna etikettexten (som kan vara tom). Om argumentet "label" anges sätter plånboken etiketten för adressen som anges av <index> till den angivna etikettexten.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1656"/> - <source>integrated_address [<payment_id> | <address>]</source> - <translation>integrated_address [<betalnings-id> | <adress>]</translation> +Om argumentet "switch" anges, växlar plånboken till det konto som anges av <index>. +Om argumentet "label" anges, sätter plånboken etiketten för kontot som anges av <index> till den angivna etikettexten. +Om argumentet "tag" anges, så tilldelas taggen <taggnamn> till det angivna kontona <kontoindex_1>, <kontoindex_2>, … +Om argumentet "untag" anges, tas tilldelade taggar bort från de angivna kontona <kontoindex_1>, <kontoindex_2> … +Om argumentet "tag_description" anges, så tilldelas taggen <taggnamn> den godtyckliga texten <beskrivning>.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1657"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2650"/> <source>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>Koda ett betalnings-ID till en integrerad adress för den aktuella plånbokens publika adress (om inget argument anges används ett slumpmässigt betalnings-ID), eller avkoda en integrerad adress till en standardadress och ett betalnings-ID</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1660"/> - <source>address_book [(add ((<address> [pid <id>])|<integrated address>) [<description possibly with whitespaces>])|(delete <index>)]</source> - <translation>address_book [(add ((<adress> [pid <id>])|<integrerad adress>) [<beskrivning eventuellt med blanktecken>])|(delete <index>)]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1661"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2654"/> <source>Print all entries in the address book, optionally adding/deleting an entry to/from it.</source> <translation>Skriv ut alla poster i adressboken, och valfritt lägg till/ta bort en post i den.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1664"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2657"/> <source>Save the wallet data.</source> <translation>Spara plånboksdata.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1667"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2660"/> <source>Save a watch-only keys file.</source> <translation>Spara en fil med granskningsnycklar.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1670"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2663"/> <source>Display the private view key.</source> <translation>Visa privat granskningsnyckel.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1673"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2666"/> <source>Display the private spend key.</source> <translation>Visa privat spendernyckel.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1676"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2669"/> <source>Display the Electrum-style mnemonic seed</source> <translation>Visa det minnesbaserade startvärdet (Electrum-typ)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1679"/> - <source>set <option> [<value>]</source> - <translation>set <alternativ> [<värde>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1680"/> - <source>Available options: - seed language - Set the wallet's 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 the default ring size (default and minimum is 5). - auto-refresh <1|0> - Whether to automatically synchronize new blocks from the daemon. - refresh-type <full|optimize-coinbase|no-coinbase|default> - Set the wallet's refresh behaviour. - priority [0|1|2|3|4] - Set the fee to default/unimportant/normal/elevated/priority. - confirm-missing-payment-id <1|0> - ask-password <1|0> - unit <monero|millinero|micronero|nanonero|piconero> - Set the 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] - Set a threshold for confirm-backlog to only warn if the transaction backlog is greater than n blocks. - refresh-from-block-height [n] - Set the height before which to ignore blocks. - auto-low-priority <1|0> - Whether to automatically use the low priority fee level when it's safe to do so.</source> - <translation>Tillgängliga alternativ: - språk för startvärde - Ange plånbokens språk för startvärde. - always-confirm-transfers <1|0> - Om ej delade transaktioner ska bekräftas. - print-ring-members <1|0> - Om detaljerad information om ringmedlemmar ska skrivas ut vid bekräftelse. - store-tx-info <1|0> - Om information om utgående transaktion ska sparas (måladress, betalnings-ID, hemlig tx-nyckel) som referens. - default-ring-size <n> - Ange standardinställning för ringstorlek (standard och minimum är 5). - auto-refresh <1|0> - Om nya block ska synkas automatiskt från daemonen. - refresh-type <full|optimize-coinbase|no-coinbase|default> - Ange plånbokens uppdateringsbeteende. - priority [0|1|2|3|4] - Sätt avgiften till default/unimportant/normal/elevated/priority. - confirm-missing-payment-id <1|0> - ask-password <1|0> - unit <monero|millinero|micronero|nanonero|piconero> - Ange standardvärde för moneroenhet. - min-outputs-count [n] - Försök att behålla åtminstone så många utgångar med åtminstone värdet min-outputs-value. - min-outputs-value [n] - Försök att behålla åtminstone min-outputs-count utgångar med åtminstone det värdet. - merge-destinations <1|0> - Om flera betalningar till samma måladress ska sammanslås. - confirm-backlog <1|0> - Om en varning ska visas om det föreligger transaktionseftersläpning. - confirm-backlog-threshold [n] - Ange ett tröskelvärde för confirm-backlog för att endast varna om transaktionseftersläpningen är större än n block. - refresh-from-block-height [n] - Ange höjden upp till vilken block ska ignoreras. - auto-low-priority <1|0> - Om avgiftsnivån för låg prioritet automatiskt ska användas när detta är säkert att göra.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1717"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2719"/> <source>Display the encrypted Electrum-style mnemonic seed.</source> <translation>Visa det krypterade minnesbaserade startvärdet (Electrum-typ).</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1720"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2722"/> <source>Rescan the blockchain for spent outputs.</source> <translation>Genomsök blockkedjan efter spenderade utgångar.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1723"/> - <source>get_tx_key <txid></source> - <translation>get_tx_key <txid></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1724"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2726"/> <source>Get the transaction key (r) for a given <txid>.</source> <translation>Hämta transaktionsnyckel (r) för ett givet <txid>.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1727"/> - <source>check_tx_key <txid> <txkey> <address></source> - <translation>check_tx_key <txid> <txkey> <adress></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1728"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2734"/> <source>Check the amount going to <address> in <txid>.</source> <translation>Kontrollera belopp som går till <adress> i <txid>.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1731"/> - <source>get_tx_proof <txid> <address> [<message>]</source> - <translation>get_tx_proof <txid> <adress> [<meddelande>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1732"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2738"/> <source>Generate a signature proving funds sent to <address> in <txid>, optionally with a challenge string <message>, using either the transaction secret key (when <address> is not your wallet's address) or the view secret key (otherwise), which does not disclose the secret key.</source> <translation>Skapa en signatur som bevisar att pengar skickades till <adress> i <txid>, valfritt med kontrollsträngen <meddelande>, genom att använda antingen transaktionens hemliga nyckel (när <adress> inte är din plånboks adress) eller den hemliga granskningsnyckeln (annars), vilket inte lämnar ut den hemliga nyckeln.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1735"/> - <source>check_tx_proof <txid> <address> <signature_file> [<message>]</source> - <translation>check_tx_proof <txid> <adress> <signaturfil> [<meddelande>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1736"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2742"/> <source>Check the proof for funds going to <address> in <txid> with the challenge string <message> if any.</source> <translation>Kontrollera beviset för pengar som skickats till <adress> i <txid> med kontrollsträngen <meddelande>, om den angivits.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1739"/> - <source>get_spend_proof <txid> [<message>]</source> - <translation>get_spend_proof <txid> [<meddelande>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1740"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2746"/> <source>Generate a signature proving that you generated <txid> using the spend secret key, optionally with a challenge string <message>.</source> <translation>Skapa en signatur som bevisar att du skapade <txid> genom att använda den hemliga spendernyckeln, valfritt med kontrollsträngen <meddelande>.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1743"/> - <source>check_spend_proof <txid> <signature_file> [<message>]</source> - <translation>check_spend_proof <txid> <signaturfil> [<meddelande>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1744"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2750"/> <source>Check a signature proving that the signer generated <txid>, optionally with a challenge string <message>.</source> <translation>Kontrollera en signatur som bevisar att signeraren skapade <txid>, valfritt med kontrollsträngen <meddelande>.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1747"/> - <source>get_reserve_proof (all|<amount>) [<message>]</source> - <translation>get_reserve_proof (all|<belopp>) [<meddelande>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1748"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2754"/> <source>Generate a signature proving that you own at least this much, optionally with a challenge string <message>. If 'all' is specified, you prove the entire sum of all of your existing accounts' balances. Otherwise, you prove the reserve of the smallest possible amount above <amount> available in your current account.</source> @@ -1842,381 +1697,242 @@ Om 'all' anges, bevisar du totalsumman av alla dina befintliga kontons Annars bevisar du reserven för det minsta möjliga belopp över <belopp> som är tillgängligt på ditt aktuella konto.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1753"/> - <source>check_reserve_proof <address> <signature_file> [<message>]</source> - <translation>check_reserve_proof <adress> <signaturfil> [<meddelande>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1754"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2760"/> <source>Check a signature proving that the owner of <address> holds at least this much, optionally with a challenge string <message>.</source> <translation>Kontrollera en signatur som bevisar att ägaren till <adress> har åtminstone så här mycket, valfritt med kontrollsträngen <meddelande>.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1757"/> - <source>show_transfers [in|out|pending|failed|pool] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]</source> - <translation>show_transfers [in|out|pending|failed|pool] [index=<N1>[, <N2>, …]] [<min_höjd> [<max_höjd>]]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1758"/> - <source>Show the incoming/outgoing transfers within an optional height range. - -Output format: -In or Coinbase: Block Number, "block"|"in", Time, Amount, Transaction Hash, Payment ID, Subaddress Index, "-", Note\ -Out: Block Number, "out", Time, Amount*, Transaction Hash, Payment ID, Fee, Destinations, Input addresses**, "-", Note -Pool: "pool", "in", Time, Amount, Transaction Hash, Payment Id, Subaddress Index, "-", Note, Double Spend Note\ -Pending or Failed: "failed"|"pending", "out", Time, Amount*, Transaction Hash, Payment ID, Fee, Input addresses**, "-", Note - -* Excluding change and fee. -** Set of address indices used as inputs in this transfer.</source> - <translation>Visa inkommande/utgående överföringar inom ett valfritt höjdintervall.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1761"/> - <source>unspent_outputs [index=<N1>[,<N2>,...]] [<min_amount> [<max_amount>]]</source> - <translation>unspent_outputs [index=<N1>[, <N2>, …]] [<min_belopp> [<max_belopp>]]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1762"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2780"/> <source>Show the unspent outputs of a specified address within an optional amount range.</source> <translation>Visa de ej spenderade utgångarna hos en angiven adress inom ett valfritt beloppsintervall.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1765"/> - <source>Rescan the blockchain from scratch.</source> - <translation>Genomsök blockkedjan från början.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1768"/> - <source>set_tx_note <txid> [free text note]</source> - <translation>set_tx_note <txid> [<fritextanteckning>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1769"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2788"/> <source>Set an arbitrary string note for a <txid>.</source> <translation>Ange en godtycklig stränganteckning för <txid>.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1772"/> - <source>get_tx_note <txid></source> - <translation>get_tx_note <txid></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1773"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2792"/> <source>Get a string note for a txid.</source> <translation>Hämta en stränganteckning för ett txid.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1776"/> - <source>set_description [free text note]</source> - <translation>set_description [<fritextanteckning>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1777"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2796"/> <source>Set an arbitrary description for the wallet.</source> <translation>Ange en godtycklig beskrivning av plånboken.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1780"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2800"/> <source>Get the description of the wallet.</source> <translation>Hämta plånbokens beskrivning.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1783"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2803"/> <source>Show the wallet's status.</source> <translation>Visa plånbokens status.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1786"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2806"/> <source>Show the wallet's information.</source> <translation>Visa information om plånboken.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1789"/> - <source>sign <file></source> - <translation>sign <fil></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1790"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2810"/> <source>Sign the contents of a file.</source> <translation>Signera innehållet i en fil.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1793"/> - <source>verify <filename> <address> <signature></source> - <translation>verify <filnamn> <adress> <signatur></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1794"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2814"/> <source>Verify a signature on the contents of a file.</source> <translation>Verifiera en signatur av innehållet in en fil.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1797"/> - <source>export_key_images <file></source> - <translation>export_key_images <fil></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1798"/> - <source>Export a signed set of key images to a <file>.</source> - <translation>Exportera en signerad uppsättning nyckelavbildningar till <fil>.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1801"/> - <source>import_key_images <file></source> - <translation>import_key_images <fil></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1802"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2822"/> <source>Import a signed key images list and verify their spent status.</source> <translation>Importera en signerad lista av nyckelavbildningar och verifiera deras spenderstatus.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1805"/> - <source>export_outputs <file></source> - <translation>export_outputs <fil></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1806"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2834"/> <source>Export a set of outputs owned by this wallet.</source> <translation>Exportera en uppsättning utgångar som ägs av denna plånbok.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1809"/> - <source>import_outputs <file></source> - <translation>import_outputs <fil></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1810"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2838"/> <source>Import a set of outputs owned by this wallet.</source> <translation>Importera en uppsättning utgångar som ägs av denna plånbok.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1813"/> - <source>show_transfer <txid></source> - <translation>show_transfer <txid></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1814"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2842"/> <source>Show information about a transfer to/from this address.</source> <translation>Visa information om en transktion till/från denna adress.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1817"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2845"/> <source>Change the wallet's password.</source> <translation>Ändra plånbokens lösenord.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1820"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2849"/> <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>Skapa ett nytt slumpmässigt betalnings-ID av normalstorlek. Dessa kommer att vara okrypterade på blockkedjan. Se integrated_address för krypterade korta betalnings-ID.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1823"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2852"/> <source>Print the information about the current fee and transaction backlog.</source> <translation>Skriv ut information om aktuell avgift och transaktionseftersläpning.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1825"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2854"/> <source>Export data needed to create a multisig wallet</source> <translation>Exportera data som krävs för att skapa en multisig-plånbok</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1827"/> - <source>make_multisig <threshold> <string1> [<string>...]</source> - <translation>make_multisig <tröskelvärde> <string1> [<sträng>…]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1828"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2857"/> <source>Turn this wallet into a multisig wallet</source> <translation>Gör denna plånbok till en multisig-plånbok</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1831"/> - <source>finalize_multisig <string> [<string>...]</source> - <translation>finalize_multisig <sträng> [<sträng>…]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1832"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2861"/> <source>Turn this wallet into a multisig wallet, extra step for N-1/N wallets</source> <translation>Gör denna plånbok till en multisig-plånbok, extra steg för plånböcker med N-1/N</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1835"/> - <source>export_multisig_info <filename></source> - <translation>export_multisig_info <filnamn></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1836"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2869"/> <source>Export multisig info for other participants</source> <translation>Exportera multisig-info för andra deltagare</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1839"/> - <source>import_multisig_info <filename> [<filename>...]</source> - <translation>import_multisig_info <filnamn> [<filnamn>…]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1840"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2873"/> <source>Import multisig info from other participants</source> <translation>Importera multisig-info från andra deltagare</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1843"/> - <source>sign_multisig <filename></source> - <translation>sign_multisig <filnamn></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1844"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2877"/> <source>Sign a multisig transaction from a file</source> <translation>Signera en a multisig-transaktion från en fil</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1847"/> - <source>submit_multisig <filename></source> - <translation>submit_multisig <filnamn></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1848"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2881"/> <source>Submit a signed multisig transaction from a file</source> <translation>Skicka en signerad multisig-transaktion från en fil</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1851"/> - <source>export_raw_multisig_tx <filename></source> - <translation>export_raw_multisig_tx <filnamn></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1852"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2885"/> <source>Export a signed multisig transaction to a file</source> <translation>Exportera en signerad multisig-transaktion till en fil</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1855"/> - <source>help [<command>]</source> - <translation>help [<kommando>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1856"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3002"/> <source>Show the help section or the documentation about a <command>.</source> <translation>Visa hjälpavsnittet eller dokumentationen för <kommando>.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1917"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3085"/> <source>integer >= </source> <translation>heltal >= </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1930"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3098"/> <source>block height</source> <translation>blockhöjd</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2012"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3203"/> <source>No wallet found with that name. Confirm creation of new wallet named: </source> <translation>Ingen plånbok med det namnet kunde hittas. Bekräfta skapande av ny plånbok med namn: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2068"/> - <source>can't specify more than one of --generate-new-wallet="wallet_name", --wallet-file="wallet_name", --generate-from-view-key="wallet_name", --generate-from-spend-key="wallet_name", --generate-from-keys="wallet_name", --generate-from-multisig-keys="wallet_name" and --generate-from-json="jsonfilename"</source> - <translation>det går inte att ange fler än en av --generate-new-wallet="plånboksnamn", --wallet-file="plånboksnamn", --generate-from-view-key="plånboksnamn", --generate-from-spend-key="plånboksnamn", --generate-from-keys="plånboksnamn", --generate-from-multisig-keys="plånboksnamn" och --generate-from-json="json-filnamn"</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2084"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3304"/> <source>can't specify both --restore-deterministic-wallet or --restore-multisig-wallet and --non-deterministic</source> <translation>det går inte att ange både --restore-deterministic-wallet eller --restore-multisig-wallet och --non-deterministic</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2090"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> <source>--restore-multisig-wallet uses --generate-new-wallet, not --wallet-file</source> <translation>--restore-multisig-wallet använder --generate-new-wallet, inte --wallet-file</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2106"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3326"/> <source>specify a recovery parameter with the --electrum-seed="multisig seed here"</source> <translation>ange en återställningsparameter med --electrum-seed="startvärde för multisig"</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2133"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3355"/> <source>Multisig seed failed verification</source> <translation>Startvärde för multisig kunde inte verifieras</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2149"/> - <source>Enter seed encryption passphrase, empty if none</source> - <translation>Ange lösenfras för kryptering av startvärde, lämna tomt om ingen</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2185"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2259"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3406"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3481"/> <source>This address is a subaddress which cannot be used here.</source> <translation>Denna adress är en underadress som inte kan användas här.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2337"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3558"/> <source>Error: expected M/N, but got: </source> <translation>Fel: förväntade M/N, men fick: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2342"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3563"/> <source>Error: expected N > 1 and N <= M, but got: </source> <translation>Fel: förväntade N > 1 och N <= M, men fick: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2347"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3568"/> <source>Error: M/N is currently unsupported. </source> <translation>Fel: M/N stöds för närvarande inte. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2350"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3571"/> <source>Generating master wallet from %u of %u multisig wallet keys</source> <translation>Skapar huvudplånbok från %u av %u multisig-plånboksnycklar</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2379"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3600"/> <source>failed to parse secret view key</source> <translation>det gick inte att parsa hemlig granskningsnyckel</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2388"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3608"/> <source>failed to verify secret view key</source> <translation>det gick inte att verifiera hemlig granskningsnyckel</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2408"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3628"/> <source>Secret spend key (%u of %u):</source> <translation>Hemlig spendernyckel (%u av %u):</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2432"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3651"/> <source>Error: M/N is currently unsupported</source> <translation>Fel: M/N stöds för närvarande inte</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2550"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3802"/> <source>Restore height </source> <translation>Återställningshöjd </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2551"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3803"/> <source>Still apply restore height? (Y/Yes/N/No): </source> <translation>Ska återställningshöjd fortfarande appliceras? (J/Ja/N/Nej): </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2582"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3829"/> <source>Warning: using an untrusted daemon at %s, privacy will be lessened</source> <translation>Varning: använder en ej betrodd daemon på %s; sekretessen kommer att vara mindre</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2636"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3888"/> <source>Daemon either is not started or wrong port was passed. Please make sure daemon is running or change the daemon address using the 'set_daemon' command.</source> <translation>Antingen har daemonen inte startat eller så angavs fel port. Se till att daemonen körs eller byt daemonadress med kommandot 'set_daemon'.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2768"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4036"/> <source>Your wallet has been generated! To start synchronizing with the daemon, use the "refresh" command. Use the "help" command to see the list of available commands. -Use "help <command>" to see a command's documentation. +Use "help <command>" to see a command's documentation. Always use the "exit" command when closing monero-wallet-cli to save your current session's state. Otherwise, you might need to synchronize your wallet again (your wallet keys are NOT at risk in any case). @@ -2224,877 +1940,2168 @@ your wallet again (your wallet keys are NOT at risk in any case). <translation>Din plånbok har skapats! Använd kommandot "refresh" för att starta synkronisering med daemonen. Använd kommandot "help" för att visa en lista över tillgängliga kommandon. -Använd "help <kommando>" för att visa dokumentation för kommandot. +Använd "help <kommando>" för att visa dokumentation för kommandot. Använd alltid kommandot "exit" när du stänger monero-wallet-cli så att ditt aktuella sessionstillstånd sparas. Annars kan du bli tvungen att synkronisera din plånbok igen (din plånboks nycklar är dock INTE hotade i vilket fall som helst). </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2850"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4180"/> <source>failed to generate new mutlisig wallet</source> <translation>det gick inte att skapa ny multisig-plånbok</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2853"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4183"/> <source>Generated new %u/%u multisig wallet: </source> <translation>Skapa ny %u/%u-multisig-plånbok: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2889"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4232"/> <source>Opened %u/%u multisig wallet%s</source> <translation>Öppnade %u/%u-multisig-plånbok%s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2942"/> - <source>Use "help <command>" to see a command's documentation. + <location filename="../src/simplewallet/simplewallet.cpp" line="4293"/> + <source>Use "help <command>" to see a command's documentation. </source> - <translation>Använd "help <kommando>" för att visa dokumentation för kommandot. + <translation>Använd "help <kommando>" för att visa dokumentation för kommandot. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3000"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4351"/> <source>wallet is multisig and cannot save a watch-only version</source> <translation>plånboken är multisig och kan inte spara en granskningsversion</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3105"/> - <source>missing daemon URL argument</source> - <translation>argument för URL till daemon saknas</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3116"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4476"/> <source>Unexpected array length - Exited simple_wallet::set_daemon()</source> <translation>Oväntad matrislängd - Lämnade simple_wallet::set_daemon()</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3130"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4517"/> <source>This does not seem to be a valid daemon URL.</source> <translation>Detta verkar inte vara en giltig daemon-URL.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3166"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3184"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4590"/> <source>txid </source> <translation>txid </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3168"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3186"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4555"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4592"/> <source>idx </source> <translation>idx </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3299"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4780"/> <source> (Some owned outputs have partial key images - import_multisig_info needed)</source> <translation> (Några ägda utgångar har partiella nyckelavbildningar - import_multisig_info krävs)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3300"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4783"/> <source>Currently selected account: [</source> <translation>Aktuellt valt konto: [</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3300"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4783"/> <source>] </source> <translation>] </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3302"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4785"/> <source>Tag: </source> <translation>Tagg: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3302"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4785"/> <source>(No tag assigned)</source> <translation>(Ingen tagg tilldelad)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3309"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4792"/> <source>Balance per address:</source> <translation>Saldo per adress:</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> <source>Address</source> <translation>Adress</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5921"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8008"/> <source>Balance</source> <translation>Saldo</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5921"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8008"/> <source>Unlocked balance</source> <translation>Upplåst saldo</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> <source>Outputs</source> <translation>Utgångar</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5921"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4793"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8008"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9122"/> <source>Label</source> <translation>Etikett</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3318"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4801"/> <source>%8u %6s %21s %21s %7u %21s</source> <translation>%8u %6s %21s %21s %7u %21s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3327"/> - <source>usage: balance [detail]</source> - <translation>användning: balance [detail]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3339"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3381"/> - <source>usage: incoming_transfers [available|unavailable] [verbose] [index=<N1>[,<N2>[,...]]]</source> - <translation>användning: incoming_transfers [available|unavailable] [verbose] [index=<N1>[,<N2>[,...]]]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> <source>spent</source> <translation>spenderat</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> <source>global index</source> <translation>globalt index</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> <source>tx id</source> <translation>tx-ID</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> <source>addr index</source> <translation>addr index</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3423"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4924"/> <source>No incoming transfers</source> <translation>Inga inkommande överföringar</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3427"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4928"/> <source>No incoming available transfers</source> <translation>Inga inkommande tillgängliga överföringar</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3431"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4932"/> <source>No incoming unavailable transfers</source> <translation>Inga inkommande otillgängliga överföringar</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3442"/> - <source>expected at least one payment ID</source> - <translation>åtminstone ett betalnings-ID förväntades</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> <source>payment</source> <translation>betalning</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> <source>transaction</source> <translation>transaktion</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> <source>height</source> <translation>höjd</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4956"/> <source>unlock time</source> <translation>upplåsningstid</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3463"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4968"/> <source>No payments with id </source> <translation>Inga betalningar med ID </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3516"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3582"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3853"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5016"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5106"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5442"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5901"/> <source>failed to get blockchain height: </source> <translation>det gick inte att hämta blockkedjans höjd: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3572"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5136"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5174"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5226"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5259"/> - <source>failed to connect to the daemon</source> - <translation>det gick inte att ansluta till daemonen</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3590"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5114"/> <source> Transaction %llu/%llu: txid=%s</source> <translation> Transaktion %llu/%llu: txid=%s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3600"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5135"/> <source> Input %llu/%llu: amount=%s</source> <translation> Ingång %llu/%llu: belopp=%s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3616"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5151"/> <source>failed to get output: </source> <translation>det gick inte att hämta utgång: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3624"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5159"/> <source>output key's originating block height shouldn't be higher than the blockchain height</source> <translation>utgångsnyckelns ursprungsblockhöjd får inte vara högre än blockkedjans höjd</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3628"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5163"/> <source> Originating block heights: </source> <translation> Ursprungsblockhöjder: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3643"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5175"/> <source> |</source> <translation> |</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3643"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5651"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5175"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7706"/> <source>| </source> <translation>| </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3660"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5192"/> <source> Warning: Some input keys being spent are from </source> <translation> Varning: Några ingångsnycklar som spenderas kommer från </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3662"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5194"/> <source>, which can break the anonymity of ring signature. Make sure this is intentional!</source> <translation>, vilket kan bryta ringsignaturens anonymitet. Se till att detta är avsiktligt!</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3705"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4184"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5234"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5853"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6156"/> <source>Ring size must not be 0</source> <translation>Ringstorlek för inte vara 0</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3717"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4196"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5246"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5865"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6168"/> <source>ring size %u is too small, minimum is %u</source> <translation>ringstorlek %uär för liten, minimum är %u</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3724"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5258"/> <source>wrong number of arguments</source> <translation>fel antal argument</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3830"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4266"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4479"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5417"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5996"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6268"/> <source>No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): </source> <translation>Inget betalnings-ID har inkluderats med denna transaktion. Är detta okej? (J/Ja/N/Nej): </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3872"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4286"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5458"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6016"/> <source>No outputs found, or daemon is not ready</source> <translation>Inga utgångar hittades, eller så är daemonen inte klar</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6743"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6428"/> + <source>Failed to parse donation address: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6442"/> + <source>Donating %s %s to The Monero Project (donate.getmonero.org or %s).</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6444"/> + <source>Donating %s %s to %s.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6759"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6770"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6777"/> + <source>failed to parse tx_key</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6786"/> + <source>Tx key successfully stored.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6790"/> + <source>Failed to store tx key: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7296"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>block</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7440"/> + <source>usage: show_transfers [in|out|all|pending|failed|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7493"/> + <source>usage: export_transfers [in|out|all|pending|failed|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]] [output=<path>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>direction</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>timestamp</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>running balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>hash</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>payment ID</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>fee</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>destination</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>index</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> + <source>note</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7572"/> + <source>CSV exported to </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7730"/> + <source>Warning: this will lose any information which can not be recovered from the blockchain.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7731"/> + <source>This includes destination addresses, tx secret keys, tx notes, etc</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7732"/> + <source>Rescan anyway ? (Y/Yes/N/No): </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7750"/> + <source>MMS received new message</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8387"/> + <source>Network type: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8388"/> + <source>Testnet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8389"/> + <source>Stagenet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8389"/> + <source>Mainnet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8559"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8605"/> + <source>command only supported by HW wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8564"/> + <source>hw wallet does not support cold KI sync</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8576"/> + <source>Please confirm the key image sync on the device</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8582"/> + <source>Key images synchronized to height </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8585"/> + <source>Running untrusted daemon, cannot determine which transaction output is spent. Use a trusted daemon with --trusted-daemon and run rescan_spent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8588"/> + <source> spent, </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8588"/> + <source> unspent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8592"/> + <source>Failed to import key images</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8597"/> + <source>Failed to import key images: </source> + <translation type="unfinished">Det gick inte att importera nyckelavbildningar: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8614"/> + <source>Failed to reconnect device</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8619"/> + <source>Failed to reconnect device: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8883"/> <source>Transaction successfully saved to </source> <translation>Transaktionen sparades till </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6743"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6745"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8883"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8885"/> <source>, txid </source> <translation>, txid </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6745"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8885"/> <source>Failed to save transaction to </source> <translation>Det gick inte att spara transaktion till </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4081"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4314"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5723"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6044"/> <source>Sweeping %s in %llu transactions for a total fee of %s. Is this okay? (Y/Yes/N/No): </source> <translation>Sveper upp %s i %llu transaktioner för en total avgift på %s. Är detta okej? (J/Ja/N/Nej): </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4087"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4320"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4519"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5729"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6050"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6310"/> <source>Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No): </source> <translation>Sveper upp %s för en total avgift på %s. Är detta okej? (J/Ja/N/Nej): </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4630"/> - <source>Donating </source> - <translation>Donerar </translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4792"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6611"/> <source>This is a watch only wallet</source> <translation>Detta är en granskningsplånbok</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6571"/> - <source>usage: show_transfer <txid></source> - <translation>användning: show_transfer <txid></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6673"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8813"/> <source>Double spend seen on the network: this transaction may or may not end up being mined</source> <translation>En dubbelspendering upptäcktes på nätverket: denna transaktion kanske aldrig blir verifierad</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6708"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8848"/> <source>Transaction ID not found</source> <translation>Transaktions-ID kunde inte hittas</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="214"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="336"/> <source>true</source> <translation>sant</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="267"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="389"/> <source>failed to parse refresh type</source> <translation>det gick inte att parsa uppdateringstyp</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="541"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="608"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="721"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="787"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="939"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="984"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1067"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1124"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1190"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1256"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1350"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1466"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1547"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6601"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6665"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6702"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6799"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7010"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7094"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8397"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8474"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8517"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8630"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8670"/> + <source>command not supported by HW wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="726"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="797"/> <source>wallet is watch-only and has no seed</source> <translation>plånboken är enbart för granskning och har inget startvärde</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="557"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="613"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="744"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="807"/> <source>wallet is non-deterministic and has no seed</source> <translation>plånboken är icke-deterministisk och har inget startvärde</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1226"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1245"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="751"/> + <source>Enter optional seed offset passphrase, empty to see raw seed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="817"/> + <source>Incorrect password</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="883"/> + <source>Current fee is %s %s per %s</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1036"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1158"/> + <source>Send this multisig info to all other participants, then use exchange_multisig_keys <info1> [<info2>...] with others' multisig info</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1167"/> + <source>Multisig wallet has been successfully created. Current wallet type: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1172"/> + <source>Failed to perform multisig keys exchange: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1499"/> + <source>Failed to load multisig transaction from MMS</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1631"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1788"/> + <source>Invalid key image</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1637"/> + <source>Invalid txid</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1649"/> + <source>Key image either not spent, or spent with mixin 0</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1664"/> + <source>Failed to get key image ring: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1679"/> + <source>File doesn't exist</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1701"/> + <source>Invalid ring specification: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1709"/> + <source>Invalid key image: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1714"/> + <source>Invalid ring type, expected relative or abosolute: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1720"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1732"/> + <source>Error reading line: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1743"/> + <source>Invalid ring: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1752"/> + <source>Invalid relative ring: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1764"/> + <source>Invalid absolute ring: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1773"/> + <source>Failed to set ring for key image: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1773"/> + <source>Continuing.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1803"/> + <source>Missing absolute or relative keyword</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1813"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1820"/> + <source>invalid index: must be a strictly positive unsigned integer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1828"/> + <source>invalid index: indices wrap</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1838"/> + <source>invalid index: indices should be in strictly ascending order</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1845"/> + <source>failed to set ring</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1890"/> + <source>First line is not an amount</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1904"/> + <source>Invalid output: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1914"/> + <source>Bad argument: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1914"/> + <source>should be "add"</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1923"/> + <source>Failed to open file</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1929"/> + <source>Invalid output key, and file doesn't exist</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1935"/> + <source>Failed to mark output spent: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1952"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1979"/> + <source>Invalid output</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1962"/> + <source>Failed to mark output unspent: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1986"/> + <source>Spent: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1988"/> + <source>Not spent: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1992"/> + <source>Failed to check whether output is spent: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2007"/> + <source>Failed to save known rings: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2022"/> + <source>Please confirm the transaction on the device</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2069"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2088"/> <source>wallet is watch-only and cannot transfer</source> <translation>plånboken är enbart för granskning och kan inte göra överföringar</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1321"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2106"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5581"/> + <source>WARNING: this is a non default ring size, which may harm your privacy. Default is recommended.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2108"/> + <source>WARNING: from v8, ring size will be fixed and this setting will be ignored.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2137"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2160"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2176"/> + <source>priority must be either 0, 1, 2, 3, or 4, or one of: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2181"/> <source>could not change default priority</source> <translation>det gick inte att ändra standardinställning för prioritet</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1919"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2249"/> + <source>invalid argument: must be either 0/never, 1/action, or 2/encrypt/decrypt</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2510"/> + <source>Device name not specified</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2519"/> + <source>Device reconnect failed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2524"/> + <source>Device reconnect failed: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2583"/> + <source>Show the incoming transfers, all or filtered by availability and address index. + +Output format: +Amount, Spent("T"|"F"), "locked"|"unlocked", RingCT, Global Index, Transaction Hash, Address Index, [Public Key, Key Image] </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2595"/> + <source>Transfer <amount> to <address>. If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding URI_2 or <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2599"/> + <source>Transfer <amount> to <address> and lock it for <lockblocks> (max. 1000000). If the parameter "index=<N1>[,<N2>,...]" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding URI_2 or <address_2> <amount_2> etcetera (before the payment ID, if it's included)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2603"/> + <source>Send all unlocked balance to an address and lock it for <lockblocks> (max. 1000000). If the parameter "index<N1>[,<N2>,...]" is specified, the wallet sweeps outputs received by those address indices. If omitted, the wallet randomly chooses an address index to be used. <priority> is the priority of the sweep. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command "set priority") is used. <ring_size> is the number of inputs to include for untraceability.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2609"/> + <source>Send all unlocked balance to an address. If the parameter "index<N1>[,<N2>,...]" is specified, the wallet sweeps outputs received by those address indices. If omitted, the wallet randomly chooses an address index to be used. If the parameter "outputs=<N>" is specified and N > 0, wallet splits the transaction into N even outputs.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2625"/> + <source>Sign a transaction from a file. If the parameter "export_raw" is specified, transaction raw hex data suitable for the daemon RPC /sendrawtransaction is exported.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2646"/> + <source>If no arguments are specified or <index> is specified, the wallet shows the default or specified address. If "all" is specified, the wallet shows all the existing addresses in the currently selected account. If "new " is specified, the wallet creates a new address with the provided label text (which can be empty). If "label" is specified, the wallet sets the label of the address specified by <index> to the provided label text.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2673"/> + <source>Available options: + seed language + Set the wallet's 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 the default ring size (obsolete). + auto-refresh <1|0> + Whether to automatically synchronize new blocks from the daemon. + refresh-type <full|optimize-coinbase|no-coinbase|default> + Set the wallet's refresh behaviour. + priority [0|1|2|3|4] + Set the fee to default/unimportant/normal/elevated/priority. + confirm-missing-payment-id <1|0> + ask-password <0|1|2 (or never|action|decrypt)> + unit <monero|millinero|micronero|nanonero|piconero> + Set the 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] + Set a threshold for confirm-backlog to only warn if the transaction backlog is greater than n blocks. + refresh-from-block-height [n] + Set the height before which to ignore blocks. + auto-low-priority <1|0> + Whether to automatically use the low priority fee level when it's safe to do so. + segregate-pre-fork-outputs <1|0> + Set this if you intend to spend outputs on both Monero AND a key reusing fork. + key-reuse-mitigation2 <1|0> + Set this if you are not sure whether you will spend on a key reusing Monero fork later. +subaddress-lookahead <major>:<minor> + Set the lookahead sizes for the subaddress hash table. + Set this if you are not sure whether you will spend on a key reusing Monero fork later. + segregation-height <n> + Set to the height of a key reusing fork you want to use, 0 to use default.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2730"/> + <source>Set the transaction key (r) for a given <txid> in case the tx was made by some other device or 3rd party wallet.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2765"/> + <source>Show the incoming/outgoing transfers within an optional height range. + +Output format: +In or Coinbase: Block Number, "block"|"in", Time, Amount, Transaction Hash, Payment ID, Subaddress Index, "-", Note +Out: Block Number, "out", Time, Amount*, Transaction Hash, Payment ID, Fee, Destinations, Input addresses**, "-", Note +Pool: "pool", "in", Time, Amount, Transaction Hash, Payment Id, Subaddress Index, "-", Note, Double Spend Note +Pending or Failed: "failed"|"pending", "out", Time, Amount*, Transaction Hash, Payment ID, Fee, Input addresses**, "-", Note + +* Excluding change and fee. +** Set of address indices used as inputs in this transfer.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2775"/> + <source>export_transfers [in|out|all|pending|failed|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]] [output=<filepath>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2776"/> + <source>Export to CSV the incoming/outgoing transfers within an optional height range.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2784"/> + <source>Rescan the blockchain from scratch, losing any information which can not be recovered from the blockchain itself.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2818"/> + <source>Export a signed set of key images to a <filename>.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2826"/> + <source>Synchronizes key images with the hw wallet.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2830"/> + <source>Attempts to reconnect HW wallet.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2865"/> + <source>Performs extra multisig keys exchange rounds. Needed for arbitrary M/N multisig wallets</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2889"/> + <source>Interface with the MMS (Multisig Messaging System) +<subcommand> is one of: + init, info, signer, list, next, sync, transfer, delete, send, receive, export, note, show, set, help + send_signer_config, start_auto_config, stop_auto_config, auto_config +Get help about a subcommand with: help mms <subcommand>, or mms help <subcommand></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2897"/> + <source>Initialize and configure the MMS for M/N = number of required signers/number of authorized signers multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2901"/> + <source>Display current MMS configuration</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2905"/> + <source>Set or modify authorized signer info (single-word label, transport address, Monero address), or list all signers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2909"/> + <source>List all messages</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2913"/> + <source>Evaluate the next possible multisig-related action(s) according to wallet state, and execute or offer for choice +By using 'sync' processing of waiting messages with multisig sync info can be forced regardless of wallet state</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2918"/> + <source>Force generation of multisig sync info regardless of wallet state, to recover from special situations like "stale data" errors</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2922"/> + <source>Initiate transfer with MMS support; arguments identical to normal 'transfer' command arguments, for info see there</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2926"/> + <source>Delete a single message by giving its id, or delete all messages by using 'all'</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2930"/> + <source>Send a single message by giving its id, or send all waiting messages</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2934"/> + <source>Check right away for new messages to receive</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2938"/> + <source>Write the content of a message to a file "mms_message_content"</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2942"/> + <source>Send a one-line message to an authorized signer, identified by its label, or show any waiting unread notes</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2946"/> + <source>Show detailed info about a single message</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2950"/> + <source>Available options: + auto-send <1|0> + Whether to automatically send newly generated messages right away. + </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2956"/> + <source>Send completed signer config to all other authorized signers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2960"/> + <source>Start auto-config at the auto-config manager's wallet by issuing auto-config tokens and optionally set others' labels</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2964"/> + <source>Delete any auto-config tokens and abort a auto-config process</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2968"/> + <source>Start auto-config by using the token received from the auto-config manager</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2972"/> + <source>Print the ring(s) used to spend a given key image or transaction (if the ring size is > 1) + +Output format: +Key Image, "absolute", list of rings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2978"/> + <source>Set the ring used for a given key image, so it can be reused in a fork</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2982"/> + <source>Save known rings to the shared rings database</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2986"/> + <source>Mark output(s) as spent so they never get selected as fake outputs in a ring</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2990"/> + <source>Marks an output as unspent so it may get selected as a fake output in a ring</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2994"/> + <source>Checks whether an output is marked as spent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2998"/> + <source>Returns version information</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3087"/> <source>full (slowest, no assumptions); optimize-coinbase (fast, assumes the whole coinbase is paid to a single address); no-coinbase (fastest, assumes we receive no coinbase transaction), default (same as optimize-coinbase)</source> <translation>full (långsammast, inga antaganden); optimize-coinbase (snabb, antar att hela coinbase-transaktionen betalas till en enda adress); no-coinbase (snabbast, antar att ingen coinbase-transaktion tas emot), default (samma som optimize-coinbase)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1923"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3088"/> + <source>0, 1, 2, 3, or 4, or one of </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3090"/> + <source>0|1|2 (or never|action|decrypt)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3091"/> <source>monero, millinero, micronero, nanonero, piconero</source> <translation>monero, millinero, micronero, nanonero, piconero</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1975"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3102"/> + <source><major>:<minor></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3106"/> + <source><device_name[:device_spec]></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3127"/> + <source>wrong number range, use: %s</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3166"/> <source>Wallet name not valid. Please try again or use Ctrl-C to quit.</source> <translation>Plånbokens namn ej giltigt. Försök igen eller använd Ctrl-C för att avsluta.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1992"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3183"/> <source>Wallet and key files found, loading...</source> <translation>Plånbok och nyckelfil hittades, läser in …</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1998"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3189"/> <source>Key file found but not wallet file. Regenerating...</source> <translation>Nyckelfilen hittades men inte plånboksfilen. Återskapar …</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2004"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3195"/> <source>Key file not found. Failed to open wallet: </source> <translation>Nyckelfilen kunde inte hittas. Det gick inte att öppna plånbok: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2023"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3214"/> <source>Generating new wallet...</source> <translation>Skapar ny plånbok …</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2141"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3232"/> + <source>NOTE: the following %s can be used to recover access to your wallet. Write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3234"/> + <source>string</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3234"/> + <source>25 words</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3273"/> + <source>Can't specify more than one of --testnet and --stagenet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3285"/> + <source>can't specify more than one of --generate-new-wallet="wallet_name", --wallet-file="wallet_name", --generate-from-view-key="wallet_name", --generate-from-spend-key="wallet_name", --generate-from-keys="wallet_name", --generate-from-multisig-keys="wallet_name", --generate-from-json="jsonfilename" and --generate-from-device="wallet_name"</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3364"/> <source>Electrum-style word list failed verification</source> <translation>Det gick inte att verifiera ordlista av Electrum-typ</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2174"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2194"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2229"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2248"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2268"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2284"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2332"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2357"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2373"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2413"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3369"/> + <source>Enter seed offset passphrase, empty if none</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3395"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3415"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3450"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3470"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3490"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3505"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3578"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3594"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3633"/> <source>No data supplied, cancelled</source> <translation>Inga data angivna, avbryter</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2180"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2254"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2363"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3791"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4240"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4454"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4926"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4994"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5058"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5266"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6106"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6353"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3401"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3476"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3584"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5371"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5969"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6243"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6818"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6886"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6950"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7154"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8193"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8454"/> <source>failed to parse address</source> <translation>det gick inte att parsa adressen</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2200"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2290"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3421"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3511"/> <source>failed to parse view key secret key</source> <translation>det gick inte att parsa hemlig granskningsnyckel</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2210"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2308"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3430"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3528"/> <source>failed to verify view key secret key</source> <translation>det gick inte att verifiera hemlig granskningsnyckel</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2214"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2312"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2393"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3434"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3532"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3613"/> <source>view key does not match standard address</source> <translation>granskningsnyckel matchar inte standardadress</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2219"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2238"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2316"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2450"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2480"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3439"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3459"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3536"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3669"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3695"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3726"/> <source>account creation failed</source> <translation>det gick inte att skapa konto</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2234"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2274"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2418"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3455"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3496"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3638"/> <source>failed to parse spend key secret key</source> <translation>det gick inte att parsa spendernyckel hemlig nyckel</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2300"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2439"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3520"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3658"/> <source>failed to verify spend key secret key</source> <translation>det gick inte att verifiera spendernyckel hemlig nyckel</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2304"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2444"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3524"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3663"/> <source>spend key does not match standard address</source> <translation>spendernyckel matchar inte standardadress</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2562"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3701"/> + <source>No restore height is specified.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3702"/> + <source>Assumed you are creating a new account, restore will be done from current estimated blockchain height.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3703"/> + <source>Use --restore-height if you want to restore an already setup account from a specific height</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3707"/> + <source>account creation aborted</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3816"/> + <source>can't specify --subaddress-lookahead and --wallet-file at the same time</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3820"/> <source>failed to open account</source> <translation>det gick inte att öppna konto</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2566"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3030"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3085"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3142"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4962"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3824"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4391"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4444"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4529"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6854"/> <source>wallet is null</source> <translation>plånbok är null</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2680"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="2685"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3832"/> + <source>Failed to initialize ring database: privacy enhancing features will be inactive</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3917"/> + <source>If your display freezes, exit blind with ^C, then run again with --use-english-language-names</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3935"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3940"/> <source>invalid language choice entered. Please try again. </source> <translation>ogiltigt språkval har angivits. Försök igen. </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2753"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4019"/> <source>View key: </source> <translation>Granskningsnyckel: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2935"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4130"/> + <source>Generated new wallet on hw device: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4209"/> + <source>Key file not found. Failed to open wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4286"/> <source>You may want to remove the file "%s" and try again</source> <translation>Du kan också prova att bort filen "%s" och försöka igen</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="2963"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4314"/> <source>failed to deinitialize wallet</source> <translation>det gick inte att avinitiera plånboken</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3021"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3524"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6410"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4367"/> + <source>Watch only wallet saved as: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4371"/> + <source>Failed to save watch only wallet: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4382"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5024"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8522"/> <source>this command requires a trusted daemon. Enable with --trusted-daemon</source> <translation>detta kommando kräver en betrodd daemon. Aktivera med --trusted-daemon</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3152"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4498"/> + <source>Expected trusted or untrusted, got </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4515"/> + <source>trusted</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4515"/> + <source>untrusted</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4539"/> <source>blockchain can't be saved: </source> <translation>blockkedjan kan inte sparas: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3239"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3538"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4569"/> + <source>NOTE: this transaction uses an encrypted payment ID: consider using subaddresses instead</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4572"/> + <source>WARNING: this transaction uses an unencrypted payment ID: consider using subaddresses instead</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4608"/> + <source>Password needed (%s) - use the refresh command</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4616"/> + <source>Enter password</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4631"/> + <source>Device requires attention</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4639"/> + <source>Enter device PIN</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4641"/> + <source>Failed to read device PIN</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4648"/> + <source>Please enter the device passphrase on the device</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4655"/> + <source>Enter device passphrase</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4657"/> + <source>Failed to read device passphrase</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4673"/> + <source>The first refresh has finished for the HW-based wallet with received money. hw_key_images_sync is needed. </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4675"/> + <source>Do you want to do it now? (Y/Yes/N/No): </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4677"/> + <source>hw_key_images_sync skipped. Run command manually before a transfer.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4720"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5038"/> <source>daemon is busy. Please try again later.</source> <translation>daemonen är upptagen. Försök igen senare.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3243"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3542"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4724"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5042"/> <source>no connection to daemon. Please make sure daemon is running.</source> <translation>ingen anslutning till daemonen. Se till att daemonen körs.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3253"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4734"/> <source>refresh error: </source> <translation>fel vid uppdatering: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3303"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4782"/> + <source> (Some owned outputs have missing key images - import_key_images needed)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4786"/> <source>Balance: </source> <translation>Saldo: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3399"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4855"/> + <source>Invalid keyword: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4893"/> <source>pubkey</source> <translation>publik nyckel</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3399"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4893"/> <source>key image</source> <translation>nyckelavbildning</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="3410"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4910"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7518"/> <source>unlocked</source> <translation>upplåst</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4894"/> <source>ringct</source> <translation>ringct</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3409"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4904"/> + <source>Heights: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4909"/> <source>T</source> <translation>S</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3409"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4909"/> <source>F</source> <translation>F</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3410"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4910"/> <source>locked</source> <translation>låst</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3411"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4911"/> <source>RingCT</source> <translation>RingCT</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3411"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4911"/> <source>-</source> <translation>-</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3485"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4990"/> <source>payment ID has invalid format, expected 16 or 64 character hex string: </source> <translation>betalnings-ID har ogiltigt format. En hexadecimal sträng med 16 eller 64 tecken förväntades: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3546"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5046"/> <source>failed to get spent status</source> <translation>det gick inte att hämta spenderstatus</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3661"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5130"/> + <source>failed to find construction data for tx input</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5193"/> <source>the same transaction</source> <translation>samma transaktion</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3661"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5193"/> <source>blocks that are temporally very close</source> <translation>block som ligger väldigt nära varandra i tiden</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3778"/> - <source>Locked blocks too high, max 1000000 (˜4 yrs)</source> - <translation>Låsta block för högt, max 1000000 (˜~4 år)</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="9015"/> + <source> (Y/Yes/N/No): </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9042"/> + <source>Choose processing:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9051"/> + <source>Sign tx</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9059"/> + <source>Send the tx for submission to </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9063"/> + <source>Send the tx for signing to </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9070"/> + <source>Submit tx</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9073"/> + <source>unknown</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9079"/> + <source>Choice: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9091"/> + <source>Wrong choice</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9098"/> + <source>Id</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9098"/> + <source>I/O</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9098"/> + <source>Authorized Signer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>Message Type</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>Height</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>R</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>Message State</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9099"/> + <source>Since</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9116"/> + <source> ago</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9122"/> + <source>#</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9122"/> + <source>Transport Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9123"/> + <source>Auto-Config Token</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9123"/> + <source>Monero Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9127"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9135"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9137"/> + <source><not set></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9178"/> + <source>Message </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9179"/> + <source>In/out: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9181"/> + <source>State: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9181"/> + <source>%s since %s, %s ago</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9185"/> + <source>Sent: Never</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9189"/> + <source>Sent: %s, %s ago</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9192"/> + <source>Authorized signer: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9193"/> + <source>Content size: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9193"/> + <source> bytes</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9194"/> + <source>Content: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9194"/> + <source>(binary data)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9224"/> + <source>Send these messages now?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9234"/> + <source>Queued for sending.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9254"/> + <source>Invalid message id</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9263"/> + <source>usage: mms init <required_signers>/<authorized_signers> <own_label> <own_transport_address></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9269"/> + <source>The MMS is already initialized. Re-initialize by deleting all signer info and messages?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9284"/> + <source>Error in the number of required signers and/or authorized signers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9301"/> + <source>The MMS is not active.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9324"/> + <source>Invalid signer number </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9329"/> + <source>mms signer [<number> <label> [<transport_address> [<monero_address>]]]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9348"/> + <source>Invalid Monero address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9355"/> + <source>Wallet state does not allow changing Monero addresses anymore</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9367"/> + <source>Usage: mms list</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9380"/> + <source>Usage: mms next [sync]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9405"/> + <source>No next step: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9415"/> + <source>prepare_multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9421"/> + <source>make_multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9436"/> + <source>exchange_multisig_keys</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9451"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9571"/> + <source>export_multisig_info</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9460"/> + <source>import_multisig_info</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9473"/> + <source>sign_multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9483"/> + <source>submit_multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9493"/> + <source>Send tx</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9504"/> + <source>Process signer config</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9516"/> + <source>Replace current signer config with the one displayed above?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9530"/> + <source>Process auto config data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9544"/> + <source>Nothing ready to process</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9564"/> + <source>Usage: mms sync</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9588"/> + <source>Usage: mms delete (<message_id> | all)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9595"/> + <source>Delete all messages?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9621"/> + <source>Usage: mms send [<message_id>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9638"/> + <source>Usage: mms receive</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9655"/> + <source>Usage: mms export <message_id></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9667"/> + <source>Message content saved to: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9671"/> + <source>Failed to to save message content</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9695"/> + <source>Usage: mms note [<label> <text>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9702"/> + <source>No signer found with label </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9724"/> + <source>Usage: mms show <message_id></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9743"/> + <source>Usage: mms set <option_name> [<option_value>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9760"/> + <source>Wrong option value</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9765"/> + <source>Auto-send is on</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9765"/> + <source>Auto-send is off</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9770"/> + <source>Unknown option</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9778"/> + <source>Usage: mms help [<subcommand>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9794"/> + <source>Usage: mms send_signer_config</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9800"/> + <source>Signer config not yet complete</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9815"/> + <source>Usage: mms start_auto_config [<label> <label> ...]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9820"/> + <source>There are signers without a label set. Complete labels before auto-config or specify them as parameters here.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9826"/> + <source>Auto-config is already running. Cancel and restart?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9850"/> + <source>Usage: mms stop_auto_config</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5077"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5188"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9853"/> + <source>Delete any auto-config tokens and stop auto-config?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9866"/> + <source>Usage: mms auto_config <auto_config_token></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9873"/> + <source>Invalid auto-config token</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9879"/> + <source>Auto-config already running. Cancel and restart?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9911"/> + <source>The MMS is not active. Activate using the "mms init" command</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9988"/> + <source>Invalid MMS subcommand</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="9993"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9997"/> + <source>Error in MMS command: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6969"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7079"/> <source>Good signature</source> <translation>Godkänd signatur</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5104"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5190"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5293"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6996"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7081"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7181"/> <source>Bad signature</source> <translation>Felaktig signatur</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6046"/> - <source>usage: integrated_address [payment ID]</source> - <translation>användning: integrated_address [betalnings-ID]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6082"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8169"/> <source>Standard address: </source> <translation>Standardadress: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6087"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8174"/> <source>failed to parse payment ID or address</source> <translation>det gick inte att parsa betalnings-ID eller adress</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6098"/> - <source>usage: address_book [(add (<address> [pid <long or short payment id>])|<integrated address> [<description possibly with whitespaces>])|(delete <index>)]</source> - <translation>användning: address_book [(add (<adress> [pid <långt eller kort betalnings-ID>])|<integrerad adress> [<beskrivning eventuellt med blanktecken>])|(delete <index>)]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6128"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8215"/> <source>failed to parse payment ID</source> <translation>det gick inte att parsa betalnings-ID</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6146"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8233"/> <source>failed to parse index</source> <translation>det gick inte att parsa index</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6154"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8241"/> <source>Address book is empty.</source> <translation>Adressboken är tom.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6160"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8247"/> <source>Index: </source> <translation>Index: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6161"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6287"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8248"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8378"/> <source>Address: </source> <translation>Adress: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6162"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8249"/> <source>Payment ID: </source> <translation>Betalnings-ID: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6163"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6286"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8250"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8377"/> <source>Description: </source> <translation>Beskrivning: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6173"/> - <source>usage: set_tx_note [txid] free text note</source> - <translation>användning: set_tx_note [txid] fritextanteckning</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6201"/> - <source>usage: get_tx_note [txid]</source> - <translation>användning: get_tx_note [txid]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6304"/> - <source>usage: sign <filename></source> - <translation>användning: sign <filnamn></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6309"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8407"/> <source>wallet is watch-only and cannot sign</source> <translation>plånboken är enbart för granskning och kan inte signera</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="951"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6323"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6346"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6501"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1289"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8421"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8447"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8684"/> <source>failed to read file </source> <translation>det gick inte att läsa filen </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5039"/> - <source>usage: check_tx_proof <txid> <address> <signature_file> [<message>]</source> - <translation>användning: check_tx_proof <txid> <adress> <signaturfil> [<meddelande>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5066"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5181"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5278"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6958"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7072"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7166"/> <source>failed to load signature file</source> <translation>det gick inte att läsa in signaturfil</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5117"/> - <source>usage: get_spend_proof <txid> [<message>]</source> - <translation>användning: get_spend_proof <txid> [<meddelande>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5123"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7020"/> <source>wallet is watch-only and cannot generate the proof</source> <translation>plånboken är enbart för granskning och kan inte skapa beviset</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5161"/> - <source>usage: check_spend_proof <txid> <signature_file> [<message>]</source> - <translation>användning: check_spend_proof <txid> <signaturfil> [<meddelande>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5202"/> - <source>usage: get_reserve_proof (all|<amount>) [<message>]</source> - <translation>användning: get_reserve_proof (all|<belopp>) [<meddelande>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5208"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7104"/> <source>The reserve proof can be generated only by a full wallet</source> <translation>Beviset på reserv kan endast skapas av en standardplånbok</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5253"/> - <source>usage: check_reserve_proof <address> <signature_file> [<message>]</source> - <translation>användning: check_reserve_proof <adress> <signaturfil> [<meddelande>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5271"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7159"/> <source>Address must not be a subaddress</source> <translation>Adressen får inte vara en underadress</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5289"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7177"/> <source>Good signature -- total: %s, spent: %s, unspent: %s</source> <translation>Godkänd signatur -- summa: %s, spenderat: %s, ej spenderat: %s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5353"/> - <source>usage: show_transfers [in|out|all|pending|failed] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]</source> - <translation>användning: show_transfers [in|out|all|pending|failed] [index=<N1>[, <N2>, …]] [<minhöjd> [<maxhöjd>]]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5490"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7365"/> <source>[Double spend seen on the network: this transaction may or may not end up being mined] </source> <translation>[En dubbelspendering upptäcktes på nätverket: denna transaktion kanske aldrig blir verifierad] </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5526"/> - <source>usage: unspent_outputs [index=<N1>[,<N2>,...]] [<min_amount> [<max_amount>]]</source> - <translation>användning: unspent_outputs [index=<N1>[, <N2>, …]] [<min_belopp> [<max_belopp>]]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5586"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7641"/> <source>There is no unspent output in the specified address</source> <translation>Det finns ingen ej spenderad utgång i den angivna adressen</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5699"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7799"/> <source> (no daemon)</source> <translation> (ingen daemon)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5701"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7801"/> <source> (out of sync)</source> <translation> (inte synkroniserad)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5758"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7852"/> <source>(Untitled account)</source> <translation>(Ej namngivet konto)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5771"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5789"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5814"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5837"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5990"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6013"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7865"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7883"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7908"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7931"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8077"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8100"/> <source>failed to parse index: </source> <translation>det gick inte att parsa index: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5776"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5995"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7870"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8082"/> <source>specify an index between 0 and </source> <translation>ange ett index mellan 0 och </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5873"/> - <source>usage: - account - account new <label text with white spaces allowed> - account switch <index> - account label <index> <label text with white spaces allowed> - account tag <tag_name> <account_index_1> [<account_index_2> ...] - account untag <account_index_1> [<account_index_2> ...] - account tag_description <tag_name> <description></source> - <translation>användning: - account - account new <etikettext med blanktecken tillåtna> - account switch <index> - account label <index> <etikettext med blanktecken tillåtna> - account tag <taggnamn> <kontoindex_1> [<kontoindex_2> …] - account untag <kontoindex_1> [<kontoindex_2> …] - account tag_description <taggnamn> <beskrivning></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5901"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7988"/> <source> Grand total: Balance: </source> @@ -3103,463 +4110,386 @@ Totalsumma: Saldo: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5901"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7988"/> <source>, unlocked balance: </source> <translation>, upplåst saldo: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5909"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7996"/> <source>Untagged accounts:</source> <translation>Otaggade konton:</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5915"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8002"/> <source>Tag %s is unregistered.</source> <translation>Taggen %s har inte registrerats.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5918"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8005"/> <source>Accounts with tag: </source> <translation>Konton med tagg: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5919"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8006"/> <source>Tag's description: </source> <translation>Taggens beskrivning: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5921"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8008"/> <source>Account</source> <translation>Konto</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5927"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8014"/> <source> %c%8u %6s %21s %21s %21s</source> <translation> %c%8u %6s %21s %21s %21s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5937"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8024"/> <source>----------------------------------------------------------------------------------</source> <translation>----------------------------------------------------------------------------------</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5938"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8025"/> <source>%15s %21s %21s</source> <translation>%15s %21s %21s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5961"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8048"/> <source>Primary address</source> <translation>Primär adress</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5961"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8048"/> <source>(used)</source> <translation>(används)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5982"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8069"/> <source>(Untitled address)</source> <translation>(Ej namngiven adress)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6022"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8109"/> <source><index_min> is already out of bound</source> <translation><index_min> är redan utanför tillåtet intervall</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6027"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8114"/> <source><index_max> exceeds the bound</source> <translation><index_max> är utanför tillåtet intervall</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6035"/> - <source>usage: address [ new <label text with white spaces allowed> | all | <index_min> [<index_max>] | label <index> <label text with white spaces allowed> ]</source> - <translation>användning: address [new <etikettext med blanktecken tillåtna> | all | <index_min> [<index_max>] | label <index> <etikettext med blanktecken tillåtna>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6053"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6065"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8140"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8152"/> <source>Integrated addresses can only be created for account 0</source> <translation>Integrerade adresser kan bara skapas för konto 0</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6077"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8164"/> <source>Integrated address: %s, payment ID: %s</source> <translation>Integrerad adress: %s, betalnings-ID: %s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6082"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8169"/> <source>Subaddress: </source> <translation>Underadress: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6242"/> - <source>usage: get_description</source> - <translation>användning: get_description</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6248"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8335"/> <source>no description found</source> <translation>ingen beskrivning hittades</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6250"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8337"/> <source>description found: </source> <translation>beskrivning hittades: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6285"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8376"/> <source>Filename: </source> <translation>Filnamn: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6290"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8381"/> <source>Watch only</source> <translation>Endast granskning</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6292"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8383"/> <source>%u/%u multisig%s</source> <translation>%u/%u multisig%s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6294"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8385"/> <source>Normal</source> <translation>Normal</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6295"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8386"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="9180"/> <source>Type: </source> <translation>Typ: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6296"/> - <source>Testnet: </source> - <translation>Testnet: </translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6296"/> - <source>Yes</source> - <translation>Ja</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6296"/> - <source>No</source> - <translation>Nej</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6314"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8412"/> <source>This wallet is multisig and cannot sign</source> <translation>Plånboken är multisig och kan inte signera</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6335"/> - <source>usage: verify <filename> <address> <signature></source> - <translation>användning: verify <filnamn> <adress> <signatur></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6360"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8461"/> <source>Bad signature from </source> <translation>Felaktig signatur från </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6364"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8465"/> <source>Good signature from </source> <translation>Godkänd signatur från </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6373"/> - <source>usage: export_key_images <filename></source> - <translation>användning: export_key_images <filnamn></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6378"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8484"/> <source>wallet is watch-only and cannot export key images</source> <translation>plånboken är enbart för granskning och kan inte exportera nyckelavbildningar</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="906"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6391"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6473"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1228"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8498"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8651"/> <source>failed to save file </source> <translation>det gick inte att spara fil </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6402"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8509"/> <source>Signed key images exported to </source> <translation>Signerade nyckelavbildningar exporterades till </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6416"/> - <source>usage: import_key_images <filename></source> - <translation>användning: import_key_images <filnamn></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6447"/> - <source>usage: export_outputs <filename></source> - <translation>användning: export_outputs <filnamn></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6484"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8662"/> <source>Outputs exported to </source> <translation>Utgångar exporterades till </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6492"/> - <source>usage: import_outputs <filename></source> - <translation>användning: import_outputs <filnamn></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3819"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5219"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5545"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5354"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6417"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7115"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7600"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7608"/> <source>amount is wrong: </source> <translation>beloppet är fel: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="3820"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5355"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6417"/> <source>expected number from 0 to </source> <translation>förväntades: ett tal från 0 till </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4079"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5721"/> <source>Sweeping </source> <translation>Sveper upp </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4559"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6350"/> <source>Money successfully sent, transaction: </source> <translation>Pengar skickades, transaktion: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4716"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6530"/> <source>Change goes to more than one address</source> <translation>Växel går till fler än en adress</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4757"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6571"/> <source>%s change to %s</source> <translation>%s växel till %s</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4760"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6574"/> <source>no change</source> <translation>ingen växel</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1044"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1057"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4826"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1435"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1448"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6646"/> <source>Transaction successfully signed to file </source> <translation>Transaktionen signerades till fil </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4876"/> - <source>usage: get_tx_key <txid></source> - <translation>användning: get_tx_key <txid></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4884"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4919"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4968"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5050"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5130"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5168"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6180"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6208"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6578"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6713"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6749"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6811"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6860"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6942"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7027"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7062"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8267"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8295"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8714"/> <source>failed to parse txid</source> <translation>det gick inte att parsa txid</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4898"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6727"/> <source>Tx key: </source> <translation>Tx-nyckel: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4903"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6732"/> <source>no tx keys found for this txid</source> <translation>inga tx-nycklar kunde hittas för detta txid</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4912"/> - <source>usage: get_tx_proof <txid> <address> [<message>]</source> - <translation>användning: get_tx_proof <txid> <adress> [<meddelande>]</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4937"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5147"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5239"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6829"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7041"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7130"/> <source>signature file saved to: </source> <translation>signaturfilen sparades till: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4939"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5149"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5241"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6831"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7043"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7132"/> <source>failed to save signature file</source> <translation>det gick inte att spara signaturfilen</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4953"/> - <source>usage: check_tx_key <txid> <txkey> <address></source> - <translation>användning: check_tx_key <txid> <txnyckel> <adress></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4976"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="4985"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6868"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6877"/> <source>failed to parse tx key</source> <translation>det gick inte att parsa txnyckel</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="4943"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5031"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5109"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6835"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6923"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7001"/> <source>error: </source> <translation>fel: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5007"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5080"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6899"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6972"/> <source>received</source> <translation>mottaget</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5007"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5080"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6899"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6972"/> <source>in txid</source> <translation>i txid</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5026"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5099"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6918"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6991"/> <source>received nothing in txid</source> <translation>tog emot ingenting i txid</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5010"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5083"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6902"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6975"/> <source>WARNING: this transaction is not yet included in the blockchain!</source> <translation>VARNING: denna transaktion är ännu inte inkluderad i blockkedjan!</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5016"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5089"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6908"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6981"/> <source>This transaction has %u confirmations</source> <translation>Denna transaktion har %u bekräftelser</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5020"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5093"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6912"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6985"/> <source>WARNING: failed to determine number of confirmations!</source> <translation>VARNING: det gick inte att bestämma antal bekräftelser!</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5401"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7266"/> <source>bad min_height parameter:</source> <translation>felaktig parameter för min_höjd:</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5413"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7278"/> <source>bad max_height parameter:</source> <translation>felaktig parameter för max_höjd:</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5473"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7296"/> <source>in</source> <translation>in</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5473"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="5514"/> - <source>out</source> - <translation>ut</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5514"/> - <source>failed</source> - <translation>misslyckades</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5514"/> - <source>pending</source> - <translation>väntande</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5560"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7615"/> <source><min_amount> should be smaller than <max_amount></source> <translation><min_belopp> måste vara mindre än <max_belopp></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5592"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7647"/> <source> Amount: </source> <translation> Belopp: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5592"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7647"/> <source>, number of keys: </source> <translation>, antal nycklar: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5597"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7652"/> <source> </source> <translation></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5602"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7657"/> <source> Min block height: </source> <translation> Minblockhöjd: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5603"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7658"/> <source> Max block height: </source> <translation> Maxblockhöjd: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5604"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7659"/> <source> Min amount found: </source> <translation> Minbelopp funnet: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5605"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7660"/> <source> Max amount found: </source> <translation> Maxbelopp funnet: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5606"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7661"/> <source> Total count: </source> <translation> Totalt antal: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5646"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7701"/> <source> Bin size: </source> <translation> Storlek för binge: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5647"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7702"/> <source> Outputs per *: </source> <translation> Utgångar per *: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5649"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7704"/> <source>count ^ </source> @@ -3568,52 +4498,52 @@ Utgångar per *: </translation> </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5651"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7706"/> <source> |</source> <translation> |</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5653"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7708"/> <source> +</source> <translation> +</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5653"/> - <source>+--> block height + <location filename="../src/simplewallet/simplewallet.cpp" line="7708"/> + <source>+--> block height </source> - <translation>+--> blockhöjd + <translation>+--> blockhöjd </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5654"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7709"/> <source> ^</source> <translation> ^</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5654"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7709"/> <source>^ </source> <translation>^ </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5655"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7710"/> <source> </source> <translation></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="5696"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="7797"/> <source>wallet</source> <translation>plånbok</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="666"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6057"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="870"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8144"/> <source>Random payment ID: </source> <translation>Slumpmässigt betalnings-ID: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6058"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8145"/> <source>Matching integrated address: </source> <translation>Matchande integrerad adress: </translation> </message> @@ -3631,11 +4561,6 @@ Utgångar per *: </translation> <translation>Ange tröskelvärde och deltagare på en gång som M/N</translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="72"/> - <source>How many participants wil share parts of the multisig wallet</source> - <translation>Hur många deltagare kommer att dela delar av multisig-plånboken</translation> - </message> - <message> <location filename="../src/gen_multisig/gen_multisig.cpp" line="73"/> <source>How many signers are required to sign a valid transaction</source> <translation>Hur många signerare krävs för att signera en giltig transaktion</translation> @@ -3646,19 +4571,34 @@ Utgångar per *: </translation> <translation>Skapa multisig-plånböcker för testnet</translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="81"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="83"/> <source>Generating %u %u/%u multisig wallets</source> <translation>Skapar %u %u/%u multisig-plånböcker</translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="138"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="142"/> <source>Error verifying multisig extra info</source> <translation>Ett fel uppstod när extra multisig-info verifierades</translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="146"/> - <source>Error finalizing multisig</source> - <translation>Ett fel uppstod vid slutförande av multisig</translation> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="72"/> + <source>How many participants will share parts of the multisig wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="75"/> + <source>Create stagenet multisig wallets</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="76"/> + <source>Create an address file for new wallets</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="107"/> + <source>Failed to verify multisig info</source> + <translation type="unfinished"></translation> </message> <message> <location filename="../src/gen_multisig/gen_multisig.cpp" line="153"/> @@ -3671,133 +4611,495 @@ Utgångar per *: </translation> <translation>Ett fel uppstod när multisig-plånböcker skapades: </translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="176"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="182"/> <source>This program generates a set of multisig wallets - use this simpler scheme only if all the participants trust each other</source> <translation>Programmet skapar en uppsättning multisig-plånböcker - använd endast detta enklare system om alla deltagare litar på varandra</translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="194"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="201"/> + <source>Error: Can't specify more than one of --testnet and --stagenet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="208"/> <source>Error: expected N/M, but got: </source> <translation>Fel: förväntade N/M, men fick: </translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="202"/> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="211"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="216"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="225"/> <source>Error: either --scheme or both of --threshold and --participants may be given</source> <translation>Fel: antingen --scheme eller både --threshold och --participants får anges</translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="218"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="232"/> <source>Error: expected N > 1 and N <= M, but got N==%u and M==%d</source> <translation>Fel: förväntade N > 1 och N <= M, men fick N=%u och M=%d</translation> </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="227"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="241"/> <source>Error: --filename-base is required</source> <translation>Fel: --filename-base måste anges</translation> </message> +</context> +<context> + <name>mms::message_store</name> + <message> + <location filename="../src/wallet/message_store.cpp" line="69"/> + <source>Use PyBitmessage instance at URL <arg></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="70"/> + <source>Specify <arg> as username:password for PyBitmessage API</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="832"/> + <source>Auto-config cannot proceed because auto config data from other signers is not complete</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="857"/> + <source>The signer config is not complete.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="909"/> + <source>Wallet can't go multisig because key sets from other signers are missing or not complete.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="951"/> + <source>Wallet can't start another key exchange round because key sets from other signers are missing or not complete.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1015"/> + <source>Syncing not done because multisig sync data from other signers are missing or not complete.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1129"/> + <source>There are waiting messages, but nothing is ready to process under normal circumstances</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1132"/> + <source> +Use "mms next sync" if you want to force processing of the waiting sync data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1136"/> + <source> +Use "mms note" to display the waiting notes</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1141"/> + <source>There are no messages waiting to be processed.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1359"/> + <source>key set</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1361"/> + <source>additional key set</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1363"/> + <source>multisig sync data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1365"/> + <source>partially signed tx</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1367"/> + <source>fully signed tx</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1369"/> + <source>note</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1371"/> + <source>signer config</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1373"/> + <source>auto-config data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1375"/> + <source>unknown message type</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1384"/> + <source>in</source> + <translation type="unfinished">in</translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1386"/> + <source>out</source> + <translation type="unfinished">ut</translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1388"/> + <source>unknown message direction</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1397"/> + <source>ready to send</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="233"/> - <source>Error: unsupported scheme: only N/N and N-1/N are supported</source> - <translation>Fel: systemet stöds inte: bara N/N och N-1/N stöds</translation> + <location filename="../src/wallet/message_store.cpp" line="1399"/> + <source>sent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1401"/> + <source>waiting</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1403"/> + <source>processed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1405"/> + <source>cancelled</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/message_store.cpp" line="1407"/> + <source>unknown message state</source> + <translation type="unfinished"></translation> </message> </context> <context> <name>sw</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="115"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="125"/> <source>Generate new wallet and save it to <arg></source> <translation>Skapa ny plånbok och spara den till <arg></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="116"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="126"/> + <source>Generate new wallet from device and save it to <arg></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="127"/> <source>Generate incoming-only wallet from view key</source> <translation>Skapa granskningsplånbok från granskningsnyckel</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="117"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="128"/> <source>Generate deterministic wallet from spend key</source> <translation>Skapa deterministisk plånbok från spendernyckel</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="118"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="129"/> <source>Generate wallet from private keys</source> <translation>Skapa plånbok från privata nycklar</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="119"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="130"/> <source>Generate a master wallet from multisig wallet keys</source> <translation>Skapa en huvudplånbok från multisig-plånboksnycklar</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="121"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="132"/> <source>Language for mnemonic</source> <translation>Språk för minnesbaserat startvärde</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="122"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="133"/> <source>Specify Electrum seed for wallet recovery/creation</source> <translation>Ange Electrum-startvärde för att återställa/skapa plånbok</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="123"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="134"/> <source>Recover wallet using Electrum-style mnemonic seed</source> <translation>Återställ plånbok genom att använda minnesbaserat startvärde (Electrum-typ)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="124"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="135"/> <source>Recover multisig wallet using Electrum-style mnemonic seed</source> <translation>Återställ multisig-plånbok genom att använda minnesbaserat startvärde (Electrum-typ)</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="125"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="136"/> <source>Generate non-deterministic view and spend keys</source> <translation>Skapa icke-deterministisk granskningsnyckel och spendernyckel</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="126"/> - <source>Enable commands which rely on a trusted daemon</source> - <translation>Aktivera kommandon som kräver en betrodd daemon</translation> + <location filename="../src/simplewallet/simplewallet.cpp" line="361"/> + <source>invalid argument: must be either 0/1, true/false, y/n, yes/no</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="127"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="417"/> + <source>DNSSEC validation passed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="421"/> + <source>WARNING: DNSSEC validation was unsuccessful, this address may not be correct!</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="424"/> + <source>For URL: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="426"/> + <source> Monero Address = </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="428"/> + <source>Is this OK? (Y/n) </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="438"/> + <source>you have cancelled the transfer request</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="459"/> + <source>failed to parse index: </source> + <translation type="unfinished">det gick inte att parsa index: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="472"/> + <source>invalid format for subaddress lookahead; must be <major>:<minor></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="489"/> + <source>no connection to daemon. Please make sure daemon is running.</source> + <translation type="unfinished">ingen anslutning till daemonen. Se till att daemonen körs.</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="494"/> + <source>RPC error: </source> + <translation type="unfinished">RPC-fel: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="498"/> + <source>failed to get random outputs to mix: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="505"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="513"/> + <source>Not enough money in unlocked balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="523"/> + <source>Failed to find a way to create transactions. This is usually due to dust which is so small it cannot pay for itself in fees, or trying to send more money than the unlocked balance, or not leaving enough for fees</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="529"/> + <source>not enough outputs for specified ring size</source> + <translation type="unfinished">inte tillräckligt med utgångar för angiven ringstorlek</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="532"/> + <source>output amount</source> + <translation type="unfinished">utgångens belopp</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="532"/> + <source>found outputs to use</source> + <translation type="unfinished">hittade utgångar att använda</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="534"/> + <source>Please use sweep_unmixable.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="538"/> + <source>transaction was not constructed</source> + <translation type="unfinished">transaktionen konstruerades inte</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="543"/> + <source>transaction %s was rejected by daemon with status: </source> + <translation type="unfinished">transaktionen %s avvisades av daemonen med status: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="546"/> + <source>Reason: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="555"/> + <source>one of destinations is zero</source> + <translation type="unfinished">ett av målen är noll</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="560"/> + <source>failed to find a suitable way to split transactions</source> + <translation type="unfinished">det gick inte att hitta ett lämpligt sätt att dela upp transaktioner</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="566"/> + <source>unknown transfer error: </source> + <translation type="unfinished">okänt överföringsfel: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="571"/> + <source>Multisig error: </source> + <translation type="unfinished">Multisig-fel: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="577"/> + <source>internal error: </source> + <translation type="unfinished">internt fel: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="582"/> + <source>unexpected error: </source> + <translation type="unfinished">oväntat fel: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="586"/> + <source>There was an error, which could mean the node may be trying to get you to retry creating a transaction, and zero in on which outputs you own. Or it could be a bona fide error. It may be prudent to disconnect from this node, and not try to send a transaction immediately. Alternatively, connect to another node so the original node cannot correlate information.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="596"/> + <source>File %s likely stores wallet private keys! Use a different file name.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="599"/> + <source>File %s already exists. Are you sure to overwrite it? (Y/Yes/N/No): </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7195"/> + <source> seconds</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7197"/> + <source> minutes</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7199"/> + <source> hours</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7201"/> + <source> days</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7203"/> + <source> months</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="7204"/> + <source>a long time</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8940"/> + <source>This is the command line monero wallet. It needs to connect to a monero +daemon to work correctly. +WARNING: Do not reuse your Monero keys on another fork, UNLESS this fork has key reuse mitigations built in. Doing so will harm your privacy.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="8965"/> + <source>Unknown command: </source> + <translation type="unfinished">Okänt kommando: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="137"/> <source>Allow communicating with a daemon that uses a different RPC version</source> <translation>Tillåt kommunikation med en daemon som använder en annan version av RPC</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="128"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="138"/> <source>Restore from specific blockchain height</source> <translation>Återställ från angiven blockkedjehöjd</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="129"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="139"/> <source>The newly created transaction will not be relayed to the monero network</source> <translation>Den nyss skapade transaktionen kommer inte att skickas vidare till monero-nätverket</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="171"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="140"/> + <source>Create an address file for new wallets</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="142"/> + <source>Display English language names</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="276"/> + <source>failed to read wallet password</source> + <translation type="unfinished">det gick inte att läsa lösenord för plånboken</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="283"/> + <source>Enter a new password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="283"/> + <source>Wallet password</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="293"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="485"/> <source>daemon is busy. Please try again later.</source> <translation>daemonen är upptagen. Försök igen senare.</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="180"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="302"/> <source>possibly lost connection to daemon</source> <translation>anslutning till daemonen kan ha förlorats</translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="197"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="319"/> <source>Error: </source> <translation>Fel: </translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6787"/> - <source>This is the command line monero wallet. It needs to connect to a monero -daemon to work correctly.</source> - <translation>Detta är kommandoradsplånboken för Monero. Den måste ansluta till en Monero- -daemon för att fungera korrekt.</translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="6801"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8959"/> <source>Failed to initialize wallet</source> <translation>Det gick inte att initiera plånbok</translation> </message> @@ -3805,300 +5107,360 @@ daemon för att fungera korrekt.</translation> <context> <name>tools::wallet2</name> <message> - <location filename="../src/wallet/wallet2.cpp" line="113"/> + <location filename="../src/wallet/wallet2.cpp" line="201"/> <source>Use daemon instance at <host>:<port></source> <translation>Använd daemonen på <värddator>:<port></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="114"/> + <location filename="../src/wallet/wallet2.cpp" line="202"/> <source>Use daemon instance at host <arg> instead of localhost</source> <translation>Använd daemonen på värddatorn <arg> istället för localhost</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="116"/> + <location filename="../src/wallet/wallet2.cpp" line="206"/> <source>Wallet password file</source> <translation>Lösenordsfil för plånboken</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="117"/> + <location filename="../src/wallet/wallet2.cpp" line="207"/> <source>Use daemon instance at port <arg> instead of 18081</source> <translation>Använd daemonen på port <arg> istället för 18081</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="119"/> + <location filename="../src/wallet/wallet2.cpp" line="209"/> <source>For testnet. Daemon must also be launched with --testnet flag</source> <translation>För testnet. Daemonen måste också startas med flaggan --testnet</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="120"/> - <source>Restricts to view-only commands</source> - <translation>Begränsar till granskningskommandon</translation> - </message> - <message> - <location filename="../src/wallet/wallet2.cpp" line="168"/> + <location filename="../src/wallet/wallet2.cpp" line="282"/> <source>can't specify daemon host or port more than once</source> <translation>det går inte ange värd eller port för daemonen mer än en gång</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="204"/> + <location filename="../src/wallet/wallet2.cpp" line="355"/> <source>can't specify more than one of --password and --password-file</source> <translation>det går inte att ange fler än en av --password och --password-file</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="217"/> + <location filename="../src/wallet/wallet2.cpp" line="368"/> <source>the password file specified could not be read</source> <translation>det gick inte att läsa angiven lösenordsfil</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="240"/> + <location filename="../src/wallet/wallet2.cpp" line="394"/> <source>Failed to load file </source> <translation>Det gick inte att läsa in fil </translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="115"/> + <location filename="../src/wallet/wallet2.cpp" line="205"/> <source>Wallet password (escape/quote as needed)</source> <translation>Lösenord för plånboken (använd escape-sekvenser eller citattecken efter behov)</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="118"/> + <location filename="../src/wallet/wallet2.cpp" line="203"/> + <source>Enable commands which rely on a trusted daemon</source> + <translation type="unfinished">Aktivera kommandon som kräver en betrodd daemon</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="204"/> + <source>Disable commands which rely on a trusted daemon</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="208"/> <source>Specify username[:password] for daemon RPC client</source> <translation>Ange användarnamn[:lösenord] för RPC-klient till daemonen</translation> </message> <message> + <location filename="../src/wallet/wallet2.cpp" line="210"/> + <source>For stagenet. Daemon must also be launched with --stagenet flag</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="212"/> + <source>Set shared ring database path</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="223"/> + <source>Number of rounds for the key derivation function</source> + <translation type="unfinished"></translation> + </message> + <message> <location filename="../src/wallet/wallet2.cpp" line="224"/> + <source>HW device to use</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="225"/> + <source>HW device wallet derivation path (e.g., SLIP-10)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="313"/> + <source>--trusted-daemon and --untrusted-daemon are both seen, assuming untrusted</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="323"/> + <source>Daemon is local, assuming trusted</source> + <translation type="unfinished">Daemonen är lokal, utgår från att den är betrodd</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="375"/> <source>no password specified; use --prompt-for-password to prompt for a password</source> <translation>inget lösenord har angivits; använd --prompt-for-password för att fråga efter lösenord</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="246"/> + <location filename="../src/wallet/wallet2.cpp" line="377"/> + <source>Enter a new password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="377"/> + <source>Wallet password</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="400"/> <source>Failed to parse JSON</source> <translation>Det gick inte att parsa JSON</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="253"/> + <location filename="../src/wallet/wallet2.cpp" line="407"/> <source>Version %u too new, we can only grok up to %u</source> <translation>Version %u är för ny, vi förstår bara upp till %u</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="269"/> + <location filename="../src/wallet/wallet2.cpp" line="423"/> <source>failed to parse view key secret key</source> <translation>det gick inte att parsa hemlig granskningsnyckel</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="274"/> - <location filename="../src/wallet/wallet2.cpp" line="339"/> - <location filename="../src/wallet/wallet2.cpp" line="380"/> + <location filename="../src/wallet/wallet2.cpp" line="428"/> + <location filename="../src/wallet/wallet2.cpp" line="496"/> + <location filename="../src/wallet/wallet2.cpp" line="539"/> <source>failed to verify view key secret key</source> <translation>det gick inte att verifiera hemlig granskningsnyckel</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="285"/> + <location filename="../src/wallet/wallet2.cpp" line="439"/> <source>failed to parse spend key secret key</source> <translation>det gick inte att parsa spendernyckel hemlig nyckel</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="290"/> - <location filename="../src/wallet/wallet2.cpp" line="349"/> - <location filename="../src/wallet/wallet2.cpp" line="405"/> + <location filename="../src/wallet/wallet2.cpp" line="444"/> + <location filename="../src/wallet/wallet2.cpp" line="506"/> + <location filename="../src/wallet/wallet2.cpp" line="565"/> <source>failed to verify spend key secret key</source> <translation>det gick inte att verifiera spendernyckel hemlig nyckel</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="302"/> + <location filename="../src/wallet/wallet2.cpp" line="456"/> <source>Electrum-style word list failed verification</source> <translation>Det gick inte att verifiera ordlista av Electrum-typ</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="319"/> - <source>At least one of Electrum-style word list and private view key and private spend key must be specified</source> - <translation>Åtminstone en av ordlista av Electrum-typ och privat granskningsnyckel och privat spendernyckel måste anges</translation> + <location filename="../src/wallet/wallet2.cpp" line="476"/> + <source>At least one of either an Electrum-style word list, private view key, or private spend key must be specified</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="323"/> + <location filename="../src/wallet/wallet2.cpp" line="480"/> <source>Both Electrum-style word list and private key(s) specified</source> <translation>Både ordlista av Electrum-typ och privat nyckel har angivits</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="333"/> + <location filename="../src/wallet/wallet2.cpp" line="490"/> <source>invalid address</source> <translation>ogiltig adress</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="342"/> + <location filename="../src/wallet/wallet2.cpp" line="499"/> <source>view key does not match standard address</source> <translation>granskningsnyckel matchar inte standardadress</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="352"/> + <location filename="../src/wallet/wallet2.cpp" line="509"/> <source>spend key does not match standard address</source> <translation>spendernyckel matchar inte standardadress</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="360"/> + <location filename="../src/wallet/wallet2.cpp" line="517"/> <source>Cannot generate deprecated wallets from JSON</source> <translation>Det går inte att skapa inaktuella plånböcker från JSON</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="392"/> + <location filename="../src/wallet/wallet2.cpp" line="551"/> <source>failed to parse address: </source> <translation>det gick inte att parsa adressen: </translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="398"/> + <location filename="../src/wallet/wallet2.cpp" line="557"/> <source>Address must be specified in order to create watch-only wallet</source> <translation>Adress måste anges för att kunna skapa granskningsplånbok</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="413"/> + <location filename="../src/wallet/wallet2.cpp" line="574"/> <source>failed to generate new wallet: </source> <translation>det gick inte att skapa ny plånbok: </translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="2813"/> - <location filename="../src/wallet/wallet2.cpp" line="2873"/> - <location filename="../src/wallet/wallet2.cpp" line="2952"/> - <location filename="../src/wallet/wallet2.cpp" line="2998"/> - <location filename="../src/wallet/wallet2.cpp" line="3089"/> - <location filename="../src/wallet/wallet2.cpp" line="3189"/> - <location filename="../src/wallet/wallet2.cpp" line="3599"/> - <location filename="../src/wallet/wallet2.cpp" line="3955"/> + <location filename="../src/wallet/wallet2.cpp" line="1382"/> + <source>Password is needed to compute key image for incoming monero</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="1383"/> + <source>Invalid password: password is needed to compute key image for incoming monero</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="3770"/> + <location filename="../src/wallet/wallet2.cpp" line="4374"/> + <location filename="../src/wallet/wallet2.cpp" line="4926"/> <source>Primary account</source> <translation>Primärt konto</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="7914"/> + <location filename="../src/wallet/wallet2.cpp" line="10157"/> <source>No funds received in this tx.</source> <translation>Inga pengar togs emot i denna tx.</translation> </message> <message> - <location filename="../src/wallet/wallet2.cpp" line="8607"/> + <location filename="../src/wallet/wallet2.cpp" line="10899"/> <source>failed to read file </source> <translation>det gick inte att läsa filen </translation> </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="141"/> + <source>Set subaddress lookahead sizes to <major>:<minor></source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>tools::wallet_rpc_server</name> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="160"/> - <source>Daemon is local, assuming trusted</source> - <translation>Daemonen är lokal, utgår från att den är betrodd</translation> - </message> - <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="175"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="180"/> <source>Failed to create directory </source> <translation>Det gick inte att skapa mapp </translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="177"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="182"/> <source>Failed to create directory %s: %s</source> <translation>Det gick inte att skapa mapp %s: %s</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="188"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="193"/> <source>Cannot specify --</source> <translation>Det går inte att ange --</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="188"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="193"/> <source> and --</source> <translation> och --</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="207"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="212"/> <source>Failed to create file </source> <translation>Det gick inte att skapa fil </translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="207"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="212"/> <source>. Check permissions or remove file</source> <translation>. Kontrollera behörigheter eller ta bort filen</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="217"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="222"/> <source>Error writing to file </source> <translation>Ett fel uppstod vid skrivning till fil </translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="220"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="225"/> <source>RPC username/password is stored in file </source> <translation>Användarnamn/lösenord för RPC har sparats i fil </translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="443"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="479"/> <source>Tag %s is unregistered.</source> <translation>Taggen %s har inte registrerats.</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2435"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3081"/> <source>Transaction not possible. Available only %s, transaction amount %s = %s + %s (fee)</source> <translation>Transaktion är inte möjlig. Endast tillgängligt %s, transaktionsbelopp %s = %s + %s (avgift)</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2870"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3947"/> <source>This is the RPC monero wallet. It needs to connect to a monero daemon to work correctly.</source> <translation>Detta är RPC-plånboken för monero. Den måste ansluta till en Monero- daemon för att fungera korrekt.</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2893"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3788"/> <source>Can't specify more than one of --wallet-file and --generate-from-json</source> <translation>Det går inte att ange fler än en av --wallet-file och --generate-from-json</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2905"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3773"/> + <source>Can't specify more than one of --testnet and --stagenet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3800"/> <source>Must specify --wallet-file or --generate-from-json or --wallet-dir</source> <translation>Måste ange --wallet-file eller --generate-from-json eller --wallet-dir</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2909"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3804"/> <source>Loading wallet...</source> <translation>Läser in plånbok …</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2942"/> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2975"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3838"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3870"/> <source>Saving wallet...</source> <translation>Sparar plånbok …</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2944"/> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2977"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3840"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3872"/> <source>Successfully saved</source> <translation>Plånboken sparades</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2947"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3843"/> <source>Successfully loaded</source> <translation>Plånboken lästes in</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2951"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3847"/> <source>Wallet initialization failed: </source> <translation>Det gick inte att initiera plånbok: </translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2958"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3853"/> <source>Failed to initialize wallet RPC server</source> <translation>Det gick inte att initiera RPC-servern för plånbok</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2962"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3857"/> <source>Starting wallet RPC server</source> <translation>Startar RPC-server för plånboken</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2969"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3864"/> <source>Failed to run wallet: </source> <translation>Det gick inte att köra plånboken: </translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2972"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3867"/> <source>Stopped wallet RPC server</source> <translation>Stoppade RPC-server för plånboken</translation> </message> <message> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2981"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3876"/> <source>Failed to save wallet: </source> <translation>Det gick inte spara plånboken: </translation> </message> @@ -4106,9 +5468,9 @@ daemon för att fungera korrekt.</translation> <context> <name>wallet_args</name> <message> - <location filename="../src/gen_multisig/gen_multisig.cpp" line="166"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="6760"/> - <location filename="../src/wallet/wallet_rpc_server.cpp" line="2856"/> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="168"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="8908"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="3928"/> <source>Wallet options</source> <translation>Alternativ för plånbok</translation> </message> @@ -4123,49 +5485,59 @@ daemon för att fungera korrekt.</translation> <translation>Använd plånbok <arg></translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="104"/> + <location filename="../src/wallet/wallet_args.cpp" line="105"/> <source>Max number of threads to use for a parallel job</source> <translation>Max antal trådar att använda för ett parallellt jobb</translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="105"/> + <location filename="../src/wallet/wallet_args.cpp" line="106"/> <source>Specify log file</source> <translation>Ange loggfil</translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="106"/> + <location filename="../src/wallet/wallet_args.cpp" line="107"/> <source>Config file</source> <translation>Konfigurationsfil</translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="115"/> + <location filename="../src/wallet/wallet_args.cpp" line="119"/> <source>General options</source> <translation>Allmänna alternativ</translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="138"/> + <location filename="../src/wallet/wallet_args.cpp" line="144"/> <source>This is the command line monero wallet. It needs to connect to a monero daemon to work correctly.</source> <translation>Detta är kommandoradsplånboken för Monero. Den måste ansluta till en Monero- daemon för att fungera korrekt.</translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="161"/> + <location filename="../src/wallet/wallet_args.cpp" line="169"/> <source>Can't find config file </source> <translation>Det gick inte att hitta konfigurationsfilen </translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="195"/> + <location filename="../src/wallet/wallet_args.cpp" line="210"/> <source>Logging to: </source> <translation>Loggar till: </translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="197"/> + <location filename="../src/wallet/wallet_args.cpp" line="212"/> <source>Logging to %s</source> <translation>Loggar till %s</translation> </message> <message> - <location filename="../src/wallet/wallet_args.cpp" line="140"/> + <location filename="../src/wallet/wallet_args.cpp" line="216"/> + <source>WARNING: You may not have a high enough lockable memory limit</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="218"/> + <source>see ulimit -l</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="146"/> <source>Usage:</source> <translation>Användning:</translation> </message> diff --git a/utils/translations/update-translations.sh b/utils/translations/update-translations.sh index 778aa5176..3f093be93 100755 --- a/utils/translations/update-translations.sh +++ b/utils/translations/update-translations.sh @@ -12,5 +12,5 @@ then fi echo "using $lupdate" -"$lupdate" `find src -name \*.cpp` -ts translations/*.ts +"$lupdate" `find src -name \*.cpp` -ts translations/*.ts -no-obsolete |