diff options
70 files changed, 6028 insertions, 342 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 78d16b2ad..4d29e8d4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -199,6 +199,9 @@ set(PER_BLOCK_CHECKPOINT 1) if(PER_BLOCK_CHECKPOINT) add_definitions("-DPER_BLOCK_CHECKPOINT") + set(Blocks "blocks") +else() + set(Blocks "") endif() list(INSERT CMAKE_MODULE_PATH 0 @@ -428,6 +431,8 @@ if (UNIX AND NOT APPLE) # Note that at the time of this writing the -Wstrict-prototypes flag added below will make this fail set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads) + add_c_flag_if_supported(-pthread CMAKE_C_FLAGS) + add_cxx_flag_if_supported(-pthread CMAKE_CXX_FLAGS) endif() # Handle OpenSSL, used for sha256sum on binary updates and light wallet ssl http @@ -672,12 +677,10 @@ else() add_linker_flag_if_supported(-Wl,-z,noexecstack noexecstack_SUPPORTED) if (noexecstack_SUPPORTED) set(LD_SECURITY_FLAGS "${LD_SECURITY_FLAGS} -Wl,-z,noexecstack") - set(LD_RAW_FLAGS ${LD_RAW_FLAGS} -z noexecstack) endif() add_linker_flag_if_supported(-Wl,-z,noexecheap noexecheap_SUPPORTED) if (noexecheap_SUPPORTED) set(LD_SECURITY_FLAGS "${LD_SECURITY_FLAGS} -Wl,-z,noexecheap") - set(LD_RAW_FLAGS ${LD_RAW_FLAGS} -z noexecheap) endif() # some windows linker bits @@ -880,7 +883,7 @@ endif() include_directories(SYSTEM ${Boost_INCLUDE_DIRS}) if(MINGW) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wa,-mbig-obj") - set(EXTRA_LIBRARIES mswsock;ws2_32;iphlpapi;crypt32) + set(EXTRA_LIBRARIES mswsock;ws2_32;iphlpapi;crypt32;bcrypt) if(DEPENDS) set(ICU_LIBRARIES ${Boost_LOCALE_LIBRARY} sicuio sicuin sicuuc sicudt sicutu iconv) else() @@ -28,6 +28,11 @@ ANDROID_STANDALONE_TOOLCHAIN_PATH ?= /usr/local/toolchain +dotgit=$(shell ls -d .git/config) +ifneq ($(dotgit), .git/config) + USE_SINGLE_BUILDDIR=1 +endif + subbuilddir:=$(shell echo `uname | sed -e 's|[:/\\ \(\)]|_|g'`/`git branch | grep '\* ' | cut -f2- -d' '| sed -e 's|[:/\\ \(\)]|_|g'`) ifeq ($(USE_SINGLE_BUILDDIR),) builddir := build/"$(subbuilddir)" @@ -41,6 +46,10 @@ endif all: release-all +depends: + cd contrib/depends && $(MAKE) HOST=$(target) && cd ../.. && mkdir -p build/$(target)/release + cd build/$(target)/release && cmake -DCMAKE_TOOLCHAIN_FILE=$(CURDIR)/contrib/depends/$(target)/share/toolchain.cmake ../../.. && $(MAKE) + cmake-debug: mkdir -p $(builddir)/debug cd $(builddir)/debug && cmake -D CMAKE_BUILD_TYPE=Debug $(topdir) @@ -32,9 +32,9 @@ These builds are of the master branch, which is used for active development and | Ubuntu 16.04 | amd64 | [![Ubuntu 16.04 amd64](https://build.getmonero.org/png?builder=monero-static-ubuntu-amd64)](https://build.getmonero.org/builders/monero-static-ubuntu-amd64) | Ubuntu 16.04 | armv7 | [![Ubuntu 16.04 armv7](https://build.getmonero.org/png?builder=monero-static-ubuntu-arm7)](https://build.getmonero.org/builders/monero-static-ubuntu-arm7) | Debian Stable | armv8 | [![Debian armv8](https://build.getmonero.org/png?builder=monero-static-debian-armv8)](https://build.getmonero.org/builders/monero-static-debian-armv8) -| OSX 10.10 | amd64 | [![OSX 10.10 amd64](https://build.getmonero.org/png?builder=monero-static-osx-10.10)](https://build.getmonero.org/builders/monero-static-osx-10.10) | OSX 10.11 | amd64 | [![OSX 10.11 amd64](https://build.getmonero.org/png?builder=monero-static-osx-10.11)](https://build.getmonero.org/builders/monero-static-osx-10.11) | OSX 10.12 | amd64 | [![OSX 10.12 amd64](https://build.getmonero.org/png?builder=monero-static-osx-10.12)](https://build.getmonero.org/builders/monero-static-osx-10.12) +| OSX 10.13 | amd64 | [![OSX 10.13 amd64](https://build.getmonero.org/png?builder=monero-static-osx-10.13)](https://build.getmonero.org/builders/monero-static-osx-10.13) | FreeBSD 11 | amd64 | [![FreeBSD 11 amd64](https://build.getmonero.org/png?builder=monero-static-freebsd64)](https://build.getmonero.org/builders/monero-static-freebsd64) | DragonFly BSD 4.6 | amd64 | [![DragonFly BSD amd64](https://build.getmonero.org/png?builder=monero-static-dragonflybsd-amd64)](https://build.getmonero.org/builders/monero-static-dragonflybsd-amd64) | Windows (MSYS2/MinGW) | i686 | [![Windows (MSYS2/MinGW) i686](https://build.getmonero.org/png?builder=monero-static-win32)](https://build.getmonero.org/builders/monero-static-win32) @@ -140,6 +140,7 @@ library archives (`.a`). | OpenSSL | basically any | NO | `libssl-dev` | `openssl` | `openssl-devel` | NO | sha256 sum | | libzmq | 3.0.0 | NO | `libzmq3-dev` | `zeromq` | `cppzmq-devel` | NO | ZeroMQ library | | OpenPGM | ? | NO | `libpgm-dev` | `libpgm` | `openpgm-devel` | NO | For ZeroMQ | +| libnorm[2] | ? | NO | `libnorm-dev` | | ` | YES | For ZeroMQ | | libunbound | 1.4.16 | YES | `libunbound-dev` | `unbound` | `unbound-devel` | NO | DNS resolver | | libsodium | ? | NO | `libsodium-dev` | `libsodium` | `libsodium-devel` | NO | cryptography | | libunwind | any | NO | `libunwind8-dev` | `libunwind` | `libunwind-devel` | YES | Stack traces | @@ -147,13 +148,14 @@ library archives (`.a`). | libreadline | 6.3.0 | NO | `libreadline6-dev` | `readline` | `readline-devel` | YES | Input editing | | ldns | 1.6.17 | NO | `libldns-dev` | `ldns` | `ldns-devel` | YES | SSL toolkit | | expat | 1.1 | NO | `libexpat1-dev` | `expat` | `expat-devel` | YES | XML parsing | -| GTest | 1.5 | YES | `libgtest-dev`^ | `gtest` | `gtest-devel` | YES | Test suite | +| GTest | 1.5 | YES | `libgtest-dev`[1] | `gtest` | `gtest-devel` | YES | Test suite | | Doxygen | any | NO | `doxygen` | `doxygen` | `doxygen` | YES | Documentation | | Graphviz | any | NO | `graphviz` | `graphviz` | `graphviz` | YES | Documentation | -[^] On Debian/Ubuntu `libgtest-dev` only includes sources and headers. You must +[1] On Debian/Ubuntu `libgtest-dev` only includes sources and headers. You must build the library binary manually. This can be done with the following command ```sudo apt-get install libgtest-dev && cd /usr/src/gtest && sudo cmake . && sudo make && sudo mv libg* /usr/lib/ ``` +[2] libnorm-dev is needed if your zmq library was built with libnorm, and not needed otherwise Debian / Ubuntu one liner for all dependencies ``` sudo apt update && sudo apt install build-essential cmake pkg-config libboost-all-dev libssl-dev libzmq3-dev libunbound-dev libsodium-dev libunwind8-dev liblzma-dev libreadline6-dev libldns-dev libexpat1-dev doxygen graphviz libpgm-dev``` @@ -179,7 +181,7 @@ invokes cmake commands as needed. * Change to the root of the source code directory, change to the most recent release branch, and build: cd monero - git checkout v0.13.0.0 + git checkout v0.13.0.4 make *Optional*: If your machine has several cores and enough memory, enable @@ -237,11 +239,13 @@ Tested on a Raspberry Pi Zero with a clean install of minimal Raspbian Stretch ( CONF_SWAPSIZE=1024 sudo /etc/init.d/dphys-swapfile start ``` +* If using an external hard disk without an external power supply, ensure it gets enough power to avoid hardware issues when syncing, by adding the line "max_usb_current=1" to /boot/config.txt + * Clone monero and checkout most recent release version: ``` git clone https://github.com/monero-project/monero.git cd monero - git checkout tags/v0.13.0.0 + git checkout tags/v0.13.0.4 ``` * Build: ``` @@ -340,7 +344,7 @@ application. * If you would like a specific [version/tag](https://github.com/monero-project/monero/tags), do a git checkout for that version. eg. 'v0.13.0.0'. If you dont care about the version and just want binaries from master, skip this step: - git checkout v0.13.0.0 + git checkout v0.13.0.4 * If you are on a 64-bit system, run: @@ -494,22 +498,19 @@ By default, in either dynamically or statically linked builds, binaries target t ### Cross Compiling -You can also cross-compile static binaries on Linux for Windows and macOS with the `depends` system. Go to `contrib/depends` and type: +You can also cross-compile static binaries on Linux for Windows and macOS with the `depends` system. -* ```make HOST=x86_64-linux-gnu``` for 64-bit linux binaries. -* ```make HOST=x86_64-w64-mingw32``` for 64-bit windows binaries. Requires: python3 nsis g++-mingw-w64-x86-64 wine1.6 bc -* ```make HOST=x86_64-apple-darwin11``` for darwin binaries. Requires: cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev -* ```make HOST=i686-linux-gnu``` for 32-bit linux binaries. Requires: g++-multilib bc -* ```make HOST=i686-w64-mingw32``` for 32-bit windows binaries. Requires: python3 nsis g++-mingw-w64-i686 -* ```make HOST=arm-linux-gnueabihf``` for armv6 binaries. Requires: g++-arm-linux-gnueabihf +* ```make depends target=x86_64-linux-gnu``` for 64-bit linux binaries. +* ```make depends target=x86_64-w64-mingw32``` for 64-bit windows binaries. Requires: python3 g++-mingw-w64-x86-64 wine1.6 bc +* ```make depends target=x86_64-apple-darwin11``` for macOS binaries. Requires: cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev +* ```make depends target=i686-linux-gnu``` for 32-bit linux binaries. Requires: g++-multilib bc +* ```make depends target=i686-w64-mingw32``` for 32-bit windows binaries. Requires: python3 g++-mingw-w64-i686 +* ```make depends target=arm-linux-gnueabihf``` for armv7 binaries. Requires: g++-arm-linux-gnueabihf +* ```make depends target=aarch64-linux-gnu``` for armv8 binaries. Requires: g++-aarch64-linux-gnu The required packages are the names for each toolchain on apt. Depending on your distro, they may have different names. -Then go back to the source dir and type: - -* ```cmake -DCMAKE_TOOLCHAIN_FILE=`pwd`/contrib/depends/<chosen triplet>/share/toolchain.cmake``` -Where <chosen triplet> is one of the above mentioned targets. -Using `depends` might also be easier to compile Monero on Windows than using MSys. Activate Windows Subsystem for Linux (WSL) with a distro (for example Ubuntu), install the apt build-essentials and follow the `depends` steps as depicted above. +Using `depends` might also be easier to compile Monero on Windows than using MSYS. Activate Windows Subsystem for Linux (WSL) with a distro (for example Ubuntu), install the apt build-essentials and follow the `depends` steps as depicted above. ## Installing Monero from a package diff --git a/contrib/depends/packages/libiconv.mk b/contrib/depends/packages/libiconv.mk index 87e30b208..dbcb28141 100644 --- a/contrib/depends/packages/libiconv.mk +++ b/contrib/depends/packages/libiconv.mk @@ -3,9 +3,22 @@ $(package)_version=1.15 $(package)_download_path=https://ftp.gnu.org/gnu/libiconv $(package)_file_name=libiconv-$($(package)_version).tar.gz $(package)_sha256_hash=ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178 +$(package)_patches=fix-whitespace.patch + +define $(package)_set_vars + $(package)_config_opts=--disable-nls + $(package)_config_opts=--enable-static + $(package)_config_opts=--disable-shared + $(package)_config_opts_linux=--with-pic +endef + +define $(package)_preprocess_cmds + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub build-aux/ &&\ + patch -p1 < $($(package)_patch_dir)/fix-whitespace.patch +endef define $(package)_config_cmds - $($(package)_autoconf) --disable-nls --enable-static --disable-shared + $($(package)_autoconf) endef define $(package)_build_cmds diff --git a/contrib/depends/packages/sodium.mk b/contrib/depends/packages/sodium.mk index c38121bf7..35f444fd5 100644 --- a/contrib/depends/packages/sodium.mk +++ b/contrib/depends/packages/sodium.mk @@ -3,6 +3,7 @@ $(package)_version=1.0.15 $(package)_download_path=https://download.libsodium.org/libsodium/releases/ $(package)_file_name=libsodium-$($(package)_version).tar.gz $(package)_sha256_hash=fb6a9e879a2f674592e4328c5d9f79f082405ee4bb05cb6e679b90afe9e178f4 +$(package)_patches=fix-whitespace.patch define $(package)_set_vars $(package)_config_opts=--enable-static --disable-shared @@ -11,6 +12,7 @@ endef define $(package)_config_cmds ./autogen.sh &&\ + patch -p1 < $($(package)_patch_dir)/fix-whitespace.patch &&\ $($(package)_autoconf) $($(package)_config_opts) endef diff --git a/contrib/depends/patches/libiconv/fix-whitespace.patch b/contrib/depends/patches/libiconv/fix-whitespace.patch new file mode 100644 index 000000000..531364b45 --- /dev/null +++ b/contrib/depends/patches/libiconv/fix-whitespace.patch @@ -0,0 +1,13 @@ +diff --git a/preload/configure b/preload/configure +index aab5c77..e20b8f0 100755 +--- a/preload/configure ++++ b/preload/configure +@@ -588,7 +588,7 @@ MAKEFLAGS= + PACKAGE_NAME='libiconv' + PACKAGE_TARNAME='libiconv' + PACKAGE_VERSION='0' +-PACKAGE_STRING='libiconv 0' ++PACKAGE_STRING='libiconv0' + PACKAGE_BUGREPORT='' + PACKAGE_URL='' + diff --git a/contrib/depends/patches/sodium/fix-whitespace.patch b/contrib/depends/patches/sodium/fix-whitespace.patch new file mode 100644 index 000000000..c11838611 --- /dev/null +++ b/contrib/depends/patches/sodium/fix-whitespace.patch @@ -0,0 +1,13 @@ +diff --git a/configure b/configure +index b29f769..ca008ae 100755 +--- a/configure ++++ b/configure +@@ -591,7 +591,7 @@ MAKEFLAGS= + PACKAGE_NAME='libsodium' + PACKAGE_TARNAME='libsodium' + PACKAGE_VERSION='1.0.15' +-PACKAGE_STRING='libsodium 1.0.15' ++PACKAGE_STRING='libsodium' + PACKAGE_BUGREPORT='https://github.com/jedisct1/libsodium/issues' + PACKAGE_URL='https://github.com/jedisct1/libsodium' + diff --git a/contrib/epee/include/console_handler.h b/contrib/epee/include/console_handler.h index 2ccf5b095..6e7efd1d7 100644 --- a/contrib/epee/include/console_handler.h +++ b/contrib/epee/include/console_handler.h @@ -352,8 +352,11 @@ eof: std::string command; bool get_line_ret = m_stdin_reader.get_line(command); - if (!m_running || m_stdin_reader.eos()) + if (!m_running) + break; + if (m_stdin_reader.eos()) { + MGINFO("EOF on stdin, exiting"); break; } if (!get_line_ret) diff --git a/contrib/epee/include/readline_buffer.h b/contrib/epee/include/readline_buffer.h index 87c8826cb..5968d243d 100644 --- a/contrib/epee/include/readline_buffer.h +++ b/contrib/epee/include/readline_buffer.h @@ -27,6 +27,7 @@ namespace rdln private: std::streambuf* m_cout_buf; + size_t m_prompt_length; static std::vector<std::string>& completion_commands(); }; diff --git a/contrib/epee/src/mlog.cpp b/contrib/epee/src/mlog.cpp index 61d853ef4..638155b6b 100644 --- a/contrib/epee/src/mlog.cpp +++ b/contrib/epee/src/mlog.cpp @@ -28,6 +28,13 @@ #ifndef _MLOG_H_ #define _MLOG_H_ +#ifdef _WIN32 +#include <windows.h> +#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING +#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 +#endif +#endif + #include <time.h> #include <atomic> #include <boost/filesystem.hpp> @@ -117,6 +124,31 @@ static const char *get_default_categories(int level) return categories; } +#ifdef WIN32 +bool EnableVTMode() +{ + // Set output mode to handle virtual terminal sequences + HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); + if (hOut == INVALID_HANDLE_VALUE) + { + return false; + } + + DWORD dwMode = 0; + if (!GetConsoleMode(hOut, &dwMode)) + { + return false; + } + + dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; + if (!SetConsoleMode(hOut, dwMode)) + { + return false; + } + return true; +} +#endif + void mlog_configure(const std::string &filename_base, bool console, const std::size_t max_log_file_size, const std::size_t max_log_files) { el::Configurations c; @@ -202,6 +234,9 @@ void mlog_configure(const std::string &filename_base, bool console, const std::s monero_log = get_default_categories(0); } mlog_set_log(monero_log); +#ifdef WIN32 + EnableVTMode(); +#endif } void mlog_set_categories(const char *categories) diff --git a/contrib/epee/src/readline_buffer.cpp b/contrib/epee/src/readline_buffer.cpp index 076a63612..da264471f 100644 --- a/contrib/epee/src/readline_buffer.cpp +++ b/contrib/epee/src/readline_buffer.cpp @@ -44,7 +44,7 @@ std::vector<std::string>& rdln::readline_buffer::completion_commands() } rdln::readline_buffer::readline_buffer() -: std::stringbuf(), m_cout_buf(NULL) +: std::stringbuf(), m_cout_buf(NULL), m_prompt_length(0) { current = this; } @@ -86,8 +86,11 @@ void rdln::readline_buffer::set_prompt(const std::string& prompt) if(m_cout_buf == NULL) return; boost::lock_guard<boost::mutex> lock(sync_mutex); + rl_set_prompt(std::string(m_prompt_length, ' ').c_str()); + rl_redisplay(); rl_set_prompt(prompt.c_str()); rl_redisplay(); + m_prompt_length = prompt.size(); } void rdln::readline_buffer::add_completion(const std::string& command) diff --git a/contrib/gitian/README.md b/contrib/gitian/README.md new file mode 100644 index 000000000..4bd326f22 --- /dev/null +++ b/contrib/gitian/README.md @@ -0,0 +1,146 @@ +Gitian building +================ + +*Setup instructions for a Gitian build of Monero using a VM or physical system.* + +Gitian is the deterministic build process that is used to build the Monero CLI +executables. It provides a way to be reasonably sure that the +executables are really built from the git source. It also makes sure that +the same, tested dependencies are used and statically built into the executable. + +Multiple developers build the source code by following a specific descriptor +("recipe"), cryptographically sign the result, and upload the resulting signature. +These results are compared and only if they match, the build is accepted and provided +for download. + +More independent Gitian builders are needed, which is why this guide exists. +It is preferred you follow these steps yourself instead of using someone else's +VM image to avoid 'contaminating' the build. + +Table of Contents +------------------ + +Please note that these instructions have been forked from bitcoin's gitian build +instructions. Please also consult their documentation, when running into problems. +The signing is left as inherited from bitcoin at the moment. + +- [Preparing the Gitian builder host](#preparing-the-gitian-builder-host) +- [Getting and building the inputs](#getting-and-building-the-inputs) +- [Building Binaries](#building-bitcoin-core) +- [Signing externally](#signing-externally) +- [Uploading signatures](#uploading-signatures) + +Preparing the Gitian builder host +--------------------------------- + +The first step is to prepare the host environment that will be used to perform the Gitian builds. +This guide explains how to set up the environment, and how to start the builds. + +Gitian builds are for now executed on Ubuntu 18.04 "Bionic Beaver". A solution is being worked on to run +it in docker in the future. Please run Ubuntu in either a VM, or on your physical machine. +You need to be logged in as the `gitianuser` in order to build gitian builds. If this user does not exist yet on your system, +create it. + +Note that a version of `lxc-execute` higher or equal to 2.1.1 is required. +You can check the version with `lxc-execute --version`. + +First we need to set up dependencies. Type/paste the following in the terminal: + +```bash +sudo apt-get install git ruby apt-cacher-ng qemu-utils debootstrap lxc python-cheetah parted kpartx bridge-utils make ubuntu-archive-keyring curl firewalld +``` + +Then set up LXC and the rest with the following, which is a complex jumble of settings and workarounds: + +```bash +sudo -s +# the version of lxc-start in Debian needs to run as root, so make sure +# that the build script can execute it without providing a password +echo "%sudo ALL=NOPASSWD: /usr/bin/lxc-start" > /etc/sudoers.d/gitian-lxc +echo "%sudo ALL=NOPASSWD: /usr/bin/lxc-execute" >> /etc/sudoers.d/gitian-lxc +# make /etc/rc.local script that sets up bridge between guest and host +echo '#!/bin/sh -e' > /etc/rc.local +echo 'brctl addbr br0' >> /etc/rc.local +echo 'ip addr add 10.0.3.1/24 broadcast 10.0.3.255 dev br0' >> /etc/rc.local +echo 'ip link set br0 up' >> /etc/rc.local +echo 'firewall-cmd --zone=trusted --add-interface=br0' >> /etc/rc.local +echo 'exit 0' >> /etc/rc.local +chmod +x /etc/rc.local +# make sure that USE_LXC is always set when logging in as gitianuser, +# and configure LXC IP addresses +echo 'export USE_LXC=1' >> /home/gitianuser/.profile +echo 'export GITIAN_HOST_IP=10.0.3.1' >> /home/gitianuser/.profile +echo 'export LXC_GUEST_IP=10.0.3.5' >> /home/gitianuser/.profile +reboot +``` + +This setup is required to enable networking in the container. + + +Manual and Building +------------------- +The instructions below use the automated script [gitian-build.py](https://github.com/betcoin/bitcoin/blob/master/contrib/gitian-build.py) which only works in Ubuntu. +It calls all available descriptors. Help for the build steps taken can be accessed with `./gitian-build.py --help`. + +Initial Gitian Setup +-------------------- +The `gitian-build.py` script will checkout different release tags, so it's best to copy it: + +```bash +cp monero/contrib/gitian/gitian-build.py . +``` + +Setup the required environment, you only need to do this once: + +``` +./gitian-build.py --setup fluffypony 0.14.0 +``` + +Where `fluffypony` is your Github name and `0.14.0` is the version tag you want to build (without `v`). + +While gitian and this build script does provide a way for you to sign the build directly, it is recommended to sign in a seperate step. +This script is only there for convenience. Seperate steps for building can still be taken. +In order to sign gitian builds on your host machine, which has your PGP key, +fork the gitian.sigs repository and clone it on your host machine, +or pass the signed assert file back to your build machine. + +``` +git clone git@github.com:monero-project/gitian.sigs.git +git remote add fluffypony git@github.com:fluffypony/gitian.sigs.git +``` + +Build Binaries +----------------------------- +To build the most recent tag: + + `./gitian-build.py --detach-sign --no-commit -b fluffypony 0.14.0` + +To speed up the build, use `-j 5 -m 5000` as the first arguments, where `5` is the number of CPU's you allocated to the VM plus one, and 5000 is a little bit less than then the MB's of RAM you allocated. If there is memory corruption on your machine, try to tweak these values. + +If all went well, this produces a number of (uncommited) `.assert` files in the gitian.sigs repository. + +If you do detached, offline signing, you need to copy these uncommited changes to your host machine, where you can sign them. For example: + +``` +export NAME=fluffypony +export VERSION=0.14 +gpg --output $VERSION-linux/$NAME/monero-linux-$VERSION-build.assert.sig --detach-sign $VERSION-linux/$NAME/monero-linux-$VERSION-build.assert +gpg --output $VERSION-osx-unsigned/$NAME/monero-osx-$VERSION-build.assert.sig --detach-sign $VERSION-osx-unsigned/$NAME/monero-osx-$VERSION-build.assert +gpg --output $VERSION-win-unsigned/$NAME/monero-win-$VERSION-build.assert.sig --detach-sign $VERSION-win-unsigned/$NAME/monero-win-$VERSION-build.assert +``` + +Make a pull request (both the `.assert` and `.assert.sig` files) to the +[monero-project/gitian.sigs](https://github.com/monero-project/gitian.sigs/) repository: + +``` +git checkout -b 0.14.0 +git commit -S -a -m "Add $NAME 0.14.0" +git push --set-upstream $NAME 0.14.0 +``` + +```bash + gpg --detach-sign ${VERSION}-linux/${SIGNER}/monero-linux-*-build.assert + gpg --detach-sign ${VERSION}-win-unsigned/${SIGNER}/monero-win-*-build.assert + gpg --detach-sign ${VERSION}-osx-unsigned/${SIGNER}/monero-osx-*-build.assert +``` + diff --git a/contrib/gitian/gitian-build.py b/contrib/gitian/gitian-build.py new file mode 100755 index 000000000..99c64e9dd --- /dev/null +++ b/contrib/gitian/gitian-build.py @@ -0,0 +1,192 @@ +#!/usr/bin/env python3 + +import argparse +import os +import subprocess +import sys + +def setup(): + global args, workdir + programs = ['ruby', 'git', 'apt-cacher-ng', 'make', 'wget'] + if args.kvm: + programs += ['python-vm-builder', 'qemu-kvm', 'qemu-utils'] + elif args.docker: + dockers = ['docker.io', 'docker-ce'] + for i in dockers: + return_code = subprocess.call(['sudo', 'apt-get', 'install', '-qq', i]) + if return_code == 0: + break + if return_code != 0: + print('Cannot find any way to install docker', file=sys.stderr) + exit(1) + else: + programs += ['lxc', 'debootstrap'] + subprocess.check_call(['sudo', 'apt-get', 'install', '-qq'] + programs) + if not os.path.isdir('gitian.sigs'): + subprocess.check_call(['git', 'clone', 'https://github.com/monero-project/gitian.sigs.git']) + if not os.path.isdir('gitian-builder'): + subprocess.check_call(['git', 'clone', 'https://github.com/devrandom/gitian-builder.git']) + if not os.path.isdir('monero'): + subprocess.check_call(['git', 'clone', 'https://github.com/monero-project/monero.git']) + os.chdir('gitian-builder') + subprocess.check_call(['git', 'checkout', '963322de8420c50502c4cc33d4d7c0d84437b576']) + make_image_prog = ['bin/make-base-vm', '--suite', 'bionic', '--arch', 'amd64'] + if args.docker: + make_image_prog += ['--docker'] + elif not args.kvm: + make_image_prog += ['--lxc'] + subprocess.check_call(make_image_prog) + os.chdir(workdir) + if args.is_bionic and not args.kvm and not args.docker: + subprocess.check_call(['sudo', 'sed', '-i', 's/lxcbr0/br0/', '/etc/default/lxc-net']) + print('Reboot is required') + exit(0) + +def build(): + global args, workdir + + os.makedirs('monero-binaries/' + args.version, exist_ok=True) + print('\nBuilding Dependencies\n') + os.chdir('gitian-builder') + os.makedirs('inputs', exist_ok=True) + + subprocess.check_call(['wget', '-N', '-P', 'inputs', 'https://downloads.sourceforge.net/project/osslsigncode/osslsigncode/osslsigncode-1.7.1.tar.gz']) + subprocess.check_call(['wget', '-N', '-P', 'inputs', 'https://bitcoincore.org/cfields/osslsigncode-Backports-to-1.7.1.patch']) + subprocess.check_output(["echo 'a8c4e9cafba922f89de0df1f2152e7be286aba73f78505169bc351a7938dd911 inputs/osslsigncode-Backports-to-1.7.1.patch' | sha256sum -c"], shell=True) + subprocess.check_output(["echo 'f9a8cdb38b9c309326764ebc937cba1523a3a751a7ab05df3ecc99d18ae466c9 inputs/osslsigncode-1.7.1.tar.gz' | sha256sum -c"], shell=True) + subprocess.check_call(['make', '-C', '../monero/contrib/depends', 'download', 'SOURCES_PATH=' + os.getcwd() + '/cache/common']) + + if args.linux: + print('\nCompiling ' + args.version + ' Linux') + subprocess.check_call(['bin/gbuild', '-j', args.jobs, '-m', args.memory, '--commit', 'monero='+args.commit, '--url', 'monero='+args.url, '../monero/contrib/gitian/gitian-linux.yml']) + subprocess.check_call(['bin/gsign', '-p', args.sign_prog, '--signer', args.signer, '--release', args.version+'-linux', '--destination', '../gitian.sigs/', '../monero/contrib/gitian/gitian-linux.yml']) + subprocess.check_call('mv build/out/monero-*.tar.gz ../monero-binaries/'+args.version, shell=True) + + if args.windows: + print('\nCompiling ' + args.version + ' Windows') + subprocess.check_call(['bin/gbuild', '-j', args.jobs, '-m', args.memory, '--commit', 'monero='+args.commit, '--url', 'monero='+args.url, '../monero/contrib/gitian/gitian-win.yml']) + subprocess.check_call(['bin/gsign', '-p', args.sign_prog, '--signer', args.signer, '--release', args.version+'-win', '--destination', '../gitian.sigs/', '../monero/contrib/gitian/gitian-win.yml']) + subprocess.check_call('mv build/out/monero*.zip ../monero-binaries/'+args.version, shell=True) + + if args.macos: + print('\nCompiling ' + args.version + ' MacOS') + subprocess.check_call(['bin/gbuild', '-j', args.jobs, '-m', args.memory, '--commit', 'monero='+args.commit, '--url', 'monero'+args.url, '../monero/contrib/gitian/gitian-osx.yml']) + subprocess.check_call(['bin/gsign', '-p', args.sign_prog, '--signer', args.signer, '--release', args.version+'-osx', '--destination', '../gitian.sigs/', '../monero/contrib/gitian/gitian-osx.yml']) + subprocess.check_call('mv build/out/monero*.tar.gz ../monero-binaries/'+args.version, shell=True) + + os.chdir(workdir) + + if args.commit_files: + print('\nCommitting '+args.version+' Unsigned Sigs\n') + os.chdir('gitian.sigs') + subprocess.check_call(['git', 'add', args.version+'-linux/'+args.signer]) + subprocess.check_call(['git', 'add', args.version+'-win/'+args.signer]) + subprocess.check_call(['git', 'add', args.version+'-osx/'+args.signer]) + subprocess.check_call(['git', 'commit', '-m', 'Add '+args.version+' unsigned sigs for '+args.signer]) + os.chdir(workdir) + +def verify(): + global args, workdir + os.chdir('gitian-builder') + + print('\nVerifying v'+args.version+' Linux\n') + subprocess.check_call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-linux', '../monero/contrib/gitian/gitian-linux.yml']) + print('\nVerifying v'+args.version+' Windows\n') + subprocess.check_call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-win', '../monero/contrib/gitian/gitian-win.yml']) + print('\nVerifying v'+args.version+' MacOS\n') + subprocess.check_call(['bin/gverify', '-v', '-d', '../gitian.sigs/', '-r', args.version+'-osx', '../monero/contrib/gitian/gitian-osx.yml']) + os.chdir(workdir) + +def main(): + global args, workdir + + parser = argparse.ArgumentParser(usage='%(prog)s [options] signer version') + parser.add_argument('-c', '--commit', action='store_true', dest='commit', help='Indicate that the version argument is for a commit or branch') + parser.add_argument('-p', '--pull', action='store_true', dest='pull', help='Indicate that the version argument is the number of a github repository pull request') + parser.add_argument('-u', '--url', dest='url', default='https://github.com/monero-project/monero', help='Specify the URL of the repository. Default is %(default)s') + parser.add_argument('-v', '--verify', action='store_true', dest='verify', help='Verify the Gitian build') + parser.add_argument('-b', '--build', action='store_true', dest='build', help='Do a Gitian build') + parser.add_argument('-B', '--buildsign', action='store_true', dest='buildsign', help='Build both signed and unsigned binaries') + parser.add_argument('-o', '--os', dest='os', default='lwm', help='Specify which Operating Systems the build is for. Default is %(default)s. l for Linux, w for Windows, m for MacOS') + parser.add_argument('-j', '--jobs', dest='jobs', default='2', help='Number of processes to use. Default %(default)s') + parser.add_argument('-m', '--memory', dest='memory', default='2000', help='Memory to allocate in MiB. Default %(default)s') + parser.add_argument('-k', '--kvm', action='store_true', dest='kvm', help='Use KVM instead of LXC') + parser.add_argument('-d', '--docker', action='store_true', dest='docker', help='Use Docker instead of LXC') + parser.add_argument('-S', '--setup', action='store_true', dest='setup', help='Set up the Gitian building environment. Uses LXC. If you want to use KVM, use the --kvm option. Only works on Debian-based systems (Ubuntu, Debian)') + parser.add_argument('-D', '--detach-sign', action='store_true', dest='detach_sign', help='Create the assert file for detached signing. Will not commit anything.') + parser.add_argument('-n', '--no-commit', action='store_false', dest='commit_files', help='Do not commit anything to git') + parser.add_argument('signer', help='GPG signer to sign each build assert file') + parser.add_argument('version', help='Version number, commit, or branch to build. If building a commit or branch, the -c option must be specified') + + args = parser.parse_args() + workdir = os.getcwd() + + args.linux = 'l' in args.os + args.windows = 'w' in args.os + args.macos = 'm' in args.os + + args.is_bionic = b'bionic' in subprocess.check_output(['lsb_release', '-cs']) + + if args.buildsign: + args.build=True + args.sign=True + + if args.kvm and args.docker: + raise Exception('Error: cannot have both kvm and docker') + + args.sign_prog = 'true' if args.detach_sign else 'gpg --detach-sign' + + # Set enviroment variable USE_LXC or USE_DOCKER, let gitian-builder know that we use lxc or docker + if args.docker: + os.environ['USE_DOCKER'] = '1' + elif not args.kvm: + os.environ['USE_LXC'] = '1' + if not 'GITIAN_HOST_IP' in os.environ.keys(): + os.environ['GITIAN_HOST_IP'] = '10.0.3.1' + if not 'LXC_GUEST_IP' in os.environ.keys(): + os.environ['LXC_GUEST_IP'] = '10.0.3.5' + + # Disable for MacOS if no SDK found + if args.macos and not os.path.isfile('gitian-builder/inputs/MacOSX10.11.sdk.tar.gz'): + print('Cannot build for MacOS, SDK does not exist. Will build for other OSes') + args.macos = False + + script_name = os.path.basename(sys.argv[0]) + # Signer and version shouldn't be empty + if args.signer == '': + print(script_name+': Missing signer.') + print('Try '+script_name+' --help for more information') + exit(1) + if args.version == '': + print(script_name+': Missing version.') + print('Try '+script_name+' --help for more information') + exit(1) + + # Add leading 'v' for tags + if args.commit and args.pull: + raise Exception('Cannot have both commit and pull') + args.commit = ('' if args.commit else) + args.version + + if args.setup: + setup() + + os.chdir('monero') + if args.pull: + subprocess.check_call(['git', 'fetch', args.url, 'refs/pull/'+args.version+'/merge']) + os.chdir('../gitian-builder/inputs/monero') + subprocess.check_call(['git', 'fetch', args.url, 'refs/pull/'+args.version+'/merge']) + args.commit = subprocess.check_output(['git', 'show', '-s', '--format=%H', 'FETCH_HEAD'], universal_newlines=True).strip() + args.version = 'pull-' + args.version + print(args.commit) + subprocess.check_call(['git', 'fetch']) + subprocess.check_call(['git', 'checkout', args.commit]) + os.chdir(workdir) + + if args.build: + build() + + if args.verify: + verify() + +if __name__ == '__main__': + main() diff --git a/contrib/gitian/gitian-linux.yml b/contrib/gitian/gitian-linux.yml new file mode 100644 index 000000000..473a7720d --- /dev/null +++ b/contrib/gitian/gitian-linux.yml @@ -0,0 +1,162 @@ +--- +name: "monero-linux-0.14" +enable_cache: true +suites: +- "bionic" +architectures: +- "amd64" +packages: +- "curl" +- "gperf" +- "gcc-7" +- "g++-7" +- "gcc" +- "g++" +- "gcc-7-aarch64-linux-gnu" +- "g++-7-aarch64-linux-gnu" +- "gcc-aarch64-linux-gnu" +- "g++-aarch64-linux-gnu" +- "binutils-aarch64-linux-gnu" +- "gcc-7-arm-linux-gnueabihf" +- "g++-7-arm-linux-gnueabihf" +- "gcc-arm-linux-gnueabihf" +- "g++-arm-linux-gnueabihf" +- "g++-7-multilib" +- "gcc-7-multilib" +- "binutils-arm-linux-gnueabihf" +- "binutils-gold" +- "git" +- "pkg-config" +- "build-essential" +- "autoconf" +- "libtool" +- "automake" +- "faketime" +- "bsdmainutils" +- "ca-certificates" +- "python" +- "cmake" +- "ccache" +- "protobuf-compiler" +- "libdbus-1-dev" +- "libharfbuzz-dev" +- "libprotobuf-dev" +- "python3-zmq" +remotes: +- "url": "https://github.com/monero-project/monero.git" + "dir": "monero" +files: [] +script: | + + WRAP_DIR=$HOME/wrapped + HOSTS="x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu i686-linux-gnu" + FAKETIME_HOST_PROGS="gcc g++" + FAKETIME_PROGS="date ar ranlib nm" + HOST_CFLAGS="-O2 -g" + HOST_CXXFLAGS="-O2 -g" + HOST_LDFLAGS=-static-libstdc++ + + export GZIP="-9n" + export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" + export TZ="UTC" + export BUILD_DIR=`pwd` + mkdir -p ${WRAP_DIR} + if test -n "$GBUILD_CACHE_ENABLED"; then + export SOURCES_PATH=${GBUILD_COMMON_CACHE} + export BASE_CACHE=${GBUILD_PACKAGE_CACHE} + mkdir -p ${BASE_CACHE} ${SOURCES_PATH} + fi + + function create_global_faketime_wrappers { + for prog in ${FAKETIME_PROGS}; do + echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog} + echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} + echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${prog} + chmod +x ${WRAP_DIR}/${prog} + done + } + + function create_per-host_faketime_wrappers { + for i in $HOSTS; do + for prog in ${FAKETIME_HOST_PROGS}; do + if which ${i}-${prog}-7 + then + echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} + echo "REAL=\`which -a ${i}-${prog}-7 | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} + echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} + chmod +x ${WRAP_DIR}/${i}-${prog} + fi + done + done + } + + # Faketime for depends so intermediate results are comparable + export PATH_orig=${PATH} + create_global_faketime_wrappers "2000-01-01 12:00:00" + create_per-host_faketime_wrappers "2000-01-01 12:00:00" + export PATH=${WRAP_DIR}:${PATH} + + EXTRA_INCLUDES_BASE=$WRAP_DIR/extra_includes + mkdir -p $EXTRA_INCLUDES_BASE + + # x86 needs /usr/include/i386-linux-gnu/asm pointed to /usr/include/x86_64-linux-gnu/asm, + # but we can't write there. Instead, create a link here and force it to be included in the + # search paths by wrapping gcc/g++. + + mkdir -p $EXTRA_INCLUDES_BASE/i686-pc-linux-gnu + rm -f $WRAP_DIR/extra_includes/i686-pc-linux-gnu/asm + ln -s /usr/include/x86_64-linux-gnu/asm $EXTRA_INCLUDES_BASE/i686-pc-linux-gnu/asm + + for prog in gcc g++; do + rm -f ${WRAP_DIR}/${prog} + cat << EOF > ${WRAP_DIR}/${prog} + #!/usr/bin/env bash + REAL="`which -a ${prog}-7 | grep -v ${WRAP_DIR}/${prog} | head -1`" + for var in "\$@" + do + if [ "\$var" = "-m32" ]; then + export C_INCLUDE_PATH="$EXTRA_INCLUDES_BASE/i686-pc-linux-gnu" + export CPLUS_INCLUDE_PATH="$EXTRA_INCLUDES_BASE/i686-pc-linux-gnu" + break + fi + done + \$REAL \$@ + EOF + chmod +x ${WRAP_DIR}/${prog} + done + + cd monero + BASEPREFIX=`pwd`/contrib/depends + # Build dependencies for each host + for i in $HOSTS; do + EXTRA_INCLUDES="$EXTRA_INCLUDES_BASE/$i" + if [ -d "$EXTRA_INCLUDES" ]; then + export HOST_ID_SALT="$EXTRA_INCLUDES" + fi + make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" -j 4 V=1 + unset HOST_ID_SALT + done + + # Faketime for binaries + export PATH=${PATH_orig} + create_global_faketime_wrappers "${REFERENCE_DATETIME}" + create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" + export PATH=${WRAP_DIR}:${PATH} + + ORIGPATH="$PATH" + # Build in a new dir for each host + for i in ${HOSTS}; do + export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH} + mkdir build && cd build + cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake + make + DISTNAME=monero-${i} + mv bin ${DISTNAME} + find ${DISTNAME}/ | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}.tar.gz + cd .. + rm -rf build + done diff --git a/contrib/gitian/gitian-osx.yml b/contrib/gitian/gitian-osx.yml new file mode 100644 index 000000000..a6fcff0da --- /dev/null +++ b/contrib/gitian/gitian-osx.yml @@ -0,0 +1,114 @@ +--- +name: "monero-osx-0.14" +enable_cache: true +suites: +- "bionic" +architectures: +- "amd64" +packages: +- "ca-certificates" +- "curl" +- "g++" +- "git" +- "pkg-config" +- "autoconf" +- "librsvg2-bin" +- "libtiff-tools" +- "libtool" +- "automake" +- "faketime" +- "bsdmainutils" +- "cmake" +- "imagemagick" +- "libcap-dev" +- "libz-dev" +- "libbz2-dev" +- "python" +- "python-dev" +- "python-setuptools" +- "fonts-tuffy" +remotes: +- "url": "https://github.com/monero-project/monero.git" + "dir": "monero" +files: +- "MacOSX10.11.sdk.tar.gz" +script: | + WRAP_DIR=$HOME/wrapped + HOSTS="x86_64-apple-darwin11" + FAKETIME_HOST_PROGS="" + FAKETIME_PROGS="ar ranlib date dmg genisoimage" + + export GZIP="-9n" + export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" + export TZ="UTC" + export BUILD_DIR=`pwd` + mkdir -p ${WRAP_DIR} + if test -n "$GBUILD_CACHE_ENABLED"; then + export SOURCES_PATH=${GBUILD_COMMON_CACHE} + export BASE_CACHE=${GBUILD_PACKAGE_CACHE} + mkdir -p ${BASE_CACHE} ${SOURCES_PATH} + fi + + export ZERO_AR_DATE=1 + + function create_global_faketime_wrappers { + for prog in ${FAKETIME_PROGS}; do + echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog} + echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} + echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${prog} + chmod +x ${WRAP_DIR}/${prog} + done + } + + function create_per-host_faketime_wrappers { + for i in $HOSTS; do + for prog in ${FAKETIME_HOST_PROGS}; do + echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} + echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} + echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} + chmod +x ${WRAP_DIR}/${i}-${prog} + done + done + } + + # Faketime for depends so intermediate results are comparable + export PATH_orig=${PATH} + create_global_faketime_wrappers "2000-01-01 12:00:00" + create_per-host_faketime_wrappers "2000-01-01 12:00:00" + export PATH=${WRAP_DIR}:${PATH} + + cd monero + BASEPREFIX=`pwd`/contrib/depends + + mkdir -p ${BASEPREFIX}/SDKs + tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.11.sdk.tar.gz + + # Build dependencies for each host + for i in $HOSTS; do + make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" + done + + # Faketime for binaries + export PATH=${PATH_orig} + create_global_faketime_wrappers "${REFERENCE_DATETIME}" + create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" + export PATH=${WRAP_DIR}:${PATH} + + ORIGPATH="$PATH" + # Build in a new dir for each host + for i in ${HOSTS}; do + export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH} + mkdir build && cd build + cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake + make + DISTNAME=monero-${i} + mv bin ${DISTNAME} + find ${DISTNAME}/ | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}.tar.gz + cd .. + rm -rf build + done + diff --git a/contrib/gitian/gitian-win.yml b/contrib/gitian/gitian-win.yml new file mode 100644 index 000000000..fef5567f9 --- /dev/null +++ b/contrib/gitian/gitian-win.yml @@ -0,0 +1,134 @@ +--- +name: "monero-win-0.14" +enable_cache: true +suites: +- "bionic" +architectures: +- "amd64" +packages: +- "curl" +- "g++" +- "git" +- "pkg-config" +- "autoconf" +- "libtool" +- "automake" +- "faketime" +- "bsdmainutils" +- "mingw-w64" +- "g++-mingw-w64" +- "zip" +- "ca-certificates" +- "python" +- "rename" +- "cmake" +remotes: +- "url": "https://github.com/monero-project/monero.git" + "dir": "monero" +files: [] +script: | + WRAP_DIR=$HOME/wrapped + HOSTS="i686-w64-mingw32 x86_64-w64-mingw32" + FAKETIME_HOST_PROGS="ar ranlib nm windres strip objcopy" + FAKETIME_PROGS="date zip" + HOST_CFLAGS="-O2 -g" + HOST_CXXFLAGS="-O2 -g" + + export GZIP="-9n" + export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" + export TZ="UTC" + export BUILD_DIR=`pwd` + mkdir -p ${WRAP_DIR} + if test -n "$GBUILD_CACHE_ENABLED"; then + export SOURCES_PATH=${GBUILD_COMMON_CACHE} + export BASE_CACHE=${GBUILD_PACKAGE_CACHE} + mkdir -p ${BASE_CACHE} ${SOURCES_PATH} + fi + + function create_global_faketime_wrappers { + for prog in ${FAKETIME_PROGS}; do + echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog} + echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} + echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${prog} + chmod +x ${WRAP_DIR}/${prog} + done + } + + function create_per-host_faketime_wrappers { + for i in $HOSTS; do + for prog in ${FAKETIME_HOST_PROGS}; do + echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} + echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} + echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} + chmod +x ${WRAP_DIR}/${i}-${prog} + done + done + } + + function create_per-host_linker_wrapper { + # This is only needed for trusty, as the mingw linker leaks a few bytes of + # heap, causing non-determinism. See discussion in https://github.com/bitcoin/bitcoin/pull/6900 + for i in $HOSTS; do + mkdir -p ${WRAP_DIR}/${i} + for prog in collect2; do + echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}/${prog} + REAL=$(${i}-gcc -print-prog-name=${prog}) + echo "export MALLOC_PERTURB_=255" >> ${WRAP_DIR}/${i}/${prog} + echo "${REAL} \$@" >> $WRAP_DIR/${i}/${prog} + chmod +x ${WRAP_DIR}/${i}/${prog} + done + for prog in gcc g++; do + echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} + echo "REAL=\`which -a ${i}-${prog}-posix | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} + echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} + echo "export COMPILER_PATH=${WRAP_DIR}/${i}" >> ${WRAP_DIR}/${i}-${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} + chmod +x ${WRAP_DIR}/${i}-${prog} + done + done + } + + # Faketime for depends so intermediate results are comparable + export PATH_orig=${PATH} + create_global_faketime_wrappers "2000-01-01 12:00:00" + create_per-host_faketime_wrappers "2000-01-01 12:00:00" + create_per-host_linker_wrapper "2000-01-01 12:00:00" + export PATH=${WRAP_DIR}:${PATH} + + cd monero + BASEPREFIX=`pwd`/contrib/depends + # Build dependencies for each host + for i in $HOSTS; do + EXTRA_INCLUDES="$EXTRA_INCLUDES_BASE/$i" + if [ -d "$EXTRA_INCLUDES" ]; then + export HOST_ID_SALT="$EXTRA_INCLUDES" + fi + make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" -j 4 V=1 + unset HOST_ID_SALT + done + + # Faketime for binaries + export PATH=${PATH_orig} + create_global_faketime_wrappers "${REFERENCE_DATETIME}" + create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" + export PATH=${WRAP_DIR}:${PATH} + + ORIGPATH="$PATH" + # Run cmake and make, for each create a new build/ directory, + # compile from there, archive, export and delete the archive again + for i in ${HOSTS}; do + export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH} + mkdir build && cd build + cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake + make + DISTNAME=monero-${i} + mv bin ${DISTNAME} + find ${DISTNAME}/ | sort | zip -X@ ${OUTDIR}/${DISTNAME}.zip + cd .. && rm -rf build + done + diff --git a/contrib/gitian/symbol-check.py b/contrib/gitian/symbol-check.py new file mode 100755 index 000000000..6808e77da --- /dev/null +++ b/contrib/gitian/symbol-check.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014 Wladimir J. van der Laan +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +''' +A script to check that the (Linux) executables produced by gitian only contain +allowed gcc, glibc and libstdc++ version symbols. This makes sure they are +still compatible with the minimum supported Linux distribution versions. + +Example usage: + + find ../gitian-builder/build -type f -executable | xargs python contrib/devtools/symbol-check.py +''' +import subprocess +import re +import sys +import os + +# Debian 6.0.9 (Squeeze) has: +# +# - g++ version 4.4.5 (https://packages.debian.org/search?suite=default§ion=all&arch=any&searchon=names&keywords=g%2B%2B) +# - libc version 2.11.3 (https://packages.debian.org/search?suite=default§ion=all&arch=any&searchon=names&keywords=libc6) +# - libstdc++ version 4.4.5 (https://packages.debian.org/search?suite=default§ion=all&arch=any&searchon=names&keywords=libstdc%2B%2B6) +# +# Ubuntu 10.04.4 (Lucid Lynx) has: +# +# - g++ version 4.4.3 (http://packages.ubuntu.com/search?keywords=g%2B%2B&searchon=names&suite=lucid§ion=all) +# - libc version 2.11.1 (http://packages.ubuntu.com/search?keywords=libc6&searchon=names&suite=lucid§ion=all) +# - libstdc++ version 4.4.3 (http://packages.ubuntu.com/search?suite=lucid§ion=all&arch=any&keywords=libstdc%2B%2B&searchon=names) +# +# Taking the minimum of these as our target. +# +# According to GNU ABI document (http://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html) this corresponds to: +# GCC 4.4.0: GCC_4.4.0 +# GCC 4.4.2: GLIBCXX_3.4.13, CXXABI_1.3.3 +# (glibc) GLIBC_2_11 +# +MAX_VERSIONS = { +'GCC': (4,4,0), +'CXXABI': (1,3,3), +'GLIBCXX': (3,4,13), +'GLIBC': (2,11) +} +# See here for a description of _IO_stdin_used: +# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=634261#109 + +# Ignore symbols that are exported as part of every executable +IGNORE_EXPORTS = { +'_edata', '_end', '_init', '__bss_start', '_fini', '_IO_stdin_used', 'stdin', 'stdout', 'stderr' +} +READELF_CMD = os.getenv('READELF', '/usr/bin/readelf') +CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt') +# Allowed NEEDED libraries +ALLOWED_LIBRARIES = { +# bitcoind and bitcoin-qt +'libgcc_s.so.1', # GCC base support +'libc.so.6', # C library +'libpthread.so.0', # threading +'libanl.so.1', # DNS resolve +'libm.so.6', # math library +'librt.so.1', # real-time (clock) +'ld-linux-x86-64.so.2', # 64-bit dynamic linker +'ld-linux.so.2', # 32-bit dynamic linker +# bitcoin-qt only +'libX11-xcb.so.1', # part of X11 +'libX11.so.6', # part of X11 +'libxcb.so.1', # part of X11 +'libfontconfig.so.1', # font support +'libfreetype.so.6', # font parsing +'libdl.so.2' # programming interface to dynamic linker +} + +class CPPFilt(object): + ''' + Demangle C++ symbol names. + + Use a pipe to the 'c++filt' command. + ''' + def __init__(self): + self.proc = subprocess.Popen(CPPFILT_CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True) + + def __call__(self, mangled): + self.proc.stdin.write(mangled + '\n') + self.proc.stdin.flush() + return self.proc.stdout.readline().rstrip() + + def close(self): + self.proc.stdin.close() + self.proc.stdout.close() + self.proc.wait() + +def read_symbols(executable, imports=True): + ''' + Parse an ELF executable and return a list of (symbol,version) tuples + for dynamic, imported symbols. + ''' + p = subprocess.Popen([READELF_CMD, '--dyn-syms', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True) + (stdout, stderr) = p.communicate() + if p.returncode: + raise IOError('Could not read symbols for %s: %s' % (executable, stderr.strip())) + syms = [] + for line in stdout.splitlines(): + line = line.split() + if len(line)>7 and re.match('[0-9]+:$', line[0]): + (sym, _, version) = line[7].partition('@') + is_import = line[6] == 'UND' + if version.startswith('@'): + version = version[1:] + if is_import == imports: + syms.append((sym, version)) + return syms + +def check_version(max_versions, version): + if '_' in version: + (lib, _, ver) = version.rpartition('_') + else: + lib = version + ver = '0' + ver = tuple([int(x) for x in ver.split('.')]) + if not lib in max_versions: + return False + return ver <= max_versions[lib] + +def read_libraries(filename): + p = subprocess.Popen([READELF_CMD, '-d', '-W', filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True) + (stdout, stderr) = p.communicate() + if p.returncode: + raise IOError('Error opening file') + libraries = [] + for line in stdout.splitlines(): + tokens = line.split() + if len(tokens)>2 and tokens[1] == '(NEEDED)': + match = re.match('^Shared library: \[(.*)\]$', ' '.join(tokens[2:])) + if match: + libraries.append(match.group(1)) + else: + raise ValueError('Unparseable (NEEDED) specification') + return libraries + +if __name__ == '__main__': + cppfilt = CPPFilt() + retval = 0 + for filename in sys.argv[1:]: + # Check imported symbols + for sym,version in read_symbols(filename, True): + if version and not check_version(MAX_VERSIONS, version): + print('%s: symbol %s from unsupported version %s' % (filename, cppfilt(sym), version)) + retval = 1 + # Check exported symbols + for sym,version in read_symbols(filename, False): + if sym in IGNORE_EXPORTS: + continue + print('%s: export of symbol %s not allowed' % (filename, cppfilt(sym))) + retval = 1 + # Check dependency libraries + for library_name in read_libraries(filename): + if library_name not in ALLOWED_LIBRARIES: + print('%s: NEEDED library %s is not allowed' % (filename, library_name)) + retval = 1 + + sys.exit(retval) + + diff --git a/src/blockchain_utilities/CMakeLists.txt b/src/blockchain_utilities/CMakeLists.txt index ecd7b754c..6e6e4c6f1 100644 --- a/src/blockchain_utilities/CMakeLists.txt +++ b/src/blockchain_utilities/CMakeLists.txt @@ -26,20 +26,6 @@ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -set(blocksdat "") -if(PER_BLOCK_CHECKPOINT) - if(APPLE AND DEPENDS) - add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && touch stub.c && ${CMAKE_C_COMPILER} --target=x86_64-apple-darwin11 -o stub.o -c stub.c COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} -r -sectcreate __DATA __blocks_dat ../blocks/checkpoints.dat -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o stub.o && rm -f stub.*) - elseif(APPLE AND NOT DEPENDS) - add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && touch stub.c && ${CMAKE_C_COMPILER} -o stub.o -c stub.c COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} ${LD_RAW_FLAGS} -r -sectcreate __DATA __blocks_dat ../blocks/checkpoints.dat -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o stub.o && rm -f stub.*) - elseif(LINUX_32) - add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && cp ../blocks/checkpoints.dat blocks.dat && ${CMAKE_LINKER} -m elf_i386 ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o blocks.dat && rm -f blocks.dat) - else() - add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && cp ../blocks/checkpoints.dat blocks.dat && ${CMAKE_LINKER} ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o blocks.dat && rm -f blocks.dat) - endif() - set(blocksdat "blocksdat.o") -endif() - set(blockchain_import_sources blockchain_import.cpp bootstrap_file.cpp @@ -119,8 +105,7 @@ monero_private_headers(blockchain_depth monero_add_executable(blockchain_import ${blockchain_import_sources} - ${blockchain_import_private_headers} - ${blocksdat}) + ${blockchain_import_private_headers}) target_link_libraries(blockchain_import PRIVATE @@ -132,7 +117,8 @@ target_link_libraries(blockchain_import ${Boost_SYSTEM_LIBRARY} ${Boost_THREAD_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} - ${EXTRA_LIBRARIES}) + ${EXTRA_LIBRARIES} + ${Blocks}) if(ARCH_WIDTH) target_compile_definitions(blockchain_import @@ -184,7 +170,7 @@ target_link_libraries(blockchain_blackball set_property(TARGET blockchain_blackball PROPERTY - OUTPUT_NAME "monero-blockchain-blackball") + OUTPUT_NAME "monero-blockchain-mark-spent-outputs") install(TARGETS blockchain_blackball DESTINATION bin) diff --git a/src/blockchain_utilities/blockchain_blackball.cpp b/src/blockchain_utilities/blockchain_blackball.cpp index 03ff3cdcd..d2ce5cf76 100644 --- a/src/blockchain_utilities/blockchain_blackball.cpp +++ b/src/blockchain_utilities/blockchain_blackball.cpp @@ -226,7 +226,7 @@ static void init(std::string cache_filename) bool tx_active = false; int dbr; - MINFO("Creating blackball cache in " << cache_filename); + MINFO("Creating spent output cache in " << cache_filename); tools::create_directories_if_necessary(cache_filename); @@ -1019,7 +1019,7 @@ int main(int argc, char* argv[]) 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_blackball_db_dir = { - "blackball-db-dir", "Specify blackball database directory", + "spent-output-db-dir", "Specify spent output database directory", get_default_db_path(), }; const command_line::arg_descriptor<std::string> arg_log_level = {"log-level", "0-4 or categories", ""}; @@ -1076,7 +1076,7 @@ int main(int argc, char* argv[]) return 1; } - mlog_configure(mlog_get_default_log_path("monero-blockchain-blackball.log"), true); + mlog_configure(mlog_get_default_log_path("monero-blockchain-find-spent-outputs.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 @@ -1114,10 +1114,10 @@ int main(int argc, char* argv[]) return 1; } - const std::string cache_dir = (output_file_path / "blackball-cache").string(); + const std::string cache_dir = (output_file_path / "spent-outputs-cache").string(); init(cache_dir); - LOG_PRINT_L0("Scanning for blackballable outputs..."); + LOG_PRINT_L0("Scanning for spent outputs..."); size_t done = 0; @@ -1215,7 +1215,7 @@ int main(int argc, char* argv[]) const std::pair<uint64_t, uint64_t> output = std::make_pair(txin.amount, absolute[0]); if (opt_verbose) { - MINFO("Blackballing output " << output.first << "/" << output.second << ", due to being used in a 1-ring"); + MINFO("Marking output " << output.first << "/" << output.second << " as spent, due to being used in a 1-ring"); std::cout << "\r" << start_idx << "/" << n_txes << " \r" << std::flush; } blackballs.push_back(output); @@ -1229,7 +1229,7 @@ int main(int argc, char* argv[]) const std::pair<uint64_t, uint64_t> output = std::make_pair(txin.amount, absolute[o]); if (opt_verbose) { - MINFO("Blackballing output " << output.first << "/" << output.second << ", due to being used in " << new_ring.size() << " identical " << new_ring.size() << "-rings"); + MINFO("Marking output " << output.first << "/" << output.second << " as spent, due to being used in " << new_ring.size() << " identical " << new_ring.size() << "-rings"); std::cout << "\r" << start_idx << "/" << n_txes << " \r" << std::flush; } blackballs.push_back(output); @@ -1244,7 +1244,7 @@ int main(int argc, char* argv[]) const std::pair<uint64_t, uint64_t> output = std::make_pair(txin.amount, absolute[o]); if (opt_verbose) { - MINFO("Blackballing output " << output.first << "/" << output.second << ", due to being used in " << new_ring.size() << " subsets of " << new_ring.size() << "-rings"); + MINFO("Marking output " << output.first << "/" << output.second << " as spent, due to being used in " << new_ring.size() << " subsets of " << new_ring.size() << "-rings"); std::cout << "\r" << start_idx << "/" << n_txes << " \r" << std::flush; } blackballs.push_back(output); @@ -1280,7 +1280,7 @@ int main(int argc, char* argv[]) const std::pair<uint64_t, uint64_t> output = std::make_pair(txin.amount, common[0]); if (opt_verbose) { - MINFO("Blackballing output " << output.first << "/" << output.second << ", due to being used in rings with a single common element"); + MINFO("Marking output " << output.first << "/" << output.second << " as spent, due to being used in rings with a single common element"); std::cout << "\r" << start_idx << "/" << n_txes << " \r" << std::flush; } blackballs.push_back(output); @@ -1392,7 +1392,7 @@ int main(int argc, char* argv[]) const std::pair<uint64_t, uint64_t> output = std::make_pair(od.amount, last_unknown); if (opt_verbose) { - MINFO("Blackballing output " << output.first << "/" << output.second << ", due to being used in a " << + MINFO("Marking output " << output.first << "/" << output.second << " as spent, due to being used in a " << absolute.size() << "-ring where all other outputs are known to be spent"); } blackballs.push_back(output); @@ -1420,7 +1420,7 @@ int main(int argc, char* argv[]) skip_secondary_passes: uint64_t diff = get_num_spent_outputs() - start_blackballed_outputs; - LOG_PRINT_L0(std::to_string(diff) << " new outputs blackballed, " << get_num_spent_outputs() << " total outputs blackballed"); + LOG_PRINT_L0(std::to_string(diff) << " new outputs marked as spent, " << get_num_spent_outputs() << " total outputs marked as spent"); MDB_txn *txn; dbr = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn); @@ -1460,7 +1460,7 @@ skip_secondary_passes: mdb_txn_abort(txn); } - LOG_PRINT_L0("Blockchain blackball data exported OK"); + LOG_PRINT_L0("Blockchain spent output data exported OK"); close_db(env0, txn0, cur0, dbi0); close(); return 0; diff --git a/src/blockchain_utilities/blockchain_import.cpp b/src/blockchain_utilities/blockchain_import.cpp index 9ec768d26..7f92ecd87 100644 --- a/src/blockchain_utilities/blockchain_import.cpp +++ b/src/blockchain_utilities/blockchain_import.cpp @@ -37,6 +37,7 @@ #include "misc_log_ex.h" #include "bootstrap_file.h" #include "bootstrap_serialization.h" +#include "blocks/blocks.h" #include "cryptonote_basic/cryptonote_format_utils.h" #include "serialization/binary_utils.h" // dump_binary(), parse_binary() #include "serialization/json_utils.h" // dump_json() @@ -758,7 +759,12 @@ int main(int argc, char* argv[]) { core.disable_dns_checkpoints(true); - if (!core.init(vm, NULL)) +#if defined(PER_BLOCK_CHECKPOINT) + const GetCheckpointsCallback& get_checkpoints = blocks::GetCheckpointsData; +#else + const GetCheckpointsCallback& get_checkpoints = nullptr; +#endif + if (!core.init(vm, nullptr, nullptr, get_checkpoints)) { std::cerr << "Failed to initialize core" << ENDL; return 1; diff --git a/src/blocks/CMakeLists.txt b/src/blocks/CMakeLists.txt index ebb5408cc..30d85adbf 100644 --- a/src/blocks/CMakeLists.txt +++ b/src/blocks/CMakeLists.txt @@ -26,20 +26,23 @@ # 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. -if(APPLE) - add_library(blocks STATIC blockexports.c) - set_target_properties(blocks PROPERTIES LINKER_LANGUAGE C) -else() - if(LINUX_32) - add_custom_command(OUTPUT blocks.o MAIN_DEPENDENCY blocks.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} -m elf_i386 ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/blocks.o blocks.dat) - add_custom_command(OUTPUT testnet_blocks.o MAIN_DEPENDENCY testnet_blocks.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} -m elf_i386 ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/testnet_blocks.o testnet_blocks.dat) - add_custom_command(OUTPUT stagenet_blocks.o MAIN_DEPENDENCY stagenet_blocks.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} -m elf_i386 ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/stagenet_blocks.o stagenet_blocks.dat) - else() - add_custom_command(OUTPUT blocks.o MAIN_DEPENDENCY blocks.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/blocks.o blocks.dat) - add_custom_command(OUTPUT testnet_blocks.o MAIN_DEPENDENCY testnet_blocks.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/testnet_blocks.o testnet_blocks.dat) - add_custom_command(OUTPUT stagenet_blocks.o MAIN_DEPENDENCY stagenet_blocks.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/stagenet_blocks.o stagenet_blocks.dat) - endif() - add_library(blocks STATIC blocks.o testnet_blocks.o stagenet_blocks.o blockexports.c) - set_target_properties(blocks PROPERTIES LINKER_LANGUAGE C) -endif() +set(GENERATED_SOURCES "") +foreach(BLOB_NAME checkpoints testnet_blocks stagenet_blocks) + set(OUTPUT_C_SOURCE "generated_${BLOB_NAME}.c") + list(APPEND GENERATED_SOURCES ${OUTPUT_C_SOURCE}) + set(INPUT_DAT_FILE "${BLOB_NAME}.dat") + add_custom_command( + OUTPUT ${OUTPUT_C_SOURCE} + MAIN_DEPENDENCY ${INPUT_DAT_FILE} + COMMAND + cd ${CMAKE_CURRENT_BINARY_DIR} && + echo "'#include\t<stddef.h>'" > ${OUTPUT_C_SOURCE} && + echo "'const\tunsigned\tchar\t${BLOB_NAME}[]={'" >> ${OUTPUT_C_SOURCE} && + od -v -An -tu1 ${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_DAT_FILE} | sed -e "'s/[0-9]\\{1,\\}/&,/g'" -e "'$$s/.$$//'" >> ${OUTPUT_C_SOURCE} && + echo "'};'" >> ${OUTPUT_C_SOURCE} && + echo "'const\tsize_t\t${BLOB_NAME}_len\t=\tsizeof(${BLOB_NAME});'" >> ${OUTPUT_C_SOURCE} + ) +endforeach() + +add_library(blocks STATIC blocks.cpp ${GENERATED_SOURCES}) diff --git a/src/blocks/blockexports.c b/src/blocks/blockexports.c deleted file mode 100644 index 0154b0413..000000000 --- a/src/blocks/blockexports.c +++ /dev/null @@ -1,87 +0,0 @@ -#include <stddef.h> - -#if defined(__APPLE__) -#include <mach-o/getsect.h> -#ifdef BUILD_SHARED_LIBS -#if !defined(__LP64__) -const struct mach_header _mh_execute_header; -#else -const struct mach_header_64 _mh_execute_header; -#endif -#else -#if !defined(__LP64__) -extern const struct mach_header _mh_execute_header; -#else -extern const struct mach_header_64 _mh_execute_header; -#endif -#endif - -const unsigned char *get_blocks_dat_start(int testnet, int stagenet) -{ - size_t size; - if (testnet) - return getsectiondata(&_mh_execute_header, "__DATA", "__testnet_blocks_dat", &size); - else if (stagenet) - return getsectiondata(&_mh_execute_header, "__DATA", "__stagenet_blocks_dat", &size); - else - return getsectiondata(&_mh_execute_header, "__DATA", "__blocks_dat", &size); -} - -size_t get_blocks_dat_size(int testnet, int stagenet) -{ - size_t size; - if (testnet) - getsectiondata(&_mh_execute_header, "__DATA", "__testnet_blocks_dat", &size); - else if (stagenet) - getsectiondata(&_mh_execute_header, "__DATA", "__stagenet_blocks_dat", &size); - else - getsectiondata(&_mh_execute_header, "__DATA", "__blocks_dat", &size); - return size; -} - -#else - -#if defined(_WIN32) && !defined(_WIN64) -#define _binary_blocks_start binary_blocks_dat_start -#define _binary_blocks_end binary_blocks_dat_end -#define _binary_testnet_blocks_start binary_testnet_blocks_dat_start -#define _binary_testnet_blocks_end binary_testnet_blocks_dat_end -#define _binary_stagenet_blocks_start binary_stagenet_blocks_dat_start -#define _binary_stagenet_blocks_end binary_stagenet_blocks_dat_end -#else -#define _binary_blocks_start _binary_blocks_dat_start -#define _binary_blocks_end _binary_blocks_dat_end -#define _binary_testnet_blocks_start _binary_testnet_blocks_dat_start -#define _binary_testnet_blocks_end _binary_testnet_blocks_dat_end -#define _binary_stagenet_blocks_start _binary_stagenet_blocks_dat_start -#define _binary_stagenet_blocks_end _binary_stagenet_blocks_dat_end -#endif - -extern const unsigned char _binary_blocks_start[]; -extern const unsigned char _binary_blocks_end[]; -extern const unsigned char _binary_testnet_blocks_start[]; -extern const unsigned char _binary_testnet_blocks_end[]; -extern const unsigned char _binary_stagenet_blocks_start[]; -extern const unsigned char _binary_stagenet_blocks_end[]; - -const unsigned char *get_blocks_dat_start(int testnet, int stagenet) -{ - if (testnet) - return _binary_testnet_blocks_start; - else if (stagenet) - return _binary_stagenet_blocks_start; - else - return _binary_blocks_start; -} - -size_t get_blocks_dat_size(int testnet, int stagenet) -{ - if (testnet) - return (size_t) (_binary_testnet_blocks_end - _binary_testnet_blocks_start); - else if (stagenet) - return (size_t) (_binary_stagenet_blocks_end - _binary_stagenet_blocks_start); - else - return (size_t) (_binary_blocks_end - _binary_blocks_start); -} - -#endif diff --git a/src/blocks/blocks.cpp b/src/blocks/blocks.cpp new file mode 100644 index 000000000..0661f8448 --- /dev/null +++ b/src/blocks/blocks.cpp @@ -0,0 +1,31 @@ +#include "blocks.h" + +#include <unordered_map> + +extern const unsigned char checkpoints[]; +extern const size_t checkpoints_len; +extern const unsigned char stagenet_blocks[]; +extern const size_t stagenet_blocks_len; +extern const unsigned char testnet_blocks[]; +extern const size_t testnet_blocks_len; + +namespace blocks +{ + + const std::unordered_map<cryptonote::network_type, const epee::span<const unsigned char>, std::hash<size_t>> CheckpointsByNetwork = { + {cryptonote::network_type::MAINNET, {checkpoints, checkpoints_len}}, + {cryptonote::network_type::STAGENET, {stagenet_blocks, stagenet_blocks_len}}, + {cryptonote::network_type::TESTNET, {testnet_blocks, testnet_blocks_len}} + }; + + const epee::span<const unsigned char> GetCheckpointsData(cryptonote::network_type network) + { + const auto it = CheckpointsByNetwork.find(network); + if (it != CheckpointsByNetwork.end()) + { + return it->second; + } + return nullptr; + } + +} diff --git a/src/blocks/blocks.dat b/src/blocks/blocks.dat deleted file mode 100644 index e69de29bb..000000000 --- a/src/blocks/blocks.dat +++ /dev/null diff --git a/src/blocks/blocks.h b/src/blocks/blocks.h index ec683f47e..14e391319 100644 --- a/src/blocks/blocks.h +++ b/src/blocks/blocks.h @@ -1,16 +1,12 @@ #ifndef SRC_BLOCKS_BLOCKS_H_ #define SRC_BLOCKS_BLOCKS_H_ -#ifdef __cplusplus -extern "C" { -#endif +#include "cryptonote_config.h" +#include "span.h" -const unsigned char *get_blocks_dat_start(int testnet, int stagenet); -size_t get_blocks_dat_size(int testnet, int stagenet); - -#ifdef __cplusplus +namespace blocks +{ + const epee::span<const unsigned char> GetCheckpointsData(cryptonote::network_type network); } -#endif - #endif /* SRC_BLOCKS_BLOCKS_H_ */ diff --git a/src/common/expect.h b/src/common/expect.h index 326242502..72e4060a7 100644 --- a/src/common/expect.h +++ b/src/common/expect.h @@ -350,7 +350,9 @@ public: using error_type = std::error_code; //! Create a successful object. - expect() = default; + expect() noexcept + : code_() + {} expect(std::error_code const& code) noexcept : code_(code) diff --git a/src/common/spawn.cpp b/src/common/spawn.cpp index 59f11675c..0a2ce8387 100644 --- a/src/common/spawn.cpp +++ b/src/common/spawn.cpp @@ -38,6 +38,7 @@ #endif #include "misc_log_ex.h" +#include "util.h" #include "spawn.h" namespace tools @@ -101,6 +102,8 @@ int spawn(const char *filename, const std::vector<std::string>& args, bool wait) // child if (pid == 0) { + tools::closefrom(3); + close(0); char *envp[] = {NULL}; execve(filename, argv, envp); MERROR("Failed to execve: " << strerror(errno)); diff --git a/src/common/util.cpp b/src/common/util.cpp index 2a1d49af0..43973c511 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -28,6 +28,7 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers +#include <unistd.h> #include <cstdio> #ifdef __GLIBC__ @@ -233,7 +234,7 @@ namespace tools MERROR("Failed to open " << filename << ": " << std::error_code(GetLastError(), std::system_category())); } #else - m_fd = open(filename.c_str(), O_RDONLY | O_CREAT, 0666); + m_fd = open(filename.c_str(), O_RDONLY | O_CREAT | O_CLOEXEC, 0666); if (m_fd != -1) { if (flock(m_fd, LOCK_EX | LOCK_NB) == -1) @@ -307,10 +308,19 @@ namespace tools StringCchCopy(pszOS, BUFSIZE, TEXT("Microsoft ")); // Test for the specific product. + if ( osvi.dwMajorVersion == 10 ) + { + if ( osvi.dwMinorVersion == 0 ) + { + if( osvi.wProductType == VER_NT_WORKSTATION ) + StringCchCat(pszOS, BUFSIZE, TEXT("Windows 10 ")); + else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2016 " )); + } + } if ( osvi.dwMajorVersion == 6 ) { - if( osvi.dwMinorVersion == 0 ) + if ( osvi.dwMinorVersion == 0 ) { if( osvi.wProductType == VER_NT_WORKSTATION ) StringCchCat(pszOS, BUFSIZE, TEXT("Windows Vista ")); @@ -324,6 +334,20 @@ namespace tools else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2008 R2 " )); } + if ( osvi.dwMinorVersion == 2 ) + { + if( osvi.wProductType == VER_NT_WORKSTATION ) + StringCchCat(pszOS, BUFSIZE, TEXT("Windows 8 ")); + else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2012 " )); + } + + if ( osvi.dwMinorVersion == 3 ) + { + if( osvi.wProductType == VER_NT_WORKSTATION ) + StringCchCat(pszOS, BUFSIZE, TEXT("Windows 8.1 ")); + else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2012 R2 " )); + } + pGPI = (PGPI) GetProcAddress( GetModuleHandle(TEXT("kernel32.dll")), "GetProductInfo"); @@ -967,4 +991,23 @@ std::string get_nix_version_display_string() } #endif + void closefrom(int fd) + { +#if defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__ || defined __DragonFly__ + ::closefrom(fd); +#else +#if defined __GLIBC__ + const int sc_open_max = sysconf(_SC_OPEN_MAX); + const int MAX_FDS = std::min(65536, sc_open_max); +#else + const int MAX_FDS = 65536; +#endif + while (fd < MAX_FDS) + { + close(fd); + ++fd; + } +#endif + } + } diff --git a/src/common/util.h b/src/common/util.h index ce773bd38..e793a42b5 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -238,4 +238,6 @@ namespace tools #ifdef _WIN32 std::string input_line_win(); #endif + + void closefrom(int fd); } diff --git a/src/cryptonote_basic/cryptonote_basic.h b/src/cryptonote_basic/cryptonote_basic.h index d4558ef7b..b0eabb0aa 100644 --- a/src/cryptonote_basic/cryptonote_basic.h +++ b/src/cryptonote_basic/cryptonote_basic.h @@ -47,7 +47,6 @@ #include "crypto/crypto.h" #include "crypto/hash.h" #include "misc_language.h" -#include "tx_extra.h" #include "ringct/rctTypes.h" #include "device/device.hpp" diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index 9e9c12605..e26aac76b 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -445,6 +445,91 @@ namespace cryptonote return true; } //--------------------------------------------------------------- + template<typename T> + static bool pick(binary_archive<true> &ar, std::vector<tx_extra_field> &fields, uint8_t tag) + { + std::vector<tx_extra_field>::iterator it; + while ((it = std::find_if(fields.begin(), fields.end(), [](const tx_extra_field &f) { return f.type() == typeid(T); })) != fields.end()) + { + bool r = ::do_serialize(ar, tag); + CHECK_AND_NO_ASSERT_MES_L1(r, false, "failed to serialize tx extra field"); + r = ::do_serialize(ar, boost::get<T>(*it)); + CHECK_AND_NO_ASSERT_MES_L1(r, false, "failed to serialize tx extra field"); + fields.erase(it); + } + return true; + } + //--------------------------------------------------------------- + bool sort_tx_extra(const std::vector<uint8_t>& tx_extra, std::vector<uint8_t> &sorted_tx_extra, bool allow_partial) + { + std::vector<tx_extra_field> tx_extra_fields; + + if(tx_extra.empty()) + { + sorted_tx_extra.clear(); + return true; + } + + std::string extra_str(reinterpret_cast<const char*>(tx_extra.data()), tx_extra.size()); + std::istringstream iss(extra_str); + binary_archive<false> ar(iss); + + bool eof = false; + size_t processed = 0; + while (!eof) + { + tx_extra_field field; + bool r = ::do_serialize(ar, field); + if (!r) + { + MWARNING("failed to deserialize extra field. extra = " << string_tools::buff_to_hex_nodelimer(std::string(reinterpret_cast<const char*>(tx_extra.data()), tx_extra.size()))); + if (!allow_partial) + return false; + break; + } + tx_extra_fields.push_back(field); + processed = iss.tellg(); + + std::ios_base::iostate state = iss.rdstate(); + eof = (EOF == iss.peek()); + iss.clear(state); + } + if (!::serialization::check_stream_state(ar)) + { + MWARNING("failed to deserialize extra field. extra = " << string_tools::buff_to_hex_nodelimer(std::string(reinterpret_cast<const char*>(tx_extra.data()), tx_extra.size()))); + if (!allow_partial) + return false; + } + MTRACE("Sorted " << processed << "/" << tx_extra.size()); + + std::ostringstream oss; + binary_archive<true> nar(oss); + + // sort by: + if (!pick<tx_extra_pub_key>(nar, tx_extra_fields, TX_EXTRA_TAG_PUBKEY)) return false; + if (!pick<tx_extra_additional_pub_keys>(nar, tx_extra_fields, TX_EXTRA_TAG_ADDITIONAL_PUBKEYS)) return false; + if (!pick<tx_extra_nonce>(nar, tx_extra_fields, TX_EXTRA_NONCE)) return false; + if (!pick<tx_extra_merge_mining_tag>(nar, tx_extra_fields, TX_EXTRA_MERGE_MINING_TAG)) return false; + if (!pick<tx_extra_mysterious_minergate>(nar, tx_extra_fields, TX_EXTRA_MYSTERIOUS_MINERGATE_TAG)) return false; + if (!pick<tx_extra_padding>(nar, tx_extra_fields, TX_EXTRA_TAG_PADDING)) return false; + + // if not empty, someone added a new type and did not add a case above + if (!tx_extra_fields.empty()) + { + MERROR("tx_extra_fields not empty after sorting, someone forgot to add a case above"); + return false; + } + + std::string oss_str = oss.str(); + if (allow_partial && processed < tx_extra.size()) + { + MDEBUG("Appending unparsed data"); + oss_str += std::string((const char*)tx_extra.data() + processed, tx_extra.size() - processed); + } + sorted_tx_extra = std::vector<uint8_t>(oss_str.begin(), oss_str.end()); + return true; + } + //--------------------------------------------------------------- crypto::public_key get_tx_pub_key_from_extra(const std::vector<uint8_t>& tx_extra, size_t pk_index) { std::vector<tx_extra_field> tx_extra_fields; diff --git a/src/cryptonote_basic/cryptonote_format_utils.h b/src/cryptonote_basic/cryptonote_format_utils.h index 725c75f4e..8d33b1ca4 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.h +++ b/src/cryptonote_basic/cryptonote_format_utils.h @@ -31,6 +31,7 @@ #pragma once #include "blobdatatype.h" #include "cryptonote_basic_impl.h" +#include "tx_extra.h" #include "account.h" #include "subaddress_index.h" #include "include_base_utils.h" @@ -65,6 +66,7 @@ namespace cryptonote } bool parse_tx_extra(const std::vector<uint8_t>& tx_extra, std::vector<tx_extra_field>& tx_extra_fields); + bool sort_tx_extra(const std::vector<uint8_t>& tx_extra, std::vector<uint8_t> &sorted_tx_extra, bool allow_partial = false); crypto::public_key get_tx_pub_key_from_extra(const std::vector<uint8_t>& tx_extra, size_t pk_index = 0); crypto::public_key get_tx_pub_key_from_extra(const transaction_prefix& tx, size_t pk_index = 0); crypto::public_key get_tx_pub_key_from_extra(const transaction& tx, size_t pk_index = 0); diff --git a/src/cryptonote_basic/miner.cpp b/src/cryptonote_basic/miner.cpp index 2bd43de94..d0b03593e 100644 --- a/src/cryptonote_basic/miner.cpp +++ b/src/cryptonote_basic/miner.cpp @@ -201,7 +201,7 @@ namespace cryptonote float hr = static_cast<float>(total_hr)/static_cast<float>(m_last_hash_rates.size()); const auto flags = std::cout.flags(); const auto precision = std::cout.precision(); - std::cout << "hashrate: " << std::setprecision(4) << std::fixed << hr << flags << precision << ENDL; + std::cout << "hashrate: " << std::setprecision(4) << std::fixed << hr << std::setiosflags(flags) << std::setprecision(precision) << ENDL; } } m_last_hr_merge_time = misc_utils::get_tick_count(); diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index a6858ce7c..c62eeb738 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -30,6 +30,7 @@ #pragma once +#include <stdexcept> #include <string> #include <boost/uuid/uuid.hpp> diff --git a/src/cryptonote_core/CMakeLists.txt b/src/cryptonote_core/CMakeLists.txt index 72844db66..231489fdb 100644 --- a/src/cryptonote_core/CMakeLists.txt +++ b/src/cryptonote_core/CMakeLists.txt @@ -41,12 +41,6 @@ set(cryptonote_core_private_headers tx_pool.h cryptonote_tx_utils.h) -if(PER_BLOCK_CHECKPOINT) - set(Blocks "blocks") -else() - set(Blocks "") -endif() - monero_private_headers(cryptonote_core ${cryptonote_core_private_headers}) monero_add_library(cryptonote_core @@ -69,5 +63,4 @@ target_link_libraries(cryptonote_core ${Boost_SYSTEM_LIBRARY} ${Boost_THREAD_LIBRARY} PRIVATE - ${Blocks} ${EXTRA_LIBRARIES}) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index eb869b795..77b6d0b69 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -53,9 +53,6 @@ #include "ringct/rctSigs.h" #include "common/perf_timer.h" #include "common/notify.h" -#if defined(PER_BLOCK_CHECKPOINT) -#include "blocks/blocks.h" -#endif #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "blockchain" @@ -341,9 +338,12 @@ uint64_t Blockchain::get_current_blockchain_height() const //------------------------------------------------------------------ //FIXME: possibly move this into the constructor, to avoid accidentally // dereferencing a null BlockchainDB pointer -bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline, const cryptonote::test_options *test_options, difficulty_type fixed_difficulty) +bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline, const cryptonote::test_options *test_options, difficulty_type fixed_difficulty, const GetCheckpointsCallback& get_checkpoints/* = nullptr*/) { LOG_PRINT_L3("Blockchain::" << __func__); + + CHECK_AND_ASSERT_MES(nettype != FAKECHAIN || test_options, false, "fake chain network type used without options"); + CRITICAL_REGION_LOCAL(m_tx_pool); CRITICAL_REGION_LOCAL1(m_blockchain_lock); @@ -439,7 +439,7 @@ bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline #if defined(PER_BLOCK_CHECKPOINT) if (m_nettype != FAKECHAIN) - load_compiled_in_block_hashes(); + load_compiled_in_block_hashes(get_checkpoints); #endif MINFO("Blockchain initialized. last block: " << m_db->height() - 1 << ", " << epee::misc_utils::get_time_interval_string(timestamp_diff) << " time ago, current difficulty: " << get_difficulty_for_next_block()); @@ -883,6 +883,15 @@ difficulty_type Blockchain::get_difficulty_for_next_block() return diff; } //------------------------------------------------------------------ +std::vector<time_t> Blockchain::get_last_block_timestamps(unsigned int blocks) const +{ + std::vector<time_t> timestamps(blocks); + uint64_t height = m_db->height(); + while (blocks--) + timestamps[blocks] = m_db->get_block_timestamp(height - blocks - 1); + return timestamps; +} +//------------------------------------------------------------------ // This function removes blocks from the blockchain until it gets to the // position where the blockchain switch started and then re-adds the blocks // that had been removed. @@ -2364,7 +2373,7 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context const bool bulletproof = rct::is_rct_bulletproof(tx.rct_signatures.type); if (bulletproof || !tx.rct_signatures.p.bulletproofs.empty()) { - MERROR("Bulletproofs are not allowed before v8"); + MERROR_VER("Bulletproofs are not allowed before v8"); tvc.m_invalid_output = true; return false; } @@ -2377,7 +2386,7 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context const bool borromean = rct::is_rct_borromean(tx.rct_signatures.type); if (borromean) { - MERROR("Borromean range proofs are not allowed after v8"); + MERROR_VER("Borromean range proofs are not allowed after v8"); tvc.m_invalid_output = true; return false; } @@ -4404,19 +4413,21 @@ void Blockchain::cancel() #if defined(PER_BLOCK_CHECKPOINT) static const char expected_block_hashes_hash[] = "954cb2bbfa2fe6f74b2cdd22a1a4c767aea249ad47ad4f7c9445f0f03260f511"; -void Blockchain::load_compiled_in_block_hashes() +void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback& get_checkpoints) { - const bool testnet = m_nettype == TESTNET; - const bool stagenet = m_nettype == STAGENET; - if (m_fast_sync && get_blocks_dat_start(testnet, stagenet) != nullptr && get_blocks_dat_size(testnet, stagenet) > 0) + if (get_checkpoints == nullptr || !m_fast_sync) { - MINFO("Loading precomputed blocks (" << get_blocks_dat_size(testnet, stagenet) << " bytes)"); - + return; + } + const epee::span<const unsigned char> &checkpoints = get_checkpoints(m_nettype); + if (!checkpoints.empty()) + { + MINFO("Loading precomputed blocks (" << checkpoints.size() << " bytes)"); if (m_nettype == MAINNET) { // first check hash crypto::hash hash; - if (!tools::sha256sum(get_blocks_dat_start(testnet, stagenet), get_blocks_dat_size(testnet, stagenet), hash)) + if (!tools::sha256sum(checkpoints.data(), checkpoints.size(), hash)) { MERROR("Failed to hash precomputed blocks data"); return; @@ -4436,9 +4447,9 @@ void Blockchain::load_compiled_in_block_hashes() } } - if (get_blocks_dat_size(testnet, stagenet) > 4) + if (checkpoints.size() > 4) { - const unsigned char *p = get_blocks_dat_start(testnet, stagenet); + const unsigned char *p = checkpoints.data(); const uint32_t nblocks = *p | ((*(p+1))<<8) | ((*(p+2))<<16) | ((*(p+3))<<24); if (nblocks > (std::numeric_limits<uint32_t>::max() - 4) / sizeof(hash)) { @@ -4446,7 +4457,7 @@ void Blockchain::load_compiled_in_block_hashes() return; } const size_t size_needed = 4 + nblocks * sizeof(crypto::hash); - if(nblocks > 0 && nblocks > (m_db->height() + HASH_OF_HASHES_STEP - 1) / HASH_OF_HASHES_STEP && get_blocks_dat_size(testnet, stagenet) >= size_needed) + if(nblocks > 0 && nblocks > (m_db->height() + HASH_OF_HASHES_STEP - 1) / HASH_OF_HASHES_STEP && checkpoints.size() >= size_needed) { p += sizeof(uint32_t); m_blocks_hash_of_hashes.reserve(nblocks); diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index ab66fac8b..f140d7719 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -38,9 +38,11 @@ #include <boost/multi_index/hashed_index.hpp> #include <boost/multi_index/member.hpp> #include <atomic> +#include <functional> #include <unordered_map> #include <unordered_set> +#include "span.h" #include "syncobj.h" #include "string_tools.h" #include "cryptonote_basic/cryptonote_basic.h" @@ -73,6 +75,15 @@ namespace cryptonote db_nosync //!< Leave syncing up to the backing db (safest, but slowest because of disk I/O) }; + /** + * @brief Callback routine that returns checkpoints data for specific network type + * + * @param network network type + * + * @return checkpoints data, empty span if there ain't any checkpoints for specific network type + */ + typedef std::function<const epee::span<const unsigned char>(cryptonote::network_type network)> GetCheckpointsCallback; + /************************************************************************/ /* */ /************************************************************************/ @@ -117,10 +128,11 @@ namespace cryptonote * @param offline true if running offline, else false * @param test_options test parameters * @param fixed_difficulty fixed difficulty for testing purposes; 0 means disabled + * @param get_checkpoints if set, will be called to get checkpoints data * * @return true on success, false if any initialization steps fail */ - bool init(BlockchainDB* db, const network_type nettype = MAINNET, bool offline = false, const cryptonote::test_options *test_options = NULL, difficulty_type fixed_difficulty = 0); + bool init(BlockchainDB* db, const network_type nettype = MAINNET, bool offline = false, const cryptonote::test_options *test_options = NULL, difficulty_type fixed_difficulty = 0, const GetCheckpointsCallback& get_checkpoints = nullptr); /** * @brief Initialize the Blockchain state @@ -952,6 +964,11 @@ namespace cryptonote */ void on_new_tx_from_block(const cryptonote::transaction &tx); + /** + * @brief returns the timestamps of the last N blocks + */ + std::vector<time_t> get_last_block_timestamps(unsigned int blocks) const; + private: // TODO: evaluate whether or not each of these typedefs are left over from blockchain_storage @@ -1369,8 +1386,10 @@ namespace cryptonote * A (possibly empty) set of block hashes can be compiled into the * monero daemon binary. This function loads those hashes into * a useful state. + * + * @param get_checkpoints if set, will be called to get checkpoints data */ - void load_compiled_in_block_hashes(); + void load_compiled_in_block_hashes(const GetCheckpointsCallback& get_checkpoints); /** * @brief expands v2 transaction data from blockchain diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 69e3c708b..d8c38bf9e 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -389,7 +389,7 @@ namespace cryptonote return m_blockchain_storage.get_alternative_blocks_count(); } //----------------------------------------------------------------------------------------------- - bool core::init(const boost::program_options::variables_map& vm, const char *config_subdir, const cryptonote::test_options *test_options) + bool core::init(const boost::program_options::variables_map& vm, const char *config_subdir, const cryptonote::test_options *test_options, const GetCheckpointsCallback& get_checkpoints/* = nullptr */) { start_time = std::time(nullptr); @@ -567,7 +567,7 @@ namespace cryptonote regtest_hard_forks }; 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); + r = m_blockchain_storage.init(db.release(), m_nettype, m_offline, regtest ? ®test_test_options : test_options, fixed_difficulty, get_checkpoints); r = m_mempool.init(max_txpool_weight); CHECK_AND_ASSERT_MES(r, false, "Failed to initialize memory pool"); @@ -856,16 +856,19 @@ namespace cryptonote } waiter.wait(&tpool); it = tx_blobs.begin(); + std::vector<bool> already_have(tx_blobs.size(), false); for (size_t i = 0; i < tx_blobs.size(); i++, ++it) { if (!results[i].res) continue; if(m_mempool.have_tx(results[i].hash)) { LOG_PRINT_L2("tx " << results[i].hash << "already have transaction in tx_pool"); + already_have[i] = true; } else if(m_blockchain_storage.have_tx(results[i].hash)) { LOG_PRINT_L2("tx " << results[i].hash << " already have transaction in blockchain"); + already_have[i] = true; } else { @@ -887,7 +890,7 @@ namespace cryptonote std::vector<tx_verification_batch_info> tx_info; tx_info.reserve(tx_blobs.size()); for (size_t i = 0; i < tx_blobs.size(); i++) { - if (!results[i].res) + if (!results[i].res || already_have[i]) continue; tx_info.push_back({&results[i].tx, results[i].hash, tvc[i], results[i].res}); } @@ -897,6 +900,8 @@ namespace cryptonote bool ok = true; it = tx_blobs.begin(); for (size_t i = 0; i < tx_blobs.size(); i++, ++it) { + if (already_have[i]) + continue; if (!results[i].res) { ok = false; @@ -1489,6 +1494,7 @@ namespace cryptonote m_txpool_auto_relayer.do_call(boost::bind(&core::relay_txpool_transactions, this)); 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_miner.on_idle(); m_mempool.on_idle(); return true; @@ -1677,6 +1683,52 @@ namespace cryptonote return true; } //----------------------------------------------------------------------------------------------- + double factorial(unsigned int n) + { + if (n <= 1) + return 1.0; + double f = n; + while (n-- > 1) + f *= n; + return f; + } + //----------------------------------------------------------------------------------------------- + static double probability(unsigned int blocks, unsigned int expected) + { + // https://www.umass.edu/wsp/resources/poisson/#computing + return pow(expected, blocks) / (factorial(blocks) * exp(expected)); + } + //----------------------------------------------------------------------------------------------- + bool core::check_block_rate() + { + if (m_offline || m_target_blockchain_height > get_current_blockchain_height()) + { + MDEBUG("Not checking block rate, offline or syncing"); + return true; + } + + static constexpr double threshold = 1. / (864000 / DIFFICULTY_TARGET_V2); // one false positive every 10 days + + 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 }; + for (size_t n = 0; n < sizeof(seconds)/sizeof(seconds[0]); ++n) + { + unsigned int b = 0; + for (time_t ts: timestamps) b += ts >= now - seconds[n]; + const double p = probability(b, seconds[n] / DIFFICULTY_TARGET_V2); + MDEBUG("blocks in the last " << seconds[n] / 60 << " minutes: " << b << " (probability " << p << ")"); + if (p < threshold) + { + 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."); + break; // no need to look further + } + } + + return true; + } + //----------------------------------------------------------------------------------------------- void core::set_target_blockchain_height(uint64_t target_blockchain_height) { m_target_blockchain_height = target_blockchain_height; diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index 58fe5b7b5..80c452f53 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -244,10 +244,11 @@ namespace cryptonote * @param vm command line parameters * @param config_subdir subdirectory for config storage * @param test_options configuration options for testing + * @param get_checkpoints if set, will be called to get checkpoints data, must return checkpoints data pointer and size or nullptr if there ain't any checkpoints for specific network type * * @return false if one of the init steps fails, otherwise true */ - bool init(const boost::program_options::variables_map& vm, const char *config_subdir = NULL, const test_options *test_options = NULL); + bool init(const boost::program_options::variables_map& vm, const char *config_subdir = NULL, const test_options *test_options = NULL, const GetCheckpointsCallback& get_checkpoints = nullptr); /** * @copydoc Blockchain::reset_and_set_genesis_block @@ -945,6 +946,13 @@ namespace cryptonote */ bool check_disk_space(); + /** + * @brief checks block rate, and warns if it's too slow + * + * @return true on success, false otherwise + */ + bool check_block_rate(); + bool m_test_drop_download = true; //!< whether or not to drop incoming blocks (for testing) uint64_t m_test_drop_download_height = 0; //!< height under which to drop incoming blocks, if doing so @@ -969,6 +977,7 @@ namespace cryptonote epee::math_helper::once_a_time_seconds<60*2, false> m_txpool_auto_relayer; //!< interval for checking re-relaying txpool transactions 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 std::atomic<bool> m_starter_message_showed; //!< has the "daemon will sync now" message been shown? diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp index 4bc33b56b..4fc2736a6 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.cpp +++ b/src/cryptonote_core/cryptonote_tx_utils.cpp @@ -38,6 +38,7 @@ using namespace epee; #include "cryptonote_tx_utils.h" #include "cryptonote_config.h" #include "cryptonote_basic/miner.h" +#include "cryptonote_basic/tx_extra.h" #include "crypto/crypto.h" #include "crypto/hash.h" #include "ringct/rctSigs.h" @@ -84,6 +85,8 @@ namespace cryptonote if(!extra_nonce.empty()) if(!add_extra_nonce_to_tx_extra(tx.extra, extra_nonce)) return false; + if (!sort_tx_extra(tx.extra, tx.extra)) + return false; txin_gen in; in.height = height; @@ -434,6 +437,9 @@ namespace cryptonote add_additional_tx_pub_keys_to_extra(tx.extra, additional_tx_public_keys); } + if (!sort_tx_extra(tx.extra, tx.extra)) + return false; + //check money if(summary_outs_money > summary_inputs_money ) { diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index 5a9fcf67e..553a22298 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -765,7 +765,7 @@ namespace cryptonote m_blockchain.for_all_txpool_txes([&tx_infos, key_image_infos, include_sensitive_data](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd){ tx_info txi; txi.id_hash = epee::string_tools::pod_to_hex(txid); - txi.tx_blob = epee::string_tools::buff_to_hex_nodelimer(*bd); + txi.tx_blob = *bd; transaction tx; if (!parse_and_validate_tx_from_blob(*bd, tx)) { diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt index f645836a4..117790455 100644 --- a/src/daemon/CMakeLists.txt +++ b/src/daemon/CMakeLists.txt @@ -26,20 +26,6 @@ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -set(blocksdat "") -if(PER_BLOCK_CHECKPOINT) - if(APPLE AND DEPENDS) - add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && touch stub.c && ${CMAKE_C_COMPILER} --target=x86_64-apple-darwin11 -o stub.o -c stub.c COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} -r -sectcreate __DATA __blocks_dat ../blocks/checkpoints.dat -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o stub.o && rm -f stub.*) - elseif(APPLE AND NOT DEPENDS) - add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && touch stub.c && ${CMAKE_C_COMPILER} -o stub.o -c stub.c COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} ${LD_RAW_FLAGS} -r -sectcreate __DATA __blocks_dat ../blocks/checkpoints.dat -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o stub.o && rm -f stub.*) - elseif(LINUX_32) - add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && cp ../blocks/checkpoints.dat blocks.dat && ${CMAKE_LINKER} -m elf_i386 ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o blocks.dat && rm -f blocks.dat) - else() - add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && cp ../blocks/checkpoints.dat blocks.dat && ${CMAKE_LINKER} ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o blocks.dat && rm -f blocks.dat) - endif() - set(blocksdat "blocksdat.o") -endif() - set(daemon_sources command_parser_executor.cpp command_server.cpp @@ -81,9 +67,7 @@ monero_private_headers(daemon monero_add_executable(daemon ${daemon_sources} ${daemon_headers} - ${daemon_private_headers} - ${blocksdat} -) + ${daemon_private_headers}) target_link_libraries(daemon PRIVATE rpc @@ -106,7 +90,8 @@ target_link_libraries(daemon ${CMAKE_THREAD_LIBS_INIT} ${ZMQ_LIB} ${GNU_READLINE_LIBRARY} - ${EXTRA_LIBRARIES}) + ${EXTRA_LIBRARIES} + ${Blocks}) set_property(TARGET daemon PROPERTY OUTPUT_NAME "monerod") diff --git a/src/daemon/core.h b/src/daemon/core.h index 475f418d6..d1defd573 100644 --- a/src/daemon/core.h +++ b/src/daemon/core.h @@ -28,6 +28,7 @@ #pragma once +#include "blocks/blocks.h" #include "cryptonote_core/cryptonote_core.h" #include "cryptonote_protocol/cryptonote_protocol_handler.h" #include "misc_log_ex.h" @@ -85,7 +86,12 @@ public: //initialize core here MGINFO("Initializing core..."); std::string config_subdir = get_config_subdir(); - if (!m_core.init(m_vm_HACK, config_subdir.empty() ? NULL : config_subdir.c_str())) +#if defined(PER_BLOCK_CHECKPOINT) + const cryptonote::GetCheckpointsCallback& get_checkpoints = blocks::GetCheckpointsData; +#else + const cryptonote::GetCheckpointsCallback& get_checkpoints = nullptr; +#endif + if (!m_core.init(m_vm_HACK, config_subdir.empty() ? NULL : config_subdir.c_str(), nullptr, get_checkpoints)) { return false; } diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index f53649518..49d6d49cf 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -137,13 +137,18 @@ bool t_daemon::run(bool interactive) throw std::runtime_error{"Can't run stopped daemon"}; } - std::atomic<bool> stop(false); - boost::thread([&stop, this] { + std::atomic<bool> stop(false), shutdown(false); + boost::thread stop_thread = boost::thread([&stop, &shutdown, this] { while (!stop) epee::misc_utils::sleep_no_w(100); - this->stop_p2p(); - }).detach(); - tools::signal_handler::install([&stop](int){ stop = true; }); + if (shutdown) + this->stop_p2p(); + }); + epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler([&](){ + stop = true; + stop_thread.join(); + }); + tools::signal_handler::install([&stop, &shutdown](int){ stop = shutdown = true; }); try { diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index 6464d372f..9a0603a10 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -449,7 +449,7 @@ bool t_rpc_command_executor::show_status() { % get_sync_percentage(ires) % (ires.testnet ? "testnet" : ires.stagenet ? "stagenet" : "mainnet") % bootstrap_msg - % (!has_mining_info ? "mining info unavailable" : mining_busy ? "syncing" : mres.active ? ( ( mres.is_background_mining_enabled ? "smart " : "" ) + std::string("mining at ") + get_mining_speed(mres.speed) ) : "not mining") + % (!has_mining_info ? "mining info unavailable" : mining_busy ? "syncing" : mres.active ? ( ( mres.is_background_mining_enabled ? "smart " : "" ) + std::string("mining at ") + get_mining_speed(mres.speed) + std::string(" to ") + mres.address ) : "not mining") % get_mining_speed(ires.difficulty / ires.target) % (unsigned)hfres.version % get_fork_extra_info(hfres.earliest_height, net_height, ires.target) diff --git a/src/daemonizer/windows_daemonizer.inl b/src/daemonizer/windows_daemonizer.inl index 8077f29fb..7e61e3603 100644 --- a/src/daemonizer/windows_daemonizer.inl +++ b/src/daemonizer/windows_daemonizer.inl @@ -31,6 +31,7 @@ #include "common/util.h" #include "daemonizer/windows_service.h" #include "daemonizer/windows_service_runner.h" +#include "cryptonote_core/cryptonote_core.h" #include <shlobj.h> #include <boost/filesystem/operations.hpp> diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index 8f446f42a..727134f75 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -58,12 +58,6 @@ endif() set(device_private_headers) -if(PER_BLOCK_CHECKPOINT) - set(Blocks "blocks") -else() - set(Blocks "") -endif() - monero_private_headers(device ${device_private_headers}) @@ -79,5 +73,4 @@ target_link_libraries(device ringct_basic ${OPENSSL_CRYPTO_LIBRARIES} PRIVATE - ${Blocks} ${EXTRA_LIBRARIES}) diff --git a/src/device/device_io_hid.cpp b/src/device/device_io_hid.cpp index 562aca8b8..666255cb3 100644 --- a/src/device/device_io_hid.cpp +++ b/src/device/device_io_hid.cpp @@ -13,6 +13,7 @@ // #if defined(HAVE_HIDAPI) +#include <boost/scope_exit.hpp> #include "log.hpp" #include "device_io_hid.hpp" @@ -69,11 +70,47 @@ namespace hw { void device_io_hid::connect(void *params) { hid_conn_params *p = (struct hid_conn_params*)params; - this->connect(p->vid, p->pid, p->interface_number, p->usage_page, p->interface_OR_page); + this->connect(p->vid, p->pid, p->interface_number, p->usage_page); } - void device_io_hid::connect(unsigned int vid, unsigned int pid, unsigned int interface_number, unsigned int usage_page, bool interface_OR_page ) { - hid_device_info *hwdev_info, *hwdev_info_list; + hid_device_info *device_io_hid::find_device(hid_device_info *devices_list, boost::optional<int> interface_number, boost::optional<unsigned short> usage_page) { + bool select_any = !interface_number && !usage_page; + + MDEBUG( "Looking for " << + (select_any ? "any HID Device" : "HID Device with") << + (interface_number ? (" interface_number " + std::to_string(interface_number.value())) : "") << + ((interface_number && usage_page) ? " or" : "") << + (usage_page ? (" usage_page " + std::to_string(usage_page.value())) : "")); + + hid_device_info *result = nullptr; + for (; devices_list != nullptr; devices_list = devices_list->next) { + BOOST_SCOPE_EXIT(&devices_list, &result) { + MDEBUG( (result == devices_list ? "SELECTED" : "SKIPPED ") << + " HID Device" << + " path " << safe_hid_path(devices_list) << + " interface_number " << devices_list->interface_number << + " usage_page " << devices_list->usage_page); + } + BOOST_SCOPE_EXIT_END + + if (result != nullptr) { + continue; + } + + if (select_any) { + result = devices_list; + } else if (interface_number && devices_list->interface_number == interface_number.value()) { + result = devices_list; + } else if (usage_page && devices_list->usage_page == usage_page.value()) { + result = devices_list; + } + } + + return result; + } + + void device_io_hid::connect(unsigned int vid, unsigned int pid, boost::optional<int> interface_number, boost::optional<unsigned short> usage_page) { + hid_device_info *hwdev_info_list; hid_device *hwdev; this->disconnect(); @@ -81,17 +118,8 @@ namespace hw { hwdev_info_list = hid_enumerate(vid, pid); ASSERT_X(hwdev_info_list, "Unable to enumerate device "+std::to_string(vid)+":"+std::to_string(vid)+ ": "+ safe_hid_error(this->usb_device)); hwdev = NULL; - hwdev_info = hwdev_info_list; - while (hwdev_info) { - if ((interface_OR_page && ((usage_page == 0xffa0) || (interface_number == 0))) || - ((usage_page == 0xffa0) && (interface_number == 0)) ) { - MDEBUG("HID Device found: " << safe_hid_path(hwdev_info)); - hwdev = hid_open_path(hwdev_info->path); - break; - } else { - MDEBUG("HID Device discard: " << safe_hid_path(hwdev_info) << "("+std::to_string(hwdev_info->usage_page) << "," << std::to_string(hwdev_info->interface_number) << ")"); - } - hwdev_info = hwdev_info->next; + if (hid_device_info *device = find_device(hwdev_info_list, interface_number, usage_page)) { + hwdev = hid_open_path(device->path); } hid_free_enumeration(hwdev_info_list); ASSERT_X(hwdev, "Unable to open device "+std::to_string(pid)+":"+std::to_string(vid)); diff --git a/src/device/device_io_hid.hpp b/src/device/device_io_hid.hpp index 6fd15a1d1..bb0f0a814 100644 --- a/src/device/device_io_hid.hpp +++ b/src/device/device_io_hid.hpp @@ -29,6 +29,7 @@ #if defined(HAVE_HIDAPI) +#include <boost/optional/optional.hpp> #include <hidapi/hidapi.h> #include "device_io.hpp" @@ -52,9 +53,8 @@ namespace hw { struct hid_conn_params { unsigned int vid; unsigned int pid; - unsigned int interface_number; - unsigned int usage_page; - bool interface_OR_page ; + int interface_number; + unsigned short usage_page; }; @@ -82,13 +82,11 @@ namespace hw { unsigned int wrapCommand(const unsigned char *command, size_t command_len, unsigned char *out, size_t out_len); unsigned int unwrapReponse(const unsigned char *data, size_t data_len, unsigned char *out, size_t out_len); + hid_device_info *find_device(hid_device_info *devices_list, boost::optional<int> interface_number, boost::optional<unsigned short> usage_page); public: bool hid_verbose = false; - static const unsigned int OR_SELECT = 1; - static const unsigned int AND_SELECT = 2; - static const unsigned short DEFAULT_CHANNEL = 0x0001; static const unsigned char DEFAULT_TAG = 0x01; static const unsigned int DEFAULT_PACKET_SIZE = 64; @@ -100,7 +98,7 @@ namespace hw { void init(); void connect(void *params); - void connect(unsigned int vid, unsigned int pid, unsigned int interface_number, unsigned int usage_page, bool interface_OR_page ); + 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); void disconnect(); diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp index a17784960..d879ee95a 100644 --- a/src/device/device_ledger.cpp +++ b/src/device/device_ledger.cpp @@ -340,7 +340,7 @@ namespace hw { bool device_ledger::connect(void) { this->disconnect(); - hw_device.connect(0x2c97,0x0001, 0, 0xffa0, hw_device.OR_SELECT); + hw_device.connect(0x2c97, 0x0001, 0, 0xffa0); this->reset(); #ifdef DEBUG_HWDEVICE cryptonote::account_public_address pubkey; diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index 9390626a8..a61b6107f 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -655,10 +655,14 @@ namespace nodetool { kill(); m_peerlist.deinit(); - m_net_server.deinit_server(); - // remove UPnP port mapping - if(!m_no_igd) - delete_upnp_port_mapping(m_listening_port); + + if (!m_offline) + { + m_net_server.deinit_server(); + // remove UPnP port mapping + if(!m_no_igd) + delete_upnp_port_mapping(m_listening_port); + } return store_config(); } //----------------------------------------------------------------------------------- @@ -2042,7 +2046,7 @@ namespace nodetool char lanAddress[64]; result = UPNP_GetValidIGD(deviceList, &urls, &igdData, lanAddress, sizeof lanAddress); freeUPNPDevlist(deviceList); - if (result != 0) { + if (result > 0) { if (result == 1) { std::ostringstream portString; portString << port; @@ -2088,7 +2092,7 @@ namespace nodetool char lanAddress[64]; result = UPNP_GetValidIGD(deviceList, &urls, &igdData, lanAddress, sizeof lanAddress); freeUPNPDevlist(deviceList); - if (result != 0) { + if (result > 0) { if (result == 1) { std::ostringstream portString; portString << port; diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index d8f556d3e..aa9d3d64b 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -212,23 +212,15 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - static cryptonote::blobdata get_pruned_tx_blob(cryptonote::transaction &tx) - { - std::stringstream ss; - binary_archive<true> ba(ss); - bool r = tx.serialize_base(ba); - CHECK_AND_ASSERT_MES(r, cryptonote::blobdata(), "Failed to serialize rct signatures base"); - return ss.str(); - } - //------------------------------------------------------------------------------------------------------------------------------ - static cryptonote::blobdata get_pruned_tx_json(cryptonote::transaction &tx) - { - std::stringstream ss; - json_archive<true> ar(ss); - bool r = tx.serialize_base(ar); - CHECK_AND_ASSERT_MES(r, cryptonote::blobdata(), "Failed to serialize rct signatures base"); - return ss.str(); - } + class pruned_transaction { + transaction& tx; + public: + pruned_transaction(transaction& tx) : tx(tx) {} + BEGIN_SERIALIZE_OBJECT() + bool r = tx.serialize_base(ar); + if (!r) return false; + END_SERIALIZE() + }; //------------------------------------------------------------------------------------------------------------------------------ bool core_rpc_server::on_get_blocks(const COMMAND_RPC_GET_BLOCKS_FAST::request& req, COMMAND_RPC_GET_BLOCKS_FAST::response& res) { @@ -564,10 +556,11 @@ namespace cryptonote crypto::hash tx_hash = *vhi++; e.tx_hash = *txhi++; - blobdata blob = req.prune ? get_pruned_tx_blob(tx) : t_serializable_object_to_blob(tx); + 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 ? get_pruned_tx_json(tx) : obj_to_json_str(tx); + e.as_json = req.prune ? obj_to_json_str(pruned_tx) : obj_to_json_str(tx); e.in_pool = pool_tx_hashes.find(tx_hash) != pool_tx_hashes.end(); if (e.in_pool) { @@ -924,6 +917,8 @@ namespace cryptonote return r; m_core.get_pool_transactions_and_spent_keys_info(res.transactions, res.spent_key_images, !request_has_rpc_origin || !m_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; } @@ -2118,6 +2113,8 @@ namespace cryptonote try { + // 0 is placeholder for the whole chain + const uint64_t req_to_height = req.to_height ? req.to_height : (m_core.get_current_blockchain_height() - 1); for (uint64_t amount: req.amounts) { static struct D @@ -2130,7 +2127,7 @@ namespace cryptonote } d; boost::unique_lock<boost::mutex> lock(d.mutex); - if (d.cached && amount == 0 && d.cached_from == req.from_height && d.cached_to == req.to_height) + if (d.cached && amount == 0 && d.cached_from == req.from_height && d.cached_to == req_to_height) { res.distributions.push_back({amount, d.cached_start_height, req.binary, d.cached_distribution, d.cached_base}); if (!req.cumulative) @@ -2145,23 +2142,23 @@ namespace cryptonote std::vector<uint64_t> distribution; uint64_t start_height, base; - if (!m_core.get_output_distribution(amount, req.from_height, req.to_height, start_height, distribution, base)) + if (!m_core.get_output_distribution(amount, req.from_height, req_to_height, start_height, distribution, base)) { error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; error_resp.message = "Failed to get rct distribution"; return false; } - if (req.to_height > 0 && req.to_height >= req.from_height) + if (req_to_height > 0 && req_to_height >= req.from_height) { uint64_t offset = std::max(req.from_height, start_height); - if (offset <= req.to_height && req.to_height - offset + 1 < distribution.size()) - distribution.resize(req.to_height - offset + 1); + if (offset <= req_to_height && req_to_height - offset + 1 < distribution.size()) + distribution.resize(req_to_height - offset + 1); } if (amount == 0) { d.cached_from = req.from_height; - d.cached_to = req.to_height; + d.cached_to = req_to_height; d.cached_distribution = distribution; d.cached_start_height = start_height; d.cached_base = base; diff --git a/src/rpc/daemon_messages.h b/src/rpc/daemon_messages.h index 8fff369df..be3138e3b 100644 --- a/src/rpc/daemon_messages.h +++ b/src/rpc/daemon_messages.h @@ -67,7 +67,7 @@ class classname \ // NOTE: when using a type with multiple template parameters, // replace any comma in the template specifier with the macro // above, or the preprocessor will eat the comma in a bad way. -#define RPC_MESSAGE_MEMBER(type, name) type name; +#define RPC_MESSAGE_MEMBER(type, name) type name = type{} namespace cryptonote diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 47b77abc6..3d92b2823 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -1640,7 +1640,7 @@ bool simple_wallet::blackball(const std::vector<std::string> &args) uint64_t amount = std::numeric_limits<uint64_t>::max(), offset, num_offsets; if (args.size() == 0) { - fail_msg_writer() << tr("usage: blackball <amount>/<offset> | <filename> [add]"); + fail_msg_writer() << tr("usage: mark_output_spent <amount>/<offset> | <filename> [add]"); return true; } @@ -1718,7 +1718,7 @@ bool simple_wallet::blackball(const std::vector<std::string> &args) } catch (const std::exception &e) { - fail_msg_writer() << tr("Failed to blackball output: ") << e.what(); + fail_msg_writer() << tr("Failed to mark output spent: ") << e.what(); } return true; @@ -1729,7 +1729,7 @@ bool simple_wallet::unblackball(const std::vector<std::string> &args) std::pair<uint64_t, uint64_t> output; if (args.size() != 1) { - fail_msg_writer() << tr("usage: unblackball <amount>/<offset>"); + fail_msg_writer() << tr("usage: mark_output_unspent <amount>/<offset>"); return true; } @@ -1745,7 +1745,7 @@ bool simple_wallet::unblackball(const std::vector<std::string> &args) } catch (const std::exception &e) { - fail_msg_writer() << tr("Failed to unblackball output: ") << e.what(); + fail_msg_writer() << tr("Failed to mark output unspent: ") << e.what(); } return true; @@ -1756,7 +1756,7 @@ bool simple_wallet::blackballed(const std::vector<std::string> &args) std::pair<uint64_t, uint64_t> output; if (args.size() != 1) { - fail_msg_writer() << tr("usage: blackballed <amount>/<offset>"); + fail_msg_writer() << tr("usage: is_output_spent <amount>/<offset>"); return true; } @@ -1769,13 +1769,13 @@ bool simple_wallet::blackballed(const std::vector<std::string> &args) try { if (m_wallet->is_output_blackballed(output)) - message_writer() << tr("Blackballed: ") << output.first << "/" << output.second; + message_writer() << tr("Spent: ") << output.first << "/" << output.second; else - message_writer() << tr("not blackballed: ") << output.first << "/" << output.second; + message_writer() << tr("Not spent: ") << output.first << "/" << output.second; } catch (const std::exception &e) { - fail_msg_writer() << tr("Failed to unblackball output: ") << e.what(); + fail_msg_writer() << tr("Failed to check whether output is spent: ") << e.what(); } return true; @@ -2599,18 +2599,18 @@ simple_wallet::simple_wallet() boost::bind(&simple_wallet::save_known_rings, this, _1), tr("save_known_rings"), tr("Save known rings to the shared rings database")); - m_cmd_binder.set_handler("blackball", + m_cmd_binder.set_handler("mark_output_spent", boost::bind(&simple_wallet::blackball, this, _1), - tr("blackball <amount>/<offset> | <filename> [add]"), - tr("Blackball output(s) so they never get selected as fake outputs in a ring")); - m_cmd_binder.set_handler("unblackball", + tr("mark_output_spent <amount>/<offset> | <filename> [add]"), + tr("Mark output(s) as spent so they never get selected as fake outputs in a ring")); + m_cmd_binder.set_handler("mark_output_unspent", boost::bind(&simple_wallet::unblackball, this, _1), - tr("unblackball <amount>/<offset>"), - tr("Unblackballs an output so it may get selected as a fake output in a ring")); - m_cmd_binder.set_handler("blackballed", + tr("mark_output_unspent <amount>/<offset>"), + tr("Marks an output as unspent so it may get selected as a fake output in a ring")); + m_cmd_binder.set_handler("is_output_spent", boost::bind(&simple_wallet::blackballed, this, _1), - tr("blackballed <amount>/<offset>"), - tr("Checks whether an output is blackballed")); + tr("is_output_spent <amount>/<offset>"), + tr("Checks whether an output is marked as spent")); m_cmd_binder.set_handler("version", boost::bind(&simple_wallet::version, this, _1), tr("version"), @@ -4715,8 +4715,6 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri if (!try_connect_to_daemon()) return true; - SCOPED_WALLET_UNLOCK(); - std::vector<std::string> local_args = args_; std::set<uint32_t> subaddr_indices; @@ -4936,6 +4934,8 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri } } + SCOPED_WALLET_UNLOCK(); + try { // figure out what tx will be necessary @@ -7050,12 +7050,6 @@ bool simple_wallet::run() void simple_wallet::stop() { m_cmd_binder.stop_handling(); - - m_idle_run.store(false, std::memory_order_relaxed); - m_wallet->stop(); - // make the background refresh thread quit - boost::unique_lock<boost::mutex> lock(m_idle_mutex); - m_idle_cond.notify_one(); } //---------------------------------------------------------------------------------------------------- bool simple_wallet::account(const std::vector<std::string> &args/* = std::vector<std::string>()*/) diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index de1bfdae1..ddf2d74ff 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -381,6 +381,7 @@ WalletImpl::WalletImpl(NetworkType nettype, uint64_t kdf_rounds) , m_synchronized(false) , m_rebuildWalletCache(false) , m_is_connected(false) + , m_refreshShouldRescan(false) { m_wallet.reset(new tools::wallet2(static_cast<cryptonote::network_type>(nettype), kdf_rounds, true)); m_history.reset(new TransactionHistoryImpl(this)); @@ -776,7 +777,7 @@ bool WalletImpl::setPassword(const std::string &password) { clearStatus(); try { - m_wallet->rewrite(m_wallet->get_wallet_file(), password); + m_wallet->change_password(m_wallet->get_wallet_file(), m_password, password); m_password = password; } catch (const std::exception &e) { setStatusError(e.what()); @@ -1011,6 +1012,20 @@ void WalletImpl::refreshAsync() m_refreshCV.notify_one(); } +bool WalletImpl::rescanBlockchain() +{ + clearStatus(); + m_refreshShouldRescan = true; + doRefresh(); + return status() == Status_Ok; +} + +void WalletImpl::rescanBlockchainAsync() +{ + m_refreshShouldRescan = true; + refreshAsync(); +} + void WalletImpl::setAutoRefreshInterval(int millis) { if (millis > MAX_REFRESH_INTERVAL_MILLIS) { @@ -1984,6 +1999,7 @@ void WalletImpl::refreshThreadFunc() LOG_PRINT_L3(__FUNCTION__ << ": refresh lock acquired..."); LOG_PRINT_L3(__FUNCTION__ << ": m_refreshEnabled: " << m_refreshEnabled); LOG_PRINT_L3(__FUNCTION__ << ": m_status: " << status()); + LOG_PRINT_L3(__FUNCTION__ << ": m_refreshShouldRescan: " << m_refreshShouldRescan); if (m_refreshEnabled) { LOG_PRINT_L3(__FUNCTION__ << ": refreshing..."); doRefresh(); @@ -1994,12 +2010,16 @@ void WalletImpl::refreshThreadFunc() void WalletImpl::doRefresh() { + bool rescan = m_refreshShouldRescan.exchange(false); // synchronizing async and sync refresh calls boost::lock_guard<boost::mutex> guarg(m_refreshMutex2); - try { + do try { + LOG_PRINT_L3(__FUNCTION__ << ": doRefresh, rescan = "<<rescan); // Syncing daemon and refreshing wallet simultaneously is very resource intensive. // Disable refresh if wallet is disconnected or daemon isn't synced. if (m_wallet->light_wallet() || daemonSynced()) { + if(rescan) + m_wallet->rescan_blockchain(false); m_wallet->refresh(trustedDaemon()); if (!m_synchronized) { m_synchronized = true; @@ -2016,7 +2036,9 @@ void WalletImpl::doRefresh() } } catch (const std::exception &e) { setStatusError(e.what()); - } + break; + }while(!rescan && (rescan=m_refreshShouldRescan.exchange(false))); // repeat if not rescanned and rescan was requested + if (m_wallet2Callback->getListener()) { m_wallet2Callback->getListener()->refreshed(); } @@ -2161,7 +2183,7 @@ bool WalletImpl::blackballOutputs(const std::vector<std::string> &outputs, bool bool ret = m_wallet->set_blackballed_outputs(raw_outputs, add); if (!ret) { - setStatusError(tr("Failed to set blackballed outputs")); + setStatusError(tr("Failed to mark outputs as spent")); return false; } return true; @@ -2183,7 +2205,7 @@ bool WalletImpl::blackballOutput(const std::string &amount, const std::string &o bool ret = m_wallet->blackball_output(std::make_pair(raw_amount, raw_offset)); if (!ret) { - setStatusError(tr("Failed to blackball output")); + setStatusError(tr("Failed to mark output as spent")); return false; } return true; @@ -2205,7 +2227,7 @@ bool WalletImpl::unblackballOutput(const std::string &amount, const std::string bool ret = m_wallet->unblackball_output(std::make_pair(raw_amount, raw_offset)); if (!ret) { - setStatusError(tr("Failed to unblackball output")); + setStatusError(tr("Failed to mark output as unspent")); return false; } return true; diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index 6d343888b..b4637b8e6 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -114,6 +114,8 @@ public: bool synchronized() const override; bool refresh() override; void refreshAsync() override; + bool rescanBlockchain() override; + void rescanBlockchainAsync() override; void setAutoRefreshInterval(int millis) override; int autoRefreshInterval() const override; void setRefreshFromBlockHeight(uint64_t refresh_from_block_height) override; @@ -232,6 +234,7 @@ private: std::atomic<bool> m_refreshEnabled; std::atomic<bool> m_refreshThreadDone; std::atomic<int> m_refreshIntervalMillis; + std::atomic<bool> m_refreshShouldRescan; // synchronizing refresh loop; boost::mutex m_refreshMutex; diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index ec1a84877..82627de29 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -644,6 +644,17 @@ struct Wallet virtual void refreshAsync() = 0; /** + * @brief rescanBlockchain - rescans the wallet, updating transactions from daemon + * @return - true if refreshed successfully; + */ + virtual bool rescanBlockchain() = 0; + + /** + * @brief rescanBlockchainAsync - rescans wallet asynchronously, starting from genesys + */ + virtual void rescanBlockchainAsync() = 0; + + /** * @brief setAutoRefreshInterval - setup interval for automatic refresh. * @param seconds - interval in millis. if zero or less than zero - automatic refresh disabled; */ diff --git a/src/wallet/ringdb.cpp b/src/wallet/ringdb.cpp index e5995e7fb..f562d6c06 100644 --- a/src/wallet/ringdb.cpp +++ b/src/wallet/ringdb.cpp @@ -412,13 +412,13 @@ bool ringdb::blackball_worker(const std::vector<std::pair<uint64_t, uint64_t>> & switch (op) { case BLACKBALL_BLACKBALL: - MDEBUG("Blackballing output " << output.first << "/" << output.second); + MDEBUG("Marking output " << output.first << "/" << output.second << " as spent"); dbr = mdb_cursor_put(cursor, &key, &data, MDB_APPENDDUP); if (dbr == MDB_KEYEXIST) dbr = 0; break; case BLACKBALL_UNBLACKBALL: - MDEBUG("Unblackballing output " << output.first << "/" << output.second); + MDEBUG("Marking output " << output.first << "/" << output.second << " as unspent"); dbr = mdb_cursor_get(cursor, &key, &data, MDB_GET_BOTH); if (dbr == 0) dbr = mdb_cursor_del(cursor, 0); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index fae972cf8..37b60c5d7 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -37,6 +37,8 @@ #include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/trim.hpp> #include <boost/algorithm/string/split.hpp> +#include <boost/algorithm/string/join.hpp> +#include <boost/range/adaptor/transformed.hpp> #include "include_base_utils.h" using namespace epee; @@ -121,6 +123,8 @@ using namespace cryptonote; #define FIRST_REFRESH_GRANULARITY 1024 +#define GAMMA_PICK_HALF_WINDOW 5 + static const std::string MULTISIG_SIGNATURE_MAGIC = "SigMultisigPkV1"; static const std::string MULTISIG_EXTRA_INFO_MAGIC = "MultisigxV1"; @@ -5612,6 +5616,10 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector<wallet2::pendin ptx.construction_data = sd; txs.push_back(ptx); + + // add tx keys only to ptx + txs.back().tx_key = tx_key; + txs.back().additional_tx_keys = additional_tx_keys; } // add key images @@ -6797,10 +6805,29 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> error::get_output_distribution, "Decreasing offsets in rct distribution: " + std::to_string(block_offset) + ": " + std::to_string(rct_offsets[block_offset]) + ", " + std::to_string(block_offset + 1) + ": " + std::to_string(rct_offsets[block_offset + 1])); - uint64_t n_rct = rct_offsets[block_offset + 1] - rct_offsets[block_offset]; + uint64_t first_block_offset = block_offset, last_block_offset = block_offset; + for (size_t half_window = 0; half_window < GAMMA_PICK_HALF_WINDOW; ++half_window) + { + // end when we have a non empty block + uint64_t cum0 = first_block_offset > 0 ? rct_offsets[first_block_offset] - rct_offsets[first_block_offset - 1] : rct_offsets[0]; + if (cum0 > 1) + break; + uint64_t cum1 = last_block_offset > 0 ? rct_offsets[last_block_offset] - rct_offsets[last_block_offset - 1] : rct_offsets[0]; + if (cum1 > 1) + break; + if (first_block_offset == 0 && last_block_offset >= rct_offsets.size() - 2) + break; + // expand up to bounds + if (first_block_offset > 0) + --first_block_offset; + if (last_block_offset < rct_offsets.size() - 1) + ++last_block_offset; + } + const uint64_t n_rct = rct_offsets[last_block_offset] - (first_block_offset == 0 ? 0 : rct_offsets[first_block_offset - 1]); if (n_rct == 0) return rct_offsets[block_offset] ? rct_offsets[block_offset] - 1 : 0; - return rct_offsets[block_offset] + crypto::rand<uint64_t>() % n_rct; + MDEBUG("Picking 1/" << n_rct << " in " << (last_block_offset - first_block_offset + 1) << " blocks centered around " << block_offset); + return rct_offsets[first_block_offset] + crypto::rand<uint64_t>() % n_rct; }; size_t num_selected_transfers = 0; @@ -6970,6 +6997,8 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> LOG_PRINT_L1("Selecting real output: " << td.m_global_output_index << " for " << print_money(amount)); } + std::unordered_map<const char*, std::set<uint64_t>> picks; + // while we still need more mixins uint64_t num_usable_outs = num_outs; bool allow_blackballed = false; @@ -6984,7 +7013,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> // outputs, we still need to reach the minimum ring size) if (allow_blackballed) break; - MINFO("Not enough non blackballed outputs, we'll allow blackballed ones"); + MINFO("Not enough output not marked as spent, we'll allow outputs marked as spent"); allow_blackballed = true; num_usable_outs = num_outs; } @@ -7068,11 +7097,15 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> } seen_indices.emplace(i); - LOG_PRINT_L2("picking " << i << " as " << type); + picks[type].insert(i); req.outputs.push_back({amount, i}); ++num_found; } + for (const auto &pick: picks) + MDEBUG("picking " << pick.first << " outputs: " << + boost::join(pick.second | boost::adaptors::transformed([](uint64_t out){return std::to_string(out);}), " ")); + // if we had enough unusable outputs, we might fall off here and still // have too few outputs, so we stuff with one to keep counts good, and // we'll error out later @@ -7088,8 +7121,15 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> [](const get_outputs_out &a, const get_outputs_out &b) { return a.index < b.index; }); } - for (auto i: req.outputs) - LOG_PRINT_L1("asking for output " << i.index << " for " << print_money(i.amount)); + if (ELPP->vRegistry()->allowed(el::Level::Debug, MONERO_DEFAULT_LOG_CATEGORY)) + { + std::map<uint64_t, std::set<uint64_t>> outs; + for (const auto &i: req.outputs) + outs[i.amount].insert(i.index); + for (const auto &o: outs) + MDEBUG("asking for outputs with amount " << print_money(o.first) << ": " << + boost::join(o.second | boost::adaptors::transformed([](uint64_t out){return std::to_string(out);}), " ")); + } // get the keys for those m_daemon_rpc_mutex.lock(); @@ -10547,7 +10587,7 @@ uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_imag + boost::lexical_cast<std::string>(signed_key_images.size()) + ", key image " + epee::string_tools::pod_to_hex(key_image)); THROW_WALLET_EXCEPTION_IF(!crypto::check_ring_signature((const crypto::hash&)key_image, key_image, pkeys, &signature), - error::wallet_internal_error, "Signature check failed: input " + boost::lexical_cast<std::string>(n) + "/" + error::signature_check_failed, boost::lexical_cast<std::string>(n) + "/" + boost::lexical_cast<std::string>(signed_key_images.size()) + ", key image " + epee::string_tools::pod_to_hex(key_image) + ", signature " + epee::string_tools::pod_to_hex(signature) + ", pubkey " + epee::string_tools::pod_to_hex(*pkeys[0])); diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h index bc518d04a..b3141985d 100644 --- a/src/wallet/wallet_errors.h +++ b/src/wallet/wallet_errors.h @@ -72,6 +72,7 @@ namespace tools // tx_parse_error // get_tx_pool_error // out_of_hashchain_bounds_error + // signature_check_failed // transfer_error * // get_outs_general_error // not_enough_unlocked_money @@ -418,6 +419,14 @@ namespace tools std::string to_string() const { return refresh_error::to_string(); } }; //---------------------------------------------------------------------------------------------------- + struct signature_check_failed : public wallet_logic_error + { + explicit signature_check_failed(std::string&& loc, const std::string& message) + : wallet_logic_error(std::move(loc), "Signature check failed " + message) + { + } + }; + //---------------------------------------------------------------------------------------------------- struct transfer_error : public wallet_logic_error { protected: diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index e0b631aaf..6dbea2e14 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -981,6 +981,8 @@ namespace tools for (auto &ptx: ptxs) { res.tx_hash_list.push_back(epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(ptx.tx))); + if (req.get_tx_keys) + res.tx_key_list.push_back(epee::string_tools::pod_to_hex(ptx.tx_key)); } if (req.export_raw) @@ -994,6 +996,171 @@ 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) + { + if (!m_wallet) return not_open(er); + if (m_restricted) + { + er.code = WALLET_RPC_ERROR_CODE_DENIED; + er.message = "Command unavailable in restricted mode."; + return false; + } + if (m_wallet->key_on_device()) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = "command not supported by HW wallet"; + return false; + } + if(m_wallet->watch_only()) + { + er.code = WALLET_RPC_ERROR_CODE_WATCH_ONLY; + er.message = "command not supported by watch-only wallet"; + return false; + } + + tools::wallet2::unsigned_tx_set exported_txs; + try + { + cryptonote::blobdata blob; + if (!epee::string_tools::parse_hexstr_to_binbuff(req.unsigned_txset, blob)) + { + er.code = WALLET_RPC_ERROR_CODE_BAD_HEX; + er.message = "Failed to parse hex."; + return false; + } + if(!m_wallet->parse_unsigned_tx_from_str(blob, exported_txs)) + { + er.code = WALLET_RPC_ERROR_CODE_BAD_UNSIGNED_TX_DATA; + er.message = "cannot load unsigned_txset"; + return false; + } + } + catch (const std::exception &e) + { + er.code = WALLET_RPC_ERROR_CODE_BAD_UNSIGNED_TX_DATA; + er.message = "failed to parse unsigned transfers: " + std::string(e.what()); + return false; + } + + std::vector<tools::wallet2::pending_tx> ptx; + try + { + // gather info to ask the user + std::unordered_map<cryptonote::account_public_address, std::pair<std::string, uint64_t>> dests; + int first_known_non_zero_change_index = -1; + for (size_t n = 0; n < exported_txs.txes.size(); ++n) + { + const tools::wallet2::tx_construction_data &cd = exported_txs.txes[n]; + res.desc.push_back({0, 0, std::numeric_limits<uint32_t>::max(), 0, {}, "", 0, "", 0, 0, ""}); + wallet_rpc::COMMAND_RPC_DESCRIBE_TRANSFER::transfer_description &desc = res.desc.back(); + + std::vector<cryptonote::tx_extra_field> tx_extra_fields; + bool has_encrypted_payment_id = false; + crypto::hash8 payment_id8 = crypto::null_hash8; + if (cryptonote::parse_tx_extra(cd.extra, tx_extra_fields)) + { + cryptonote::tx_extra_nonce extra_nonce; + if (find_tx_extra_field_by_type(tx_extra_fields, extra_nonce)) + { + crypto::hash payment_id; + if(cryptonote::get_encrypted_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id8)) + { + desc.payment_id = epee::string_tools::pod_to_hex(payment_id8); + has_encrypted_payment_id = true; + } + else if (cryptonote::get_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id)) + { + desc.payment_id = epee::string_tools::pod_to_hex(payment_id); + } + } + } + + for (size_t s = 0; s < cd.sources.size(); ++s) + { + desc.amount_in += cd.sources[s].amount; + size_t ring_size = cd.sources[s].outputs.size(); + if (ring_size < desc.ring_size) + desc.ring_size = ring_size; + } + for (size_t d = 0; d < cd.splitted_dsts.size(); ++d) + { + const cryptonote::tx_destination_entry &entry = cd.splitted_dsts[d]; + std::string address = cryptonote::get_account_address_as_str(m_wallet->nettype(), entry.is_subaddress, entry.addr); + if (has_encrypted_payment_id && !entry.is_subaddress) + address = cryptonote::get_account_integrated_address_as_str(m_wallet->nettype(), entry.addr, payment_id8); + auto i = dests.find(entry.addr); + if (i == dests.end()) + dests.insert(std::make_pair(entry.addr, std::make_pair(address, entry.amount))); + else + i->second.second += entry.amount; + desc.amount_out += entry.amount; + } + if (cd.change_dts.amount > 0) + { + auto it = dests.find(cd.change_dts.addr); + if (it == dests.end()) + { + er.code = WALLET_RPC_ERROR_CODE_BAD_UNSIGNED_TX_DATA; + er.message = "Claimed change does not go to a paid address"; + return false; + } + if (it->second.second < cd.change_dts.amount) + { + er.code = WALLET_RPC_ERROR_CODE_BAD_UNSIGNED_TX_DATA; + er.message = "Claimed change is larger than payment to the change address"; + return false; + } + if (cd.change_dts.amount > 0) + { + if (first_known_non_zero_change_index == -1) + first_known_non_zero_change_index = n; + const tools::wallet2::tx_construction_data &cdn = exported_txs.txes[first_known_non_zero_change_index]; + if (memcmp(&cd.change_dts.addr, &cdn.change_dts.addr, sizeof(cd.change_dts.addr))) + { + er.code = WALLET_RPC_ERROR_CODE_BAD_UNSIGNED_TX_DATA; + er.message = "Change goes to more than one address"; + return false; + } + } + desc.change_amount += cd.change_dts.amount; + it->second.second -= cd.change_dts.amount; + if (it->second.second == 0) + dests.erase(cd.change_dts.addr); + } + + size_t n_dummy_outputs = 0; + for (auto i = dests.begin(); i != dests.end(); ) + { + if (i->second.second > 0) + { + desc.recipients.push_back({i->second.first, i->second.second}); + } + else + ++desc.dummy_outputs; + ++i; + } + + if (desc.change_amount > 0) + { + const tools::wallet2::tx_construction_data &cd0 = exported_txs.txes[0]; + desc.change_address = get_account_address_as_str(m_wallet->nettype(), cd0.subaddr_account > 0, cd0.change_dts.addr); + } + + desc.fee = desc.amount_in - desc.amount_out; + desc.unlock_time = cd.unlock_time; + desc.extra = epee::to_hex::string({cd.extra.data(), cd.extra.size()}); + } + } + catch (const std::exception &e) + { + er.code = WALLET_RPC_ERROR_CODE_BAD_UNSIGNED_TX_DATA; + er.message = "failed to parse unsigned transfers"; + return false; + } + + 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) { if (!m_wallet) return not_open(er); @@ -2822,8 +2989,7 @@ namespace tools { try { - m_wallet->rewrite(m_wallet->get_wallet_file(), req.new_password); - m_wallet->store(); + m_wallet->change_password(m_wallet->get_wallet_file(), req.old_password, req.new_password); LOG_PRINT_L0("Wallet password changed."); } catch (const std::exception& e) @@ -2906,6 +3072,11 @@ namespace tools er.code = WALLET_RPC_ERROR_CODE_ADDRESS_INDEX_OUT_OF_BOUNDS; er.message = e.what(); } + catch (const error::signature_check_failed& e) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_SIGNATURE; + er.message = e.what(); + } catch (const std::exception& e) { er.code = default_error_code; diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index 35ea11902..887723ed5 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -87,6 +87,7 @@ namespace tools MAP_JON_RPC_WE("transfer", on_transfer, wallet_rpc::COMMAND_RPC_TRANSFER) MAP_JON_RPC_WE("transfer_split", on_transfer_split, wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT) MAP_JON_RPC_WE("sign_transfer", on_sign_transfer, wallet_rpc::COMMAND_RPC_SIGN_TRANSFER) + MAP_JON_RPC_WE("describe_transfer", on_describe_transfer, wallet_rpc::COMMAND_RPC_DESCRIBE_TRANSFER) MAP_JON_RPC_WE("submit_transfer", on_submit_transfer, wallet_rpc::COMMAND_RPC_SUBMIT_TRANSFER) MAP_JON_RPC_WE("sweep_dust", on_sweep_dust, wallet_rpc::COMMAND_RPC_SWEEP_DUST) MAP_JON_RPC_WE("sweep_unmixable", on_sweep_dust, wallet_rpc::COMMAND_RPC_SWEEP_DUST) @@ -167,6 +168,7 @@ namespace tools 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); diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index 2377b69e3..924f3a0f1 100644 --- a/src/wallet/wallet_rpc_server_commands_defs.h +++ b/src/wallet/wallet_rpc_server_commands_defs.h @@ -47,7 +47,7 @@ // advance which version they will stop working with // Don't go over 32767 for any of these #define WALLET_RPC_VERSION_MAJOR 1 -#define WALLET_RPC_VERSION_MINOR 4 +#define WALLET_RPC_VERSION_MINOR 5 #define MAKE_WALLET_RPC_VERSION(major,minor) (((major)<<16)|(minor)) #define WALLET_RPC_VERSION MAKE_WALLET_RPC_VERSION(WALLET_RPC_VERSION_MAJOR, WALLET_RPC_VERSION_MINOR) namespace tools @@ -531,16 +531,79 @@ namespace wallet_rpc }; }; + struct COMMAND_RPC_DESCRIBE_TRANSFER + { + struct recipient + { + std::string address; + uint64_t amount; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(address) + KV_SERIALIZE(amount) + END_KV_SERIALIZE_MAP() + }; + + struct transfer_description + { + uint64_t amount_in; + uint64_t amount_out; + uint32_t ring_size; + uint64_t unlock_time; + std::list<recipient> recipients; + std::string payment_id; + uint64_t change_amount; + std::string change_address; + uint64_t fee; + uint32_t dummy_outputs; + std::string extra; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(amount_in) + KV_SERIALIZE(amount_out) + KV_SERIALIZE(ring_size) + KV_SERIALIZE(unlock_time) + KV_SERIALIZE(recipients) + KV_SERIALIZE(payment_id) + KV_SERIALIZE(change_amount) + KV_SERIALIZE(change_address) + KV_SERIALIZE(fee) + KV_SERIALIZE(dummy_outputs) + KV_SERIALIZE(extra) + END_KV_SERIALIZE_MAP() + }; + + struct request + { + std::string unsigned_txset; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(unsigned_txset) + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::list<transfer_description> desc; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(desc) + END_KV_SERIALIZE_MAP() + }; + }; + struct COMMAND_RPC_SIGN_TRANSFER { struct request { std::string unsigned_txset; bool export_raw; + bool get_tx_keys; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(unsigned_txset) KV_SERIALIZE_OPT(export_raw, false) + KV_SERIALIZE_OPT(get_tx_keys, false) END_KV_SERIALIZE_MAP() }; @@ -549,11 +612,13 @@ namespace wallet_rpc std::string signed_txset; std::list<std::string> tx_hash_list; std::list<std::string> tx_raw_list; + std::list<std::string> tx_key_list; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(signed_txset) KV_SERIALIZE(tx_hash_list) KV_SERIALIZE(tx_raw_list) + KV_SERIALIZE(tx_key_list) END_KV_SERIALIZE_MAP() }; }; diff --git a/tests/functional_tests/CMakeLists.txt b/tests/functional_tests/CMakeLists.txt index 4b21b945c..7a2a7fbd1 100644 --- a/tests/functional_tests/CMakeLists.txt +++ b/tests/functional_tests/CMakeLists.txt @@ -26,10 +26,6 @@ # 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. -if(WIN32) - set(EXTRA_LIBRARIES "${EXTRA_LIBRARIES};bcrypt") -endif() - set(functional_tests_sources main.cpp transactions_flow_test.cpp diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt index e248ed965..7687e3c52 100644 --- a/tests/unit_tests/CMakeLists.txt +++ b/tests/unit_tests/CMakeLists.txt @@ -123,7 +123,7 @@ SET_PROPERTY(SOURCE memwipe.cpp PROPERTY COMPILE_FLAGS -Ofast) add_test( NAME unit_tests - COMMAND unit_tests --data-dir "${TEST_DATA_DIR} --binary-dir ${CMAKE_BINARY_DIR}") + COMMAND unit_tests --data-dir "${TEST_DATA_DIR}") add_executable(test_notifier test_notifier.cpp) target_link_libraries(test_notifier ${EXTRA_LIBRARIES}) diff --git a/tests/unit_tests/aligned.cpp b/tests/unit_tests/aligned.cpp index ad4837bec..2b733faf2 100644 --- a/tests/unit_tests/aligned.cpp +++ b/tests/unit_tests/aligned.cpp @@ -84,3 +84,24 @@ TEST(aligned, contents_smaller) aligned_free(ptr2); } +TEST(aligned, alignment) +{ + static const size_t good_alignments[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192}; + for (size_t a = 0; a <= 8192; ++a) + { + bool good = false; + for (const auto t: good_alignments) if (a == t) good = true; + void *ptr = aligned_malloc(1, a); + if (good) + { + ASSERT_TRUE(ptr != NULL); + aligned_free(ptr); + } + else + { + ASSERT_TRUE(ptr == NULL); + } + } + + ASSERT_TRUE(aligned_malloc(1, ~0) == NULL); +} diff --git a/tests/unit_tests/notify.cpp b/tests/unit_tests/notify.cpp index d6811c6bd..e2477a76e 100644 --- a/tests/unit_tests/notify.cpp +++ b/tests/unit_tests/notify.cpp @@ -26,6 +26,10 @@ // 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. +#ifdef __GLIBC__ +#include <sys/stat.h> +#endif + #include "gtest/gtest.h" #include <boost/filesystem.hpp> @@ -37,8 +41,14 @@ TEST(notify, works) { +#ifdef __GLIBC__ + mode_t prevmode = umask(077); +#endif char name_template[] = "/tmp/monero-notify-unit-test-XXXXXX"; int fd = mkstemp(name_template); +#ifdef __GLIBC__ + umask(prevmode); +#endif ASSERT_TRUE(fd >= 0); close(fd); diff --git a/tests/unit_tests/ringdb.cpp b/tests/unit_tests/ringdb.cpp index 0d92049ac..ab634ea82 100644 --- a/tests/unit_tests/ringdb.cpp +++ b/tests/unit_tests/ringdb.cpp @@ -136,21 +136,21 @@ TEST(ringdb, different_genesis) ASSERT_FALSE(ringdb.get_ring(KEY_2, KEY_IMAGE_1, outs2)); } -TEST(blackball, not_found) +TEST(spent_outputs, not_found) { RingDB ringdb; ASSERT_TRUE(ringdb.blackball(OUTPUT_1)); ASSERT_FALSE(ringdb.blackballed(OUTPUT_2)); } -TEST(blackball, found) +TEST(spent_outputs, found) { RingDB ringdb; ASSERT_TRUE(ringdb.blackball(OUTPUT_1)); ASSERT_TRUE(ringdb.blackballed(OUTPUT_1)); } -TEST(blackball, vector) +TEST(spent_outputs, vector) { RingDB ringdb; std::vector<std::pair<uint64_t, uint64_t>> outputs; @@ -174,7 +174,7 @@ TEST(blackball, vector) ASSERT_TRUE(ringdb.blackballed(std::make_pair(30, 5))); } -TEST(blackball, unblackball) +TEST(spent_outputs, mark_as_unspent) { RingDB ringdb; ASSERT_TRUE(ringdb.blackball(OUTPUT_1)); @@ -182,7 +182,7 @@ TEST(blackball, unblackball) ASSERT_FALSE(ringdb.blackballed(OUTPUT_1)); } -TEST(blackball, clear) +TEST(spent_outputs, clear) { RingDB ringdb; ASSERT_TRUE(ringdb.blackball(OUTPUT_1)); diff --git a/tests/unit_tests/test_tx_utils.cpp b/tests/unit_tests/test_tx_utils.cpp index 8a9f983e6..55c76c3b6 100644 --- a/tests/unit_tests/test_tx_utils.cpp +++ b/tests/unit_tests/test_tx_utils.cpp @@ -33,6 +33,8 @@ #include <vector> #include "common/util.h" +#include "cryptonote_basic/cryptonote_basic.h" +#include "cryptonote_basic/tx_extra.h" #include "cryptonote_core/cryptonote_tx_utils.h" namespace @@ -203,3 +205,85 @@ TEST(validate_parse_amount_case, validate_parse_amount) r = cryptonote::parse_amount(res, "1 00.00 00"); ASSERT_FALSE(r); } + +TEST(sort_tx_extra, empty) +{ + std::vector<uint8_t> extra, sorted; + ASSERT_TRUE(cryptonote::sort_tx_extra(extra, sorted)); + ASSERT_EQ(extra, sorted); +} + +TEST(sort_tx_extra, pubkey) +{ + std::vector<uint8_t> sorted; + const uint8_t extra_arr[] = {1, 30, 208, 98, 162, 133, 64, 85, 83, 112, 91, 188, 89, 211, 24, 131, 39, 154, 22, 228, + 80, 63, 198, 141, 173, 111, 244, 183, 4, 149, 186, 140, 230}; + std::vector<uint8_t> extra(&extra_arr[0], &extra_arr[0] + sizeof(extra_arr)); + ASSERT_TRUE(cryptonote::sort_tx_extra(extra, sorted)); + ASSERT_EQ(extra, sorted); +} + +TEST(sort_tx_extra, two_pubkeys) +{ + std::vector<uint8_t> sorted; + const uint8_t extra_arr[] = {1, 30, 208, 98, 162, 133, 64, 85, 83, 112, 91, 188, 89, 211, 24, 131, 39, 154, 22, 228, + 80, 63, 198, 141, 173, 111, 244, 183, 4, 149, 186, 140, 230, + 1, 30, 208, 98, 162, 133, 64, 85, 83, 112, 91, 188, 89, 211, 24, 131, 39, 154, 22, 228, + 80, 63, 198, 141, 173, 111, 244, 183, 4, 149, 186, 140, 230}; + std::vector<uint8_t> extra(&extra_arr[0], &extra_arr[0] + sizeof(extra_arr)); + ASSERT_TRUE(cryptonote::sort_tx_extra(extra, sorted)); + ASSERT_EQ(extra, sorted); +} + +TEST(sort_tx_extra, keep_order) +{ + std::vector<uint8_t> sorted; + const uint8_t extra_arr[] = {1, 30, 208, 98, 162, 133, 64, 85, 83, 112, 91, 188, 89, 211, 24, 131, 39, 154, 22, 228, + 80, 63, 198, 141, 173, 111, 244, 183, 4, 149, 186, 140, 230, + 2, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0}; + std::vector<uint8_t> extra(&extra_arr[0], &extra_arr[0] + sizeof(extra_arr)); + ASSERT_TRUE(cryptonote::sort_tx_extra(extra, sorted)); + ASSERT_EQ(extra, sorted); +} + +TEST(sort_tx_extra, switch_order) +{ + std::vector<uint8_t> sorted; + const uint8_t extra_arr[] = {2, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 30, 208, 98, 162, 133, 64, 85, 83, 112, 91, 188, 89, 211, 24, 131, 39, 154, 22, 228, + 80, 63, 198, 141, 173, 111, 244, 183, 4, 149, 186, 140, 230}; + const uint8_t expected_arr[] = {1, 30, 208, 98, 162, 133, 64, 85, 83, 112, 91, 188, 89, 211, 24, 131, 39, 154, 22, 228, + 80, 63, 198, 141, 173, 111, 244, 183, 4, 149, 186, 140, 230, + 2, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0}; + std::vector<uint8_t> extra(&extra_arr[0], &extra_arr[0] + sizeof(extra_arr)); + ASSERT_TRUE(cryptonote::sort_tx_extra(extra, sorted)); + std::vector<uint8_t> expected(&expected_arr[0], &expected_arr[0] + sizeof(expected_arr)); + ASSERT_EQ(expected, sorted); +} + +TEST(sort_tx_extra, invalid) +{ + std::vector<uint8_t> sorted; + const uint8_t extra_arr[] = {1}; + std::vector<uint8_t> extra(&extra_arr[0], &extra_arr[0] + sizeof(extra_arr)); + ASSERT_FALSE(cryptonote::sort_tx_extra(extra, sorted)); +} + +TEST(sort_tx_extra, invalid_suffix_strict) +{ + std::vector<uint8_t> sorted; + const uint8_t extra_arr[] = {2, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + std::vector<uint8_t> extra(&extra_arr[0], &extra_arr[0] + sizeof(extra_arr)); + ASSERT_FALSE(cryptonote::sort_tx_extra(extra, sorted)); +} + +TEST(sort_tx_extra, invalid_suffix_partial) +{ + std::vector<uint8_t> sorted; + const uint8_t extra_arr[] = {2, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + const uint8_t expected_arr[] = {2, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + std::vector<uint8_t> extra(&extra_arr[0], &extra_arr[0] + sizeof(extra_arr)); + ASSERT_TRUE(cryptonote::sort_tx_extra(extra, sorted, true)); + std::vector<uint8_t> expected(&expected_arr[0], &expected_arr[0] + sizeof(expected_arr)); + ASSERT_EQ(sorted, expected); +} diff --git a/translations/monero_ja.ts b/translations/monero_ja.ts new file mode 100644 index 000000000..17815d982 --- /dev/null +++ b/translations/monero_ja.ts @@ -0,0 +1,4072 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.1" language="ja" sourcelanguage="en"> +<context> + <name>Monero::AddressBookImpl</name> + <message> + <location filename="../src/wallet/api/address_book.cpp" line="53"/> + <source>Invalid destination address</source> + <translation>不正な宛先アドレス</translation> + </message> + <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ありっます。インテグレーテットアドレスにだけ短いペイメントIDを使えます</translation> + </message> + <message> + <location filename="../src/wallet/api/address_book.cpp" line="70"/> + <source>Invalid payment ID</source> + <translation>不正なペイメントID</translation> + </message> + <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>同じ時にインテグレーテットアドレスと長いペイメントIDを使えません</translation> + </message> +</context> +<context> + <name>Monero::PendingTransactionImpl</name> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="90"/> + <source>Attempting to save transaction to file, but specified file(s) exist. Exiting to not risk overwriting. File:</source> + <translation>ファイルは既に存在するのでファイルに取引を書き出せなかった。上書きしないにエグジットしてます。ファイル:</translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="97"/> + <source>Failed to write transaction(s) to file</source> + <translation>取引をファイルに書き込めませんでした</translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="115"/> + <source>daemon is busy. Please try again later.</source> + <translation>デーモンは忙しいです。後でもう一度試してください。</translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="118"/> + <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"/> + <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"/> + <source>. Reason: </source> + <translation>。 理由: </translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="129"/> + <source>Unknown exception: </source> + <translation>未知の例外: </translation> + </message> + <message> + <location filename="../src/wallet/api/pending_transaction.cpp" line="132"/> + <source>Unhandled exception</source> + <translation>未処理の例外</translation> + </message> +</context> +<context> + <name>Monero::UnsignedTransactionImpl</name> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="75"/> + <source>This is a watch only wallet</source> + <translation>これは閲覧専用ウォレットです</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="85"/> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="92"/> + <source>Failed to sign transaction</source> + <translation>取引を署名できませんでした</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="168"/> + <source>Claimed change does not go to a paid address</source> + <translation>請求したお釣りはもうお金に送ったアドレス送りません</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="174"/> + <source>Claimed change is larger than payment to the change address</source> + <translation>請求したお釣りはお釣りのアドレスに送ったペイメントより大きいです</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="184"/> + <source>Change goes to more than one address</source> + <translation>お釣りは複数のアドレスに送ります</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="197"/> + <source>sending %s to %s</source> + <translation>%s を %s に送ってます</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="203"/> + <source>with no destinations</source> + <translation>目的地なし</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="209"/> + <source>%s change to %s</source> + <translation>%s のお釣り %s に</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="212"/> + <source>no change</source> + <translation>お釣りありません</translation> + </message> + <message> + <location filename="../src/wallet/api/unsigned_transaction.cpp" line="214"/> + <source>Loaded %lu transactions, for %s, fee %s, %s, %s, with min ring size %lu. %s</source> + <translation>取引は %lu ロードした、 %s に、%s のの手数料、 %s 、 %s 、最小リングサイズ %lu 。%s</translation> + </message> +</context> +<context> + <name>Monero::WalletImpl</name> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1111"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <source>found outputs to use</source> + <translation>使うためにアウトプットを見つかれました</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1201"/> + <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"/> + <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"/> + <source>failed to parse address</source> + <translation>アドレスの解析に失敗しました</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="486"/> + <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"/> + <source>failed to parse secret view key</source> + <translation>秘密なビューキーの解析に失敗しました</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="513"/> + <source>failed to verify secret spend key</source> + <translation>秘密なスペンドキーの検証に失敗しました</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="518"/> + <source>spend key does not match address</source> + <translation>スペンドキーがアドレスと一致しませんでした</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="524"/> + <source>failed to verify secret view key</source> + <translation>秘密なビューキーの検証に失敗しました</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="529"/> + <source>view key does not match address</source> + <translation>ビューキーがアドレスと一致しませんでした</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="548"/> + <source>failed to generate new wallet: </source> + <translation>新しいウォレットの生成に失敗しました: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="773"/> + <source>Failed to send import wallet request</source> + <translation>インポートウォレットリクエストの送信に失敗しました</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="919"/> + <source>Failed to load unsigned transactions</source> + <translation>未署名の取引を読み込めませんでした</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="940"/> + <source>Failed to load transaction from file</source> + <translation>ファイルからの取引のロードに失敗しました</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="958"/> + <source>Wallet is view only</source> + <translation>閲覧専用ウォレットです</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="967"/> + <source>failed to save file </source> + <translation>ファイルを保存できませんでした </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="986"/> + <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"/> + <source>Failed to import key images: </source> + <translation>キーイメージをインポートできませんでした: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1032"/> + <source>Failed to get subaddress label: </source> + <translation>サブアドレスラベルを取得できませんでした: </translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1046"/> + <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> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1179"/> + <location filename="../src/wallet/api/wallet.cpp" line="1283"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <source>Failed to parse txid</source> + <translation>txidの解析に失敗しました</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1430"/> + <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"/> + <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"/> + <source>Failed to parse address</source> + <translation>アドレスの解析に失敗しました</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1627"/> + <source>Address must not be a subaddress</source> + <translation>アドレスはサブアドレスであってはならないです</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="1849"/> + <source>Rescan spent can only be used with a trusted daemon</source> + <translation>信頼できるデーモンしかで再スキャンしません</translation> + </message> +</context> +<context> + <name>Wallet</name> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="246"/> + <source>Failed to parse address</source> + <translation>アドレスの解析に失敗しました</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="253"/> + <source>Failed to parse key</source> + <translation>キーの解析に失敗しました</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="261"/> + <source>failed to verify key</source> + <translation>キーの検証に失敗しました</translation> + </message> + <message> + <location filename="../src/wallet/api/wallet.cpp" line="271"/> + <source>key does not match address</source> + <translation>キーがアドレスと一致しませんでした</translation> + </message> +</context> +<context> + <name>command_line</name> + <message> + <location filename="../src/common/command_line.cpp" line="57"/> + <source>yes</source> + <translation>はい</translation> + </message> + <message> + <location filename="../src/common/command_line.cpp" line="71"/> + <source>no</source> + <translation>いいえ</translation> + </message> +</context> +<context> + <name>cryptonote::rpc_args</name> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="40"/> + <source>Specify IP to bind RPC server</source> + <translation>RPCサーバに接続するIPを指定してください</translation> + </message> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="41"/> + <source>Specify username[:password] required for RPC server</source> + <translation>RPCサーバを使うためにユーザー名[:パスワード]を指定してください</translation> + </message> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="42"/> + <source>Confirm rpc-bind-ip value is NOT a loopback (local) IP</source> + <translation>rpc-bind-ipの価はループバック(ローカル)IPじゃないことを確認してください</translation> + </message> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="43"/> + <source>Specify a comma separated list of origins to allow cross origin resource sharing</source> + <translation>クロスオリジンリソース共同をできるためにコンマ区切りリストを指定してください</translation> + </message> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="70"/> + <source>Invalid IP address given for --</source> + <translation>このRPCサーバーのIPはだめです --</translation> + </message> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="78"/> + <source> permits inbound unencrypted external connections. Consider SSH tunnel or SSL proxy instead. Override with --</source> + <translation> は暗号化されていない外部接続をできますがSSHトンネルやSSLプロキシの方がいいです。これでオーバーライド --</translation> + </message> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="95"/> + <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"/> + <source> cannot be empty</source> + <translation> 入力する必要があります</translation> + </message> + <message> + <location filename="../src/rpc/rpc_args.cpp" line="105"/> + <source> requires RPC server password --</source> + <translation> のRPCサーバのパスワードありません --</translation> + </message> +</context> +<context> + <name>cryptonote::simple_wallet</name> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="479"/> + <source>Commands: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3008"/> + <source>failed to read wallet password</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2699"/> + <source>invalid password</source> + <translation>不正なパスワード</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1905"/> + <source>set seed: needs an argument. available options: language</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1933"/> + <source>set: unrecognized argument(s)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2869"/> + <source>wallet file path not valid: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1987"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <source>wallet failed to connect to daemon: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2643"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <source>failed to generate new wallet: </source> + <translation>新しいウォレットの生成に失敗しました: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2887"/> + <source>Opened watch-only wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2891"/> + <source>Opened wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2901"/> + <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"/> + <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"/> + <source>failed to load wallet: </source> + <translation>ウォレットをロードできませんでした: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2941"/> + <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"/> + <source>Wallet data saved</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3072"/> + <source>Mining started in daemon</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3074"/> + <source>mining has NOT been started: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3093"/> + <source>Mining stopped in daemon</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3095"/> + <source>mining has NOT been stopped: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3150"/> + <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"/> + <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"/> + <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"/> + <source>Starting refresh...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3232"/> + <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"/> + <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="3773"/> + <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"/> + <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"/> + <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"/> + <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"/> + <source>Is this okay anyway? (Y/Yes/N/No): </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3900"/> + <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"/> + <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"/> + <source> +Transaction </source> + <translation> +取引 </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3951"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="4307"/> + <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"/> + <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"/> + <source>Sending %s. </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3958"/> + <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"/> + <source>The transaction fee is %s</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3967"/> + <source>, of which %s is dust from change</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3968"/> + <source>.</source> + <translation>。</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3968"/> + <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"/> + <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> + <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"/> + <source>Unsigned transaction(s) successfully written to file: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4066"/> + <source>No unmixable outputs found</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4149"/> + <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> + <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"/> + <source>failed to parse key image</source> + <translation>キーイメージの解析に失敗しました</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4499"/> + <source>No outputs found</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4504"/> + <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"/> + <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"/> + <source>missing threshold amount</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4591"/> + <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"/> + <source>Claimed change does not go to a paid address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4707"/> + <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="4738"/> + <source>sending %s to %s</source> + <translation>%s を %s に送ってます</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4748"/> + <source> dummy output(s)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4751"/> + <source>with no destinations</source> + <translation>目的地なし</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4763"/> + <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> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4787"/> + <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"/> + <source>Failed to sign transaction</source> + <translation>取引を署名できませんでした</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4815"/> + <source>Failed to sign transaction: </source> + <translation>取引を署名できませんでした: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4836"/> + <source>Transaction raw hex data exported to </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4852"/> + <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"/> + <source>RPC error: </source> + <translation>RPCエラー: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="522"/> + <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"/> + <source>Your original password was incorrect.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="650"/> + <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"/> + <source>invalid unit</source> + <translation>不正なユニット</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1422"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1484"/> + <source>invalid count: must be an unsigned integer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1440"/> + <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"/> + <source>(Y/Yes/N/No): </source> + <translation>(はい (Y) いいえ (N)): </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2509"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2536"/> + <source>bad m_restore_height parameter: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2514"/> + <source>date format must be YYYY-MM-DD</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2527"/> + <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"/> + <source>Is this okay? (Y/Yes/N/No): </source> + <translation>これは大丈夫ですか? (はい (Y) いいえ (N)): </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2575"/> + <source>Daemon is local, assuming trusted</source> + <translation>デーモンはローカルです。信頼できるデーモン予期してます</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3004"/> + <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"/> + <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"/> + <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"/> + <source>unknown error</source> + <translation>不明なエラー</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3273"/> + <source>refresh failed: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3273"/> + <source>Blocks received: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3304"/> + <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"/> + <source>amount</source> + <translation>金額</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="219"/> + <source>false</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="493"/> + <source>Unknown command: </source> + <translation>未知のコマンド: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="500"/> + <source>Command usage: </source> + <translation>コマンドの使用: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="503"/> + <source>Command description: </source> + <translation>コマンドの記述: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="551"/> + <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"/> + <source>Failed to retrieve seed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="603"/> + <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"/> + <source>Error: failed to estimate backlog array size: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="700"/> + <source>Error: bad estimated backlog array size</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="712"/> + <source> (current)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="715"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <source>Invalid threshold</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="807"/> + <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"/> + <source>Error creating multisig: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="822"/> + <source>Error creating multisig: new wallet is not multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="825"/> + <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"/> + <source>This wallet is not multisig</source> + <translation>これはマルチシッグウォレットではありません</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="841"/> + <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"/> + <source>Failed to finalize multisig</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="868"/> + <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"/> + <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"/> + <source>Error exporting multisig info: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="917"/> + <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"/> + <source>Multisig info imported</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="969"/> + <source>Failed to import multisig info: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="980"/> + <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"/> + <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"/> + <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"/> + <source>Failed to sign multisig transaction</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1030"/> + <source>Multisig error: </source> + <translation>マルチサインエラー: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1035"/> + <source>Failed to sign multisig transaction: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1058"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <source>Failed to export multisig transaction to file </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1180"/> + <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"/> + <source>ring size must be an integer >= </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1277"/> + <source>could not change default ring size</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1518"/> + <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> + <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> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1568"/> + <source>Stop mining in the daemon.</source> + <translation type="unfinished"></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"/> + <source>Set another daemon to connect to.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1575"/> + <source>Save the current blockchain data.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1578"/> + <source>Synchronize the transactions and balance.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1581"/> + <source>balance [detail]</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> + <translation type="unfinished"></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.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1589"/> + <source>payments <PID_1> [<PID_2> ... <PID_N>]</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> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1593"/> + <source>Show the blockchain height.</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> + <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 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> + <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 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> + <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> + <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> + <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> + <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 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> + <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> + <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> + <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> + <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> + <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> + <translation type="unfinished"></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 type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1629"/> + <source>Submit a signed transaction from a file.</source> + <translation type="unfinished"></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"/> + <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="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"/> + <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="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 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="1656"/> + <source>integrated_address [<payment_id> | <address>]</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> + <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"/> + <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"/> + <source>Save the wallet data.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1667"/> + <source>Save a watch-only keys file.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1670"/> + <source>Display the private view key.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1673"/> + <source>Display the private spend key.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1676"/> + <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"/> + <source>Display the encrypted Electrum-style mnemonic seed.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1720"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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.</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"/> + <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"/> + <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"/> + <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"/> + <source>Set an arbitrary description for the wallet.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1780"/> + <source>Get the description of the wallet.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1783"/> + <source>Show the wallet's status.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1786"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <source>Change the wallet's password.</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> + <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> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1825"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <source>integer >= </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1930"/> + <source>block height</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> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <source>Error: expected M/N, but got: </source> + <translation>エラー: N/Mを欲しかったでもこれを貰いました: </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> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2347"/> + <source>Error: M/N is currently unsupported. </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> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2379"/> + <source>failed to parse secret view key</source> + <translation>秘密なビューキーの解析に失敗しました</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2388"/> + <source>failed to verify secret view key</source> + <translation>秘密なビューキーの検証に失敗しました</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2408"/> + <source>Secret spend key (%u of %u):</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2432"/> + <source>Error: M/N is currently unsupported</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2550"/> + <source>Restore height </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> + <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> + <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> + <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> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2850"/> + <source>failed to generate new mutlisig wallet</source> + <translation>新しいマルチシッグウォレットの生成に失敗しました</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2853"/> + <source>Generated new %u/%u multisig wallet: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2889"/> + <source>Opened %u/%u multisig wallet%s</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> + <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> + <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"/> + <source>Unexpected array length - Exited simple_wallet::set_daemon()</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> + <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> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3168"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3186"/> + <source>idx </source> + <translation>idx </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3299"/> + <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"/> + <source>Currently selected account: [</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3300"/> + <source>] </source> + <translation>] </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3302"/> + <source>Tag: </source> + <translation>タグ: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3302"/> + <source>(No tag assigned)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3309"/> + <source>Balance per address:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> + <source>Address</source> + <translation>アドレス</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5921"/> + <source>Balance</source> + <translation>残高</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> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> + <source>Outputs</source> + <translation>アウトプット</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3310"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5921"/> + <source>Label</source> + <translation>ラベル</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3318"/> + <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=<N>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> + <source>spent</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> + <source>global index</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> + <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"/> + <source>addr index</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3423"/> + <source>No incoming transfers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3427"/> + <source>No incoming available transfers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3431"/> + <source>No incoming unavailable transfers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3442"/> + <source>expected at least one payment ID</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> + <source>payment</source> + <translation>ペイメント</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> + <source>transaction</source> + <translation>取引</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> + <source>height</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3451"/> + <source>unlock time</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3463"/> + <source>No payments with id </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> + <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> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3590"/> + <source> +Transaction %llu/%llu: txid=%s</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3600"/> + <source> +Input %llu/%llu: amount=%s</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3616"/> + <source>failed to get output: </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> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3628"/> + <source> +Originating block heights: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3643"/> + <source> +|</source> + <translation> +|</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3643"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5651"/> + <source>| +</source> + <translation>| +</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3660"/> + <source> +Warning: Some input keys being spent are from </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> + <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> + <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> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3724"/> + <source>wrong number of arguments</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> + <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> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6743"/> + <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"/> + <source>, txid </source> + <translation>、txid </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6745"/> + <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"/> + <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="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> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4630"/> + <source>Donating </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> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6571"/> + <source>usage: show_transfer <txid></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> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6708"/> + <source>Transaction ID not found</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="214"/> + <source>true</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="267"/> + <source>failed to parse refresh type</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> + <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> + <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> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1321"/> + <source>could not change default priority</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1919"/> + <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"/> + <source>monero, millinero, micronero, nanonero, piconero</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1975"/> + <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"/> + <source>Wallet and key files found, loading...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1998"/> + <source>Key file found but not wallet file. Regenerating...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2004"/> + <source>Key file not found. Failed to open wallet: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2023"/> + <source>Generating new wallet...</source> + <translation>新しいウォレットを生じてます...</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2141"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <source>spend key does not match standard address</source> + <translation>スペンドキーが一般的なアドレスと一致しませんでした</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2562"/> + <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"/> + <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"/> + <source>invalid language choice entered. Please try again. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2753"/> + <source>View key: </source> + <translation>ビューキー: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2935"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <source>no connection to daemon. Please make sure daemon is running.</source> + <translation>デーモンの接続が確立ありません。デーモンが実行中になっていることを確認してください。</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3253"/> + <source>refresh error: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3303"/> + <source>Balance: </source> + <translation>残高: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3399"/> + <source>pubkey</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3399"/> + <source>key image</source> + <translation>キーイメージ</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3410"/> + <source>unlocked</source> + <translation></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3400"/> + <source>ringct</source> + <translation>ringct</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3409"/> + <source>T</source> + <translation>T</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3409"/> + <source>F</source> + <translation>F</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3410"/> + <source>locked</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3411"/> + <source>RingCT</source> + <translation>RingCT</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3411"/> + <source>-</source> + <translation>-</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3485"/> + <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"/> + <source>failed to get spent status</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3661"/> + <source>the same transaction</source> + <translation>同じ取引</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3661"/> + <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> + <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> + <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> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6046"/> + <source>usage: integrated_address [payment ID]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6082"/> + <source>Standard address: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6087"/> + <source>failed to parse payment ID or address</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> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6128"/> + <source>failed to parse payment ID</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6146"/> + <source>failed to parse index</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6154"/> + <source>Address book is empty.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6160"/> + <source>Index: </source> + <translation>インデックス: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6161"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6287"/> + <source>Address: </source> + <translation>アドレス: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6162"/> + <source>Payment ID: </source> + <translation>ペイメントID: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6163"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6286"/> + <source>Description: </source> + <translation>記述: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6173"/> + <source>usage: set_tx_note [txid] free text note</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6201"/> + <source>usage: get_tx_note [txid]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6304"/> + <source>usage: sign <filename></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6309"/> + <source>wallet is watch-only and cannot sign</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> + </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"/> + <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"/> + <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"/> + <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"/> + <source>Address must not be a subaddress</source> + <translation>アドレスはサブアドレスであってはならないです</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5289"/> + <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"/> + <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"/> + <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"/> + <source> (no daemon)</source> + <translation> (デーモンありません)</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5701"/> + <source> (out of sync)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5758"/> + <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"/> + <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"/> + <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"/> + <source> +Grand total: + Balance: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5901"/> + <source>, unlocked balance: </source> + <translation>、ロック解除された残高: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5909"/> + <source>Untagged accounts:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5915"/> + <source>Tag %s is unregistered.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5918"/> + <source>Accounts with tag: </source> + <translation>タグを持ってるアカウント: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5919"/> + <source>Tag's description: </source> + <translation>タグの記述: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5921"/> + <source>Account</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5927"/> + <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"/> + <source>----------------------------------------------------------------------------------</source> + <translation>----------------------------------------------------------------------------------</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5938"/> + <source>%15s %21s %21s</source> + <translation>%15s %21s %21s</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5961"/> + <source>Primary address</source> + <translation>プライマリアドレス</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5961"/> + <source>(used)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5982"/> + <source>(Untitled address)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6022"/> + <source><index_min> is already out of bound</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6027"/> + <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"/> + <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"/> + <source>Integrated address: %s, payment ID: %s</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6082"/> + <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"/> + <source>no description found</source> + <translation>記述を見つかれませんでした</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6250"/> + <source>description found: </source> + <translation>記述を見つかれました: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6285"/> + <source>Filename: </source> + <translation>ファイル名: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6290"/> + <source>Watch only</source> + <translation>閲覧専用</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6292"/> + <source>%u/%u multisig%s</source> + <translation>%u/%u マルチサイン%s</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6294"/> + <source>Normal</source> + <translation>ノーマル</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6295"/> + <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"/> + <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"/> + <source>Bad signature from </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6364"/> + <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"/> + <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"/> + <source>failed to save file </source> + <translation>ファイルを保存できませんでした </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6402"/> + <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"/> + <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"/> + <source>amount is wrong: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3820"/> + <source>expected number from 0 to </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4079"/> + <source>Sweeping </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4559"/> + <source>Money successfully sent, transaction: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4716"/> + <source>Change goes to more than one address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4757"/> + <source>%s change to %s</source> + <translation>%s のお釣り %s に</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4760"/> + <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"/> + <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"/> + <source>failed to parse txid</source> + <translation>txidの解析に失敗しました</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4898"/> + <source>Tx key: </source> + <translation>txキー: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="4903"/> + <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> + </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"/> + <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"/> + <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"/> + <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"/> + <source>error: </source> + <translation>エラー: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5007"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5080"/> + <source>received</source> + <translation>貰いました</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5007"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="5080"/> + <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"/> + <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"/> + <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"/> + <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"/> + <source>WARNING: failed to determine number of confirmations!</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5401"/> + <source>bad min_height parameter:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5413"/> + <source>bad max_height parameter:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5473"/> + <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"/> + <source><min_amount> should be smaller than <max_amount></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5592"/> + <source> +Amount: </source> + <translation> +金額: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5592"/> + <source>, number of keys: </source> + <translation>、キーの数: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5597"/> + <source> </source> + <translation> </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5602"/> + <source> +Min block height: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5603"/> + <source> +Max block height: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5604"/> + <source> +Min amount found: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5605"/> + <source> +Max amount found: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5606"/> + <source> +Total count: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5646"/> + <source> +Bin size: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5647"/> + <source> +Outputs per *: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5649"/> + <source>count + ^ +</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5651"/> + <source> |</source> + <translation> |</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5653"/> + <source> +</source> + <translation> +</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5653"/> + <source>+--> block height +</source> + <translation>+--> ブロック高 +</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5654"/> + <source> ^</source> + <translation> ^</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5654"/> + <source>^ +</source> + <translation>^ +</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5655"/> + <source> </source> + <translation> </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="5696"/> + <source>wallet</source> + <translation>ウォレット</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="666"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="6057"/> + <source>Random payment ID: </source> + <translation>ランダムなペイメントID: </translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="6058"/> + <source>Matching integrated address: </source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>genms</name> + <message> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="70"/> + <source>Base filename (-1, -2, etc suffixes will be appended as needed)</source> + <translation>ベースファイル名(必要があれば-1、-2、とかのサフィックスを追加します)</translation> + </message> + <message> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="71"/> + <source>Give threshold and participants at once as M/N</source> + <translation>M/Nってのフォーマットで同じ時に閾値と参加者をください</translation> + </message> + <message> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="72"/> + <source>How many participants will share parts of the multisig wallet</source> + <translation>マルチサインウォレットを分ける人はいくついますか</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>有効な取引を署名するために必要な人いくついますか</translation> + </message> + <message> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="74"/> + <source>Create testnet multisig wallets</source> + <translation>テストネットのマルチサインウォレットを作る</translation> + </message> + <message> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="81"/> + <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> + </message> + <message> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="146"/> + <source>Error finalizing multisig</source> + <translation>マルチサイン締結中にエラーありました</translation> + </message> + <message> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="153"/> + <source>Generated multisig wallets for address </source> + <translation>アドレスのためにマルチサインウォレットを生じなかった </translation> + </message> + <message> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="157"/> + <source>Error creating multisig wallets: </source> + <translation>マルチサインウォレットを樹立中にエラーありました: </translation> + </message> + <message> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="176"/> + <source>This program generates a set of multisig wallets - use this simpler scheme only if all the participants trust each other</source> + <translation>このプログラムはマルチサインウォレットのセットを生じます - みんながみんなを信用する場合にだけこの単純なスキームを使ってください</translation> + </message> + <message> + <location filename="../src/gen_multisig/gen_multisig.cpp" line="194"/> + <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"/> + <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"/> + <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"/> + <source>Error: --filename-base is required</source> + <translation>エラー: --filename-baseを使う必要だがあります</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> + </message> +</context> +<context> + <name>sw</name> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="115"/> + <source>Generate new wallet and save it to <arg></source> + <translation>新しいウォレットを生じろ <arg> をこっちにセーブしてください</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="116"/> + <source>Generate incoming-only wallet from view key</source> + <translation>ビューキーで閲覧専用ウォレットを生じろください</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="117"/> + <source>Generate deterministic wallet from spend key</source> + <translation>スペンドキーで決定論的なウォレットを生じろください</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="118"/> + <source>Generate wallet from private keys</source> + <translation>秘密なキーでウォレットを生じろください</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="119"/> + <source>Generate a master wallet from multisig wallet keys</source> + <translation>マルチシガーウォレットキーでマスターウォレットを生じろください</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="121"/> + <source>Language for mnemonic</source> + <translation>ニーモニックのための言語</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="122"/> + <source>Specify Electrum seed for wallet recovery/creation</source> + <translation>ウォレットの回収や作成のためにElectrumなニーモニックシードを指定してください</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="123"/> + <source>Recover wallet using Electrum-style mnemonic seed</source> + <translation>Electrumなニーモニックシードでウォレットを復元してください</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="124"/> + <source>Recover multisig wallet using Electrum-style mnemonic seed</source> + <translation>Electrumなニーモニックシードでマルチシガーウォレットを復元してください</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="125"/> + <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> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="127"/> + <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"/> + <source>Restore from specific blockchain height</source> + <translation>特定ブロックチェイン高で復元してください</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="129"/> + <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"/> + <source>daemon is busy. Please try again later.</source> + <translation>デーモンは忙しいです。後でもう一度試してください。</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="180"/> + <source>possibly lost connection to daemon</source> + <translation>デモンの接続が切れましたかもしりません</translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="197"/> + <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"/> + <source>Failed to initialize wallet</source> + <translation>ウォレットを初期化できませんでした</translation> + </message> +</context> +<context> + <name>tools::wallet2</name> + <message> + <location filename="../src/wallet/wallet2.cpp" line="113"/> + <source>Use daemon instance at <host>:<port></source> + <translation><host>:<port>でデーモンインスタンスを使ってください</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="114"/> + <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"/> + <source>Wallet password file</source> + <translation>ウォレットのパスワードファイル</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="117"/> + <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"/> + <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"/> + <source>can't specify daemon host or port more than once</source> + <translation>デーモンのホストやポートを複数回指定することはできません</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="204"/> + <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"/> + <source>the password file specified could not be read</source> + <translation>指定されたパスワードファイルを読み取れません</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="240"/> + <source>Failed to load file </source> + <translation>ファイルのロードに失敗しました </translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="115"/> + <source>Wallet password (escape/quote as needed)</source> + <translation>ウォレットのパスワード(随時にエスケープ文字を使ってください)</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="118"/> + <source>Specify username[:password] for daemon RPC client</source> + <translation>デーモンのRPCクライアントを使うためにユーザー名[:パスワード]を指定してください</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="224"/> + <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"/> + <source>Failed to parse JSON</source> + <translation>JSONを解析に失敗しました</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="253"/> + <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"/> + <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"/> + <source>failed to verify view key secret key</source> + <translation>秘密なビューキーの検証に失敗しました</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="285"/> + <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"/> + <source>failed to verify spend key secret key</source> + <translation>秘密なスペンドキーの検証に失敗しました</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="302"/> + <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> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="323"/> + <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"/> + <source>invalid address</source> + <translation>不正なアドレス</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="342"/> + <source>view key does not match standard address</source> + <translation>ビューキーが一般的なアドレスと一致しませんでした</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="352"/> + <source>spend key does not match standard address</source> + <translation>スペンドキーが一般的なアドレスと一致しませんでした</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="360"/> + <source>Cannot generate deprecated wallets from JSON</source> + <translation>JSONで非推奨のウォレットを生成することはできません</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="392"/> + <source>failed to parse address: </source> + <translation>アドレスの解析に失敗しました: </translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="398"/> + <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"/> + <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"/> + <source>Primary account</source> + <translation>プライマリア カウント</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="7914"/> + <source>No funds received in this tx.</source> + <translation>この取引から資金貰いませんでした。</translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="8607"/> + <source>failed to read file </source> + <translation>ファイルの読み込みに失敗しました </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"/> + <source>Failed to create directory </source> + <translation>ディレクトリの作成に失敗しました </translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="177"/> + <source>Failed to create directory %s: %s</source> + <translation>%s %s ディレクトリの作成に失敗しました</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="188"/> + <source>Cannot specify --</source> + <translation>これを指定しません: --</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="188"/> + <source> and --</source> + <translation> と --</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="207"/> + <source>Failed to create file </source> + <translation>ファイルの作成に失敗しました </translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="207"/> + <source>. Check permissions or remove file</source> + <translation>。 パーミッションを確認するか、ファイルを削除してください</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="217"/> + <source>Error writing to file </source> + <translation>ファイルへの書き込みエラー </translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="220"/> + <source>RPC username/password is stored in file </source> + <translation>RPCユーザー名/パスワードはファイルに保存しました </translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="443"/> + <source>Tag %s is unregistered.</source> + <translation>タグ %s を登録してません。</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="2435"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <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"/> + <source>Successfully saved</source> + <translation>保存しました</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="2947"/> + <source>Successfully loaded</source> + <translation>ロードしました</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="2951"/> + <source>Wallet initialization failed: </source> + <translation>ウォレットを初期化できませんでした: </translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="2958"/> + <source>Failed to initialize wallet RPC server</source> + <translation>ウォレットのRPCサーバを初期化できませんでした</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="2962"/> + <source>Starting wallet RPC server</source> + <translation>ウォレットのRPCサーバを開始してます</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="2969"/> + <source>Failed to run wallet: </source> + <translation>ウォレットを起動することできませんでした: </translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="2972"/> + <source>Stopped wallet RPC server</source> + <translation>ウォレットのRPCサーバを停止しました</translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="2981"/> + <source>Failed to save wallet: </source> + <translation>ウォレットを保存することできませんでした: </translation> + </message> +</context> +<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"/> + <source>Wallet options</source> + <translation>ウォレットのオプション</translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="73"/> + <source>Generate wallet from JSON format file</source> + <translation>JSONフォーマットファイルでウォレットを生じてください</translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="77"/> + <source>Use wallet <arg></source> + <translation>ウォレットの <arg> を使てください</translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="104"/> + <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"/> + <source>Specify log file</source> + <translation>ログファイルを指定してください</translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="106"/> + <source>Config file</source> + <translation>設定ファイル</translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="115"/> + <source>General options</source> + <translation>ジェネラルオプション</translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="138"/> + <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"/> + <source>Can't find config file </source> + <translation>設定ファイルを見つかりませんでした </translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="195"/> + <source>Logging to: </source> + <translation>こっちにログをしてます: </translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="197"/> + <source>Logging to %s</source> + <translation>%s にログをしてます</translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="140"/> + <source>Usage:</source> + <translation>使用:</translation> + </message> +</context> +</TS> |