diff options
395 files changed, 16768 insertions, 5677 deletions
diff --git a/.travis.yml b/.travis.yml index 1f6eb15c27..c8785144ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ os: linux language: cpp +compiler: gcc env: global: - MAKEJOBS=-j3 @@ -30,18 +31,21 @@ matrix: - compiler: ": ARM" env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" - compiler: ": Win32" - env: HOST=i686-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2" + env: HOST=i686-w64-mingw32 PPA="ppa:ubuntu-wine/ppa" PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine1.7 bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2" - compiler: ": 32-bit + dash" env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" - compiler: ": Win64" - env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2" + env: HOST=x86_64-w64-mingw32 PPA="ppa:ubuntu-wine/ppa" PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine1.7 bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2" - compiler: ": bitcoind" env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER" - compiler: ": No wallet" env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" - compiler: ": Cross-Mac" env: HOST=x86_64-apple-darwin11 PACKAGES="cmake libcap-dev libz-dev libbz2-dev" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy" + exclude: + - compiler: gcc install: + - if [ -n "$PPA" ]; then travis_retry sudo add-apt-repository "$PPA" -y; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi before_script: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..1d42dea843 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,108 @@ +Contributing to Bitcoin Core +============================ + +The Bitcoin Core project operates an open contributor model where anyone is welcome to contribute towards development in the form of peer review, testing and patches. This document explains the practical process and guidelines for contributing. + +Firstly in terms of structure, there is no particular concept of “Core developers” in the sense of privileged people. Open source often naturally revolves around meritocracy where longer term contributors gain more trust from the developer community. However, some hierarchy is necessary for practical purposes. As such there are repository “maintainers” who are responsible for merging pull requests as well as a “lead maintainer” who is responsible for the release cycle, overall merging, moderation and appointment of maintainers. + + +Contributor Workflow +-------------------- + +The codebase is maintained using the “contributor workflow” where everyone without exception contributes patch proposals using “pull requests”. This facilitates social contribution, easy testing and peer review. + +To contribute a patch, the workflow is as follows: + + - Fork repository + - Create topic branch + - Commit patches + +The project coding conventions in [doc/developer-notes.md](doc/developer-notes.md) must be adhered to. + +In general [commits should be atomic](https://en.wikipedia.org/wiki/Atomic_commit#Atomic_commit_convention) and diffs should be easy to read. For this reason do not mix any formatting fixes or code moves with actual code changes. + +Commit messages should be verbose by default consisting of a short subject line (50 chars max), a blank line and detailed explanatory text as separate paragraph(s); unless the title alone is self-explanatory (like "Corrected typo in main.cpp") then a single title line is sufficient. Commit messages should be helpful to people reading your code in the future, so explain the reasoning for your decisions. Further explanation [here](http://chris.beams.io/posts/git-commit/). + +If a particular commit references another issue, please add the reference, for example "refs #1234", or "fixes #4321". Using "fixes or closes" keywords will cause the corresponding issue to be closed when the pull request is merged. + +Please refer to the [Git manual](https://git-scm.com/doc) for more information about Git. + + - Push changes to your fork + - Create pull request + +The title of the pull request should be prefixed by the component or area that the pull request affects. Examples: + + Consensus: Add new opcode for BIP-XXXX OP_CHECKAWESOMESIG + Net: Automatically create hidden service, listen on Tor + Qt: Add feed bump button + Trivial: fix typo + +If a pull request is specifically not to be considered for merging (yet) please prefix the title with [WIP] or use [Tasks Lists](https://github.com/blog/1375-task-lists-in-gfm-issues-pulls-comments) in the body of the pull request to indicate tasks are pending. + +The body of the pull request should contain enough description about what the patch does together with any justification/reasoning. You should include references to any discussions (for example other tickets or mailing list discussions). + +At this stage one should expect comments and review from other contributors. You can add more commits to your pull request by committing them locally and pushing to your fork until you have satisfied all feedback. If your pull request is accepted for merging, you may be asked by a maintainer to squash and or rebase your commits before it will be merged. The length of time required for peer review is unpredictable and will vary from patch to patch. + + +Pull Request Philosophy +----------------------- + +Patchsets should always be focused. For example, a pull request could add a feature, fix a bug, or refactor code; but not a mixture. Please also avoid super pull requests which attempt to do too much, are overly large, or overly complex as this makes review difficult. + + +###Features + +When adding a new feature, thought must be given to the long term technical debt and maintenance that feature may require after inclusion. Before proposing a new feature that will require maintenance, please consider if you are willing to maintain it (including bug fixing). If features get orphaned with no maintainer in the future, they may be removed by the Repository Maintainer. + + +###Refactoring + +Refactoring is a necessary part of any software project's evolution. The following guidelines cover refactoring pull requests for the project. + +There are three categories of refactoring, code only moves, code style fixes, code refactoring. In general refactoring pull requests should not mix these three kinds of activity in order to make refactoring pull requests easy to review and uncontroversial. In all cases, refactoring PRs must not change the behaviour of code within the pull request (bugs must be preserved as is). + +Project maintainers aim for a quick turnaround on refactoring pull requests, so where possible keep them short, uncomplex and easy to verify. + + +"Decision Making" Process +------------------------- + +The following applies to code changes to the Bitcoin Core project (and related projects such as libsecp256k1), and is not to be confused with overall Bitcoin Network Protocol consensus changes. + +Whether a pull request is merged into Bitcoin Core rests with the project merge maintainers and ultimately the project lead. + +Maintainers will take into consideration if a patch is in line with the general principles of the project; meets the minimum standards for inclusion; and will judge the general consensus of contributors. + +In general, all pull requests must: + + - have a clear use case, fix a demonstrable bug or serve the greater good of the project (for example refactoring for modularisation); + - be well peer reviewed; + - have unit tests and functional tests where appropriate; + - follow code style guidelines; + - not break the existing test suite; + - where bugs are fixed, where possible, there should be unit tests demonstrating the bug and also proving the fix. This helps prevent regression. + +Patches that change Bitcoin consensus rules are considerably more involved than normal because they affect the entire ecosystem and so must be preceded by extensive mailing list discussions and have a numbered BIP. While each case will be different, one should be prepared to expend more time and effort than for other kinds of patches because of increased peer review and consensus building requirements. + + +###Peer Review + +Anyone may participate in peer review which is expressed by comments in the pull request. Typically reviewers will review the code for obvious errors, as well as test out the patch set and opine on the technical merits of the patch. Project maintainers take into account the peer review when determining if there is consensus to merge a pull request (remember that discussions may have been spread out over github, mailing list and IRC discussions). The following language is used within pull-request comments: + + - ACK means "I have tested the code and I agree it should be merged"; + - NACK means "I disagree this should be merged", and must be accompanied by sound technical justification. NACKs without accompanying reasoning may be disregarded; + - utACK means "I have not tested the code, but I have reviewed it and it looks OK, I agree it can be merged"; + - Concept ACK means "I agree in the general principle of this pull request"; + - Nit refers to trivial, often non-blocking issues. + +Project maintainers reserve the right to weigh the opinions of peer reviewers using common sense judgement and also may weight based on meritocracy: Those that have demonstrated a deeper commitment and understanding towards the project (over time) or have clear domain expertise may naturally have more weight, as one would expect in all walks of life. + +Where a patch set affects consensus critical code, the bar will be set much higher in terms of discussion and peer review requirements, keeping in mind that mistakes could be very costly to the wider community. This includes refactoring of consensus critical code. + +Where a patch set proposes to change the Bitcoin consensus, it must have been discussed extensively on the mailing list and IRC, be accompanied by a widely discussed BIP and have a generally widely perceived technical consensus of being a worthwhile change based on the judgement of the maintainers. + + +Release Policy +-------------- + +The project leader is the release manager for each Bitcoin Core release. @@ -1,3 +1,5 @@ +The MIT License (MIT) + Copyright (c) 2009-2015 The Bitcoin Core developers Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/Makefile.am b/Makefile.am index ab68d8fa6d..dfde0d43ec 100644 --- a/Makefile.am +++ b/Makefile.am @@ -204,7 +204,7 @@ endif dist_noinst_SCRIPTS = autogen.sh -EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.sh qa/pull-tester/run-bitcoin-cli qa/rpc-tests $(DIST_DOCS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING) +EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.sh qa/rpc-tests $(DIST_DOCS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING) CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER) @@ -23,28 +23,21 @@ License Bitcoin Core is released under the terms of the MIT license. See [COPYING](COPYING) for more information or see http://opensource.org/licenses/MIT. -Development process +Development Process ------------------- -Developers work in their own trees, then submit pull requests when they think -their feature or bug fix is ready. - -If it is a simple/trivial/non-controversial change, then one of the Bitcoin -development team members simply pulls it. - -If it is a *more complicated or potentially controversial* change, then the patch -submitter will be asked to start a discussion (if they haven't already) on the -[mailing list](https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev) - -The patch will be accepted if there is broad consensus that it is a good thing. -Developers should expect to rework and resubmit patches if the code doesn't -match the project's coding conventions (see [doc/developer-notes.md](doc/developer-notes.md)) or are -controversial. - The `master` branch is regularly built and tested, but is not guaranteed to be completely stable. [Tags](https://github.com/bitcoin/bitcoin/tags) are created regularly to indicate new official, stable release versions of Bitcoin. +The contribution workflow is described in [CONTRIBUTING.md](CONTRIBUTING.md). + +The developer [mailing list](https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev) +should be used to discuss complicated or controversial changes before working +on a patch set. + +Developer IRC can be found on Freenode at #bitcoin-core-dev. + Testing ------- diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 100b8653a8..121e10bd37 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -110,13 +110,8 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ if test x$bitcoin_qt_got_major_vers = x5; then _BITCOIN_QT_IS_STATIC if test x$bitcoin_cv_static_qt = xyes; then + _BITCOIN_QT_FIND_STATIC_PLUGINS AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static]) - if test x$qt_plugin_path != x; then - QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms" - fi - if test x$use_pkgconfig = xyes; then - PKG_CHECK_MODULES([QTPLATFORM], [Qt5PlatformSupport], [QT_LIBS="$QTPLATFORM_LIBS $QT_LIBS"]) - fi AC_CACHE_CHECK(for Qt < 5.4, bitcoin_cv_need_acc_widget,[AC_COMPILE_IFELSE([AC_LANG_PROGRAM( [[#include <QtCore>]],[[ #if QT_VERSION >= 0x050400 @@ -127,25 +122,15 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ [bitcoin_cv_need_acc_widget=no]) ]) if test "x$bitcoin_cv_need_acc_widget" = "xyes"; then - if test x$qt_plugin_path != x; then - QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible" - fi _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(AccessibleFactory)], [-lqtaccessiblewidgets]) fi if test x$TARGET_OS = xwindows; then _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)],[-lqwindows]) AC_DEFINE(QT_QPA_PLATFORM_WINDOWS, 1, [Define this symbol if the qt platform is windows]) elif test x$TARGET_OS = xlinux; then - PKG_CHECK_MODULES([X11XCB], [x11-xcb], [QT_LIBS="$X11XCB_LIBS $QT_LIBS"]) - if ${PKG_CONFIG} --exists "Qt5Core >= 5.5" 2>/dev/null; then - PKG_CHECK_MODULES([QTXCBQPA], [Qt5XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"]) - fi _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)],[-lqxcb -lxcb-static]) AC_DEFINE(QT_QPA_PLATFORM_XCB, 1, [Define this symbol if the qt platform is xcb]) elif test x$TARGET_OS = xdarwin; then - if test x$use_pkgconfig = xyes; then - PKG_CHECK_MODULES([QTPRINT], [Qt5PrintSupport], [QT_LIBS="$QTPRINT_LIBS $QT_LIBS"]) - fi AX_CHECK_LINK_FLAG([[-framework IOKit]],[QT_LIBS="$QT_LIBS -framework IOKit"],[AC_MSG_ERROR(could not iokit framework)]) _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin)],[-lqcocoa]) AC_DEFINE(QT_QPA_PLATFORM_COCOA, 1, [Define this symbol if the qt platform is cocoa]) @@ -154,10 +139,6 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ else if test x$TARGET_OS = xwindows; then AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static]) - if test x$qt_plugin_path != x; then - QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible" - QT_LIBS="$QT_LIBS -L$qt_plugin_path/codecs" - fi _BITCOIN_QT_CHECK_STATIC_PLUGINS([ Q_IMPORT_PLUGIN(qcncodecs) Q_IMPORT_PLUGIN(qjpcodecs) @@ -297,6 +278,39 @@ AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_PLUGINS],[ LIBS="$CHECK_STATIC_PLUGINS_TEMP_LIBS" ]) +dnl Internal. Find paths necessary for linking qt static plugins +dnl Inputs: bitcoin_qt_got_major_vers. 4 or 5. +dnl Inputs: qt_plugin_path. optional. +dnl Outputs: QT_LIBS is appended +AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[ + if test x$bitcoin_qt_got_major_vers = x5; then + if test x$qt_plugin_path != x; then + QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms" + if test -d "$qt_plugin_path/accessible"; then + QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible" + fi + fi + m4_ifdef([PKG_CHECK_MODULES],[ + if test x$use_pkgconfig = xyes; then + PKG_CHECK_MODULES([QTPLATFORM], [Qt5PlatformSupport], [QT_LIBS="$QTPLATFORM_LIBS $QT_LIBS"]) + if test x$TARGET_OS = xlinux; then + PKG_CHECK_MODULES([X11XCB], [x11-xcb], [QT_LIBS="$X11XCB_LIBS $QT_LIBS"]) + if ${PKG_CONFIG} --exists "Qt5Core >= 5.5" 2>/dev/null; then + PKG_CHECK_MODULES([QTXCBQPA], [Qt5XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"]) + fi + elif test x$TARGET_OS = xdarwin; then + PKG_CHECK_MODULES([QTPRINT], [Qt5PrintSupport], [QT_LIBS="$QTPRINT_LIBS $QT_LIBS"]) + fi + fi + ]) + else + if test x$qt_plugin_path != x; then + QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible" + QT_LIBS="$QT_LIBS -L$qt_plugin_path/codecs" + fi + fi +]) + dnl Internal. Find Qt libraries using pkg-config. dnl Inputs: bitcoin_qt_want_version (from --with-gui=). The version to check dnl first. diff --git a/configure.ac b/configure.ac index 7f90b5f395..d530f8c262 100644 --- a/configure.ac +++ b/configure.ac @@ -137,9 +137,15 @@ AC_ARG_ENABLE([glibc-back-compat], [use_glibc_compat=$enableval], [use_glibc_compat=no]) +AC_ARG_ENABLE([zmq], + [AS_HELP_STRING([--disable-zmq], + [Disable ZMQ notifications])], + [use_zmq=$enableval], + [use_zmq=yes]) + AC_ARG_WITH([protoc-bindir],[AS_HELP_STRING([--with-protoc-bindir=BIN_DIR],[specify protoc bin path])], [protoc_bin_path=$withval], []) -# Enable debug +# Enable debug AC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug], [use debug compiler flags and macros (default is no)])], @@ -151,11 +157,11 @@ if test "x$enable_debug" = xyes; then if test "x$GCC" = xyes; then CFLAGS="$CFLAGS -g3 -O0" fi - + if test "x$GXX" = xyes; then CXXFLAGS="$CXXFLAGS -g3 -O0" fi -fi +fi ## TODO: Remove these hard-coded paths and flags. They are here for the sake of ## compatibility with the legacy buildsystem. @@ -664,6 +670,12 @@ if test x$use_pkgconfig = xyes; then if test x$use_qr != xno; then BITCOIN_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])]) fi + if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then + PKG_CHECK_MODULES([EVENT], [libevent],, [AC_MSG_ERROR(libevent not found.)]) + if test x$TARGET_OS != xwindows; then + PKG_CHECK_MODULES([EVENT_PTHREADS], [libevent_pthreads],, [AC_MSG_ERROR(libevent_pthreads not found.)]) + fi + fi ] ) else @@ -673,6 +685,14 @@ else AC_CHECK_HEADER([openssl/ssl.h],, AC_MSG_ERROR(libssl headers missing),) AC_CHECK_LIB([ssl], [main],SSL_LIBS=-lssl, AC_MSG_ERROR(libssl missing)) + if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then + AC_CHECK_HEADER([event2/event.h],, AC_MSG_ERROR(libevent headers missing),) + AC_CHECK_LIB([event],[main],EVENT_LIBS=-levent,AC_MSG_ERROR(libevent missing)) + if test x$TARGET_OS != xwindows; then + AC_CHECK_LIB([event_pthreads],[main],EVENT_PTHREADS_LIBS=-levent_pthreads,AC_MSG_ERROR(libevent_pthreads missing)) + fi + fi + BITCOIN_QT_CHECK(AC_CHECK_LIB([protobuf] ,[main],[PROTOBUF_LIBS=-lprotobuf], BITCOIN_QT_FAIL(libprotobuf not found))) if test x$use_qr != xno; then BITCOIN_QT_CHECK([AC_CHECK_LIB([qrencode], [main],[QR_LIBS=-lqrencode], [have_qrencode=no])]) @@ -680,19 +700,26 @@ else fi fi -AC_CHECK_LIB([crypto],[RAND_egd],[],[ - AC_ARG_WITH([libressl], - [AS_HELP_STRING([--with-libressl],[Build with system LibreSSL (default is no; DANGEROUS; NOT SUPPORTED)])], - [AC_MSG_WARN([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])], - [AC_MSG_ERROR([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])] - ) -]) - CFLAGS_TEMP="$CFLAGS" LIBS_TEMP="$LIBS" CFLAGS="$CFLAGS $SSL_CFLAGS $CRYPTO_CFLAGS" LIBS="$LIBS $SSL_LIBS $CRYPTO_LIBS" AC_CHECK_HEADER([openssl/ec.h],, AC_MSG_ERROR(OpenSSL ec header missing),) + +AC_MSG_CHECKING(for a supported OpenSSL version) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include <openssl/rand.h> + ]], + [[RAND_egd(NULL);]])], + [AC_MSG_RESULT(yes)], + [ + AC_ARG_WITH([libressl], + [AS_HELP_STRING([--with-libressl],[Build with system LibreSSL (default is no; DANGEROUS; NOT SUPPORTED)])], + [AC_MSG_WARN([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])], + [AC_MSG_ERROR([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])] + )] +) + CFLAGS="$CFLAGS_TEMP" LIBS="$LIBS_TEMP" @@ -812,6 +839,22 @@ if test x$bitcoin_enable_qt != xno; then fi fi +# conditional search for and use libzmq +AC_MSG_CHECKING([whether to build ZMQ support]) +if test "x$use_zmq" = "xyes"; then + AC_MSG_RESULT([yes]) + PKG_CHECK_MODULES([ZMQ],[libzmq >= 4], + [AC_DEFINE([ENABLE_ZMQ],[1],[Define to 1 to enable ZMQ functions])], + [AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) + AC_MSG_WARN([libzmq version 4.x or greater not found, disabling]) + use_zmq=no]) +else + AC_MSG_RESULT([no, --disable-zmq used]) + AC_DEFINE_UNQUOTED([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) +fi + +AM_CONDITIONAL([ENABLE_ZMQ], [test "x$use_zmq" = "xyes"]) + AC_MSG_CHECKING([whether to build test_bitcoin]) if test x$use_tests = xyes; then AC_MSG_RESULT([yes]) diff --git a/contrib/README.md b/contrib/README.md index 7d4b91e887..125594312b 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -1,9 +1,6 @@ Wallet Tools --------------------- -### [BitRPC](/contrib/bitrpc) ### -Allows for sending of all standard Bitcoin commands via RPC rather than as command line args. - ### [SpendFrom](/contrib/spendfrom) ### Use the raw transactions API to send coins received on a particular diff --git a/contrib/bitcoin-qt.pro b/contrib/bitcoin-qt.pro index 3a72d10f47..b8133bf789 100644 --- a/contrib/bitcoin-qt.pro +++ b/contrib/bitcoin-qt.pro @@ -11,7 +11,7 @@ FORMS += \ ../src/qt/forms/overviewpage.ui \ ../src/qt/forms/receivecoinsdialog.ui \ ../src/qt/forms/receiverequestdialog.ui \ - ../src/qt/forms/rpcconsole.ui \ + ../src/qt/forms/debugwindow.ui \ ../src/qt/forms/sendcoinsdialog.ui \ ../src/qt/forms/sendcoinsentry.ui \ ../src/qt/forms/signverifymessagedialog.ui \ diff --git a/contrib/bitcoind.bash-completion b/contrib/bitcoind.bash-completion index 3cc959c0a6..1338d2f2b5 100644 --- a/contrib/bitcoind.bash-completion +++ b/contrib/bitcoind.bash-completion @@ -96,7 +96,7 @@ _bitcoind() { esac case "$cur" in - -conf=*|-pid=*|-loadblock=*|-wallet=*|-rpcsslcertificatechainfile=*|-rpcsslprivatekeyfile=*) + -conf=*|-pid=*|-loadblock=*|-wallet=*) cur="${cur#*=}" _filedir return 0 diff --git a/contrib/bitrpc/README.md b/contrib/bitrpc/README.md deleted file mode 100644 index f5ef2f0405..0000000000 --- a/contrib/bitrpc/README.md +++ /dev/null @@ -1,8 +0,0 @@ -### BitRPC -Allows for sending of all standard Bitcoin commands via RPC rather than as command line args. - -### Looking for Wallet Tools? -BitRPC.py is able to do the exact same thing as `walletchangepass.py` and `walletunlock.py`. Their respective commands in BitRPC.py are: - - bitrpc.py walletpassphrasechange - bitrpc.py walletpassphrase
\ No newline at end of file diff --git a/contrib/bitrpc/bitrpc.py b/contrib/bitrpc/bitrpc.py deleted file mode 100644 index c3ce9d7936..0000000000 --- a/contrib/bitrpc/bitrpc.py +++ /dev/null @@ -1,335 +0,0 @@ -from jsonrpc import ServiceProxy -import sys -import string -import getpass - -# ===== BEGIN USER SETTINGS ===== -# if you do not set these you will be prompted for a password for every command -rpcuser = "" -rpcpass = "" -# ====== END USER SETTINGS ====== - - -if rpcpass == "": - access = ServiceProxy("http://127.0.0.1:8332") -else: - access = ServiceProxy("http://"+rpcuser+":"+rpcpass+"@127.0.0.1:8332") -cmd = sys.argv[1].lower() - -if cmd == "backupwallet": - try: - path = raw_input("Enter destination path/filename: ") - print access.backupwallet(path) - except Exception as inst: - print inst - -elif cmd == "encryptwallet": - try: - pwd = getpass.getpass(prompt="Enter passphrase: ") - pwd2 = getpass.getpass(prompt="Repeat passphrase: ") - if pwd == pwd2: - access.encryptwallet(pwd) - print "\n---Wallet encrypted. Server stopping, restart to run with encrypted wallet---\n" - else: - print "\n---Passphrases do not match---\n" - except Exception as inst: - print inst - -elif cmd == "getaccount": - try: - addr = raw_input("Enter a Bitcoin address: ") - print access.getaccount(addr) - except Exception as inst: - print inst - -elif cmd == "getaccountaddress": - try: - acct = raw_input("Enter an account name: ") - print access.getaccountaddress(acct) - except Exception as inst: - print inst - -elif cmd == "getaddressesbyaccount": - try: - acct = raw_input("Enter an account name: ") - print access.getaddressesbyaccount(acct) - except Exception as inst: - print inst - -elif cmd == "getbalance": - try: - acct = raw_input("Enter an account (optional): ") - mc = raw_input("Minimum confirmations (optional): ") - try: - print access.getbalance(acct, mc) - except: - print access.getbalance() - except Exception as inst: - print inst - -elif cmd == "getblockbycount": - try: - height = raw_input("Height: ") - print access.getblockbycount(height) - except Exception as inst: - print inst - -elif cmd == "getblockcount": - try: - print access.getblockcount() - except Exception as inst: - print inst - -elif cmd == "getblocknumber": - try: - print access.getblocknumber() - except Exception as inst: - print inst - -elif cmd == "getconnectioncount": - try: - print access.getconnectioncount() - except Exception as inst: - print inst - -elif cmd == "getdifficulty": - try: - print access.getdifficulty() - except Exception as inst: - print inst - -elif cmd == "getgenerate": - try: - print access.getgenerate() - except Exception as inst: - print inst - -elif cmd == "gethashespersec": - try: - print access.gethashespersec() - except Exception as inst: - print inst - -elif cmd == "getinfo": - try: - print access.getinfo() - except Exception as inst: - print inst - -elif cmd == "getnewaddress": - try: - acct = raw_input("Enter an account name: ") - try: - print access.getnewaddress(acct) - except: - print access.getnewaddress() - except Exception as inst: - print inst - -elif cmd == "getreceivedbyaccount": - try: - acct = raw_input("Enter an account (optional): ") - mc = raw_input("Minimum confirmations (optional): ") - try: - print access.getreceivedbyaccount(acct, mc) - except: - print access.getreceivedbyaccount() - except Exception as inst: - print inst - -elif cmd == "getreceivedbyaddress": - try: - addr = raw_input("Enter a Bitcoin address (optional): ") - mc = raw_input("Minimum confirmations (optional): ") - try: - print access.getreceivedbyaddress(addr, mc) - except: - print access.getreceivedbyaddress() - except Exception as inst: - print inst - -elif cmd == "gettransaction": - try: - txid = raw_input("Enter a transaction ID: ") - print access.gettransaction(txid) - except Exception as inst: - print inst - -elif cmd == "getwork": - try: - data = raw_input("Data (optional): ") - try: - print access.gettransaction(data) - except: - print access.gettransaction() - except Exception as inst: - print inst - -elif cmd == "help": - try: - cmd = raw_input("Command (optional): ") - try: - print access.help(cmd) - except: - print access.help() - except Exception as inst: - print inst - -elif cmd == "listaccounts": - try: - mc = raw_input("Minimum confirmations (optional): ") - try: - print access.listaccounts(mc) - except: - print access.listaccounts() - except Exception as inst: - print inst - -elif cmd == "listreceivedbyaccount": - try: - mc = raw_input("Minimum confirmations (optional): ") - incemp = raw_input("Include empty? (true/false, optional): ") - try: - print access.listreceivedbyaccount(mc, incemp) - except: - print access.listreceivedbyaccount() - except Exception as inst: - print inst - -elif cmd == "listreceivedbyaddress": - try: - mc = raw_input("Minimum confirmations (optional): ") - incemp = raw_input("Include empty? (true/false, optional): ") - try: - print access.listreceivedbyaddress(mc, incemp) - except: - print access.listreceivedbyaddress() - except Exception as inst: - print inst - -elif cmd == "listtransactions": - try: - acct = raw_input("Account (optional): ") - count = raw_input("Number of transactions (optional): ") - frm = raw_input("Skip (optional):") - try: - print access.listtransactions(acct, count, frm) - except: - print access.listtransactions() - except Exception as inst: - print inst - -elif cmd == "move": - try: - frm = raw_input("From: ") - to = raw_input("To: ") - amt = raw_input("Amount:") - mc = raw_input("Minimum confirmations (optional): ") - comment = raw_input("Comment (optional): ") - try: - print access.move(frm, to, amt, mc, comment) - except: - print access.move(frm, to, amt) - except Exception as inst: - print inst - -elif cmd == "sendfrom": - try: - frm = raw_input("From: ") - to = raw_input("To: ") - amt = raw_input("Amount:") - mc = raw_input("Minimum confirmations (optional): ") - comment = raw_input("Comment (optional): ") - commentto = raw_input("Comment-to (optional): ") - try: - print access.sendfrom(frm, to, amt, mc, comment, commentto) - except: - print access.sendfrom(frm, to, amt) - except Exception as inst: - print inst - -elif cmd == "sendmany": - try: - frm = raw_input("From: ") - to = raw_input("To (in format address1:amount1,address2:amount2,...): ") - mc = raw_input("Minimum confirmations (optional): ") - comment = raw_input("Comment (optional): ") - try: - print access.sendmany(frm,to,mc,comment) - except: - print access.sendmany(frm,to) - except Exception as inst: - print inst - -elif cmd == "sendtoaddress": - try: - to = raw_input("To (in format address1:amount1,address2:amount2,...): ") - amt = raw_input("Amount:") - comment = raw_input("Comment (optional): ") - commentto = raw_input("Comment-to (optional): ") - try: - print access.sendtoaddress(to,amt,comment,commentto) - except: - print access.sendtoaddress(to,amt) - except Exception as inst: - print inst - -elif cmd == "setaccount": - try: - addr = raw_input("Address: ") - acct = raw_input("Account:") - print access.setaccount(addr,acct) - except Exception as inst: - print inst - -elif cmd == "setgenerate": - try: - gen= raw_input("Generate? (true/false): ") - cpus = raw_input("Max processors/cores (-1 for unlimited, optional):") - try: - print access.setgenerate(gen, cpus) - except: - print access.setgenerate(gen) - except Exception as inst: - print inst - -elif cmd == "settxfee": - try: - amt = raw_input("Amount:") - print access.settxfee(amt) - except Exception as inst: - print inst - -elif cmd == "stop": - try: - print access.stop() - except Exception as inst: - print inst - -elif cmd == "validateaddress": - try: - addr = raw_input("Address: ") - print access.validateaddress(addr) - except Exception as inst: - print inst - -elif cmd == "walletpassphrase": - try: - pwd = getpass.getpass(prompt="Enter wallet passphrase: ") - access.walletpassphrase(pwd, 60) - print "\n---Wallet unlocked---\n" - except Exception as inst: - print inst - -elif cmd == "walletpassphrasechange": - try: - pwd = getpass.getpass(prompt="Enter old wallet passphrase: ") - pwd2 = getpass.getpass(prompt="Enter new wallet passphrase: ") - access.walletpassphrasechange(pwd, pwd2) - print - print "\n---Passphrase changed---\n" - except Exception as inst: - print inst - -else: - print "Command not found or not supported" diff --git a/contrib/debian/bitcoin-tx.install b/contrib/debian/bitcoin-tx.install new file mode 100644 index 0000000000..2c21052a68 --- /dev/null +++ b/contrib/debian/bitcoin-tx.install @@ -0,0 +1 @@ +usr/local/bin/bitcoin-tx usr/bin diff --git a/contrib/debian/changelog b/contrib/debian/changelog index 7ce3babc1b..bd7ab3524c 100644 --- a/contrib/debian/changelog +++ b/contrib/debian/changelog @@ -149,7 +149,7 @@ bitcoin (0.5.3-natty0) natty; urgency=low bitcoin (0.5.2-natty1) natty; urgency=low * Remove mentions on anonymity in package descriptions and manpage. - These should never have been there, bitcoin isnt anonymous without + These should never have been there, bitcoin isn't anonymous without a ton of work that virtually no users will ever be willing and capable of doing @@ -190,7 +190,7 @@ bitcoin (0.5.0~rc1-natty1) natty; urgency=low * Add test_bitcoin to build test * Fix clean - * Remove uneccessary build-dependancies + * Remove unnecessary build-dependancies -- Matt Corallo <matt@bluematt.me> Wed, 26 Oct 2011 14:37:18 -0400 @@ -350,7 +350,7 @@ bitcoin (0.3.20.01~dfsg-1) unstable; urgency=low bitcoin (0.3.19~dfsg-6) unstable; urgency=low - * Fix override agressive optimizations. + * Fix override aggressive optimizations. * Fix tighten build-dependencies to really fit backporting to Lenny: + Add fallback build-dependency on libdb4.6++-dev. + Tighten unversioned Boost build-dependencies to recent versions, diff --git a/contrib/debian/control b/contrib/debian/control index 4392bb3385..01625b8438 100644 --- a/contrib/debian/control +++ b/contrib/debian/control @@ -56,3 +56,17 @@ Description: peer-to-peer network based digital currency - Qt GUI requires 20+ GB of space, slowly growing. . This package provides Bitcoin-Qt, a GUI for Bitcoin based on Qt. + +Package: bitcoin-tx +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: peer-to-peer digital currency - standalone transaction tool + Bitcoin is a free open source peer-to-peer electronic cash system that + is completely decentralized, without the need for a central server or + trusted parties. Users hold the crypto keys to their own money and + transact directly with each other, with the help of a P2P network to + check for double-spending. + . + This package provides bitcoin-tx, a command-line transaction creation + tool which can be used without a bitcoin daemon. Some means of + exchanging minimal transaction data with peers is still required. diff --git a/contrib/debian/copyright b/contrib/debian/copyright index 55ebcaab42..83ce560a79 100644 --- a/contrib/debian/copyright +++ b/contrib/debian/copyright @@ -1,19 +1,15 @@ -Format: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?rev=174 +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: Bitcoin Upstream-Contact: Satoshi Nakamoto <satoshin@gmx.com> irc://#bitcoin@freenode.net Source: https://github.com/bitcoin/bitcoin Files: * -Copyright: 2009-2012, Bitcoin Core Developers +Copyright: 2009-2015, Bitcoin Core Developers License: Expat Comment: The Bitcoin Core Developers encompasses the current developers listed on bitcoin.org, as well as the numerous contributors to the project. -Files: src/json/* -Copyright: 2007-2009, John W. Wilkinson -License: Expat - Files: debian/* Copyright: 2010-2011, Jonas Smedegaard <dr@jones.dk> 2011, Matt Corallo <matt@bluematt.me> @@ -23,60 +19,66 @@ Files: debian/manpages/* Copyright: Micah Anderson <micah@debian.org> License: GPL-3+ -Files: src/qt/res/icons/clock*.png, src/qt/res/icons/tx*.png, - src/qt/res/src/*.svg -Copyright: Wladimir van der Laan +Files: src/qt/res/icons/add.png + src/qt/res/icons/address-book.png + src/qt/res/icons/configure.png + src/qt/res/icons/debugwindow.png + src/qt/res/icons/edit.png + src/qt/res/icons/editcopy.png + src/qt/res/icons/editpaste.png + src/qt/res/icons/export.png + src/qt/res/icons/eye.png + src/qt/res/icons/filesave.png + src/qt/res/icons/history.png + src/qt/res/icons/info.png + src/qt/res/icons/key.png + src/qt/res/icons/lock_*.png + src/qt/res/icons/open.png + src/qt/res/icons/overview.png + src/qt/res/icons/quit.png + src/qt/res/icons/receive.png + src/qt/res/icons/remove.png + src/qt/res/icons/send.png + src/qt/res/icons/synced.png + src/qt/res/icons/transaction*.png + src/qt/res/icons/tx_output.png + src/qt/res/icons/warning.png +Copyright: Stephen Hutchings (and more) + http://typicons.com License: Expat - -Files: src/qt/res/icons/address-book.png, src/qt/res/icons/export.png, - src/qt/res/icons/history.png, src/qt/res/icons/key.png, - src/qt/res/icons/lock_*.png, src/qt/res/icons/overview.png, - src/qt/res/icons/receive.png, src/qt/res/icons/send.png, - src/qt/res/icons/synced.png, src/qt/res/icons/filesave.png -Copyright: David Vignoni (david@icon-king.com) - ICON KING - www.icon-king.com -License: LGPL -Comment: NUVOLA ICON THEME for KDE 3.x - Original icons: kaddressbook, klipper_dock, view-list-text, - key-password, encrypted/decrypted, go-home, go-down, - go-next, dialog-ok - Site: http://www.icon-king.com/projects/nuvola/ +Comment: Site: https://github.com/stephenhutchings/typicons.font Files: src/qt/res/icons/connect*.png -Copyright: schollidesign -License: GPL-3+ -Comment: Icon Pack: Human-O2 - Site: http://findicons.com/icon/93743/blocks_gnome_netstatus_0 - -Files: src/qt/res/icons/transaction*.png -Copyright: md2k7 + src/qt/res/src/connect-*.svg +Copyright: Marco Falke License: Expat -Comment: Site: https://bitcointalk.org/index.php?topic=15276.0 +Comment: Inspired by Stephan Hutchings Typicons -Files: src/qt/res/icons/configure.png, src/qt/res/icons/quit.png, - src/qt/res/icons/editcopy.png, src/qt/res/icons/editpaste.png, - src/qt/res/icons/add.png, src/qt/res/icons/edit.png, - src/qt/res/icons/remove.png -Copyright: http://www.everaldo.com -License: LGPL -Comment: Icon Pack: Crystal SVG +Files: src/qt/res/icons/tx_mined.png + src/qt/res/src/mine.svg +Copyright: Jonas Schnelli +License: Expat +Comment: -Files: src/qt/res/icons/bitcoin.png, src/qt/res/icons/toolbar.png -Copyright: Bitboy (optimized for 16x16 by Wladimir van der Laan) -License: PUB-DOM +Files: src/qt/res/icons/clock*.png + src/qt/res/icons/eye_*.png + src/qt/res/icons/verify.png + src/qt/res/icons/tx_in*.png + src/qt/res/src/clock_*.svg + src/qt/res/src/tx_*.svg + src/qt/res/src/verify.svg +Copyright: Stephan Hutching, Jonas Schnelli +License: Expat +Comment: Modifications of Stephan Hutchings Typicons + +Files: src/qt/res/icons/about.png + src/qt/res/icons/bitcoin.* + share/pixmaps/bitcoin* + src/qt/res/src/bitcoin.svg +Copyright: Bitboy, Jonas Schnelli +License: public-domain Comment: Site: https://bitcointalk.org/?topic=1756.0 -Files: scripts/img/reload.xcf, src/qt/res/movies/*.png -Copyright: Everaldo (Everaldo Coelho) -License: GPL-3+ -Comment: Icon Pack: Kids - Site: http://findicons.com/icon/17102/reload?id=17102 - -Files: src/qt/res/images/splash2.jpg -License: PUB-DOM -Copyright: Crobbo (forum) -Comment: Site: https://bitcointalk.org/index.php?topic=32273.0 - License: Expat Permission is hereby granted, free of charge, to any person obtaining a @@ -98,20 +100,6 @@ License: Expat TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -License: ISC - Permission to use, copy, modify, and distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - . - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR - BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES - OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, - ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - SOFTWARE. - License: GPL-2+ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -140,22 +128,5 @@ Comment: You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. -License: LGPL - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - . - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -Comment: - On Debian systems the GNU Lesser General Public License (LGPL) is - located in '/usr/share/common-licenses/LGPL'. - . - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - -License: PUB-DOM +License: public-domain This work is in the public domain. diff --git a/contrib/debian/examples/bitcoin.conf b/contrib/debian/examples/bitcoin.conf index ade80d60ea..2831c07292 100644 --- a/contrib/debian/examples/bitcoin.conf +++ b/contrib/debian/examples/bitcoin.conf @@ -60,7 +60,7 @@ # JSON-RPC options (for controlling a running Bitcoin/bitcoind process) # -# server=1 tells Bitcoin-QT and bitcoind to accept JSON-RPC commands +# server=1 tells Bitcoin-Qt and bitcoind to accept JSON-RPC commands #server=0 # Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. @@ -73,7 +73,7 @@ # How many seconds bitcoin will wait for a complete RPC HTTP request. # after the HTTP connection is established. -#rpctimeout=30 +#rpcclienttimeout=30 # By default, only RPC connections from localhost are allowed. # Specify as many rpcallowip= settings as you like to allow connections from other hosts, @@ -82,7 +82,7 @@ # NOTE: opening up the RPC port to hosts outside your local trusted network is NOT RECOMMENDED, # because the rpcpassword is transmitted over the network unencrypted. -# server=1 tells Bitcoin-QT to accept JSON-RPC commands. +# server=1 tells Bitcoin-Qt to accept JSON-RPC commands. # it is also read by bitcoind to determine if RPC should be enabled #rpcallowip=10.1.1.34/255.255.255.0 #rpcallowip=1.2.3.4/24 @@ -95,15 +95,6 @@ # running on another host using this option: #rpcconnect=127.0.0.1 -# Use Secure Sockets Layer (also known as TLS or HTTPS) to communicate -# with Bitcoin -server or bitcoind -#rpcssl=1 - -# OpenSSL settings used when rpcssl=1 -#rpcsslciphers=TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH -#rpcsslcertificatechainfile=server.cert -#rpcsslprivatekeyfile=server.pem - # Transaction Fee Changes in 0.10.0 # Send transactions as zero-fee transactions if possible (default: 0) diff --git a/contrib/debian/manpages/bitcoin-cli.1 b/contrib/debian/manpages/bitcoin-cli.1 index f953ae9db7..154b458739 100644 --- a/contrib/debian/manpages/bitcoin-cli.1 +++ b/contrib/debian/manpages/bitcoin-cli.1 @@ -36,9 +36,6 @@ Listen for JSON\-RPC connections on <port> (default: 8332 or testnet: 18332). .TP \fB\-rpcconnect=\fR<ip> Send commands to node running on <ip> (default: 127.0.0.1). -.TP -\fB\-rpcssl\fR=\fI1\fR -Use OpenSSL (https) for JSON\-RPC connections (see the Bitcoin Wiki for SSL setup instructions). .SH "SEE ALSO" \fBbitcoind\fP, \fBbitcoin.conf\fP diff --git a/contrib/debian/manpages/bitcoin-qt.1 b/contrib/debian/manpages/bitcoin-qt.1 index a023582bc0..05eadc94cd 100644 --- a/contrib/debian/manpages/bitcoin-qt.1 +++ b/contrib/debian/manpages/bitcoin-qt.1 @@ -178,18 +178,6 @@ Set maximum block size in bytes (default: 250000) .HP \fB\-blockprioritysize=\fR<n> Set maximum size of high\-priority/low\-fee transactions in bytes (default: 27000) .PP -SSL options: (see the Bitcoin Wiki for SSL setup instructions) -.TP -\fB\-rpcssl\fR -Use OpenSSL (https) for JSON\-RPC connections -.TP -\fB\-rpcsslcertificatechainfile=\fR<file.cert> -Server certificate file (default: server.cert) -.TP -\fB\-rpcsslprivatekeyfile=\fR<file.pem> -Server private key (default: server.pem) -.TP -\fB\-rpcsslciphers=\fR<ciphers> Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) .SS "UI options:" .TP diff --git a/contrib/debian/manpages/bitcoin.conf.5 b/contrib/debian/manpages/bitcoin.conf.5 index 8a0078d5d5..0cf4d991e3 100644 --- a/contrib/debian/manpages/bitcoin.conf.5 +++ b/contrib/debian/manpages/bitcoin.conf.5 @@ -46,16 +46,6 @@ Listen for RPC connections on this TCP port. \fBrpcconnect=\fR\fI'127.0.0.1'\fR You can use *bitcoin* or *bitcoind(1)* to send commands to *bitcoin*/*bitcoind(1)* running on another host using this option. .TP -\fBrpcssl=\fR\fI'1'\fR -Use Secure Sockets Layer (also known as TLS or HTTPS) to communicate with *bitcoin* '\-server' or *bitcoind(1)*. Example of OpenSSL settings used when *rpcssl*='1': -.TP -\fB\-rpcsslciphers=\fR<ciphers> -Acceptable ciphers (default: TLSv1+HIGH:\:!SSLv2:\:!aNULL:\:!eNULL:\:!AH:\:!3DES:\:@STRENGTH) -.TP -\fBrpcsslcertificatechainfile=\fR\fI'server.cert'\fR -.TP -\fBrpcsslprivatekeyfile=\fR\fI'server.pem'\fR -.TP .SH MISCELLANEOUS OPTIONS .TP \fBgen=\fR[\fI'0'\fR|\fI'1'\fR] diff --git a/contrib/debian/manpages/bitcoind.1 b/contrib/debian/manpages/bitcoind.1 index c225b9f3e9..5b0f2921aa 100644 --- a/contrib/debian/manpages/bitcoind.1 +++ b/contrib/debian/manpages/bitcoind.1 @@ -62,20 +62,6 @@ Allow JSON\-RPC connections from specified IP address .TP \fB\-rpcconnect=\fR<ip> Send commands to node running on <ip> -.PP -SSL options: (see the Bitcoin Wiki for SSL setup instructions) -.TP -\fB\-rpcssl\fR=\fI1\fR -Use OpenSSL (https) for JSON\-RPC connections -.TP -\fB\-rpcsslcertificatchainfile=\fR<file.cert> -Server certificate file (default: server.cert) -.TP -\fB\-rpcsslprivatekeyfile=\fR<file.pem> -Server private key (default: server.pem) -.TP -\fB\-rpcsslciphers=\fR<ciphers> -Acceptable ciphers (default: TLSv1+HIGH:\:!SSLv2:\:!aNULL:\:!eNULL:\:!AH:\:!3DES:\:@STRENGTH) .TP \-? This help message diff --git a/contrib/devtools/github-merge.sh b/contrib/devtools/github-merge.sh index ec7a1f4c4b..afb53f0390 100755 --- a/contrib/devtools/github-merge.sh +++ b/contrib/devtools/github-merge.sh @@ -161,7 +161,11 @@ if [[ "d$REPLY" =~ ^d[Ss]$ ]]; then cleanup exit 1 else - git commit -q --gpg-sign --amend --no-edit + if ! git commit -q --gpg-sign --amend --no-edit; then + echo "Error signing, exiting." + cleanup + exit 1 + fi fi else echo "Not signing off on merge, exiting." diff --git a/contrib/devtools/optimize-pngs.py b/contrib/devtools/optimize-pngs.py index 38aaa00f31..b6d6a097d6 100755 --- a/contrib/devtools/optimize-pngs.py +++ b/contrib/devtools/optimize-pngs.py @@ -1,5 +1,8 @@ #!/usr/bin/env python - +''' +Run this scrip every time you change one of the png files. Using pngcrush, it will optimize the png files, remove various color profiles, remove ancillary chunks (alla) and text chunks (text). +#pngcrush -brute -ow -rem gAMA -rem cHRM -rem iCCP -rem sRGB -rem alla -rem text +''' import os import sys import subprocess @@ -18,14 +21,12 @@ def content_hash(filename): data = i.tostring() return hashlib.sha256(data).hexdigest() -#optimize png, remove various color profiles, remove ancillary chunks (alla) and text chunks (text) -#pngcrush -brute -ow -rem gAMA -rem cHRM -rem iCCP -rem sRGB -rem alla -rem text - pngcrush = 'pngcrush' git = 'git' -folders = ["src/qt/res/movies", "src/qt/res/icons", "src/qt/res/images"] +folders = ["src/qt/res/movies", "src/qt/res/icons"] basePath = subprocess.check_output([git, 'rev-parse', '--show-toplevel']).rstrip('\n') totalSaveBytes = 0 +noHashChange = True outputArray = [] for folder in folders: @@ -68,6 +69,7 @@ for fileDict in outputArray: oldHash = fileDict['sha256Old'] newHash = fileDict['sha256New'] totalSaveBytes += fileDict['osize'] - fileDict['psize'] + noHashChange = noHashChange and (oldHash == newHash) print fileDict['file']+"\n size diff from: "+str(fileDict['osize'])+" to: "+str(fileDict['psize'])+"\n old sha256: "+oldHash+"\n new sha256: "+newHash+"\n" -print "completed. Total reduction: "+str(totalSaveBytes)+" bytes" +print "completed. Checksum stable: "+str(noHashChange)+". Total reduction: "+str(totalSaveBytes)+" bytes" diff --git a/contrib/verify-commits/trusted-git-root b/contrib/verify-commits/trusted-git-root index eb13f8762e..838b8d1ea8 100644 --- a/contrib/verify-commits/trusted-git-root +++ b/contrib/verify-commits/trusted-git-root @@ -1 +1 @@ -053038e5ba116cb319fb85f3cb3e062cf1b3df15 +165e323d851cc87213c7673c6f278e87a6f2e752 diff --git a/contrib/zmq/zmq_sub.py b/contrib/zmq/zmq_sub.py new file mode 100755 index 0000000000..decf29d42a --- /dev/null +++ b/contrib/zmq/zmq_sub.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python2 + +import array +import binascii +import zmq + +port = 28332 + +zmqContext = zmq.Context() +zmqSubSocket = zmqContext.socket(zmq.SUB) +zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashblock") +zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashtx") +zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "rawblock") +zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "rawtx") +zmqSubSocket.connect("tcp://127.0.0.1:%i" % port) + +try: + while True: + msg = zmqSubSocket.recv_multipart() + topic = str(msg[0]) + body = msg[1] + + if topic == "hashblock": + print "- HASH BLOCK -" + print binascii.hexlify(body) + elif topic == "hashtx": + print '- HASH TX -' + print binascii.hexlify(body) + elif topic == "rawblock": + print "- RAW BLOCK HEADER -" + print binascii.hexlify(body[:80]) + elif topic == "rawtx": + print '- RAW TX -' + print binascii.hexlify(body) + +except KeyboardInterrupt: + zmqContext.destroy() diff --git a/depends/config.guess b/depends/config.guess index f7eb141e75..f357ec6c8f 100755 --- a/depends/config.guess +++ b/depends/config.guess @@ -1117,7 +1117,7 @@ EOF # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that + # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; diff --git a/depends/packages/libevent.mk b/depends/packages/libevent.mk new file mode 100644 index 0000000000..2e9be1e98c --- /dev/null +++ b/depends/packages/libevent.mk @@ -0,0 +1,31 @@ +package=libevent +$(package)_version=2.0.22 +$(package)_download_path=https://github.com/libevent/libevent/releases/download/release-2.0.22-stable +$(package)_file_name=$(package)-$($(package)_version)-stable.tar.gz +$(package)_sha256_hash=71c2c49f0adadacfdbe6332a372c38cf9c8b7895bb73dabeaa53cdcc1d4e1fa3 +$(package)_patches=reuseaddr.patch + +define $(package)_preprocess_cmds + patch -p1 < $($(package)_patch_dir)/reuseaddr.patch +endef + +define $(package)_set_vars + $(package)_config_opts=--disable-shared --disable-openssl --disable-libevent-regress + $(package)_config_opts_release=--disable-debug-mode + $(package)_config_opts_linux=--with-pic +endef + +define $(package)_config_cmds + $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef + +define $(package)_postprocess_cmds +endef diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk index e6573986f7..ee1ee2f4b8 100644 --- a/depends/packages/miniupnpc.mk +++ b/depends/packages/miniupnpc.mk @@ -1,8 +1,8 @@ package=miniupnpc -$(package)_version=1.9.20150609 +$(package)_version=1.9.20150730 $(package)_download_path=http://miniupnp.free.fr/files $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=86e6ccec5b660ba6889893d1f3fca21db087c6466b1a90f495a1f87ab1cd1c36 +$(package)_sha256_hash=1d64fab1fd3b4c8545139341ba197f19329a863f4f21b578fc2a228ab586a604 define $(package)_set_vars $(package)_build_opts=CC="$($(package)_cc)" diff --git a/depends/packages/native_ccache.mk b/depends/packages/native_ccache.mk index 745d7a3982..317674f795 100644 --- a/depends/packages/native_ccache.mk +++ b/depends/packages/native_ccache.mk @@ -1,8 +1,8 @@ package=native_ccache -$(package)_version=3.2.2 +$(package)_version=3.2.3 $(package)_download_path=http://samba.org/ftp/ccache $(package)_file_name=ccache-$($(package)_version).tar.bz2 -$(package)_sha256_hash=440f5e15141cc72d2bfff467c977020979810eb800882e3437ad1a7153cce7b2 +$(package)_sha256_hash=b07165d4949d107d17f2f84b90b52953617bf1abbf249d5cc20636f43337c98c define $(package)_set_vars $(package)_config_opts= diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 03908aba59..02cc188420 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -1,4 +1,6 @@ -packages:=boost openssl +packages:=boost openssl libevent +darwin_packages:=zeromq +linux_packages:=zeromq native_packages := native_ccache native_comparisontool qt_native_packages = native_protobuf diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk new file mode 100644 index 0000000000..24e8e5f1c9 --- /dev/null +++ b/depends/packages/zeromq.mk @@ -0,0 +1,26 @@ +package=zeromq +$(package)_version=4.0.4 +$(package)_download_path=http://download.zeromq.org +$(package)_file_name=$(package)-$($(package)_version).tar.gz +$(package)_sha256_hash=1ef71d46e94f33e27dd5a1661ed626cd39be4d2d6967792a275040e34457d399 + +define $(package)_set_vars + $(package)_config_opts=--without-documentation --disable-shared + $(package)_config_opts_linux=--with-pic +endef + +define $(package)_config_cmds + $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) -C src +endef + +define $(package)_stage_cmds + $(MAKE) -C src DESTDIR=$($(package)_staging_dir) install +endef + +define $(package)_postprocess_cmds + rm -rf bin share +endef diff --git a/depends/patches/libevent/reuseaddr.patch b/depends/patches/libevent/reuseaddr.patch new file mode 100644 index 0000000000..58695c11f5 --- /dev/null +++ b/depends/patches/libevent/reuseaddr.patch @@ -0,0 +1,21 @@ +--- old/evutil.c 2015-08-28 19:26:23.488765923 -0400 ++++ new/evutil.c 2015-08-28 19:27:41.392767019 -0400 +@@ -321,15 +321,16 @@ + int + evutil_make_listen_socket_reuseable(evutil_socket_t sock) + { +-#ifndef WIN32 + int one = 1; ++#ifndef WIN32 + /* REUSEADDR on Unix means, "don't hang on to this address after the + * listener is closed." On Windows, though, it means "don't keep other + * processes from binding to this address while we're using it. */ + return setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &one, + (ev_socklen_t)sizeof(one)); + #else +- return 0; ++ return setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*) &one, ++ (ev_socklen_t)sizeof(one)); + #endif + } + diff --git a/doc/README.md b/doc/README.md index 7b0c39d383..3e3f4a294f 100644 --- a/doc/README.md +++ b/doc/README.md @@ -64,7 +64,8 @@ The Bitcoin repo's [root README](https://github.com/bitcoin/bitcoin/blob/master/ ### Resources * Discuss on the [BitcoinTalk](https://bitcointalk.org/) forums, in the [Development & Technical Discussion board](https://bitcointalk.org/index.php?board=6.0). -* Discuss on [#bitcoin-dev](http://webchat.freenode.net/?channels=bitcoin) on Freenode. If you don't have an IRC client use [webchat here](http://webchat.freenode.net/?channels=bitcoin-dev). +* Discuss project-specific development on #bitcoin-core-dev on Freenode. If you don't have an IRC client use [webchat here](http://webchat.freenode.net/?channels=bitcoin-core-dev). +* Discuss general Bitcoin development on #bitcoin-dev on Freenode. If you don't have an IRC client use [webchat here](http://webchat.freenode.net/?channels=bitcoin-dev). ### Miscellaneous - [Assets Attribution](assets-attribution.md) diff --git a/doc/REST-interface.md b/doc/REST-interface.md index ac7cd45f70..bf669235e3 100644 --- a/doc/REST-interface.md +++ b/doc/REST-interface.md @@ -77,6 +77,20 @@ $ curl localhost:18332/rest/getutxos/checkmempool/b2cdfd7b89def827ff8af7cd9bff76 } ``` +####Memory pool +`GET /rest/mempool/info.json` + +Returns various information about the TX mempool. +Only supports JSON as output format. +* size : (numeric) the number of transactions in the TX mempool +* bytes : (numeric) size of the TX mempool in bytes +* usage : (numeric) total TX mempool memory usage + +`GET /rest/mempool/contents.json` + +Returns transactions in the TX mempool. +Only supports JSON as output format. + Risks ------------- Running a web browser on the same node with a REST enabled bitcoind can be a risk. Accessing prepared XSS websites could read out tx/block data of your node by placing links like `<script src="http://127.0.0.1:8332/rest/tx/1234567890.json">` which might break the nodes privacy. diff --git a/doc/assets-attribution.md b/doc/assets-attribution.md index c6da1a4586..2dd930d6a4 100644 --- a/doc/assets-attribution.md +++ b/doc/assets-attribution.md @@ -1,46 +1 @@ -The following is a list of assets used in the bitcoin source and their proper attribution. - -[Typicons/Stephen Hutchings](http://typicons.com) ------------------------ - -### Info -* Icon Pack: Typicons (http://typicons.com) -* Designer: Stephen Hutchings (and more) -* License: MIT -* Site: [https://github.com/stephenhutchings/typicons.font](https://github.com/stephenhutchings/typicons.font) - -### Assets Used - src/qt/res/icons/add.png, src/qt/res/icons/address-book.png, - src/qt/res/icons/configure.png, src/qt/res/icons/connect4.png, - src/qt/res/icons/debugwindow.png, src/qt/res/icons/edit.png, - src/qt/res/icons/exitcopy.png, src/qt/res/icons/editpaste.png, - src/qt/res/icons/export.png, src/qt/res/icons/eye.png, - src/qt/res/icons/filesave.png, src/qt/res/icons/history.png, - src/qt/res/icons/info.png, src/qt/res/icons/key.png, - src/qt/res/icons/lock_*.png, src/qt/res/icons/open.png, - src/qt/res/icons/overview.png, src/qt/res/icons/quit.png, - src/qt/res/icons/receive.png, src/qt/res/icons/remove.png, - src/qt/res/icons/send.png, src/qt/res/icons/synced.png, - src/qt/res/icons/transaction*.png, src/qt/res/icons/tx_output.png, - src/qt/res/icons/warning.png - -Jonas Schnelli ------------------------ - -### Info -* Designer: Jonas Schnelli -* Bitcoin Icon: (based on the original bitcoin logo from Bitboy) -* Some icons are based on Stephan Hutchings Typicons -* License: MIT - -### Assets Used - src/qt/res/icons/about.png, src/qt/res/icons/about_qt.png, - src/qt/res/icons/bitcoin.icns, src/qt/res/icons/bitcoin.ico, - src/qt/res/icons/bitcoin.png, src/qt/res/icons/clock*.png, - src/qt/res/icons/connect[0-3].png, src/qt/res/icons/eye_minus.png, - src/qt/res/icons/eye_plus.png, src/qt/res/icons/verify.png, - src/qt/res/icons/tx_inout.png, src/qt/res/icons/tx_input.png, - src/qt/res/src/verify.svg, src/qt/res/src/bitcoin.svg, - src/qt/res/src/clock*.svg, src/qt/res/src/connect*.svg, - src/qt/res/src/mine.svg, src/qt/res/src/qt.svg, src/qt/res/src/tx*.svg, - src/qt/res/src/verify.svg, +The list of assets used in the bitcoin source and their attribution can now be found in [contrib/debian/copyright](../contrib/debian/copyright). diff --git a/doc/bips.md b/doc/bips.md index 90e98ed419..c84bd966f5 100644 --- a/doc/bips.md +++ b/doc/bips.md @@ -1,4 +1,4 @@ -BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.10.0**): +BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.12.0**): * [`BIP 11`](https://github.com/bitcoin/bips/blob/master/bip-0011.mediawiki): Multisig outputs are standard since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)). * [`BIP 13`](https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki): The address format for P2SH addresses has been implemented since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)). @@ -16,3 +16,4 @@ BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.10.0**): * [`BIP 61`](https://github.com/bitcoin/bips/blob/master/bip-0061.mediawiki): The 'reject' protocol message (and the protocol version bump to 70002) was added in **v0.9.0** ([PR #3185](https://github.com/bitcoin/bitcoin/pull/3185)). * [`BIP 66`](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki): The strict DER rules and associated version 3 blocks have been implemented since **v0.10.0** ([PR #5713](https://github.com/bitcoin/bitcoin/pull/5713)). * [`BIP 70`](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) [`71`](https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki) [`72`](https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki): Payment Protocol support has been available in Bitcoin Core GUI since **v0.9.0** ([PR #5216](https://github.com/bitcoin/bitcoin/pull/5216)). +* [`BIP 111`](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki): `NODE_BLOOM` service bit added, but only enforced for peer versions `>=70011` as of **v0.12.0** ([PR #6579](https://github.com/bitcoin/bitcoin/pull/6579)). diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md new file mode 100644 index 0000000000..28fa784515 --- /dev/null +++ b/doc/build-openbsd.md @@ -0,0 +1,187 @@ +OpenBSD build guide +====================== +(updated for OpenBSD 5.7) + +This guide describes how to build bitcoind and command-line utilities on OpenBSD. + +As OpenBSD is most common as a server OS, we will not bother with the GUI. + +Preparation +------------- + +Run the following as root to install the base dependencies for building: + +```bash +pkg_add gmake libtool libevent +pkg_add autoconf # (select highest version, e.g. 2.69) +pkg_add automake # (select highest version, e.g. 1.15) +pkg_add python # (select version 2.7.x, not 3.x) +ln -sf /usr/local/bin/python2.7 /usr/local/bin/python2 +``` + +The default C++ compiler that comes with OpenBSD 5.7 is g++ 4.2. This version is old (from 2007), and is not able to compile the current version of Bitcoin Core. It is possible to patch it up to compile, but with the planned transition to C++11 this is a losing battle. So here we will be installing a newer compiler. + +GCC +------- + +You can install a newer version of gcc with: + +```bash +pkg_add g++ # (select newest 4.x version, e.g. 4.9.2) +``` + +This compiler will not overwrite the system compiler, it will be installed as `egcc` and `eg++` in `/usr/local/bin`. + +### Building boost + +Do not use `pkg_add boost`! The boost version installed thus is compiled using the `g++` compiler not `eg++`, which will result in a conflict between `/usr/local/lib/libestdc++.so.XX.0` and `/usr/lib/libstdc++.so.XX.0`, resulting in a test crash: + + test_bitcoin:/usr/lib/libstdc++.so.57.0: /usr/local/lib/libestdc++.so.17.0 : WARNING: symbol(_ZN11__gnu_debug17_S_debug_me ssagesE) size mismatch, relink your program + ... + Segmentation fault (core dumped) + +This makes it necessary to build boost, or at least the parts used by Bitcoin Core, manually: + +``` +# Pick some path to install boost to, here we create a directory within the bitcoin directory +BITCOIN_ROOT=$(pwd) +BOOST_PREFIX="${BITCOIN_ROOT}/boost" +mkdir -p $BOOST_PREFIX + +# Fetch the source and verify that it is not tampered with +wget http://heanet.dl.sourceforge.net/project/boost/boost/1.59.0/boost_1_59_0.tar.bz2 +echo '727a932322d94287b62abb1bd2d41723eec4356a7728909e38adb65ca25241ca boost_1_59_0.tar.bz2' | sha256 -c +# MUST output: (SHA256) boost_1_59_0.tar.bz2: OK +tar -xjf boost_1_59_0.tar.bz2 + +# Boost 1.59 needs two small patches for OpenBSD +cd boost_1_59_0 +# Also here: https://gist.githubusercontent.com/laanwj/bf359281dc319b8ff2e1/raw/92250de8404b97bb99d72ab898f4a8cb35ae1ea3/patch-boost_test_impl_execution_monitor_ipp.patch +patch -p0 < /usr/ports/devel/boost/patches/patch-boost_test_impl_execution_monitor_ipp +# https://github.com/boostorg/filesystem/commit/90517e459681790a091566dce27ca3acabf9a70c +sed 's/__OPEN_BSD__/__OpenBSD__/g' < libs/filesystem/src/path.cpp > libs/filesystem/src/path.cpp.tmp +mv libs/filesystem/src/path.cpp.tmp libs/filesystem/src/path.cpp + +# Build w/ minimum configuration necessary for bitcoin +echo 'using gcc : : eg++ : <cxxflags>"-fvisibility=hidden -fPIC" <linkflags>"" <archiver>"ar" <striper>"strip" <ranlib>"ranlib" <rc>"" : ;' > user-config.jam +config_opts="runtime-link=shared threadapi=pthread threading=multi link=static variant=release --layout=tagged --build-type=complete --user-config=user-config.jam -sNO_BZIP2=1" +./bootstrap.sh --without-icu --with-libraries=chrono,filesystem,program_options,system,thread,test +./b2 -d2 -j2 -d1 ${config_opts} --prefix=${BOOST_PREFIX} stage +./b2 -d0 -j4 ${config_opts} --prefix=${BOOST_PREFIX} install +``` + +### OpenSSL + +OpenBSD uses a replacement of OpenSSL: LibreSSL. This can cause compatibility issues, hence `./configure` will bark if you try to compile with this library: + + Detected LibreSSL: This is NOT supported, and may break consensus compatibility! + +To install a 'real' OpenSSL use: + + pkg_add openssl + +Any program linked against this library can only be used after setting the dynamic library path: + + export LD_LIBRARY_PATH="/usr/local/lib/eopenssl" + +(otherwise there will be an error about not being able to find `libcrypto.so.1.0`) + +Alternatively, pass `--with-libressl` to `./configure`, however as the warning says, this is NOT supported, and may cause problems syncing the chain, or the node to fork off the network in unexpected circumstances. + +### Building BerkeleyDB + +BerkeleyDB is only necessary for the wallet functionality. To skip this, pass `--disable-wallet` to `./configure`. + +See "Berkeley DB" in [build_unix.md](build_unix.md) for instructions on how to build BerkeleyDB 4.8. +You cannot use the BerkeleyDB library from ports, for the same reason as boost above (g++/libstd++ incompatibility). + +```bash +# Pick some path to install BDB to, here we create a directory within the bitcoin directory +BITCOIN_ROOT=$(pwd) +BDB_PREFIX="${BITCOIN_ROOT}/db4" +mkdir -p $BDB_PREFIX + +# Fetch the source and verify that it is not tampered with +wget 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz' +echo '12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef db-4.8.30.NC.tar.gz' | sha256 -c +# MUST output: (SHA256) db-4.8.30.NC.tar.gz: OK +tar -xzf db-4.8.30.NC.tar.gz + +# Build the library and install to specified prefix +cd db-4.8.30.NC/build_unix/ +# Note: Do a static build so that it can be embedded into the executable, instead of having to find a .so at runtime +../dist/configure --enable-cxx --disable-shared --with-pic --prefix=$BDB_PREFIX CC=egcc CXX=eg++ CPP=ecpp +make install +``` + +### Building Bitcoin Core + +**Important**: use `gmake`, not `make`. The non-GNU `make` will exit with a horrible error. + +Preparation: +```bash +export AUTOCONF_VERSION=2.69 # replace this with the autoconf version that you installed +export AUTOMAKE_VERSION=1.15 # replace this with the automake version that you installed +./autogen.sh +``` + +To configure with wallet: +```bash +./configure --with-gui=no --with-boost=$BOOST_PREFIX \ + CC=egcc CXX=eg++ CPP=ecpp \ + SSL_CFLAGS="-I/usr/local/include/eopenssl" SSL_LIBS="-L/usr/local/lib/eopenssl -lssl" \ + CRYPTO_CFLAGS="-I/usr/local/include/eopenssl" CRYPTO_LIBS="-L/usr/local/lib/eopenssl -lcrypto" \ + LDFLAGS="-L${BDB_PREFIX}/lib/" CPPFLAGS="-I${BDB_PREFIX}/include/" +``` + +To configure without wallet: +```bash +./configure --disable-wallet --with-gui=no --with-boost=$BOOST_PREFIX \ + CC=egcc CXX=eg++ CPP=ecpp \ + SSL_CFLAGS="-I/usr/local/include/eopenssl" SSL_LIBS="-L/usr/local/lib/eopenssl -lssl" \ + CRYPTO_CFLAGS="-I/usr/local/include/eopenssl" CRYPTO_LIBS="-L/usr/local/lib/eopenssl -lcrypto" +``` + +Build and run the tests: +```bash +gmake +export LD_LIBRARY_PATH="/usr/local/lib/eopenssl" +gmake check +``` + +Clang (not currently working) +------------------------------ + +Using a newer g++ results in linking the new code to a new libstdc++. +Libraries built with the old g++, will still import the old library. +This gives conflicts, necessitating rebuild of all C++ dependencies of the application. + +With clang this can - at least theoretically - be avoided because it uses the +base system's libstdc++. + +```bash +pkg_add llvm boost +``` + +```bash +./configure --disable-wallet --with-gui=no CC=clang CXX=clang++ \ + SSL_CFLAGS="-I/usr/local/include/eopenssl" SSL_LIBS="-L/usr/local/lib/eopenssl -lssl" \ + CRYPTO_CFLAGS="-I/usr/local/include/eopenssl" CRYPTO_LIBS="-L/usr/local/lib/eopenssl -lcrypto" +gmake +``` + +However, this does not appear to work. Compilation succeeds, but link fails +with many 'local symbol discarded' errors: + + local symbol 150: discarded in section `.text._ZN10tinyformat6detail14FormatIterator6finishEv' from libbitcoin_util.a(libbitcoin_util_a-random.o) + local symbol 151: discarded in section `.text._ZN10tinyformat6detail14FormatIterator21streamStateFromFormatERSoRjPKcii' from libbitcoin_util.a(libbitcoin_util_a-random.o) + local symbol 152: discarded in section `.text._ZN10tinyformat6detail12convertToIntIA13_cLb0EE6invokeERA13_Kc' from libbitcoin_util.a(libbitcoin_util_a-random.o) + +According to similar reported errors this is a binutils (ld) issue in 2.15, the +version installed by OpenBSD 5.7: + +- http://openbsd-archive.7691.n7.nabble.com/UPDATE-cppcheck-1-65-td248900.html +- https://llvm.org/bugs/show_bug.cgi?id=9758 + +There is no known workaround for this. + diff --git a/doc/build-osx.md b/doc/build-osx.md index dc319dd1c4..201fe9522b 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -32,7 +32,7 @@ Instructions: Homebrew #### Install dependencies using Homebrew - brew install autoconf automake berkeley-db4 libtool boost miniupnpc openssl pkg-config protobuf qt5 + brew install autoconf automake berkeley-db4 libtool boost miniupnpc openssl pkg-config protobuf qt5 libevent NOTE: Building with Qt4 is still supported, however, could result in a broken UI. As such, building with Qt5 is recommended. @@ -70,7 +70,7 @@ Download Qt Creator from http://www.qt.io/download/. Download the "community edi 6. Confirm the "summary page" 7. In the "Projects" tab select "Manage Kits..." 8. Select the default "Desktop" kit and select "Clang (x86 64bit in /usr/bin)" as compiler -9. Select LLDB as debugger (you might need to set the path to your installtion) +9. Select LLDB as debugger (you might need to set the path to your installation) 10. Start debugging with Qt Creator Creating a release build diff --git a/doc/build-unix.md b/doc/build-unix.md index 92aed7725e..a9a0028c4a 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -1,6 +1,8 @@ UNIX BUILD NOTES ==================== -Some notes on how to build Bitcoin in Unix. +Some notes on how to build Bitcoin in Unix. + +(for OpenBSD specific instructions, see [build-openbsd.md](build-openbsd.md)) Note --------------------- @@ -31,8 +33,9 @@ These dependencies are required: Library | Purpose | Description ------------|------------------|---------------------- - libssl | SSL Support | Secure communications - libboost | Boost | C++ Library + libssl | Crypto | Random Number Generation, Elliptic Curve Cryptography + libboost | Utility | Library for threading, data structures, etc + libevent | Networking | OS independent asynchronous networking Optional dependencies: @@ -43,6 +46,7 @@ Optional dependencies: qt | GUI | GUI toolkit (only needed when GUI enabled) protobuf | Payments in GUI | Data interchange format used for payment protocol (only needed when GUI enabled) libqrencode | QR codes in GUI | Optional for generating QR codes (only needed when GUI enabled) + libzmq3 | ZMQ notification | Optional, allows generating ZMQ notifications (requires ZMQ version >= 4.x) For the versions used in the release, see [release-process.md](release-process.md) under *Fetch and build inputs*. @@ -57,8 +61,8 @@ Dependency Build Instructions: Ubuntu & Debian ---------------------------------------------- Build requirements: - sudo apt-get install build-essential libtool autotools-dev autoconf pkg-config libssl-dev - + sudo apt-get install build-essential libtool autotools-dev autoconf pkg-config libssl-dev libevent-dev + For Ubuntu 12.04 and later or Debian 7 and later libboost-all-dev has to be installed: sudo apt-get install libboost-all-dev @@ -80,6 +84,11 @@ Optional: sudo apt-get install libminiupnpc-dev (see --with-miniupnpc and --enable-upnp-default) +ZMQ dependencies: + + sudo apt-get install libzmq3-dev (provides ZMQ API 4.x) + + Dependencies for the GUI: Ubuntu & Debian ----------------------------------------- @@ -154,7 +163,8 @@ make install # Configure Bitcoin Core to use our own-built instance of BDB cd $BITCOIN_ROOT -./configure (other args...) LDFLAGS="-L${BDB_PREFIX}/lib/" CPPFLAGS="-I${BDB_PREFIX}/include/" +./autogen.sh +./configure LDFLAGS="-L${BDB_PREFIX}/lib/" CPPFLAGS="-I${BDB_PREFIX}/include/" # (other args...) ``` **Note**: You only need Berkeley DB if the wallet is enabled (see the section *Disable-Wallet mode* below). @@ -227,4 +237,3 @@ In this case there is no dependency on Berkeley DB 4.8. Mining is also possible in disable-wallet mode, but only using the `getblocktemplate` RPC call not `getwork`. - diff --git a/doc/developer-notes.md b/doc/developer-notes.md index 7d3d78adfc..8302a78562 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -1,5 +1,5 @@ -Coding -==================== +Coding Standards +================ Various coding styles have been used during the history of the codebase, and the result is not very consistent. However, we're now trying to converge to @@ -171,16 +171,3 @@ Threads - BitcoinMiner : Generates bitcoins (if wallet is enabled). - Shutdown : Does an orderly shutdown of everything. - -Pull Request Terminology ------------------------- - -Concept ACK - Agree with the idea and overall direction, but have neither reviewed nor tested the code changes. - -utACK (untested ACK) - Reviewed and agree with the code changes but haven't actually tested them. - -Tested ACK - Reviewed the code changes and have verified the functionality or bug fix. - -ACK - A loose ACK can be confusing. It's best to avoid them unless it's a documentation/comment only change in which case there is nothing to test/verify; therefore the tested/untested distinction is not there. - -NACK - Disagree with the code changes/concept. Should be accompanied by an explanation. diff --git a/doc/files.md b/doc/files.md index 80195535bb..c083bcb038 100644 --- a/doc/files.md +++ b/doc/files.md @@ -1,12 +1,17 @@ -Used in 0.8.0 ---------------------- -* wallet.dat: personal wallet (BDB) with keys and transactions -* peers.dat: peer IP address database (custom format); since 0.7.0 + +* banlist.dat: stores the IPs/Subnets of banned nodes +* bitcoin.conf: contains configuration settings for bitcoind or bitcoin-qt +* bitcoind.pid: stores the process id of bitcoind while running * blocks/blk000??.dat: block data (custom, 128 MiB per file); since 0.8.0 * blocks/rev000??.dat; block undo data (custom); since 0.8.0 (format changed since pre-0.8) * blocks/index/*; block index (LevelDB); since 0.8.0 * chainstate/*; block chain state database (LevelDB); since 0.8.0 * database/*: BDB database environment; only used for wallet since 0.8.0 +* db.log: wallet database log file +* debug.log: contains debug information and general logging generated by bitcoind or bitcoin-qt +* fee_estimates.dat: stores statistics used to estimate minimum transaction fees and priorities required for confirmation; since 0.10.0 +* peers.dat: peer IP address database (custom format); since 0.7.0 +* wallet.dat: personal wallet (BDB) with keys and transactions Only used in pre-0.8.0 --------------------- diff --git a/doc/gitian-building.md b/doc/gitian-building.md index 630b3c04a7..265fbd586d 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -5,7 +5,7 @@ Gitian building Gitian is the deterministic build process that is used to build the Bitcoin Core executables. It provides a way to be reasonably sure that the -executables are really built from source on GitHub. It also makes sure that +executables are really built from the source on GitHub. 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 @@ -13,8 +13,8 @@ Multiple developers build the source code by following a specific descriptor These results are compared and only if they match, the build is accepted and uploaded to bitcoin.org. -More independent gitian builders are needed, which is why I wrote this -guide. It is preferred to follow these steps yourself instead of using someone else's +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 @@ -39,46 +39,46 @@ This guide explains how to set up the environment, and how to start the builds. Debian Linux was chosen as the host distribution because it has a lightweight install (in contrast to Ubuntu) and is readily available. Any kind of virtualization can be used, for example: -- [VirtualBox](https://www.virtualbox.org/), covered by this guide +- [VirtualBox](https://www.virtualbox.org/) (covered by this guide) - [KVM](http://www.linux-kvm.org/page/Main_Page) - [LXC](https://linuxcontainers.org/), see also [Gitian host docker container](https://github.com/gdm85/tenku/tree/master/docker/gitian-bitcoin-host/README.md). -You can also install on actual hardware instead of using virtualization. +You can also install gitian on actual hardware instead of using virtualization. Create a new VirtualBox VM --------------------------- In the VirtualBox GUI click "Create" and choose the following parameters in the wizard: -![](gitian-building/create_vm_page1.png) +![](gitian-building/create_new_vm.png) -- Type: Linux, Debian (64 bit) +- Type: Linux, Debian (64-bit) ![](gitian-building/create_vm_memsize.png) -- Memory Size: at least 1024MB, anything lower will really slow the build down +- Memory Size: at least 1024MB, anything less will really slow down the build. -![](gitian-building/create_vm_hard_drive.png) +![](gitian-building/create_vm_hard_disk.png) -- Hard Drive: Create a virtual hard drive now +- Hard Disk: Create a virtual hard disk now -![](gitian-building/create_vm_hard_drive_file_type.png) +![](gitian-building/create_vm_hard_disk_file_type.png) -- Hard Drive file type: Use the default, VDI (VirtualBox Disk Image) +- Hard Disk file type: Use the default, VDI (VirtualBox Disk Image) -![](gitian-building/create_vm_storage_physical_hard_drive.png) +![](gitian-building/create_vm_storage_physical_hard_disk.png) -- Storage on Physical hard drive: Dynamically Allocated +- Storage on physical hard disk: Dynamically Allocated ![](gitian-building/create_vm_file_location_size.png) -- Disk size: at least 40GB; as low as 20GB *may* be possible, but better to err on the safe side -- Push the `Create` button +- File location and size: at least 40GB; as low as 20GB *may* be possible, but better to err on the safe side +- Click `Create` -Get the [Debian 7.8 net installer](http://cdimage.debian.org/cdimage/archive/7.8.0/amd64/iso-cd/debian-7.8.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)). +Get the [Debian 8.x net installer](http://cdimage.debian.org/debian-cd/8.2.0/amd64/iso-cd/debian-8.2.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)). This DVD image can be validated using a SHA256 hashing tool, for example on Unixy OSes by entering the following in a terminal: - echo "e39c36d6adc0fd86c6edb0e03e22919086c883b37ca194d063b8e3e8f6ff6a3a debian-7.8.0-amd64-netinst.iso" | sha256sum -c + echo "d393d17ac6b3113c81186e545c416a00f28ed6e05774284bb5e8f0df39fcbcb9 debian-8.2.0-amd64-netinst.iso" | sha256sum -c # (must return OK) After creating the VM, we need to configure it. @@ -115,8 +115,9 @@ This section will explain how to install Debian on the newly created VM. ![](gitian-building/debian_install_1_boot_menu.png) -**Note**: Navigation in the Debian installer: To keep a setting at the default -and proceed, just press `Enter`. To select a different button, press `Tab`. +**Note**: Navigating in the Debian installer: +To keep a setting at the default and proceed, just press `Enter`. +To select a different button, press `Tab`. - Choose locale and keyboard settings (doesn't matter, you can just go with the defaults or select your own information) @@ -126,7 +127,7 @@ and proceed, just press `Enter`. To select a different button, press `Tab`. - The VM will detect network settings using DHCP, this should all proceed automatically - Configure the network: - - System name `debian`. + - Hostname `debian`. - Leave domain name empty. ![](gitian-building/debian_install_5_configure_the_network.png) @@ -136,6 +137,7 @@ and proceed, just press `Enter`. To select a different button, press `Tab`. ![](gitian-building/debian_install_6a_set_up_root_password.png) - Name the new user `debian` (the full name doesn't matter, you can leave it empty) +- Set the account username as `debian` ![](gitian-building/debian_install_7_set_up_user_fullname.png) ![](gitian-building/debian_install_8_set_up_username.png) @@ -158,13 +160,9 @@ and proceed, just press `Enter`. To select a different button, press `Tab`. ![](gitian-building/debian_install_12_choose_disk.png) - - Partitioning scheme: All files in one partition - -![](gitian-building/debian_install_13_partition_scheme.png) - - Finish partitioning and write changes to disk -> *Yes* (`Tab`, `Enter` to select the `Yes` button) -![](gitian-building/debian_install_14_finish.png) +![](gitian-building/debian_install_14_finish.png) ![](gitian-building/debian_install_15_write_changes.png) - The base system will be installed, this will take a minute or so @@ -172,51 +170,79 @@ and proceed, just press `Enter`. To select a different button, press `Tab`. ![](gitian-building/debian_install_16_choose_a_mirror.png) -- Enter proxy information (unless you are on an intranet, you can leave this empty) +- Enter proxy information (unless you are on an intranet, leave this empty) ![](gitian-building/debian_install_18_proxy_settings.png) - Wait a bit while 'Select and install software' runs - Participate in popularity contest -> *No* -- Choose software to install. We need just the base system. +- Choose software to install. We need just the base system. +- Make sure only 'SSH server' and 'Standard System Utilities' are checked +- Uncheck 'Debian Desktop Environment' and 'Print Server' ![](gitian-building/debian_install_19_software_selection.png) -- Make sure only 'SSH server' and 'Standard System Utilities' are checked -- Uncheck 'Debian Desktop Environment' and 'Print Server' +- Install the GRUB boot loader to the master boot record? -> Yes ![](gitian-building/debian_install_20_install_grub.png) -- Install the GRUB boot loader to the master boot record? -> Yes +- Device for boot loader installation -> ata-VBOX_HARDDISK -![](gitian-building/debian_install_21_finish_installation.png) +![](gitian-building/debian_install_21_install_grub_bootloader.png) - Installation Complete -> *Continue* - After installation, the VM will reboot and you will have a working Debian VM. Congratulations! +![](gitian-building/debian_install_22_finish_installation.png) + + +After Installation +------------------- +The next step in the guide involves logging in as root via SSH. +SSH login for root users is disabled by default, so we'll enable that now. + +Login to the VM using username `root` and the root password you choose earlier. +You'll be presented with a screen similar to this. + +![](gitian-building/debian_root_login.png) + +Type: + +``` +sed -i 's/^PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config +``` +and press enter. Then, +``` +/etc/init.d/ssh restart +``` +and enter to restart SSH. Logout by typing 'logout' and pressing 'enter'. + Connecting to the VM ---------------------- After the VM has booted you can connect to it using SSH, and files can be copied from and to the VM using a SFTP utility. Connect to `localhost`, port `22222` (or the port configured when installing the VM). -On Windows you can use putty[1] and WinSCP[2]. +On Windows you can use [putty](http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html) and [WinSCP](http://winscp.net/eng/index.php). -For example to connect as `root` from a Linux command prompt use +For example, to connect as `root` from a Linux command prompt use $ ssh root@localhost -p 22222 The authenticity of host '[localhost]:22222 ([127.0.0.1]:22222)' can't be established. - ECDSA key fingerprint is 8e:71:f9:5b:62:46:de:44:01:da:fb:5f:34:b5:f2:18. + RSA key fingerprint is ae:f5:c8:9f:17:c6:c7:1b:c2:1b:12:31:1d:bb:d0:c7. Are you sure you want to continue connecting (yes/no)? yes - Warning: Permanently added '[localhost]:22222' (ECDSA) to the list of known hosts. + Warning: Permanently added '[localhost]:22222' (RSA) to the list of known hosts. root@localhost's password: (enter root password configured during install) - Linux debian 3.2.0-4-amd64 #1 SMP Debian 3.2.54-2 x86_64 + + The programs included with the Debian GNU/Linux system are free software; + the exact distribution terms for each program are described in the + individual files in /usr/share/doc/*/copyright. + + Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent + permitted by applicable law. root@debian:~# Replace `root` with `debian` to log in as user. -[1] http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html -[2] http://winscp.net/eng/index.php - Setting up Debian for gitian building -------------------------------------- @@ -226,13 +252,10 @@ First we need to log in as `root` to set up dependencies and make sure that our user can use the sudo command. Type/paste the following in the terminal: ```bash -apt-get install git ruby sudo apt-cacher-ng qemu-utils debootstrap lxc python-cheetah parted kpartx bridge-utils +apt-get install git ruby sudo apt-cacher-ng qemu-utils debootstrap lxc python-cheetah parted kpartx bridge-utils make ubuntu-archive-keyring adduser debian sudo ``` -When you get a colorful screen with a question about the 'LXC directory', just -go with the default (`/var/lib/lxc`). - Then set up LXC and the rest with the following, which is a complex jumble of settings and workarounds: ```bash @@ -255,7 +278,7 @@ reboot ``` At the end the VM is rebooted to make sure that the changes take effect. The steps in this -section need only to be performed once. +section only need to be performed once. Installing gitian ------------------ @@ -300,26 +323,27 @@ cd gitian-builder bin/make-base-vm --lxc --arch amd64 --suite precise ``` -There will be a lot of warnings printed during build of the image. These can be ignored. +There will be a lot of warnings printed during the build of the image. These can be ignored. **Note**: When sudo asks for a password, enter the password for the user *debian* not for *root*. Getting and building the inputs -------------------------------- -Follow the instructions in [doc/release-process.md](release-process.md) in the bitcoin repository -under 'Fetch and build inputs' to install sources which require manual intervention. Also follow -the next step: 'Seed the Gitian sources cache', which will fetch all necessary source files allowing -for gitian to work offline. +Follow the instructions in [doc/release-process.md](release-process.md#fetch-and-build-inputs-first-time-or-when-dependency-versions-change) +in the bitcoin repository under 'Fetch and build inputs' to install sources which require +manual intervention. Also optionally follow the next step: 'Seed the Gitian sources cache +and offline git repositories' which will fetch the remaining files required for building +offline. Building Bitcoin ---------------- To build Bitcoin (for Linux, OSX and Windows) just follow the steps under 'perform -gitian builds' in [doc/release-process.md](release-process.md) in the bitcoin repository. +gitian builds' in [doc/release-process.md](release-process.md#perform-gitian-builds) in the bitcoin repository. -This may take a long time as it also builds the dependencies needed for each descriptor. -These dependencies will be cached after a successful build to avoid rebuilding them where possible. +This may take some time as it will build all the dependencies needed for each descriptor. +These dependencies will be cached after a successful build to avoid rebuilding them when possible. At any time you can check the package installation and build progress with @@ -331,13 +355,13 @@ tail -f var/build.log Output from `gbuild` will look something like Initialized empty Git repository in /home/debian/gitian-builder/inputs/bitcoin/.git/ - remote: Reusing existing pack: 35606, done. - remote: Total 35606 (delta 0), reused 0 (delta 0) - Receiving objects: 100% (35606/35606), 26.52 MiB | 4.28 MiB/s, done. - Resolving deltas: 100% (25724/25724), done. + remote: Counting objects: 57959, done. + remote: Total 57959 (delta 0), reused 0 (delta 0), pack-reused 57958 + Receiving objects: 100% (57959/57959), 53.76 MiB | 484.00 KiB/s, done. + Resolving deltas: 100% (41590/41590), done. From https://github.com/bitcoin/bitcoin ... (new tags, new branch etc) - --- Building for precise x86_64 --- + --- Building for precise amd64 --- Stopping target if it is up Making a new image copy stdin: is not a tty @@ -368,6 +392,57 @@ COMMIT=2014_03_windows_unicode_path ./bin/gbuild --commit bitcoin=${COMMIT} --url bitcoin=${URL} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml ``` +Building fully offline +----------------------- + +For building fully offline including attaching signatures to unsigned builds, the detached-sigs repository +and the bitcoin git repository with the desired tag must both be available locally, and then gbuild must be +told where to find them. It also requires an apt-cacher-ng which is fully-populated but set to offline mode, or +manually disabling gitian-builder's use of apt-get to update the VM build environment. + +To configure apt-cacher-ng as an offline cacher, you will need to first populate its cache with the relevant +files. You must additionally patch target-bin/bootstrap-fixup to set its apt sources to something other than +plain archive.ubuntu.com: us.archive.ubuntu.com works. + +So, if you use LXC: + +```bash +export PATH="$PATH":/path/to/gitian-builder/libexec +export USE_LXC=1 +cd /path/to/gitian-builder +./libexec/make-clean-vm --suite precise --arch amd64 + +LXC_ARCH=amd64 LXC_SUITE=precise on-target -u root apt-get update +LXC_ARCH=amd64 LXC_SUITE=precise on-target -u root \ + -e DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends -y install \ + $( sed -ne '/^packages:/,/[^-] .*/ {/^- .*/{s/"//g;s/- //;p}}' ../bitcoin/contrib/gitian-descriptors/*|sort|uniq ) +LXC_ARCH=amd64 LXC_SUITE=precise on-target -u root apt-get -q -y purge grub +LXC_ARCH=amd64 LXC_SUITE=precise on-target -u root -e DEBIAN_FRONTEND=noninteractive apt-get -y dist-upgrade +``` + +And then set offline mode for apt-cacher-ng: + +``` +/etc/apt-cacher-ng/acng.conf +[...] +Offlinemode: 1 +[...] + +service apt-cacher-ng restart +``` + +Then when building, override the remote URLs that gbuild would otherwise pull from the gitian descriptors:: +```bash + +cd /some/root/path/ +git clone https://github.com/bitcoin/bitcoin-detached-sigs.git + +BTCPATH=/some/root/path/bitcoin.git +SIGPATH=/some/root/path/bitcoin-detached-sigs.git + +./bin/gbuild --url bitcoin=${BTCPATH},signature=${SIGPATH} ../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml +``` + Signing externally ------------------- diff --git a/doc/gitian-building/create_new_vm.png b/doc/gitian-building/create_new_vm.png Binary files differnew file mode 100644 index 0000000000..dd22428e17 --- /dev/null +++ b/doc/gitian-building/create_new_vm.png diff --git a/doc/gitian-building/create_vm_hard_disk.png b/doc/gitian-building/create_vm_hard_disk.png Binary files differnew file mode 100644 index 0000000000..8e29816fab --- /dev/null +++ b/doc/gitian-building/create_vm_hard_disk.png diff --git a/doc/gitian-building/create_vm_hard_disk_file_type.png b/doc/gitian-building/create_vm_hard_disk_file_type.png Binary files differnew file mode 100644 index 0000000000..a157211cf5 --- /dev/null +++ b/doc/gitian-building/create_vm_hard_disk_file_type.png diff --git a/doc/gitian-building/create_vm_hard_drive.png b/doc/gitian-building/create_vm_hard_drive.png Binary files differdeleted file mode 100644 index a1706e14fd..0000000000 --- a/doc/gitian-building/create_vm_hard_drive.png +++ /dev/null diff --git a/doc/gitian-building/create_vm_hard_drive_file_type.png b/doc/gitian-building/create_vm_hard_drive_file_type.png Binary files differdeleted file mode 100644 index 251b8ee3e2..0000000000 --- a/doc/gitian-building/create_vm_hard_drive_file_type.png +++ /dev/null diff --git a/doc/gitian-building/create_vm_memsize.png b/doc/gitian-building/create_vm_memsize.png Binary files differindex 33717867a5..5abfee5337 100644 --- a/doc/gitian-building/create_vm_memsize.png +++ b/doc/gitian-building/create_vm_memsize.png diff --git a/doc/gitian-building/create_vm_page1.png b/doc/gitian-building/create_vm_page1.png Binary files differdeleted file mode 100644 index edaebc6223..0000000000 --- a/doc/gitian-building/create_vm_page1.png +++ /dev/null diff --git a/doc/gitian-building/create_vm_storage_physical_hard_disk.png b/doc/gitian-building/create_vm_storage_physical_hard_disk.png Binary files differnew file mode 100644 index 0000000000..cee16a6c63 --- /dev/null +++ b/doc/gitian-building/create_vm_storage_physical_hard_disk.png diff --git a/doc/gitian-building/create_vm_storage_physical_hard_drive.png b/doc/gitian-building/create_vm_storage_physical_hard_drive.png Binary files differdeleted file mode 100644 index 987efaa40c..0000000000 --- a/doc/gitian-building/create_vm_storage_physical_hard_drive.png +++ /dev/null diff --git a/doc/gitian-building/debian_install_10_configure_clock.png b/doc/gitian-building/debian_install_10_configure_clock.png Binary files differindex 467c79018e..7cda038ae4 100644 --- a/doc/gitian-building/debian_install_10_configure_clock.png +++ b/doc/gitian-building/debian_install_10_configure_clock.png diff --git a/doc/gitian-building/debian_install_11_partition_disks.png b/doc/gitian-building/debian_install_11_partition_disks.png Binary files differindex 18110734df..2a648c517f 100644 --- a/doc/gitian-building/debian_install_11_partition_disks.png +++ b/doc/gitian-building/debian_install_11_partition_disks.png diff --git a/doc/gitian-building/debian_install_12_choose_disk.png b/doc/gitian-building/debian_install_12_choose_disk.png Binary files differindex a00d4abf17..0f3acc498e 100644 --- a/doc/gitian-building/debian_install_12_choose_disk.png +++ b/doc/gitian-building/debian_install_12_choose_disk.png diff --git a/doc/gitian-building/debian_install_13_partition_scheme.png b/doc/gitian-building/debian_install_13_partition_scheme.png Binary files differdeleted file mode 100644 index 2f80f19b63..0000000000 --- a/doc/gitian-building/debian_install_13_partition_scheme.png +++ /dev/null diff --git a/doc/gitian-building/debian_install_14_finish.png b/doc/gitian-building/debian_install_14_finish.png Binary files differindex 411d457e95..c8ef0b37ad 100644 --- a/doc/gitian-building/debian_install_14_finish.png +++ b/doc/gitian-building/debian_install_14_finish.png diff --git a/doc/gitian-building/debian_install_15_write_changes.png b/doc/gitian-building/debian_install_15_write_changes.png Binary files differindex f26093982c..d8de00dec6 100644 --- a/doc/gitian-building/debian_install_15_write_changes.png +++ b/doc/gitian-building/debian_install_15_write_changes.png diff --git a/doc/gitian-building/debian_install_16_choose_a_mirror.png b/doc/gitian-building/debian_install_16_choose_a_mirror.png Binary files differindex d2c2e9523b..0bd985b38c 100644 --- a/doc/gitian-building/debian_install_16_choose_a_mirror.png +++ b/doc/gitian-building/debian_install_16_choose_a_mirror.png diff --git a/doc/gitian-building/debian_install_17_choose_a_mirror2.png b/doc/gitian-building/debian_install_17_choose_a_mirror2.png Binary files differdeleted file mode 100644 index cef2db0781..0000000000 --- a/doc/gitian-building/debian_install_17_choose_a_mirror2.png +++ /dev/null diff --git a/doc/gitian-building/debian_install_18_proxy_settings.png b/doc/gitian-building/debian_install_18_proxy_settings.png Binary files differindex 24ba25c109..2c19919f64 100644 --- a/doc/gitian-building/debian_install_18_proxy_settings.png +++ b/doc/gitian-building/debian_install_18_proxy_settings.png diff --git a/doc/gitian-building/debian_install_19_software_selection.png b/doc/gitian-building/debian_install_19_software_selection.png Binary files differindex d462757aff..5430456b14 100644 --- a/doc/gitian-building/debian_install_19_software_selection.png +++ b/doc/gitian-building/debian_install_19_software_selection.png diff --git a/doc/gitian-building/debian_install_1_boot_menu.png b/doc/gitian-building/debian_install_1_boot_menu.png Binary files differindex 27fd849b4f..216502e1c6 100644 --- a/doc/gitian-building/debian_install_1_boot_menu.png +++ b/doc/gitian-building/debian_install_1_boot_menu.png diff --git a/doc/gitian-building/debian_install_20_install_grub.png b/doc/gitian-building/debian_install_20_install_grub.png Binary files differindex de4f9be0c9..d853c15871 100644 --- a/doc/gitian-building/debian_install_20_install_grub.png +++ b/doc/gitian-building/debian_install_20_install_grub.png diff --git a/doc/gitian-building/debian_install_21_install_grub_bootloader.png b/doc/gitian-building/debian_install_21_install_grub_bootloader.png Binary files differnew file mode 100644 index 0000000000..493ab806a6 --- /dev/null +++ b/doc/gitian-building/debian_install_21_install_grub_bootloader.png diff --git a/doc/gitian-building/debian_install_21_finish_installation.png b/doc/gitian-building/debian_install_22_finish_installation.png Binary files differindex b967c3550d..7c4445585b 100644 --- a/doc/gitian-building/debian_install_21_finish_installation.png +++ b/doc/gitian-building/debian_install_22_finish_installation.png diff --git a/doc/gitian-building/debian_install_2_select_a_language.png b/doc/gitian-building/debian_install_2_select_a_language.png Binary files differindex 1c9e0bcfc1..0228ae2c01 100644 --- a/doc/gitian-building/debian_install_2_select_a_language.png +++ b/doc/gitian-building/debian_install_2_select_a_language.png diff --git a/doc/gitian-building/debian_install_3_select_location.png b/doc/gitian-building/debian_install_3_select_location.png Binary files differindex 005c395656..7b18fba975 100644 --- a/doc/gitian-building/debian_install_3_select_location.png +++ b/doc/gitian-building/debian_install_3_select_location.png diff --git a/doc/gitian-building/debian_install_4_configure_keyboard.png b/doc/gitian-building/debian_install_4_configure_keyboard.png Binary files differindex 580c8af7c5..8e46117de4 100644 --- a/doc/gitian-building/debian_install_4_configure_keyboard.png +++ b/doc/gitian-building/debian_install_4_configure_keyboard.png diff --git a/doc/gitian-building/debian_install_5_configure_the_network.png b/doc/gitian-building/debian_install_5_configure_the_network.png Binary files differindex a7fdffc66b..8e3720f243 100644 --- a/doc/gitian-building/debian_install_5_configure_the_network.png +++ b/doc/gitian-building/debian_install_5_configure_the_network.png diff --git a/doc/gitian-building/debian_install_6a_set_up_root_password.png b/doc/gitian-building/debian_install_6a_set_up_root_password.png Binary files differindex 31bd210f38..dcade11967 100644 --- a/doc/gitian-building/debian_install_6a_set_up_root_password.png +++ b/doc/gitian-building/debian_install_6a_set_up_root_password.png diff --git a/doc/gitian-building/debian_install_7_set_up_user_fullname.png b/doc/gitian-building/debian_install_7_set_up_user_fullname.png Binary files differindex bffc6ccd7a..6763c6e08a 100644 --- a/doc/gitian-building/debian_install_7_set_up_user_fullname.png +++ b/doc/gitian-building/debian_install_7_set_up_user_fullname.png diff --git a/doc/gitian-building/debian_install_8_set_up_username.png b/doc/gitian-building/debian_install_8_set_up_username.png Binary files differindex 9e2750ad4e..bb04de96d2 100644 --- a/doc/gitian-building/debian_install_8_set_up_username.png +++ b/doc/gitian-building/debian_install_8_set_up_username.png diff --git a/doc/gitian-building/debian_install_9_user_password.png b/doc/gitian-building/debian_install_9_user_password.png Binary files differindex a26d30cba5..981f1181d7 100644 --- a/doc/gitian-building/debian_install_9_user_password.png +++ b/doc/gitian-building/debian_install_9_user_password.png diff --git a/doc/gitian-building/debian_root_login.png b/doc/gitian-building/debian_root_login.png Binary files differnew file mode 100644 index 0000000000..14cdd5ba5b --- /dev/null +++ b/doc/gitian-building/debian_root_login.png diff --git a/doc/gitian-building/network_settings.png b/doc/gitian-building/network_settings.png Binary files differindex 1d9b6428a7..9e714fd154 100644 --- a/doc/gitian-building/network_settings.png +++ b/doc/gitian-building/network_settings.png diff --git a/doc/gitian-building/port_forwarding_rules.png b/doc/gitian-building/port_forwarding_rules.png Binary files differindex e45c9efffc..9e1fa2af20 100644 --- a/doc/gitian-building/port_forwarding_rules.png +++ b/doc/gitian-building/port_forwarding_rules.png diff --git a/doc/gitian-building/select_startup_disk.png b/doc/gitian-building/select_startup_disk.png Binary files differindex 729b368fd1..5acdc3fe10 100644 --- a/doc/gitian-building/select_startup_disk.png +++ b/doc/gitian-building/select_startup_disk.png diff --git a/doc/init.md b/doc/init.md index 1f206a6c02..ed9ce72154 100644 --- a/doc/init.md +++ b/doc/init.md @@ -29,28 +29,32 @@ file, however it is recommended that a strong and secure password be used as this password is security critical to securing the wallet should the wallet be enabled. -If bitcoind is run with "-daemon" flag, and no rpcpassword is set, it will -print a randomly generated suitable password to stderr. You can also -generate one from the shell yourself like this: +If bitcoind is run with the "-server" flag (set by default), and no rpcpassword is set, +it will use a special cookie file for authentication. The cookie is generated with random +content when the daemon starts, and deleted when it exits. Read access to this file +controls who can access it through RPC. -bash -c 'tr -dc a-zA-Z0-9 < /dev/urandom | head -c32 && echo' +By default the cookie is stored in the data directory, but it's location can be overridden +with the option '-rpccookiefile'. -Once you have a password in hand, set rpcpassword= in /etc/bitcoin/bitcoin.conf +This allows for running bitcoind without having to do any manual configuration. + +`conf`, `pid`, and `wallet` accept relative paths which are interpreted as +relative to the data directory. `wallet` *only* supports relative paths. For an example configuration file that describes the configuration settings, -see contrib/debian/examples/bitcoin.conf. +see `contrib/debian/examples/bitcoin.conf`. 3. Paths --------------------------------- All three configurations assume several paths that might need to be adjusted. -Binary: /usr/bin/bitcoind -Configuration file: /etc/bitcoin/bitcoin.conf -Data directory: /var/lib/bitcoind -PID file: /var/run/bitcoind/bitcoind.pid (OpenRC and Upstart) - /var/lib/bitcoind/bitcoind.pid (systemd) -Lock file: /var/lock/subsys/bitcoind (CentOS) +Binary: `/usr/bin/bitcoind` +Configuration file: `/etc/bitcoin/bitcoin.conf` +Data directory: `/var/lib/bitcoind` +PID file: `/var/run/bitcoind/bitcoind.pid` (OpenRC and Upstart) or `/var/lib/bitcoind/bitcoind.pid` (systemd) +Lock file: `/var/lock/subsys/bitcoind` (CentOS) The configuration file, PID directory (if applicable) and data directory should all be owned by the bitcoin user and group. It is advised for security @@ -65,21 +69,21 @@ can then be controlled by group membership. Installing this .service file consists of just copying it to /usr/lib/systemd/system directory, followed by the command -"systemctl daemon-reload" in order to update running systemd configuration. +`systemctl daemon-reload` in order to update running systemd configuration. -To test, run "systemctl start bitcoind" and to enable for system startup run -"systemctl enable bitcoind" +To test, run `systemctl start bitcoind` and to enable for system startup run +`systemctl enable bitcoind` 4b) OpenRC Rename bitcoind.openrc to bitcoind and drop it in /etc/init.d. Double check ownership and permissions and make it executable. Test it with -"/etc/init.d/bitcoind start" and configure it to run on startup with -"rc-update add bitcoind" +`/etc/init.d/bitcoind start` and configure it to run on startup with +`rc-update add bitcoind` 4c) Upstart (for Debian/Ubuntu based distributions) -Drop bitcoind.conf in /etc/init. Test by running "service bitcoind start" +Drop bitcoind.conf in /etc/init. Test by running `service bitcoind start` it will automatically start on reboot. NOTE: This script is incompatible with CentOS 5 and Amazon Linux 2014 as they @@ -87,7 +91,7 @@ use old versions of Upstart and do not supply the start-stop-daemon utility. 4d) CentOS -Copy bitcoind.init to /etc/init.d/bitcoind. Test by running "service bitcoind start". +Copy bitcoind.init to /etc/init.d/bitcoind. Test by running `service bitcoind start`. Using this script, you can adjust the path and flags to the bitcoind program by setting the BITCOIND and FLAGS environment variables in the file @@ -99,4 +103,3 @@ setting the BITCOIND and FLAGS environment variables in the file Auto respawning is currently only configured for Upstart and systemd. Reasonable defaults have been chosen but YMMV. - diff --git a/doc/release-notes.md b/doc/release-notes.md index 7480a7cd21..70623a3939 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -4,6 +4,59 @@ release-notes at release time) Notable changes =============== +SSL support for RPC dropped +---------------------------- + +SSL support for RPC, previously enabled by the option `rpcssl` has been dropped +from both the client and the server. This was done in preparation for removing +the dependency on OpenSSL for the daemon completely. + +Trying to use `rpcssl` will result in an error: + + Error: SSL mode for RPC (-rpcssl) is no longer supported. + +If you are one of the few people that relies on this feature, a flexible +migration path is to use `stunnel`. This is an utility that can tunnel +arbitrary TCP connections inside SSL. On e.g. Ubuntu it can be installed with: + + sudo apt-get install stunnel4 + +Then, to tunnel a SSL connection on 28332 to a RPC server bound on localhost on port 18332 do: + + stunnel -d 28332 -r 127.0.0.1:18332 -p stunnel.pem -P '' + +It can also be set up system-wide in inetd style. + +Another way to re-attain SSL would be to setup a httpd reverse proxy. This solution +would allow the use of different authentication, loadbalancing, on-the-fly compression and +caching. A sample config for apache2 could look like: + + Listen 443 + + NameVirtualHost *:443 + <VirtualHost *:443> + + SSLEngine On + SSLCertificateFile /etc/apache2/ssl/server.crt + SSLCertificateKeyFile /etc/apache2/ssl/server.key + + <Location /bitcoinrpc> + ProxyPass http://127.0.0.1:8332/ + ProxyPassReverse http://127.0.0.1:8332/ + # optional enable digest auth + # AuthType Digest + # ... + + # optional bypass bitcoind rpc basic auth + # RequestHeader set Authorization "Basic <hash>" + # get the <hash> from the shell with: base64 <<< bitcoinrpc:<password> + </Location> + + # Or, balance the load: + # ProxyPass / balancer://balancer_cluster_name + + </VirtualHost> + Random-cookie RPC authentication --------------------------------- @@ -27,6 +80,40 @@ Low-level RPC API changes advantage if a JSON library insists on using a lossy floating point type for numbers, which would be dangerous for monetary amounts. +Option parsing behavior +----------------------- + +Command line options are now parsed strictly in the order in which they are +specified. It used to be the case that `-X -noX` ends up, unintuitively, with X +set, as `-X` had precedence over `-noX`. This is no longer the case. Like for +other software, the last specified value for an option will hold. + +`NODE_BLOOM` service bit +------------------------ + +Support for the `NODE_BLOOM` service bit, as described in [BIP +111](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki), has been +added to the P2P protocol code. + +BIP 111 defines a service bit to allow peers to advertise that they support +bloom filters (such as used by SPV clients) explicitly. It also bumps the protocol +version to allow peers to identify old nodes which allow bloom filtering of the +connection despite lacking the new service bit. + +In this version, it is only enforced for peers that send protocol versions +`>=70011`. For the next major version it is planned that this restriction will be +removed. It is recommended to update SPV clients to check for the `NODE_BLOOM` +service bit for nodes that report versions newer than 70011. + +Merkle branches removed from wallet +----------------------------------- + +Previously, every wallet transaction stored a Merkle branch to prove its +presence in blocks. This wasn't being used for more than an expensive +sanity check. Since 0.12, these are no longer stored. When loading a +0.12 wallet into an older version, it will automatically rescan to avoid +failed checks. + 0.12.0 Change log ================= @@ -37,6 +124,33 @@ git merge commit are mentioned. ### RPC and REST +Asm representations of scriptSig signatures now contain SIGHASH type decodes +---------------------------------------------------------------------------- + +The `asm` property of each scriptSig now contains the decoded signature hash +type for each signature that provides a valid defined hash type. + +The following items contain assembly representations of scriptSig signatures +and are affected by this change: + +- RPC `getrawtransaction` +- RPC `decoderawtransaction` +- REST `/rest/tx/` (JSON format) +- REST `/rest/block/` (JSON format when including extended tx details) +- `bitcoin-tx -json` + +For example, the `scriptSig.asm` property of a transaction input that +previously showed an assembly representation of: + + 304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c509001 + +now shows as: + + 304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090[ALL] + +Note that the output of the RPC `decodescript` did not change because it is +configured specifically to process scriptPubKey and not scriptSig scripts. + ### Configuration and command-line options ### Block and transaction handling @@ -55,3 +169,13 @@ git merge commit are mentioned. ### Miscellaneous +- Removed bitrpc.py from contrib + +Addition of ZMQ-based Notifcations +================================== + +Bitcoind can now (optionally) asynchronously notify clients through a +ZMQ-based PUB socket of the arrival of new transactions and blocks. +This feature requires installation of the ZMQ C API library 4.x and +configuring its use through the command line or configuration file. +Please see docs/zmq.md for details of operation. diff --git a/doc/release-notes/release-notes-0.10.1.md b/doc/release-notes/release-notes-0.10.1.md index 5e939600a0..8f59f1f68c 100644 --- a/doc/release-notes/release-notes-0.10.1.md +++ b/doc/release-notes/release-notes-0.10.1.md @@ -101,7 +101,7 @@ Tests: Miscellaneous: - `c9e022b` Initialization: set Boost path locale in main thread - `23126a0` Sanitize command strings before logging them. -- `323de27` Initialization: setup environment before starting QT tests +- `323de27` Initialization: setup environment before starting Qt tests - `7494e09` Initialization: setup environment before starting tests - `df45564` Initialization: set fallback locale as environment variable diff --git a/doc/release-notes/release-notes-0.11.0.md b/doc/release-notes/release-notes-0.11.0.md new file mode 100644 index 0000000000..28e49fb7ea --- /dev/null +++ b/doc/release-notes/release-notes-0.11.0.md @@ -0,0 +1,505 @@ +Bitcoin Core version 0.11.0 is now available from: + + <https://bitcoin.org/bin/bitcoin-core-0.11.0/> + +This is a new major version release, bringing both new features and +bug fixes. + +Please report bugs using the issue tracker at github: + + <https://github.com/bitcoin/bitcoin/issues> + +Upgrading and downgrading +========================= + +How to Upgrade +-------------- + +If you are running an older version, shut it down. Wait until it has completely +shut down (which might take a few minutes for older versions), then run the +installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or +bitcoind/bitcoin-qt (on Linux). + +Downgrade warning +------------------ + +Because release 0.10.0 and later makes use of headers-first synchronization and +parallel block download (see further), the block files and databases are not +backwards-compatible with pre-0.10 versions of Bitcoin Core or other software: + +* Blocks will be stored on disk out of order (in the order they are +received, really), which makes it incompatible with some tools or +other programs. Reindexing using earlier versions will also not work +anymore as a result of this. + +* The block index database will now hold headers for which no block is +stored on disk, which earlier versions won't support. + +If you want to be able to downgrade smoothly, make a backup of your entire data +directory. Without this your node will need start syncing (or importing from +bootstrap.dat) anew afterwards. It is possible that the data from a completely +synchronised 0.10 node may be usable in older versions as-is, but this is not +supported and may break as soon as the older version attempts to reindex. + +This does not affect wallet forward or backward compatibility. There are no +known problems when downgrading from 0.11.x to 0.10.x. + +Important information +====================== + +Transaction flooding +--------------------- + +At the time of this release, the P2P network is being flooded with low-fee +transactions. This causes a ballooning of the mempool size. + +If this growth of the mempool causes problematic memory use on your node, it is +possible to change a few configuration options to work around this. The growth +of the mempool can be monitored with the RPC command `getmempoolinfo`. + +One is to increase the minimum transaction relay fee `minrelaytxfee`, which +defaults to 0.00001. This will cause transactions with fewer BTC/kB fee to be +rejected, and thus fewer transactions entering the mempool. + +The other is to restrict the relaying of free transactions with +`limitfreerelay`. This option sets the number of kB/minute at which +free transactions (with enough priority) will be accepted. It defaults to 15. +Reducing this number reduces the speed at which the mempool can grow due +to free transactions. + +For example, add the following to `bitcoin.conf`: + + minrelaytxfee=0.00005 + limitfreerelay=5 + +More robust solutions are being worked on for a follow-up release. + +Notable changes +=============== + +Block file pruning +---------------------- + +This release supports running a fully validating node without maintaining a copy +of the raw block and undo data on disk. To recap, there are four types of data +related to the blockchain in the bitcoin system: the raw blocks as received over +the network (blk???.dat), the undo data (rev???.dat), the block index and the +UTXO set (both LevelDB databases). The databases are built from the raw data. + +Block pruning allows Bitcoin Core to delete the raw block and undo data once +it's been validated and used to build the databases. At that point, the raw data +is used only to relay blocks to other nodes, to handle reorganizations, to look +up old transactions (if -txindex is enabled or via the RPC/REST interfaces), or +for rescanning the wallet. The block index continues to hold the metadata about +all blocks in the blockchain. + +The user specifies how much space to allot for block & undo files. The minimum +allowed is 550MB. Note that this is in addition to whatever is required for the +block index and UTXO databases. The minimum was chosen so that Bitcoin Core will +be able to maintain at least 288 blocks on disk (two days worth of blocks at 10 +minutes per block). In rare instances it is possible that the amount of space +used will exceed the pruning target in order to keep the required last 288 +blocks on disk. + +Block pruning works during initial sync in the same way as during steady state, +by deleting block files "as you go" whenever disk space is allocated. Thus, if +the user specifies 550MB, once that level is reached the program will begin +deleting the oldest block and undo files, while continuing to download the +blockchain. + +For now, block pruning disables block relay. In the future, nodes with block +pruning will at a minimum relay "new" blocks, meaning blocks that extend their +active chain. + +Block pruning is currently incompatible with running a wallet due to the fact +that block data is used for rescanning the wallet and importing keys or +addresses (which require a rescan.) However, running the wallet with block +pruning will be supported in the near future, subject to those limitations. + +Block pruning is also incompatible with -txindex and will automatically disable +it. + +Once you have pruned blocks, going back to unpruned state requires +re-downloading the entire blockchain. To do this, re-start the node with +-reindex. Note also that any problem that would cause a user to reindex (e.g., +disk corruption) will cause a pruned node to redownload the entire blockchain. +Finally, note that when a pruned node reindexes, it will delete any blk???.dat +and rev???.dat files in the data directory prior to restarting the download. + +To enable block pruning on the command line: + +- `-prune=N`: where N is the number of MB to allot for raw block & undo data. + +Modified RPC calls: + +- `getblockchaininfo` now includes whether we are in pruned mode or not. +- `getblock` will check if the block's data has been pruned and if so, return an +error. +- `getrawtransaction` will no longer be able to locate a transaction that has a +UTXO but where its block file has been pruned. + +Pruning is disabled by default. + +Big endian support +-------------------- + +Experimental support for big-endian CPU architectures was added in this +release. All little-endian specific code was replaced with endian-neutral +constructs. This has been tested on at least MIPS and PPC hosts. The build +system will automatically detect the endianness of the target. + +Memory usage optimization +-------------------------- + +There have been many changes in this release to reduce the default memory usage +of a node, among which: + +- Accurate UTXO cache size accounting (#6102); this makes the option `-dbcache` + precise where this grossly underestimated memory usage before +- Reduce size of per-peer data structure (#6064 and others); this increases the + number of connections that can be supported with the same amount of memory +- Reduce the number of threads (#5964, #5679); lowers the amount of (esp. + virtual) memory needed + +Fee estimation changes +---------------------- + +This release improves the algorithm used for fee estimation. Previously, -1 +was returned when there was insufficient data to give an estimate. Now, -1 +will also be returned when there is no fee or priority high enough for the +desired confirmation target. In those cases, it can help to ask for an estimate +for a higher target number of blocks. It is not uncommon for there to be no +fee or priority high enough to be reliably (85%) included in the next block and +for this reason, the default for `-txconfirmtarget=n` has changed from 1 to 2. + +Privacy: Disable wallet transaction broadcast +---------------------------------------------- + +This release adds an option `-walletbroadcast=0` to prevent automatic +transaction broadcast and rebroadcast (#5951). This option allows separating +transaction submission from the node functionality. + +Making use of this, third-party scripts can be written to take care of +transaction (re)broadcast: + +- Send the transaction as normal, either through RPC or the GUI +- Retrieve the transaction data through RPC using `gettransaction` (NOT + `getrawtransaction`). The `hex` field of the result will contain the raw + hexadecimal representation of the transaction +- The transaction can then be broadcasted through arbitrary mechanisms + supported by the script + +One such application is selective Tor usage, where the node runs on the normal +internet but transactions are broadcasted over Tor. + +For an example script see [bitcoin-submittx](https://github.com/laanwj/bitcoin-submittx). + +Privacy: Stream isolation for Tor +---------------------------------- + +This release adds functionality to create a new circuit for every peer +connection, when the software is used with Tor. The new option, +`-proxyrandomize`, is on by default. + +When enabled, every outgoing connection will (potentially) go through a +different exit node. That significantly reduces the chance to get unlucky and +pick a single exit node that is either malicious, or widely banned from the P2P +network. This improves connection reliability as well as privacy, especially +for the initial connections. + +**Important note:** If a non-Tor SOCKS5 proxy is configured that supports +authentication, but doesn't require it, this change may cause that proxy to reject +connections. A user and password is sent where they weren't before. This setup +is exceedingly rare, but in this case `-proxyrandomize=0` can be passed to +disable the behavior. + +0.11.0 Change log +================= + +Detailed release notes follow. This overview includes changes that affect +behavior, not code moves, refactors and string updates. For convenience in locating +the code changes and accompanying discussion, both the pull request and +git merge commit are mentioned. + +### RPC and REST +- #5461 `5f7279a` signrawtransaction: validate private key +- #5444 `103f66b` Add /rest/headers/<count>/<hash>.<ext> +- #4964 `95ecc0a` Add scriptPubKey field to validateaddress RPC call +- #5476 `c986972` Add time offset into getpeerinfo output +- #5540 `84eba47` Add unconfirmed and immature balances to getwalletinfo +- #5599 `40e96a3` Get rid of the internal miner's hashmeter +- #5711 `87ecfb0` Push down RPC locks +- #5754 `1c4e3f9` fix getblocktemplate lock issue +- #5756 `5d901d8` Fix getblocktemplate_proposals test by mining one block +- #5548 `d48ce48` Add /rest/chaininfos +- #5992 `4c4f1b4` Push down RPC reqWallet flag +- #6036 `585b5db` Show zero value txouts in listunspent +- #5199 `6364408` Add RPC call `gettxoutproof` to generate and verify merkle blocks +- #5418 `16341cc` Report missing inputs in sendrawtransaction +- #5937 `40f5e8d` show script verification errors in signrawtransaction result +- #5420 `1fd2d39` getutxos REST command (based on Bip64) +- #6193 `42746b0` [REST] remove json input for getutxos, limit to query max. 15 outpoints +- #6226 `5901596` json: fail read_string if string contains trailing garbage + +### Configuration and command-line options +- #5636 `a353ad4` Add option `-allowselfsignedrootcertificate` to allow self signed root certs (for testing payment requests) +- #5900 `3e8a1f2` Add a consistency check `-checkblockindex` for the block chain data structures +- #5951 `7efc9cf` Make it possible to disable wallet transaction broadcast (using `-walletbroadcast=0`) +- #5911 `b6ea3bc` privacy: Stream isolation for Tor (on by default, use `-proxyrandomize=0` to disable) +- #5863 `c271304` Add autoprune functionality (`-prune=<size>`) +- #6153 `0bcf04f` Parameter interaction: disable upnp if -proxy set +- #6274 `4d9c7fe` Add option `-alerts` to opt out of alert system + +### Block and transaction handling +- #5367 `dcc1304` Do all block index writes in a batch +- #5253 `203632d` Check against MANDATORY flags prior to accepting to mempool +- #5459 `4406c3e` Reject headers that build on an invalid parent +- #5481 `055f3ae` Apply AreSane() checks to the fees from the network +- #5580 `40d65eb` Preemptively catch a few potential bugs +- #5349 `f55c5e9` Implement test for merkle tree malleability in CPartialMerkleTree +- #5564 `a89b837` clarify obscure uses of EvalScript() +- #5521 `8e4578a` Reject non-final txs even in testnet/regtest +- #5707 `6af674e` Change hardcoded character constants to descriptive named constants for db keys +- #5286 `fcf646c` Change the default maximum OP_RETURN size to 80 bytes +- #5710 `175d86e` Add more information to errors in ReadBlockFromDisk +- #5948 `b36f1ce` Use GetAncestor to compute new target +- #5959 `a0bfc69` Add additional block index consistency checks +- #6058 `7e0e7f8` autoprune minor post-merge improvements +- #5159 `2cc1372` New fee estimation code +- #6102 `6fb90d8` Implement accurate UTXO cache size accounting +- #6129 `2a82298` Bug fix for clearing fCheckForPruning +- #5947 `e9af4e6` Alert if it is very likely we are getting a bad chain +- #6203 `c00ae64` Remove P2SH coinbase flag, no longer interesting +- #5985 `37b4e42` Fix removing of orphan transactions +- #6221 `6cb70ca` Prune: Support noncontiguous block files +- #6256 `fce474c` Use best header chain timestamps to detect partitioning +- #6233 `a587606` Advance pindexLastCommonBlock for blocks in chainActive + +### P2P protocol and network code +- #5507 `844ace9` Prevent DOS attacks on in-flight data structures +- #5770 `32a8b6a` Sanitize command strings before logging them +- #5859 `dd4ffce` Add correct bool combiner for net signals +- #5876 `8e4fd0c` Add a NODE_GETUTXO service bit and document NODE_NETWORK +- #6028 `b9311fb` Move nLastTry from CAddress to CAddrInfo +- #5662 `5048465` Change download logic to allow calling getdata on inbound peers +- #5971 `18d2832` replace absolute sleep with conditional wait +- #5918 `7bf5d5e` Use equivalent PoW for non-main-chain requests +- #6059 `f026ab6` chainparams: use SeedSpec6's rather than CAddress's for fixed seeds +- #6080 `31c0bf1` Add jonasschnellis dns seeder +- #5976 `9f7809f` Reduce download timeouts as blocks arrive +- #6172 `b4bbad1` Ignore getheaders requests when not synced +- #5875 `304892f` Be stricter in processing unrequested blocks +- #6333 `41bbc85` Hardcoded seeds update June 2015 + +### Validation +- #5143 `48e1765` Implement BIP62 rule 6 +- #5713 `41e6e4c` Implement BIP66 + +### Build system +- #5501 `c76c9d2` Add mips, mipsel and aarch64 to depends platforms +- #5334 `cf87536` libbitcoinconsensus: Add pkg-config support +- #5514 `ed11d53` Fix 'make distcheck' +- #5505 `a99ef7d` Build winshutdownmonitor.cpp on Windows only +- #5582 `e8a6639` Osx toolchain update +- #5684 `ab64022` osx: bump build sdk to 10.9 +- #5695 `23ef5b7` depends: latest config.guess and config.sub +- #5509 `31dedb4` Fixes when compiling in c++11 mode +- #5819 `f8e68f7` release: use static libstdc++ and disable reduced exports by default +- #5510 `7c3fbc3` Big endian support +- #5149 `c7abfa5` Add script to verify all merge commits are signed +- #6082 `7abbb7e` qt: disable qt tests when one of the checks for the gui fails +- #6244 `0401aa2` configure: Detect (and reject) LibreSSL +- #6269 `95aca44` gitian: Use the new bitcoin-detached-sigs git repo for OSX signatures +- #6285 `ef1d506` Fix scheduler build with some boost versions. +- #6280 `25c2216` depends: fix Boost 1.55 build on GCC 5 +- #6303 `b711599` gitian: add a gitian-win-signer descriptor +- #6246 `8ea6d37` Fix build on FreeBSD +- #6282 `daf956b` fix crash on shutdown when e.g. changing -txindex and abort action +- #6354 `bdf0d94` Gitian windows signing normalization + +### Wallet +- #2340 `811c71d` Discourage fee sniping with nLockTime +- #5485 `d01bcc4` Enforce minRelayTxFee on wallet created tx and add a maxtxfee option +- #5508 `9a5cabf` Add RandAddSeedPerfmon to MakeNewKey +- #4805 `8204e19` Do not flush the wallet in AddToWalletIfInvolvingMe(..) +- #5319 `93b7544` Clean up wallet encryption code +- #5831 `df5c246` Subtract fee from amount +- #6076 `6c97fd1` wallet: fix boost::get usage with boost 1.58 +- #5511 `23c998d` Sort pending wallet transactions before reaccepting +- #6126 `26e08a1` Change default nTxConfirmTarget to 2 +- #6183 `75a4d51` Fix off-by-one error w/ nLockTime in the wallet +- #6276 `c9fd907` Fix getbalance * 0 + +### GUI +- #5219 `f3af0c8` New icons +- #5228 `bb3c75b` HiDPI (retina) support for splash screen +- #5258 `73cbf0a` The RPC Console should be a QWidget to make window more independent +- #5488 `851dfc7` Light blue icon color for regtest +- #5547 `a39aa74` New icon for the debug window +- #5493 `e515309` Adopt style colour for button icons +- #5557 `70477a0` On close of splashscreen interrupt verifyDB +- #5559 `83be8fd` Make the command-line-args dialog better +- #5144 `c5380a9` Elaborate on signverify message dialog warning +- #5489 `d1aa3c6` Optimize PNG files +- #5649 `e0cd2f5` Use text-color icons for system tray Send/Receive menu entries +- #5651 `848f55d` Coin Control: Use U+2248 "ALMOST EQUAL TO" rather than a simple tilde +- #5626 `ab0d798` Fix icon sizes and column width +- #5683 `c7b22aa` add new osx dmg background picture +- #5620 `7823598` Payment request expiration bug fix +- #5729 `9c4a5a5` Allow unit changes for read-only BitcoinAmountField +- #5753 `0f44672` Add bitcoin logo to about screen +- #5629 `a956586` Prevent amount overflow problem with payment requests +- #5830 `215475a` Don't save geometry for options and about/help window +- #5793 `d26f0b2` Honor current network when creating autostart link +- #5847 `f238add` Startup script for centos, with documentation +- #5915 `5bd3a92` Fix a static qt5 crash when using certain versions of libxcb +- #5898 `bb56781` Fix rpc console font size to flexible metrics +- #5467 `bc8535b` Payment request / server work - part 2 +- #6161 `180c164` Remove movable option for toolbar +- #6160 `0d862c2` Overviewpage: make sure warning icons gets colored + +### Tests +- #5453 `2f2d337` Add ability to run single test manually to RPC tests +- #5421 `886eb57` Test unexecuted OP_CODESEPARATOR +- #5530 `565b300` Additional rpc tests +- #5611 `37b185c` Fix spurious windows test failures after 012598880c +- #5613 `2eda47b` Fix smartfees test for change to relay policy +- #5612 `e3f5727` Fix zapwallettxes test +- #5642 `30a5b5f` Prepare paymentservertests for new unit tests +- #5784 `e3a3cd7` Fix usage of NegateSignatureS in script_tests +- #5813 `ee9f2bf` Add unit tests for next difficulty calculations +- #5855 `d7989c0` Travis: run unit tests in different orders +- #5852 `cdae53e` Reinitialize state in between individual unit tests. +- #5883 `164d7b6` tests: add a BasicTestingSetup and apply to all tests +- #5940 `446bb70` Regression test for ResendWalletTransactions +- #6052 `cf7adad` fix and enable bip32 unit test +- #6039 `734f80a` tests: Error when setgenerate is used on regtest +- #6074 `948beaf` Correct the PUSHDATA4 minimal encoding test in script_invalid.json +- #6032 `e08886d` Stop nodes after RPC tests, even with --nocleanup +- #6075 `df1609f` Add additional script edge condition tests +- #5981 `da38dc6` Python P2P testing +- #5958 `9ef00c3` Add multisig rpc tests +- #6112 `fec5c0e` Add more script edge condition tests + +### Miscellaneous +- #5457, #5506, #5952, #6047 Update libsecp256k1 +- #5437 `84857e8` Add missing CAutoFile::IsNull() check in main +- #5490 `ec20fd7` Replace uint256/uint160 with opaque blobs where possible +- #5654, #5764 Adding jonasschnelli's GPG key +- #5477 `5f04d1d` OS X 10.10: LSSharedFileListItemResolve() is deprecated +- #5679 `beff11a` Get rid of DetectShutdownThread +- #5787 `9bd8c9b` Add fanquake PGP key +- #5366 `47a79bb` No longer check osx compatibility in RenameThread +- #5689 `07f4386` openssl: abstract out OPENSSL_cleanse +- #5708 `8b298ca` Add list of implemented BIPs +- #5809 `46bfbe7` Add bitcoin-cli man page +- #5839 `86eb461` keys: remove libsecp256k1 verification until it's actually supported +- #5749 `d734d87` Help messages correctly formatted (79 chars) +- #5884 `7077fe6` BUGFIX: Stack around the variable 'rv' was corrupted +- #5849 `41259ca` contrib/init/bitcoind.openrc: Compatibility with previous OpenRC init script variables +- #5950 `41113e3` Fix locale fallback and guard tests against invalid locale settings +- #5965 `7c6bfb1` Add git-subtree-check.sh script +- #6033 `1623f6e` FreeBSD, OpenBSD thread renaming +- #6064 `b46e7c2` Several changes to mruset +- #6104 `3e2559c` Show an init message while activating best chain +- #6125 `351f73e` Clean up parsing of bool command line args +- #5964 `b4c219b` Lightweight task scheduler +- #6116 `30dc3c1` [OSX] rename Bitcoin-Qt.app to Bitcoin-Core.app +- #6168 `b3024f0` contrib/linearize: Support linearization of testnet blocks +- #6098 `7708fcd` Update Windows resource files (and add one for bitcoin-tx) +- #6159 `e1412d3` Catch errors on datadir lock and pidfile delete +- #6186 `182686c` Fix two problems in CSubnet parsing +- #6174 `df992b9` doc: add translation strings policy +- #6210 `dfdb6dd` build: disable optional use of gmp in internal secp256k1 build +- #6264 `94cd705` Remove translation for -help-debug options +- #6286 `3902c15` Remove berkeley-db4 workaround in MacOSX build docs +- #6319 `3f8fcc9` doc: update mailing list address + +Credits +======= + +Thanks to everyone who directly contributed to this release: + +- 21E14 +- Adam Weiss +- Alex Morcos +- ayeowch +- azeteki +- Ben Holden-Crowther +- bikinibabe +- BitcoinPRReadingGroup +- Blake Jakopovic +- BtcDrak +- charlescharles +- Chris Arnesen +- Ciemon +- CohibAA +- Corinne Dashjr +- Cory Fields +- Cozz Lovan +- Daira Hopwood +- Daniel Kraft +- Dave Collins +- David A. Harding +- dexX7 +- Earlz +- Eric Lombrozo +- Eric R. Schulz +- Everett Forth +- Flavien Charlon +- fsb4000 +- Gavin Andresen +- Gregory Maxwell +- Heath +- Ivan Pustogarov +- Jacob Welsh +- Jameson Lopp +- Jason Lewicki +- Jeff Garzik +- Jonas Schnelli +- Jonathan Brown +- Jorge Timón +- joshr +- jtimon +- Julian Yap +- Luca Venturini +- Luke Dashjr +- Manuel Araoz +- MarcoFalke +- Matt Bogosian +- Matt Corallo +- Micha +- Michael Ford +- Mike Hearn +- mrbandrews +- Nicolas Benoit +- paveljanik +- Pavel Janík +- Pavel Vasin +- Peter Todd +- Philip Kaufmann +- Pieter Wuille +- pstratem +- randy-waterhouse +- rion +- Rob Van Mieghem +- Ross Nicoll +- Ruben de Vries +- sandakersmann +- Shaul Kfir +- Shawn Wilkinson +- sinetek +- Suhas Daftuar +- svost +- Thomas Zander +- Tom Harding +- UdjinM6 +- Vitalii Demianets +- Wladimir J. van der Laan + +And all those who contributed additional code review and/or security research: + +- Sergio Demian Lerner + +As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). + diff --git a/doc/release-process.md b/doc/release-process.md index 5ecb9334f5..1bfdb8fabd 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -6,39 +6,54 @@ Release Process * * * -###update (commit) version in sources +###first time only or for new builders, check out the source in the following directory hierarchy + cd /path/to/your/toplevel/build + git clone https://github.com/bitcoin/gitian.sigs.git + git clone https://github.com/devrandom/gitian-builder.git + git clone https://github.com/bitcoin/bitcoin.git + +###for bitcoin maintainers/release engineers, update (commit) version in sources + + pushd ./bitcoin contrib/verifysfbinaries/verify.sh doc/README* share/setup.nsi src/clientversion.h (change CLIENT_VERSION_IS_RELEASE to true) -###tag version in git +###for bitcoin maintainers/release engineers, tag version in git git tag -s v(new version, e.g. 0.8.0) -###write release notes. git shortlog helps a lot, for example: +###for bitcoin maintainers/release engineers, write release notes. git shortlog helps a lot, for example: git shortlog --no-merges v(current version, e.g. 0.7.2)..v(new version, e.g. 0.8.0) + popd * * * -###update gitian - - In order to take advantage of the new caching features in gitian, be sure to update to a recent version (`e9741525c` or later is recommended) +###update gitian, gitian.sigs, checkout bitcoin version, and perform gitian builds -###perform gitian builds - - From a directory containing the bitcoin source, gitian-builder and gitian.sigs + To ensure your gitian descriptors are accurate for direct reference for gbuild, below, run the following from a directory containing the bitcoin source: + pushd ./bitcoin export SIGNER=(your gitian key, ie bluematt, sipa, etc) export VERSION=(new version, e.g. 0.8.0) - pushd ./bitcoin git checkout v${VERSION} popd + + Ensure your gitian.sigs are up-to-date if you wish to gverify your builds against other gitian signatures: + + pushd ./gitian.sigs + git pull + popd + + Ensure your gitian-builder sources are up-to-date to take advantage of the new caching features of gitian (`e9741525c` or later is recommended) + pushd ./gitian-builder + git pull -###fetch and build inputs: (first time, or when dependency versions change) +###fetch and create inputs: (first time, or when dependency versions change) mkdir -p inputs wget -P inputs https://bitcoincore.org/cfields/osslsigncode-Backports-to-1.7.1.patch @@ -52,28 +67,44 @@ Release Process tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.9.sdk.tar.gz MacOSX10.9.sdk -###Optional: Seed the Gitian sources cache +###Optional: Seed the Gitian sources cache and offline git repositories - By default, gitian will fetch source files as needed. For offline builds, they can be fetched ahead of time: +By default, gitian will fetch source files as needed. To cache them ahead of time: make -C ../bitcoin/depends download SOURCES_PATH=`pwd`/cache/common - Only missing files will be fetched, so this is safe to re-run for each build. +Only missing files will be fetched, so this is safe to re-run for each build. + +Clone the detached-sigs repository: + + popd + git clone https://github.com/bitcoin/bitcoin-detached-sigs.git + pushd ./bitcoin-builder + +NOTE: Offline builds must use the --url flag to ensure gitian fetches only from local URLs. +For example: ./bin/bguild --url bitcoin=/path/to/bitcoin,signature=/path/to/sigs {rest of arguments} +The following gbuild invocations DO NOT DO THIS by default. -###Build Bitcoin Core for Linux, Windows, and OS X: +###Build (and optionally verify) Bitcoin Core for Linux, Windows, and OS X: ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-linux --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml + ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-linux ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml mv build/out/bitcoin-*.tar.gz build/out/src/bitcoin-*.tar.gz ../ + ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-win-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win.yml + ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-win-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-win.yml mv build/out/bitcoin-*-win-unsigned.tar.gz inputs/bitcoin-win-unsigned.tar.gz mv build/out/bitcoin-*.zip build/out/bitcoin-*.exe ../ + ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-osx-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml + ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-osx-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml mv build/out/bitcoin-*-osx-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../ popd + Build output expected: 1. source tarball (bitcoin-${VERSION}.tar.gz) @@ -98,19 +129,21 @@ Commit your signature to gitian.sigs: Once the Windows/OSX builds each have 3 matching signatures, they will be signed with their respective release keys. Detached signatures will then be committed to the bitcoin-detached-sigs repository, which can be combined with the unsigned apps to create signed binaries. - Create the signed OSX binary: + Create (and optionally verify) the signed OSX binary: pushd ./gitian-builder ./bin/gbuild -i --commit signature=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-osx-signed --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml + ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-osx-signed ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml mv build/out/bitcoin-osx-signed.dmg ../bitcoin-${VERSION}-osx.dmg popd - Create the signed Windows binaries: + Create (and optionally verify) the signed Windows binaries: pushd ./gitian-builder ./bin/gbuild -i --commit signature=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-win-signed --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml + ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-win-signed ../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml mv build/out/bitcoin-*win64-setup.exe ../bitcoin-${VERSION}-win64-setup.exe mv build/out/bitcoin-*win32-setup.exe ../bitcoin-${VERSION}-win32-setup.exe popd diff --git a/doc/shared-libraries.md b/doc/shared-libraries.md index 1fc32112ce..f1448f7258 100644 --- a/doc/shared-libraries.md +++ b/doc/shared-libraries.md @@ -40,3 +40,4 @@ The interface is defined in the C header `bitcoinconsensus.h` located in `src/s ### Example Implementations - [NBitcoin](https://github.com/NicolasDorier/NBitcoin/blob/master/NBitcoin/Script.cs#L814) (.NET Bindings) - [node-libbitcoinconsensus](https://github.com/bitpay/node-libbitcoinconsensus) (Node.js Bindings) +- [java-libbitcoinconsensus](https://github.com/dexX7/java-libbitcoinconsensus) (Java Bindings) diff --git a/doc/tor.md b/doc/tor.md index 560f71fa27..f8b94d19d1 100644 --- a/doc/tor.md +++ b/doc/tor.md @@ -70,9 +70,14 @@ In a typical situation, where you're only reachable via Tor, this should suffice ./bitcoind -proxy=127.0.0.1:9050 -externalip=57qr3yd1nyntf5k.onion -listen -(obviously, replace the Onion address with your own). If you don't care too much -about hiding your node, and want to be reachable on IPv4 as well, additionally -specify: +(obviously, replace the Onion address with your own). It should be noted that you still +listen on all devices and another node could establish a clearnet connection, when knowing +your address. To mitigate this, additionally bind the address of your Tor proxy: + + ./bitcoind ... -bind=127.0.0.1 + +If you don't care too much about hiding your node, and want to be reachable on IPv4 +as well, use `discover` instead: ./bitcoind ... -discover diff --git a/doc/translation_process.md b/doc/translation_process.md index 3653e53021..b06975e1d8 100644 --- a/doc/translation_process.md +++ b/doc/translation_process.md @@ -106,6 +106,6 @@ To create a new language template, you will need to edit the languages manifest **Note:** that the language translation file **must end in `.qm`** (the compiled extension), and not `.ts`. ### Questions and general assistance -The Bitcoin-Core translation maintainers include *tcatm, seone, Diapolo, wumpus and luke-jr*.You can find them, and others, in the Freenode IRC chatroom - `irc.freenode.net #bitcoin-dev`. +The Bitcoin-Core translation maintainers include *tcatm, seone, Diapolo, wumpus and luke-jr*. You can find them, and others, in the Freenode IRC chatroom - `irc.freenode.net #bitcoin-core-dev`. If you are a translator, you should also subscribe to the mailing list, https://groups.google.com/forum/#!forum/bitcoin-translators. Announcements will be posted during application pre-releases to notify translators to check for updates. diff --git a/doc/zmq.md b/doc/zmq.md new file mode 100644 index 0000000000..358d29d046 --- /dev/null +++ b/doc/zmq.md @@ -0,0 +1,101 @@ +# Block and Transaction Broadcasting With ZeroMQ + +[ZeroMQ](http://zeromq.org/) is a lightweight wrapper around TCP +connections, inter-process communication, and shared-memory, +providing various message-oriented semantics such as publish/subcribe, +request/reply, and push/pull. + +The Bitcoin Core daemon can be configured to act as a trusted "border +router", implementing the bitcoin wire protocol and relay, making +consensus decisions, maintaining the local blockchain database, +broadcasting locally generated transactions into the network, and +providing a queryable RPC interface to interact on a polled basis for +requesting blockchain related data. However, there exists only a +limited service to notify external software of events like the arrival +of new blocks or transactions. + +The ZeroMQ facility implements a notification interface through a set +of specific notifiers. Currently there are notifiers that publish +blocks and transactions. This read-only facility requires only the +connection of a corresponding ZeroMQ subscriber port in receiving +software; it is not authenticated nor is there any two-way protocol +involvement. Therefore, subscribers should validate the received data +since it may be out of date, incomplete or even invalid. + +ZeroMQ sockets are self-connecting and self-healing; that is, +connections made between two endpoints will be automatically restored +after an outage, and either end may be freely started or stopped in +any order. + +Because ZeroMQ is message oriented, subscribers receive transactions +and blocks all-at-once and do not need to implement any sort of +buffering or reassembly. + +## Prerequisites + +The ZeroMQ feature in Bitcoin Core requires ZeroMQ API version 4.x or +newer. Typically, it is packaged by distributions as something like +*libzmq3-dev*. The C++ wrapper for ZeroMQ is *not* needed. + +In order to run the example Python client scripts in contrib/ one must +also install *python-zmq*, though this is not necessary for daemon +operation. + +## Enabling + +By default, the ZeroMQ port functionality is enabled. Two steps are +required to enable--compiling in the ZeroMQ code, and configuring +runtime operation on the command-line or configuration file. + + $ ./configure --enable-zmq (other options) + +This will produce a binary that is capable of providing the ZeroMQ +facility, but will not do so until also configured properly. + +## Usage + +Currently, the following notifications are supported: + + -zmqpubhashtx=address + -zmqpubhashblock=address + -zmqpubrawblock=address + -zmqpubrawtx=address + +The socket type is PUB and the address must be a valid ZeroMQ socket +address. The same address can be used in more than one notification. + +For instance: + + $ bitcoind -zmqpubhashtx=tcp://127.0.0.1:28332 \ + -zmqpubrawtx=ipc:///tmp/bitcoind.tx.raw + +Each PUB notification has a topic and body, where the header +corresponds to the notification type. For instance, for the +notification `-zmqpubhashtx` the topic is `hashtx` (no null +terminator) and the body is the hexadecimal transaction hash (32 +bytes). + +These options can also be provided in bitcoin.conf. + +ZeroMQ endpoint specifiers for TCP (and others) are documented in the +[ZeroMQ API](http://api.zeromq.org). + +Client side, then, the ZeroMQ subscriber socket must have the +ZMQ_SUBSCRIBE option set to one or either of these prefixes (for +instance, just `hash`); without doing so will result in no messages +arriving. Please see `contrib/zmq/zmq_sub.py` for a working example. + +## Remarks + +From the perspective of bitcoind, the ZeroMQ socket is write-only; PUB +sockets don't even have a read function. Thus, there is no state +introduced into bitcoind directly. Furthermore, no information is +broadcast that wasn't already received from the public P2P network. + +No authentication or authorization is done on connecting clients; it +is assumed that the ZeroMQ port is exposed only to trusted entities, +using other means such as firewalling. + +Note that when the block chain tip changes, a reorganisation may occur +and just the tip will be notified. It is up to the subscriber to +retrieve the chain from the last known block to the new tip. diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index 72a282bc00..2e8a7c69ce 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -5,8 +5,8 @@ CURDIR=$(cd $(dirname "$0"); pwd) # Get BUILDDIR and REAL_BITCOIND . "${CURDIR}/tests-config.sh" -export BITCOINCLI=${BUILDDIR}/qa/pull-tester/run-bitcoin-cli export BITCOIND=${REAL_BITCOIND} +export BITCOINCLI=${REAL_BITCOINCLI} if [ "x${EXEEXT}" = "x.exe" ]; then echo "Win tests currently disabled" @@ -36,6 +36,7 @@ testScripts=( 'nodehandling.py' 'reindex.py' 'decodescript.py' + 'p2p-fullblocktest.py' ); testScriptsExt=( 'bipdersig-p2p.py' @@ -56,8 +57,13 @@ testScriptsExt=( 'invalidblockrequest.py' # 'forknotify.py' 'p2p-acceptblock.py' + 'mempool_packages.py' ); +#if [ "x$ENABLE_ZMQ" = "x1" ]; then +# testScripts+=('zmq_test.py') +#fi + extArg="-extended" passOn=${@#$extArg} diff --git a/qa/pull-tester/run-bitcoin-cli b/qa/pull-tester/run-bitcoin-cli deleted file mode 100755 index 93c25bb9fc..0000000000 --- a/qa/pull-tester/run-bitcoin-cli +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -# This is a thin wrapper around bitcoin-cli that strips the Windows-style EOLs -# from the output if present. It is necessary when using bitcoin-cli.exe on -# Linux since shells will interpret the line-endings as part of the result. - -CURDIR=$(cd $(dirname "$0"); pwd) -# Get BUILDDIR and REAL_BITCOIND - -# Grab the value of $REAL_BITCOINCLI which may be bitcoin-cli.exe. -. "${CURDIR}/tests-config.sh" - -"${REAL_BITCOINCLI}" "$@" | sed 's/\r//' diff --git a/qa/pull-tester/tests-config.sh.in b/qa/pull-tester/tests-config.sh.in index 10f4d33e47..e881a95110 100755 --- a/qa/pull-tester/tests-config.sh.in +++ b/qa/pull-tester/tests-config.sh.in @@ -10,6 +10,7 @@ EXEEXT="@EXEEXT@" @ENABLE_WALLET_TRUE@ENABLE_WALLET=1 @BUILD_BITCOIN_UTILS_TRUE@ENABLE_UTILS=1 @BUILD_BITCOIND_TRUE@ENABLE_BITCOIND=1 +@ENABLE_ZMQ_TRUE@ENABLE_ZMQ=1 REAL_BITCOIND="$BUILDDIR/src/bitcoind${EXEEXT}" REAL_BITCOINCLI="$BUILDDIR/src/bitcoin-cli${EXEEXT}" diff --git a/qa/rpc-tests/README.md b/qa/rpc-tests/README.md index cfda8fe91f..c6d1721282 100644 --- a/qa/rpc-tests/README.md +++ b/qa/rpc-tests/README.md @@ -1,5 +1,5 @@ -Regression tests of RPC interface -================================= +Regression tests +================ ### [python-bitcoinrpc](https://github.com/jgarzik/python-bitcoinrpc) Git subtree of [https://github.com/jgarzik/python-bitcoinrpc](https://github.com/jgarzik/python-bitcoinrpc). @@ -12,6 +12,28 @@ Base class for new regression tests. ### [test_framework/util.py](test_framework/util.py) Generally useful functions. +### [test_framework/mininode.py](test_framework/mininode.py) +Basic code to support p2p connectivity to a bitcoind. + +### [test_framework/comptool.py](test_framework/comptool.py) +Framework for comparison-tool style, p2p tests. + +### [test_framework/script.py](test_framework/script.py) +Utilities for manipulating transaction scripts (originally from python-bitcoinlib) + +### [test_framework/blockstore.py](test_framework/blockstore.py) +Implements disk-backed block and tx storage. + +### [test_framework/key.py](test_framework/key.py) +Wrapper around OpenSSL EC_Key (originally from python-bitcoinlib) + +### [test_framework/bignum.py](test_framework/bignum.py) +Helpers for script.py + +### [test_framework/blocktools.py](test_framework/blocktools.py) +Helper functions for creating blocks and transactions. + + Notes ===== @@ -49,3 +71,82 @@ to recover with: rm -rf cache killall bitcoind ``` + +P2P test design notes +--------------------- + +## Mininode + +* ```mininode.py``` contains all the definitions for objects that pass +over the network (```CBlock```, ```CTransaction```, etc, along with the network-level +wrappers for them, ```msg_block```, ```msg_tx```, etc). + +* P2P tests have two threads. One thread handles all network communication +with the bitcoind(s) being tested (using python's asyncore package); the other +implements the test logic. + +* ```NodeConn``` is the class used to connect to a bitcoind. If you implement +a callback class that derives from ```NodeConnCB``` and pass that to the +```NodeConn``` object, your code will receive the appropriate callbacks when +events of interest arrive. NOTE: be sure to call +```self.create_callback_map()``` in your derived classes' ```__init__``` +function, so that the correct mappings are set up between p2p messages and your +callback functions. + +* You can pass the same handler to multiple ```NodeConn```'s if you like, or pass +different ones to each -- whatever makes the most sense for your test. + +* Call ```NetworkThread.start()``` after all ```NodeConn``` objects are created to +start the networking thread. (Continue with the test logic in your existing +thread.) + +* RPC calls are available in p2p tests. + +* Can be used to write free-form tests, where specific p2p-protocol behavior +is tested. Examples: ```p2p-accept-block.py```, ```maxblocksinflight.py```. + +## Comptool + +* Testing framework for writing tests that compare the block/tx acceptance +behavior of a bitcoind against 1 or more other bitcoind instances, or against +known outcomes, or both. + +* Set the ```num_nodes``` variable (defined in ```ComparisonTestFramework```) to start up +1 or more nodes. If using 1 node, then ```--testbinary``` can be used as a command line +option to change the bitcoind binary used by the test. If using 2 or more nodes, +then ```--refbinary``` can be optionally used to change the bitcoind that will be used +on nodes 2 and up. + +* Implement a (generator) function called ```get_tests()``` which yields ```TestInstance```s. +Each ```TestInstance``` consists of: + - a list of ```[object, outcome, hash]``` entries + * ```object``` is a ```CBlock```, ```CTransaction```, or + ```CBlockHeader```. ```CBlock```'s and ```CTransaction```'s are tested for + acceptance. ```CBlockHeader```s can be used so that the test runner can deliver + complete headers-chains when requested from the bitcoind, to allow writing + tests where blocks can be delivered out of order but still processed by + headers-first bitcoind's. + * ```outcome``` is ```True```, ```False```, or ```None```. If ```True``` + or ```False```, the tip is compared with the expected tip -- either the + block passed in, or the hash specified as the optional 3rd entry. If + ```None``` is specified, then the test will compare all the bitcoind's + being tested to see if they all agree on what the best tip is. + * ```hash``` is the block hash of the tip to compare against. Optional to + specify; if left out then the hash of the block passed in will be used as + the expected tip. This allows for specifying an expected tip while testing + the handling of either invalid blocks or blocks delivered out of order, + which complete a longer chain. + - ```sync_every_block```: ```True/False```. If ```False```, then all blocks + are inv'ed together, and the test runner waits until the node receives the + last one, and tests only the last block for tip acceptance using the + outcome and specified tip. If ```True```, then each block is tested in + sequence and synced (this is slower when processing many blocks). + - ```sync_every_transaction```: ```True/False```. Analogous to + ```sync_every_block```, except if the outcome on the last tx is "None", + then the contents of the entire mempool are compared across all bitcoind + connections. If ```True``` or ```False```, then only the last tx's + acceptance is tested against the given outcome. + +* For examples of tests written in this framework, see + ```invalidblockrequest.py``` and ```p2p-fullblocktest.py```. + diff --git a/qa/rpc-tests/bipdersig-p2p.py b/qa/rpc-tests/bipdersig-p2p.py index 41717377b2..ec1678cc2c 100755 --- a/qa/rpc-tests/bipdersig-p2p.py +++ b/qa/rpc-tests/bipdersig-p2p.py @@ -75,6 +75,7 @@ class BIP66Test(ComparisonTestFramework): def get_tests(self): self.coinbase_blocks = self.nodes[0].generate(2) + height = 3 # height of the next block to build self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0) self.nodeaddress = self.nodes[0].getnewaddress() self.last_block_time = time.time() @@ -82,25 +83,27 @@ class BIP66Test(ComparisonTestFramework): ''' 98 more version 2 blocks ''' test_blocks = [] for i in xrange(98): - block = create_block(self.tip, create_coinbase(2), self.last_block_time + 1) + block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 2 block.rehash() block.solve() test_blocks.append([block, True]) self.last_block_time += 1 self.tip = block.sha256 + height += 1 yield TestInstance(test_blocks, sync_every_block=False) ''' Mine 749 version 3 blocks ''' test_blocks = [] for i in xrange(749): - block = create_block(self.tip, create_coinbase(2), self.last_block_time + 1) + block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 3 block.rehash() block.solve() test_blocks.append([block, True]) self.last_block_time += 1 self.tip = block.sha256 + height += 1 yield TestInstance(test_blocks, sync_every_block=False) ''' @@ -112,7 +115,7 @@ class BIP66Test(ComparisonTestFramework): unDERify(spendtx) spendtx.rehash() - block = create_block(self.tip, create_coinbase(2), self.last_block_time + 1) + block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 3 block.vtx.append(spendtx) block.hashMerkleRoot = block.calc_merkle_root() @@ -121,6 +124,7 @@ class BIP66Test(ComparisonTestFramework): self.last_block_time += 1 self.tip = block.sha256 + height += 1 yield TestInstance([[block, True]]) ''' @@ -132,7 +136,7 @@ class BIP66Test(ComparisonTestFramework): unDERify(spendtx) spendtx.rehash() - block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1) + block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 3 block.vtx.append(spendtx) block.hashMerkleRoot = block.calc_merkle_root() @@ -144,35 +148,38 @@ class BIP66Test(ComparisonTestFramework): ''' Mine 199 new version blocks on last valid tip ''' test_blocks = [] for i in xrange(199): - block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1) + block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 3 block.rehash() block.solve() test_blocks.append([block, True]) self.last_block_time += 1 self.tip = block.sha256 + height += 1 yield TestInstance(test_blocks, sync_every_block=False) ''' Mine 1 old version block ''' - block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1) + block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 2 block.rehash() block.solve() self.last_block_time += 1 self.tip = block.sha256 + height += 1 yield TestInstance([[block, True]]) ''' Mine 1 new version block ''' - block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1) + block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 3 block.rehash() block.solve() self.last_block_time += 1 self.tip = block.sha256 + height += 1 yield TestInstance([[block, True]]) ''' Mine 1 old version block, should be invalid ''' - block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1) + block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) block.nVersion = 2 block.rehash() block.solve() diff --git a/qa/rpc-tests/decodescript.py b/qa/rpc-tests/decodescript.py index ce3bc94ef7..4bca623380 100755 --- a/qa/rpc-tests/decodescript.py +++ b/qa/rpc-tests/decodescript.py @@ -5,6 +5,9 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * +from test_framework.mininode import * +from binascii import hexlify, unhexlify +from cStringIO import StringIO class DecodeScriptTest(BitcoinTestFramework): """Tests decoding scripts via RPC command "decodescript".""" @@ -107,10 +110,77 @@ class DecodeScriptTest(BitcoinTestFramework): rpc_result = self.nodes[0].decodescript('63' + push_public_key + 'ad670320a107b17568' + push_public_key + 'ac') assert_equal('OP_IF ' + public_key + ' OP_CHECKSIGVERIFY OP_ELSE 500000 OP_NOP2 OP_DROP OP_ENDIF ' + public_key + ' OP_CHECKSIG', rpc_result['asm']) + def decoderawtransaction_asm_sighashtype(self): + """Tests decoding scripts via RPC command "decoderawtransaction". + + This test is in with the "decodescript" tests because they are testing the same "asm" script decodes. + """ + + # this test case uses a random plain vanilla mainnet transaction with a single P2PKH input and output + tx = '0100000001696a20784a2c70143f634e95227dbdfdf0ecd51647052e70854512235f5986ca010000008a47304402207174775824bec6c2700023309a168231ec80b82c6069282f5133e6f11cbb04460220570edc55c7c5da2ca687ebd0372d3546ebc3f810516a002350cac72dfe192dfb014104d3f898e6487787910a690410b7a917ef198905c27fb9d3b0a42da12aceae0544fc7088d239d9a48f2828a15a09e84043001f27cc80d162cb95404e1210161536ffffffff0100e1f505000000001976a914eb6c6e0cdb2d256a32d97b8df1fc75d1920d9bca88ac00000000' + rpc_result = self.nodes[0].decoderawtransaction(tx) + assert_equal('304402207174775824bec6c2700023309a168231ec80b82c6069282f5133e6f11cbb04460220570edc55c7c5da2ca687ebd0372d3546ebc3f810516a002350cac72dfe192dfb[ALL] 04d3f898e6487787910a690410b7a917ef198905c27fb9d3b0a42da12aceae0544fc7088d239d9a48f2828a15a09e84043001f27cc80d162cb95404e1210161536', rpc_result['vin'][0]['scriptSig']['asm']) + + # this test case uses a mainnet transaction that has a P2SH input and both P2PKH and P2SH outputs. + # it's from James D'Angelo's awesome introductory videos about multisig: https://www.youtube.com/watch?v=zIbUSaZBJgU and https://www.youtube.com/watch?v=OSA1pwlaypc + # verify that we have not altered scriptPubKey decoding. + tx = '01000000018d1f5635abd06e2c7e2ddf58dc85b3de111e4ad6e0ab51bb0dcf5e84126d927300000000fdfe0000483045022100ae3b4e589dfc9d48cb82d41008dc5fa6a86f94d5c54f9935531924602730ab8002202f88cf464414c4ed9fa11b773c5ee944f66e9b05cc1e51d97abc22ce098937ea01483045022100b44883be035600e9328a01b66c7d8439b74db64187e76b99a68f7893b701d5380220225bf286493e4c4adcf928c40f785422572eb232f84a0b83b0dea823c3a19c75014c695221020743d44be989540d27b1b4bbbcfd17721c337cb6bc9af20eb8a32520b393532f2102c0120a1dda9e51a938d39ddd9fe0ebc45ea97e1d27a7cbd671d5431416d3dd87210213820eb3d5f509d7438c9eeecb4157b2f595105e7cd564b3cdbb9ead3da41eed53aeffffffff02611e0000000000001976a914dc863734a218bfe83ef770ee9d41a27f824a6e5688acee2a02000000000017a9142a5edea39971049a540474c6a99edf0aa4074c588700000000' + rpc_result = self.nodes[0].decoderawtransaction(tx) + assert_equal('8e3730608c3b0bb5df54f09076e196bc292a8e39a78e73b44b6ba08c78f5cbb0', rpc_result['txid']) + assert_equal('0 3045022100ae3b4e589dfc9d48cb82d41008dc5fa6a86f94d5c54f9935531924602730ab8002202f88cf464414c4ed9fa11b773c5ee944f66e9b05cc1e51d97abc22ce098937ea[ALL] 3045022100b44883be035600e9328a01b66c7d8439b74db64187e76b99a68f7893b701d5380220225bf286493e4c4adcf928c40f785422572eb232f84a0b83b0dea823c3a19c75[ALL] 5221020743d44be989540d27b1b4bbbcfd17721c337cb6bc9af20eb8a32520b393532f2102c0120a1dda9e51a938d39ddd9fe0ebc45ea97e1d27a7cbd671d5431416d3dd87210213820eb3d5f509d7438c9eeecb4157b2f595105e7cd564b3cdbb9ead3da41eed53ae', rpc_result['vin'][0]['scriptSig']['asm']) + assert_equal('OP_DUP OP_HASH160 dc863734a218bfe83ef770ee9d41a27f824a6e56 OP_EQUALVERIFY OP_CHECKSIG', rpc_result['vout'][0]['scriptPubKey']['asm']) + assert_equal('OP_HASH160 2a5edea39971049a540474c6a99edf0aa4074c58 OP_EQUAL', rpc_result['vout'][1]['scriptPubKey']['asm']) + txSave = CTransaction() + txSave.deserialize(StringIO(unhexlify(tx))) + + # make sure that a specifically crafted op_return value will not pass all the IsDERSignature checks and then get decoded as a sighash type + tx = '01000000015ded05872fdbda629c7d3d02b194763ce3b9b1535ea884e3c8e765d42e316724020000006b48304502204c10d4064885c42638cbff3585915b322de33762598321145ba033fc796971e2022100bb153ad3baa8b757e30a2175bd32852d2e1cb9080f84d7e32fcdfd667934ef1b012103163c0ff73511ea1743fb5b98384a2ff09dd06949488028fd819f4d83f56264efffffffff0200000000000000000b6a0930060201000201000180380100000000001976a9141cabd296e753837c086da7a45a6c2fe0d49d7b7b88ac00000000' + rpc_result = self.nodes[0].decoderawtransaction(tx) + assert_equal('OP_RETURN 300602010002010001', rpc_result['vout'][0]['scriptPubKey']['asm']) + + # verify that we have not altered scriptPubKey processing even of a specially crafted P2PKH pubkeyhash and P2SH redeem script hash that is made to pass the der signature checks + tx = '01000000018d1f5635abd06e2c7e2ddf58dc85b3de111e4ad6e0ab51bb0dcf5e84126d927300000000fdfe0000483045022100ae3b4e589dfc9d48cb82d41008dc5fa6a86f94d5c54f9935531924602730ab8002202f88cf464414c4ed9fa11b773c5ee944f66e9b05cc1e51d97abc22ce098937ea01483045022100b44883be035600e9328a01b66c7d8439b74db64187e76b99a68f7893b701d5380220225bf286493e4c4adcf928c40f785422572eb232f84a0b83b0dea823c3a19c75014c695221020743d44be989540d27b1b4bbbcfd17721c337cb6bc9af20eb8a32520b393532f2102c0120a1dda9e51a938d39ddd9fe0ebc45ea97e1d27a7cbd671d5431416d3dd87210213820eb3d5f509d7438c9eeecb4157b2f595105e7cd564b3cdbb9ead3da41eed53aeffffffff02611e0000000000001976a914301102070101010101010102060101010101010188acee2a02000000000017a91430110207010101010101010206010101010101018700000000' + rpc_result = self.nodes[0].decoderawtransaction(tx) + assert_equal('OP_DUP OP_HASH160 3011020701010101010101020601010101010101 OP_EQUALVERIFY OP_CHECKSIG', rpc_result['vout'][0]['scriptPubKey']['asm']) + assert_equal('OP_HASH160 3011020701010101010101020601010101010101 OP_EQUAL', rpc_result['vout'][1]['scriptPubKey']['asm']) + + # some more full transaction tests of varying specific scriptSigs. used instead of + # tests in decodescript_script_sig because the decodescript RPC is specifically + # for working on scriptPubKeys (argh!). + push_signature = hexlify(txSave.vin[0].scriptSig)[2:(0x48*2+4)] + signature = push_signature[2:] + der_signature = signature[:-2] + signature_sighash_decoded = der_signature + '[ALL]' + signature_2 = der_signature + '82' + push_signature_2 = '48' + signature_2 + signature_2_sighash_decoded = der_signature + '[NONE|ANYONECANPAY]' + + # 1) P2PK scriptSig + txSave.vin[0].scriptSig = unhexlify(push_signature) + rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize())) + assert_equal(signature_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm']) + + # make sure that the sighash decodes come out correctly for a more complex / lesser used case. + txSave.vin[0].scriptSig = unhexlify(push_signature_2) + rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize())) + assert_equal(signature_2_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm']) + + # 2) multisig scriptSig + txSave.vin[0].scriptSig = unhexlify('00' + push_signature + push_signature_2) + rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize())) + assert_equal('0 ' + signature_sighash_decoded + ' ' + signature_2_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm']) + + # 3) test a scriptSig that contains more than push operations. + # in fact, it contains an OP_RETURN with data specially crafted to cause improper decode if the code does not catch it. + txSave.vin[0].scriptSig = unhexlify('6a143011020701010101010101020601010101010101') + rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize())) + print(hexlify('636174')) + assert_equal('OP_RETURN 3011020701010101010101020601010101010101', rpc_result['vin'][0]['scriptSig']['asm']) + def run_test(self): self.decodescript_script_sig() self.decodescript_script_pub_key() + self.decoderawtransaction_asm_sighashtype() if __name__ == '__main__': DecodeScriptTest().main() - diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index ce52247b2e..fc29789218 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -13,14 +13,15 @@ class RawTransactionsTest(BitcoinTestFramework): def setup_chain(self): print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 3) + initialize_chain_clean(self.options.tmpdir, 4) def setup_network(self, split=False): - self.nodes = start_nodes(3, self.options.tmpdir) + self.nodes = start_nodes(4, self.options.tmpdir) connect_nodes_bi(self.nodes,0,1) connect_nodes_bi(self.nodes,1,2) connect_nodes_bi(self.nodes,0,2) + connect_nodes_bi(self.nodes,0,3) self.is_network_split=False self.sync_all() @@ -31,11 +32,20 @@ class RawTransactionsTest(BitcoinTestFramework): self.nodes[2].generate(1) self.sync_all() - self.nodes[0].generate(101) + self.nodes[0].generate(121) self.sync_all() + + watchonly_address = self.nodes[0].getnewaddress() + watchonly_pubkey = self.nodes[0].validateaddress(watchonly_address)["pubkey"] + watchonly_amount = 200 + self.nodes[3].importpubkey(watchonly_pubkey, "", True) + watchonly_txid = self.nodes[0].sendtoaddress(watchonly_address, watchonly_amount) + self.nodes[0].sendtoaddress(self.nodes[3].getnewaddress(), watchonly_amount / 10); + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.5); self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.0); self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),5.0); + self.sync_all() self.nodes[0].generate(1) self.sync_all() @@ -428,11 +438,12 @@ class RawTransactionsTest(BitcoinTestFramework): stop_nodes(self.nodes) wait_bitcoinds() - self.nodes = start_nodes(3, self.options.tmpdir) + self.nodes = start_nodes(4, self.options.tmpdir) connect_nodes_bi(self.nodes,0,1) connect_nodes_bi(self.nodes,1,2) connect_nodes_bi(self.nodes,0,2) + connect_nodes_bi(self.nodes,0,3) self.is_network_split=False self.sync_all() @@ -541,5 +552,45 @@ class RawTransactionsTest(BitcoinTestFramework): assert_equal(len(dec_tx['vout']), 2) # one change output added + ################################################## + # test a fundrawtransaction using only watchonly # + ################################################## + + inputs = [] + outputs = {self.nodes[2].getnewaddress() : watchonly_amount / 2} + rawtx = self.nodes[3].createrawtransaction(inputs, outputs) + + result = self.nodes[3].fundrawtransaction(rawtx, True) + res_dec = self.nodes[0].decoderawtransaction(result["hex"]) + assert_equal(len(res_dec["vin"]), 1) + assert_equal(res_dec["vin"][0]["txid"], watchonly_txid) + + assert_equal("fee" in result.keys(), True) + assert_greater_than(result["changepos"], -1) + + ############################################################### + # test fundrawtransaction using the entirety of watched funds # + ############################################################### + + inputs = [] + outputs = {self.nodes[2].getnewaddress() : watchonly_amount} + rawtx = self.nodes[3].createrawtransaction(inputs, outputs) + + result = self.nodes[3].fundrawtransaction(rawtx, True) + res_dec = self.nodes[0].decoderawtransaction(result["hex"]) + assert_equal(len(res_dec["vin"]), 2) + assert(res_dec["vin"][0]["txid"] == watchonly_txid or res_dec["vin"][1]["txid"] == watchonly_txid) + + assert_greater_than(result["fee"], 0) + assert_greater_than(result["changepos"], -1) + assert_equal(result["fee"] + res_dec["vout"][result["changepos"]]["value"], watchonly_amount / 10) + + signedtx = self.nodes[3].signrawtransaction(result["hex"]) + assert(not signedtx["complete"]) + signedtx = self.nodes[0].signrawtransaction(signedtx["hex"]) + assert(signedtx["complete"]) + self.nodes[0].sendrawtransaction(signedtx["hex"]) + + if __name__ == '__main__': RawTransactionsTest().main() diff --git a/qa/rpc-tests/httpbasics.py b/qa/rpc-tests/httpbasics.py index 8ccb821286..b66533543d 100755 --- a/qa/rpc-tests/httpbasics.py +++ b/qa/rpc-tests/httpbasics.py @@ -22,7 +22,7 @@ except ImportError: class HTTPBasicsTest (BitcoinTestFramework): def setup_nodes(self): - return start_nodes(4, self.options.tmpdir, extra_args=[['-rpckeepalive=1'], ['-rpckeepalive=0'], [], []]) + return start_nodes(4, self.options.tmpdir) def run_test(self): @@ -84,9 +84,8 @@ class HTTPBasicsTest (BitcoinTestFramework): conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) out1 = conn.getresponse().read(); assert_equal('"error":null' in out1, True) - assert_equal(conn.sock!=None, False) #connection must be closed because keep-alive was set to false - #node2 (third node) is running with standard keep-alive parameters which means keep-alive is off + #node2 (third node) is running with standard keep-alive parameters which means keep-alive is on urlNode2 = urlparse.urlparse(self.nodes[2].url) authpair = urlNode2.username + ':' + urlNode2.password headers = {"Authorization": "Basic " + base64.b64encode(authpair)} diff --git a/qa/rpc-tests/invalidblockrequest.py b/qa/rpc-tests/invalidblockrequest.py index 64b8e26395..6a7980cd45 100755 --- a/qa/rpc-tests/invalidblockrequest.py +++ b/qa/rpc-tests/invalidblockrequest.py @@ -46,12 +46,14 @@ class InvalidBlockRequestTest(ComparisonTestFramework): ''' Create a new block with an anyone-can-spend coinbase ''' - block = create_block(self.tip, create_coinbase(), self.block_time) + height = 1 + block = create_block(self.tip, create_coinbase(height), self.block_time) self.block_time += 1 block.solve() # Save the coinbase for later self.block1 = block self.tip = block.sha256 + height += 1 yield TestInstance([[block, True]]) ''' @@ -59,11 +61,12 @@ class InvalidBlockRequestTest(ComparisonTestFramework): ''' test = TestInstance(sync_every_block=False) for i in xrange(100): - block = create_block(self.tip, create_coinbase(), self.block_time) + block = create_block(self.tip, create_coinbase(height), self.block_time) block.solve() self.tip = block.sha256 self.block_time += 1 test.blocks_and_transactions.append([block, True]) + height += 1 yield test ''' @@ -73,7 +76,7 @@ class InvalidBlockRequestTest(ComparisonTestFramework): coinbase, spend of that spend). Duplicate the 3rd transaction to leave merkle root and blockheader unchanged but invalidate the block. ''' - block2 = create_block(self.tip, create_coinbase(), self.block_time) + block2 = create_block(self.tip, create_coinbase(height), self.block_time) self.block_time += 1 # chr(81) is OP_TRUE @@ -95,11 +98,12 @@ class InvalidBlockRequestTest(ComparisonTestFramework): self.tip = block2.sha256 yield TestInstance([[block2, False], [block2_orig, True]]) + height += 1 ''' Make sure that a totally screwed up block is not valid. ''' - block3 = create_block(self.tip, create_coinbase(), self.block_time) + block3 = create_block(self.tip, create_coinbase(height), self.block_time) self.block_time += 1 block3.vtx[0].vout[0].nValue = 100*100000000 # Too high! block3.vtx[0].sha256=None diff --git a/qa/rpc-tests/keypool.py b/qa/rpc-tests/keypool.py index aee29a596a..5a67220021 100755 --- a/qa/rpc-tests/keypool.py +++ b/qa/rpc-tests/keypool.py @@ -73,6 +73,21 @@ def run_test(nodes, tmpdir): except JSONRPCException,e: assert(e.error['code']==-12) + # refill keypool with three new addresses + nodes[0].walletpassphrase('test', 12000) + nodes[0].keypoolrefill(3) + nodes[0].walletlock() + + # drain them by mining + nodes[0].generate(1) + nodes[0].generate(1) + nodes[0].generate(1) + nodes[0].generate(1) + try: + nodes[0].generate(1) + raise AssertionError('Keypool should be exhausted after three addesses') + except JSONRPCException,e: + assert(e.error['code']==-12) def main(): import optparse diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index eeae2d2fa2..b30a6bc9d1 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -93,6 +93,16 @@ class ListTransactionsTest(BitcoinTestFramework): {"category":"receive","amount":Decimal("0.44")}, {"txid":txid, "account" : "toself"} ) + multisig = self.nodes[1].createmultisig(1, [self.nodes[1].getnewaddress()]) + self.nodes[0].importaddress(multisig["redeemScript"], "watchonly", False, True) + txid = self.nodes[1].sendtoaddress(multisig["address"], 0.1) + self.nodes[1].generate(1) + self.sync_all() + assert(len(self.nodes[0].listtransactions("watchonly", 100, 0, False)) == 0) + check_array_result(self.nodes[0].listtransactions("watchonly", 100, 0, True), + {"category":"receive","amount":Decimal("0.1")}, + {"txid":txid, "account" : "watchonly"} ) + if __name__ == '__main__': ListTransactionsTest().main() diff --git a/qa/rpc-tests/mempool_packages.py b/qa/rpc-tests/mempool_packages.py new file mode 100755 index 0000000000..6bc6e43f0b --- /dev/null +++ b/qa/rpc-tests/mempool_packages.py @@ -0,0 +1,178 @@ +#!/usr/bin/env python2 +# Copyright (c) 2014-2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# Test descendant package tracking code + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * + +def satoshi_round(amount): + return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN) + +class MempoolPackagesTest(BitcoinTestFramework): + + def setup_network(self): + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, ["-maxorphantx=1000", "-relaypriority=0", "-debug"])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-maxorphantx=1000", "-relaypriority=0", "-limitancestorcount=5", "-debug"])) + connect_nodes(self.nodes[0], 1) + self.is_network_split = False + self.sync_all() + + # Build a transaction that spends parent_txid:vout + # Return amount sent + def chain_transaction(self, node, parent_txid, vout, value, fee, num_outputs): + send_value = satoshi_round((value - fee)/num_outputs) + inputs = [ {'txid' : parent_txid, 'vout' : vout} ] + outputs = {} + for i in xrange(num_outputs): + outputs[node.getnewaddress()] = send_value + rawtx = node.createrawtransaction(inputs, outputs) + signedtx = node.signrawtransaction(rawtx) + txid = node.sendrawtransaction(signedtx['hex']) + fulltx = node.getrawtransaction(txid, 1) + assert(len(fulltx['vout']) == num_outputs) # make sure we didn't generate a change output + return (txid, send_value) + + def run_test(self): + ''' Mine some blocks and have them mature. ''' + self.nodes[0].generate(101) + utxo = self.nodes[0].listunspent(10) + txid = utxo[0]['txid'] + vout = utxo[0]['vout'] + value = utxo[0]['amount'] + + fee = Decimal("0.0001") + # 100 transactions off a confirmed tx should be fine + chain = [] + for i in xrange(100): + (txid, sent_value) = self.chain_transaction(self.nodes[0], txid, 0, value, fee, 1) + value = sent_value + chain.append(txid) + + # Check mempool has 100 transactions in it, and descendant + # count and fees should look correct + mempool = self.nodes[0].getrawmempool(True) + assert_equal(len(mempool), 100) + descendant_count = 1 + descendant_fees = 0 + descendant_size = 0 + SATOSHIS = 100000000 + + for x in reversed(chain): + assert_equal(mempool[x]['descendantcount'], descendant_count) + descendant_fees += mempool[x]['fee'] + assert_equal(mempool[x]['descendantfees'], SATOSHIS*descendant_fees) + descendant_size += mempool[x]['size'] + assert_equal(mempool[x]['descendantsize'], descendant_size) + descendant_count += 1 + + # Adding one more transaction on to the chain should fail. + try: + self.chain_transaction(self.nodes[0], txid, vout, value, fee, 1) + except JSONRPCException as e: + print "too-long-ancestor-chain successfully rejected" + + # TODO: check that node1's mempool is as expected + + # TODO: test ancestor size limits + + # Now test descendant chain limits + txid = utxo[1]['txid'] + value = utxo[1]['amount'] + vout = utxo[1]['vout'] + + transaction_package = [] + # First create one parent tx with 10 children + (txid, sent_value) = self.chain_transaction(self.nodes[0], txid, vout, value, fee, 10) + parent_transaction = txid + for i in xrange(10): + transaction_package.append({'txid': txid, 'vout': i, 'amount': sent_value}) + + for i in xrange(1000): + utxo = transaction_package.pop(0) + try: + (txid, sent_value) = self.chain_transaction(self.nodes[0], utxo['txid'], utxo['vout'], utxo['amount'], fee, 10) + for j in xrange(10): + transaction_package.append({'txid': txid, 'vout': j, 'amount': sent_value}) + if i == 998: + mempool = self.nodes[0].getrawmempool(True) + assert_equal(mempool[parent_transaction]['descendantcount'], 1000) + except JSONRPCException as e: + print e.error['message'] + assert_equal(i, 999) + print "tx that would create too large descendant package successfully rejected" + + # TODO: check that node1's mempool is as expected + + # TODO: test descendant size limits + + # Test reorg handling + # First, the basics: + self.nodes[0].generate(1) + sync_blocks(self.nodes) + self.nodes[1].invalidateblock(self.nodes[0].getbestblockhash()) + self.nodes[1].reconsiderblock(self.nodes[0].getbestblockhash()) + + # Now test the case where node1 has a transaction T in its mempool that + # depends on transactions A and B which are in a mined block, and the + # block containing A and B is disconnected, AND B is not accepted back + # into node1's mempool because its ancestor count is too high. + + # Create 8 transactions, like so: + # Tx0 -> Tx1 (vout0) + # \--> Tx2 (vout1) -> Tx3 -> Tx4 -> Tx5 -> Tx6 -> Tx7 + # + # Mine them in the next block, then generate a new tx8 that spends + # Tx1 and Tx7, and add to node1's mempool, then disconnect the + # last block. + + # Create tx0 with 2 outputs + utxo = self.nodes[0].listunspent() + txid = utxo[0]['txid'] + value = utxo[0]['amount'] + vout = utxo[0]['vout'] + + send_value = satoshi_round((value - fee)/2) + inputs = [ {'txid' : txid, 'vout' : vout} ] + outputs = {} + for i in xrange(2): + outputs[self.nodes[0].getnewaddress()] = send_value + rawtx = self.nodes[0].createrawtransaction(inputs, outputs) + signedtx = self.nodes[0].signrawtransaction(rawtx) + txid = self.nodes[0].sendrawtransaction(signedtx['hex']) + tx0_id = txid + value = send_value + + # Create tx1 + (tx1_id, tx1_value) = self.chain_transaction(self.nodes[0], tx0_id, 0, value, fee, 1) + + # Create tx2-7 + vout = 1 + txid = tx0_id + for i in xrange(6): + (txid, sent_value) = self.chain_transaction(self.nodes[0], txid, vout, value, fee, 1) + vout = 0 + value = sent_value + + # Mine these in a block + self.nodes[0].generate(1) + self.sync_all() + + # Now generate tx8, with a big fee + inputs = [ {'txid' : tx1_id, 'vout': 0}, {'txid' : txid, 'vout': 0} ] + outputs = { self.nodes[0].getnewaddress() : send_value + value - 4*fee } + rawtx = self.nodes[0].createrawtransaction(inputs, outputs) + signedtx = self.nodes[0].signrawtransaction(rawtx) + txid = self.nodes[0].sendrawtransaction(signedtx['hex']) + sync_mempools(self.nodes) + + # Now try to disconnect the tip on each node... + self.nodes[1].invalidateblock(self.nodes[1].getbestblockhash()) + self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) + sync_blocks(self.nodes) + +if __name__ == '__main__': + MempoolPackagesTest().main() diff --git a/qa/rpc-tests/nodehandling.py b/qa/rpc-tests/nodehandling.py index d89cfcf59b..e383a3a12c 100755 --- a/qa/rpc-tests/nodehandling.py +++ b/qa/rpc-tests/nodehandling.py @@ -55,7 +55,7 @@ class NodeHandlingTest (BitcoinTestFramework): self.nodes[2].setban("192.168.0.1", "add", 1) #ban for 1 seconds self.nodes[2].setban("2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/19", "add", 1000) #ban for 1000 seconds listBeforeShutdown = self.nodes[2].listbanned(); - assert_equal("192.168.0.1/255.255.255.255", listBeforeShutdown[2]['address']) #must be here + assert_equal("192.168.0.1/32", listBeforeShutdown[2]['address']) #must be here time.sleep(2) #make 100% sure we expired 192.168.0.1 node time #stop node @@ -63,9 +63,9 @@ class NodeHandlingTest (BitcoinTestFramework): self.nodes[2] = start_node(2, self.options.tmpdir) listAfterShutdown = self.nodes[2].listbanned(); - assert_equal("127.0.0.0/255.255.255.0", listAfterShutdown[0]['address']) - assert_equal("127.0.0.0/255.255.255.255", listAfterShutdown[1]['address']) - assert_equal("2001:4000::/ffff:e000:0:0:0:0:0:0", listAfterShutdown[2]['address']) + assert_equal("127.0.0.0/24", listAfterShutdown[0]['address']) + assert_equal("127.0.0.0/32", listAfterShutdown[1]['address']) + assert_equal("/19" in listAfterShutdown[2]['address'], True) ########################### # RPC disconnectnode test # diff --git a/qa/rpc-tests/p2p-acceptblock.py b/qa/rpc-tests/p2p-acceptblock.py index 83c03eeb78..700deab207 100755 --- a/qa/rpc-tests/p2p-acceptblock.py +++ b/qa/rpc-tests/p2p-acceptblock.py @@ -153,7 +153,7 @@ class AcceptBlockTest(BitcoinTestFramework): blocks_h2 = [] # the height 2 blocks on each node's chain block_time = time.time() + 1 for i in xrange(2): - blocks_h2.append(create_block(tips[i], create_coinbase(), block_time)) + blocks_h2.append(create_block(tips[i], create_coinbase(2), block_time)) blocks_h2[i].solve() block_time += 1 test_node.send_message(msg_block(blocks_h2[0])) @@ -167,7 +167,7 @@ class AcceptBlockTest(BitcoinTestFramework): # 3. Send another block that builds on the original tip. blocks_h2f = [] # Blocks at height 2 that fork off the main chain for i in xrange(2): - blocks_h2f.append(create_block(tips[i], create_coinbase(), blocks_h2[i].nTime+1)) + blocks_h2f.append(create_block(tips[i], create_coinbase(2), blocks_h2[i].nTime+1)) blocks_h2f[i].solve() test_node.send_message(msg_block(blocks_h2f[0])) white_node.send_message(msg_block(blocks_h2f[1])) @@ -186,7 +186,7 @@ class AcceptBlockTest(BitcoinTestFramework): # 4. Now send another block that builds on the forking chain. blocks_h3 = [] for i in xrange(2): - blocks_h3.append(create_block(blocks_h2f[i].sha256, create_coinbase(), blocks_h2f[i].nTime+1)) + blocks_h3.append(create_block(blocks_h2f[i].sha256, create_coinbase(3), blocks_h2f[i].nTime+1)) blocks_h3[i].solve() test_node.send_message(msg_block(blocks_h3[0])) white_node.send_message(msg_block(blocks_h3[1])) @@ -217,7 +217,7 @@ class AcceptBlockTest(BitcoinTestFramework): all_blocks = [] # node0's blocks for j in xrange(2): for i in xrange(288): - next_block = create_block(tips[j].sha256, create_coinbase(), tips[j].nTime+1) + next_block = create_block(tips[j].sha256, create_coinbase(i + 4), tips[j].nTime+1) next_block.solve() if j==0: test_node.send_message(msg_block(next_block)) diff --git a/qa/rpc-tests/p2p-fullblocktest.py b/qa/rpc-tests/p2p-fullblocktest.py new file mode 100755 index 0000000000..9555940cec --- /dev/null +++ b/qa/rpc-tests/p2p-fullblocktest.py @@ -0,0 +1,272 @@ +#!/usr/bin/env python2 + +# +# Distributed under the MIT/X11 software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# + +from test_framework.test_framework import ComparisonTestFramework +from test_framework.util import * +from test_framework.comptool import TestManager, TestInstance +from test_framework.mininode import * +from test_framework.blocktools import * +import logging +import copy +import time +import numbers +from test_framework.key import CECKey +from test_framework.script import CScript, CScriptOp, SignatureHash, SIGHASH_ALL, OP_TRUE + +class PreviousSpendableOutput(object): + def __init__(self, tx = CTransaction(), n = -1): + self.tx = tx + self.n = n # the output we're spending + +''' +This reimplements tests from the bitcoinj/FullBlockTestGenerator used +by the pull-tester. + +We use the testing framework in which we expect a particular answer from +each test. +''' + +class FullBlockTest(ComparisonTestFramework): + + ''' Can either run this test as 1 node with expected answers, or two and compare them. + Change the "outcome" variable from each TestInstance object to only do the comparison. ''' + def __init__(self): + self.num_nodes = 1 + self.block_heights = {} + self.coinbase_key = CECKey() + self.coinbase_key.set_secretbytes(bytes("horsebattery")) + self.coinbase_pubkey = self.coinbase_key.get_pubkey() + self.block_time = int(time.time())+1 + self.tip = None + self.blocks = {} + + def run_test(self): + test = TestManager(self, self.options.tmpdir) + test.add_all_connections(self.nodes) + NetworkThread().start() # Start up network handling in another thread + test.run() + + def add_transactions_to_block(self, block, tx_list): + [ tx.rehash() for tx in tx_list ] + block.vtx.extend(tx_list) + block.hashMerkleRoot = block.calc_merkle_root() + block.rehash() + return block + + # Create a block on top of self.tip, and advance self.tip to point to the new block + # if spend is specified, then 1 satoshi will be spent from that to an anyone-can-spend output, + # and rest will go to fees. + def next_block(self, number, spend=None, additional_coinbase_value=0, script=None): + if self.tip == None: + base_block_hash = self.genesis_hash + else: + base_block_hash = self.tip.sha256 + # First create the coinbase + height = self.block_heights[base_block_hash] + 1 + coinbase = create_coinbase(height, self.coinbase_pubkey) + coinbase.vout[0].nValue += additional_coinbase_value + if (spend != None): + coinbase.vout[0].nValue += spend.tx.vout[spend.n].nValue - 1 # all but one satoshi to fees + coinbase.rehash() + block = create_block(base_block_hash, coinbase, self.block_time) + if (spend != None): + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(spend.tx.sha256, spend.n), "", 0xffffffff)) # no signature yet + # This copies the java comparison tool testing behavior: the first + # txout has a garbage scriptPubKey, "to make sure we're not + # pre-verifying too much" (?) + tx.vout.append(CTxOut(0, CScript([random.randint(0,255), height & 255]))) + if script == None: + tx.vout.append(CTxOut(1, CScript([OP_TRUE]))) + else: + tx.vout.append(CTxOut(1, script)) + # Now sign it if necessary + scriptSig = "" + scriptPubKey = bytearray(spend.tx.vout[spend.n].scriptPubKey) + if (scriptPubKey[0] == OP_TRUE): # looks like an anyone-can-spend + scriptSig = CScript([OP_TRUE]) + else: + # We have to actually sign it + (sighash, err) = SignatureHash(spend.tx.vout[spend.n].scriptPubKey, tx, 0, SIGHASH_ALL) + scriptSig = CScript([self.coinbase_key.sign(sighash) + bytes(bytearray([SIGHASH_ALL]))]) + tx.vin[0].scriptSig = scriptSig + # Now add the transaction to the block + block = self.add_transactions_to_block(block, [tx]) + block.solve() + self.tip = block + self.block_heights[block.sha256] = height + self.block_time += 1 + assert number not in self.blocks + self.blocks[number] = block + return block + + def get_tests(self): + self.genesis_hash = int(self.nodes[0].getbestblockhash(), 16) + self.block_heights[self.genesis_hash] = 0 + spendable_outputs = [] + + # save the current tip so it can be spent by a later block + def save_spendable_output(): + spendable_outputs.append(self.tip) + + # get an output that we previous marked as spendable + def get_spendable_output(): + return PreviousSpendableOutput(spendable_outputs.pop(0).vtx[0], 0) + + # returns a test case that asserts that the current tip was accepted + def accepted(): + return TestInstance([[self.tip, True]]) + + # returns a test case that asserts that the current tip was rejected + def rejected(): + return TestInstance([[self.tip, False]]) + + # move the tip back to a previous block + def tip(number): + self.tip = self.blocks[number] + + # creates a new block and advances the tip to that block + block = self.next_block + + + # Create a new block + block(0) + save_spendable_output() + yield accepted() + + + # Now we need that block to mature so we can spend the coinbase. + test = TestInstance(sync_every_block=False) + for i in range(100): + block(1000 + i) + test.blocks_and_transactions.append([self.tip, True]) + save_spendable_output() + yield test + + + # Start by bulding a couple of blocks on top (which output is spent is in parentheses): + # genesis -> b1 (0) -> b2 (1) + out0 = get_spendable_output() + block(1, spend=out0) + save_spendable_output() + yield accepted() + + out1 = get_spendable_output() + block(2, spend=out1) + # Inv again, then deliver twice (shouldn't break anything). + yield accepted() + + + # so fork like this: + # + # genesis -> b1 (0) -> b2 (1) + # \-> b3 (1) + # + # Nothing should happen at this point. We saw b2 first so it takes priority. + tip(1) + block(3, spend=out1) + # Deliver twice (should still not break anything) + yield rejected() + + + # Now we add another block to make the alternative chain longer. + # + # genesis -> b1 (0) -> b2 (1) + # \-> b3 (1) -> b4 (2) + out2 = get_spendable_output() + block(4, spend=out2) + yield accepted() + + + # ... and back to the first chain. + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b3 (1) -> b4 (2) + tip(2) + block(5, spend=out2) + save_spendable_output() + yield rejected() + + out3 = get_spendable_output() + block(6, spend=out3) + yield accepted() + + + # Try to create a fork that double-spends + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b7 (2) -> b8 (4) + # \-> b3 (1) -> b4 (2) + tip(5) + block(7, spend=out2) + yield rejected() + + out4 = get_spendable_output() + block(8, spend=out4) + yield rejected() + + + # Try to create a block that has too much fee + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b9 (4) + # \-> b3 (1) -> b4 (2) + tip(6) + block(9, spend=out4, additional_coinbase_value=1) + yield rejected() + + + # Create a fork that ends in a block with too much fee (the one that causes the reorg) + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b10 (3) -> b11 (4) + # \-> b3 (1) -> b4 (2) + tip(5) + block(10, spend=out3) + yield rejected() + + block(11, spend=out4, additional_coinbase_value=1) + yield rejected() + + + # Try again, but with a valid fork first + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b12 (3) -> b13 (4) -> b14 (5) + # (b12 added last) + # \-> b3 (1) -> b4 (2) + tip(5) + b12 = block(12, spend=out3) + save_spendable_output() + #yield TestInstance([[b12, False]]) + b13 = block(13, spend=out4) + # Deliver the block header for b12, and the block b13. + # b13 should be accepted but the tip won't advance until b12 is delivered. + yield TestInstance([[CBlockHeader(b12), None], [b13, False]]) + + save_spendable_output() + out5 = get_spendable_output() + # b14 is invalid, but the node won't know that until it tries to connect + # Tip still can't advance because b12 is missing + block(14, spend=out5, additional_coinbase_value=1) + yield rejected() + + yield TestInstance([[b12, True, b13.sha256]]) # New tip should be b13. + + + # Test that a block with a lot of checksigs is okay + lots_of_checksigs = CScript([OP_CHECKSIG] * (1000000 / 50 - 1)) + tip(13) + block(15, spend=out5, script=lots_of_checksigs) + yield accepted() + + + # Test that a block with too many checksigs is rejected + out6 = get_spendable_output() + too_many_checksigs = CScript([OP_CHECKSIG] * (1000000 / 50)) + block(16, spend=out6, script=too_many_checksigs) + yield rejected() + + + +if __name__ == '__main__': + FullBlockTest().main() diff --git a/qa/rpc-tests/rest.py b/qa/rpc-tests/rest.py index b0cde7268e..e084ad55ab 100755 --- a/qa/rpc-tests/rest.py +++ b/qa/rpc-tests/rest.py @@ -32,10 +32,20 @@ def deser_uint256(f): r += t << (i * 32) return r -#allows simple http get calls with a request body -def http_get_call(host, port, path, requestdata = '', response_object = 0): +#allows simple http get calls +def http_get_call(host, port, path, response_object = 0): conn = httplib.HTTPConnection(host, port) - conn.request('GET', path, requestdata) + conn.request('GET', path) + + if response_object: + return conn.getresponse() + + return conn.getresponse().read() + +#allows simple http post calls with a request body +def http_post_call(host, port, path, requestdata = '', response_object = 0): + conn = httplib.HTTPConnection(host, port) + conn.request('POST', path, requestdata) if response_object: return conn.getresponse() @@ -137,7 +147,7 @@ class RESTTest (BitcoinTestFramework): binaryRequest += binascii.unhexlify(vintx); binaryRequest += pack("i", 0); - bin_response = http_get_call(url.hostname, url.port, '/rest/getutxos'+self.FORMAT_SEPARATOR+'bin', binaryRequest) + bin_response = http_post_call(url.hostname, url.port, '/rest/getutxos'+self.FORMAT_SEPARATOR+'bin', binaryRequest) output = StringIO.StringIO() output.write(bin_response) output.seek(0) @@ -175,14 +185,14 @@ class RESTTest (BitcoinTestFramework): #do some invalid requests json_request = '{"checkmempool' - response = http_get_call(url.hostname, url.port, '/rest/getutxos'+self.FORMAT_SEPARATOR+'json', json_request, True) + response = http_post_call(url.hostname, url.port, '/rest/getutxos'+self.FORMAT_SEPARATOR+'json', json_request, True) assert_equal(response.status, 500) #must be a 500 because we send a invalid json request json_request = '{"checkmempool' - response = http_get_call(url.hostname, url.port, '/rest/getutxos'+self.FORMAT_SEPARATOR+'bin', json_request, True) + response = http_post_call(url.hostname, url.port, '/rest/getutxos'+self.FORMAT_SEPARATOR+'bin', json_request, True) assert_equal(response.status, 500) #must be a 500 because we send a invalid bin request - response = http_get_call(url.hostname, url.port, '/rest/getutxos/checkmempool'+self.FORMAT_SEPARATOR+'bin', '', True) + response = http_post_call(url.hostname, url.port, '/rest/getutxos/checkmempool'+self.FORMAT_SEPARATOR+'bin', '', True) assert_equal(response.status, 500) #must be a 500 because we send a invalid bin request #test limits @@ -190,17 +200,17 @@ class RESTTest (BitcoinTestFramework): for x in range(0, 20): json_request += txid+'-'+str(n)+'/' json_request = json_request.rstrip("/") - response = http_get_call(url.hostname, url.port, '/rest/getutxos'+json_request+self.FORMAT_SEPARATOR+'json', '', True) + response = http_post_call(url.hostname, url.port, '/rest/getutxos'+json_request+self.FORMAT_SEPARATOR+'json', '', True) assert_equal(response.status, 500) #must be a 500 because we exceeding the limits json_request = '/checkmempool/' for x in range(0, 15): json_request += txid+'-'+str(n)+'/' json_request = json_request.rstrip("/"); - response = http_get_call(url.hostname, url.port, '/rest/getutxos'+json_request+self.FORMAT_SEPARATOR+'json', '', True) + response = http_post_call(url.hostname, url.port, '/rest/getutxos'+json_request+self.FORMAT_SEPARATOR+'json', '', True) assert_equal(response.status, 200) #must be a 500 because we exceeding the limits - self.nodes[0].generate(1) #generate block to not affect upcomming tests + self.nodes[0].generate(1) #generate block to not affect upcoming tests self.sync_all() ################ @@ -208,27 +218,27 @@ class RESTTest (BitcoinTestFramework): ################ # check binary format - response = http_get_call(url.hostname, url.port, '/rest/block/'+bb_hash+self.FORMAT_SEPARATOR+"bin", "", True) + response = http_get_call(url.hostname, url.port, '/rest/block/'+bb_hash+self.FORMAT_SEPARATOR+"bin", True) assert_equal(response.status, 200) assert_greater_than(int(response.getheader('content-length')), 80) response_str = response.read() # compare with block header - response_header = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"bin", "", True) + response_header = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"bin", True) assert_equal(response_header.status, 200) assert_equal(int(response_header.getheader('content-length')), 80) response_header_str = response_header.read() assert_equal(response_str[0:80], response_header_str) # check block hex format - response_hex = http_get_call(url.hostname, url.port, '/rest/block/'+bb_hash+self.FORMAT_SEPARATOR+"hex", "", True) + response_hex = http_get_call(url.hostname, url.port, '/rest/block/'+bb_hash+self.FORMAT_SEPARATOR+"hex", True) assert_equal(response_hex.status, 200) assert_greater_than(int(response_hex.getheader('content-length')), 160) response_hex_str = response_hex.read() assert_equal(response_str.encode("hex")[0:160], response_hex_str[0:160]) # compare with hex block header - response_header_hex = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"hex", "", True) + response_header_hex = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"hex", True) assert_equal(response_header_hex.status, 200) assert_greater_than(int(response_header_hex.getheader('content-length')), 160) response_header_hex_str = response_header_hex.read() @@ -241,7 +251,7 @@ class RESTTest (BitcoinTestFramework): assert_equal(block_json_obj['hash'], bb_hash) # compare with json block header - response_header_json = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"json", "", True) + response_header_json = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"json", True) assert_equal(response_header_json.status, 200) response_header_json_str = response_header_json.read() json_obj = json.loads(response_header_json_str, parse_float=decimal.Decimal) @@ -265,7 +275,7 @@ class RESTTest (BitcoinTestFramework): #see if we can get 5 headers in one response self.nodes[1].generate(5) self.sync_all() - response_header_json = http_get_call(url.hostname, url.port, '/rest/headers/5/'+bb_hash+self.FORMAT_SEPARATOR+"json", "", True) + response_header_json = http_get_call(url.hostname, url.port, '/rest/headers/5/'+bb_hash+self.FORMAT_SEPARATOR+"json", True) assert_equal(response_header_json.status, 200) response_header_json_str = response_header_json.read() json_obj = json.loads(response_header_json_str) @@ -278,7 +288,7 @@ class RESTTest (BitcoinTestFramework): assert_equal(json_obj['txid'], tx_hash) # check hex format response - hex_string = http_get_call(url.hostname, url.port, '/rest/tx/'+tx_hash+self.FORMAT_SEPARATOR+"hex", "", True) + hex_string = http_get_call(url.hostname, url.port, '/rest/tx/'+tx_hash+self.FORMAT_SEPARATOR+"hex", True) assert_equal(hex_string.status, 200) assert_greater_than(int(response.getheader('content-length')), 10) @@ -292,6 +302,19 @@ class RESTTest (BitcoinTestFramework): txs.append(self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)) self.sync_all() + # check that there are exactly 3 transactions in the TX memory pool before generating the block + json_string = http_get_call(url.hostname, url.port, '/rest/mempool/info'+self.FORMAT_SEPARATOR+'json') + json_obj = json.loads(json_string) + assert_equal(json_obj['size'], 3) + # the size of the memory pool should be greater than 3x ~100 bytes + assert_greater_than(json_obj['bytes'], 300) + + # check that there are our submitted transactions in the TX memory pool + json_string = http_get_call(url.hostname, url.port, '/rest/mempool/contents'+self.FORMAT_SEPARATOR+'json') + json_obj = json.loads(json_string) + for tx in txs: + assert_equal(tx in json_obj, True) + # now mine the transactions newblockhash = self.nodes[1].generate(1) self.sync_all() diff --git a/qa/rpc-tests/script_test.py b/qa/rpc-tests/script_test.py index 860fa56b64..afc44b51b5 100755 --- a/qa/rpc-tests/script_test.py +++ b/qa/rpc-tests/script_test.py @@ -124,10 +124,10 @@ def ParseScript(json_script): return parsed_script class TestBuilder(object): - def create_credit_tx(self, scriptPubKey): + def create_credit_tx(self, scriptPubKey, height): # self.tx1 is a coinbase transaction, modeled after the one created by script_tests.cpp # This allows us to reuse signatures created in the unit test framework. - self.tx1 = create_coinbase() # this has a bip34 scriptsig, + self.tx1 = create_coinbase(height) # this has a bip34 scriptsig, self.tx1.vin[0].scriptSig = CScript([0, 0]) # but this matches the unit tests self.tx1.vout[0].nValue = 0 self.tx1.vout[0].scriptPubKey = scriptPubKey @@ -168,7 +168,7 @@ class ScriptTest(ComparisonTestFramework): test = TestInstance(sync_every_block=False) test_build = TestBuilder() - test_build.create_credit_tx(scriptpubkey) + test_build.create_credit_tx(scriptpubkey, self.height) test_build.create_spend_tx(scriptsig) test_build.rehash() @@ -176,16 +176,18 @@ class ScriptTest(ComparisonTestFramework): self.block_time += 1 block.solve() self.tip = block.sha256 + self.height += 1 test.blocks_and_transactions = [[block, True]] for i in xrange(100): - block = create_block(self.tip, create_coinbase(), self.block_time) + block = create_block(self.tip, create_coinbase(self.height), self.block_time) self.block_time += 1 block.solve() self.tip = block.sha256 + self.height += 1 test.blocks_and_transactions.append([block, True]) - block = create_block(self.tip, create_coinbase(), self.block_time) + block = create_block(self.tip, create_coinbase(self.height), self.block_time) self.block_time += 1 block.vtx.append(test_build.tx2) block.hashMerkleRoot = block.calc_merkle_root() @@ -198,14 +200,16 @@ class ScriptTest(ComparisonTestFramework): def get_tests(self): self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0) self.block_time = 1333230000 # before the BIP16 switchover + self.height = 1 ''' Create a new block with an anyone-can-spend coinbase ''' - block = create_block(self.tip, create_coinbase(), self.block_time) + block = create_block(self.tip, create_coinbase(self.height), self.block_time) self.block_time += 1 block.solve() self.tip = block.sha256 + self.height += 1 yield TestInstance(objects=[[block, True]]) ''' @@ -213,11 +217,12 @@ class ScriptTest(ComparisonTestFramework): ''' test = TestInstance(objects=[], sync_every_block=False, sync_every_tx=False) for i in xrange(100): - b = create_block(self.tip, create_coinbase(), self.block_time) + b = create_block(self.tip, create_coinbase(self.height), self.block_time) b.solve() test.blocks_and_transactions.append([b, True]) self.tip = b.sha256 self.block_time += 1 + self.height += 1 yield test ''' Iterate through script tests. ''' @@ -229,6 +234,7 @@ class ScriptTest(ComparisonTestFramework): self.nodes[1].invalidateblock(self.nodes[1].getblockhash(102)) self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0) + self.height = 102 [scriptsig, scriptpubkey, flags] = script_test[0:3] flags = ParseScriptFlags(flags) diff --git a/qa/rpc-tests/test_framework/authproxy.py b/qa/rpc-tests/test_framework/authproxy.py index bc7d655fdf..33014dc139 100644 --- a/qa/rpc-tests/test_framework/authproxy.py +++ b/qa/rpc-tests/test_framework/authproxy.py @@ -106,6 +106,26 @@ class AuthServiceProxy(object): name = "%s.%s" % (self.__service_name, name) return AuthServiceProxy(self.__service_url, name, connection=self.__conn) + def _request(self, method, path, postdata): + ''' + Do a HTTP request, with retry if we get disconnected (e.g. due to a timeout). + This is a workaround for https://bugs.python.org/issue3566 which is fixed in Python 3.5. + ''' + headers = {'Host': self.__url.hostname, + 'User-Agent': USER_AGENT, + 'Authorization': self.__auth_header, + 'Content-type': 'application/json'} + try: + self.__conn.request(method, path, postdata, headers) + return self._get_response() + except httplib.BadStatusLine as e: + if e.line == "''": # if connection was closed, try again + self.__conn.close() + self.__conn.request(method, path, postdata, headers) + return self._get_response() + else: + raise + def __call__(self, *args): AuthServiceProxy.__id_count += 1 @@ -115,13 +135,7 @@ class AuthServiceProxy(object): 'method': self.__service_name, 'params': args, 'id': AuthServiceProxy.__id_count}, default=EncodeDecimal) - self.__conn.request('POST', self.__url.path, postdata, - {'Host': self.__url.hostname, - 'User-Agent': USER_AGENT, - 'Authorization': self.__auth_header, - 'Content-type': 'application/json'}) - - response = self._get_response() + response = self._request('POST', self.__url.path, postdata) if response['error'] is not None: raise JSONRPCException(response['error']) elif 'result' not in response: @@ -133,13 +147,7 @@ class AuthServiceProxy(object): def _batch(self, rpc_call_list): postdata = json.dumps(list(rpc_call_list), default=EncodeDecimal) log.debug("--> "+postdata) - self.__conn.request('POST', self.__url.path, postdata, - {'Host': self.__url.hostname, - 'User-Agent': USER_AGENT, - 'Authorization': self.__auth_header, - 'Content-type': 'application/json'}) - - return self._get_response() + return self._request('POST', self.__url.path, postdata) def _get_response(self): http_response = self.__conn.getresponse() diff --git a/qa/rpc-tests/test_framework/blockstore.py b/qa/rpc-tests/test_framework/blockstore.py index c57b6df81b..b9775b477c 100644 --- a/qa/rpc-tests/test_framework/blockstore.py +++ b/qa/rpc-tests/test_framework/blockstore.py @@ -10,6 +10,7 @@ class BlockStore(object): def __init__(self, datadir): self.blockDB = dbm.open(datadir + "/blocks", 'c') self.currentBlock = 0L + self.headers_map = dict() def close(self): self.blockDB.close() @@ -26,24 +27,30 @@ class BlockStore(object): ret.calc_sha256() return ret + def get_header(self, blockhash): + try: + return self.headers_map[blockhash] + except KeyError: + return None + # Note: this pulls full blocks out of the database just to retrieve # the headers -- perhaps we could keep a separate data structure # to avoid this overhead. def headers_for(self, locator, hash_stop, current_tip=None): if current_tip is None: current_tip = self.currentBlock - current_block = self.get(current_tip) - if current_block is None: + current_block_header = self.get_header(current_tip) + if current_block_header is None: return None response = msg_headers() - headersList = [ CBlockHeader(current_block) ] + headersList = [ current_block_header ] maxheaders = 2000 while (headersList[0].sha256 not in locator.vHave): prevBlockHash = headersList[0].hashPrevBlock - prevBlock = self.get(prevBlockHash) - if prevBlock is not None: - headersList.insert(0, CBlockHeader(prevBlock)) + prevBlockHeader = self.get_header(prevBlockHash) + if prevBlockHeader is not None: + headersList.insert(0, prevBlockHeader) else: break headersList = headersList[:maxheaders] # truncate if we have too many @@ -61,6 +68,10 @@ class BlockStore(object): except TypeError as e: print "Unexpected error: ", sys.exc_info()[0], e.args self.currentBlock = block.sha256 + self.headers_map[block.sha256] = CBlockHeader(block) + + def add_header(self, header): + self.headers_map[header.sha256] = header def get_blocks(self, inv): responses = [] diff --git a/qa/rpc-tests/test_framework/blocktools.py b/qa/rpc-tests/test_framework/blocktools.py index f397fe7cd6..59aa8c15cc 100644 --- a/qa/rpc-tests/test_framework/blocktools.py +++ b/qa/rpc-tests/test_framework/blocktools.py @@ -5,7 +5,7 @@ # from mininode import * -from script import CScript, CScriptOp +from script import CScript, CScriptOp, OP_TRUE, OP_CHECKSIG # Create a block (with regtest difficulty) def create_block(hashprev, coinbase, nTime=None): @@ -37,19 +37,21 @@ def serialize_script_num(value): r[-1] |= 0x80 return r -counter=1 -# Create an anyone-can-spend coinbase transaction, assuming no miner fees -def create_coinbase(heightAdjust = 0): - global counter +# Create a coinbase transaction, assuming no miner fees. +# If pubkey is passed in, the coinbase output will be a P2PK output; +# otherwise an anyone-can-spend output. +def create_coinbase(height, pubkey = None): coinbase = CTransaction() coinbase.vin.append(CTxIn(COutPoint(0, 0xffffffff), - ser_string(serialize_script_num(counter+heightAdjust)), 0xffffffff)) - counter += 1 + ser_string(serialize_script_num(height)), 0xffffffff)) coinbaseoutput = CTxOut() coinbaseoutput.nValue = 50*100000000 - halvings = int((counter+heightAdjust)/150) # regtest + halvings = int(height/150) # regtest coinbaseoutput.nValue >>= halvings - coinbaseoutput.scriptPubKey = "" + if (pubkey != None): + coinbaseoutput.scriptPubKey = CScript([pubkey, OP_CHECKSIG]) + else: + coinbaseoutput.scriptPubKey = CScript([OP_TRUE]) coinbase.vout = [ coinbaseoutput ] coinbase.calc_sha256() return coinbase diff --git a/qa/rpc-tests/test_framework/comptool.py b/qa/rpc-tests/test_framework/comptool.py index 7fb31d4a06..e0b3ce040d 100755 --- a/qa/rpc-tests/test_framework/comptool.py +++ b/qa/rpc-tests/test_framework/comptool.py @@ -27,6 +27,20 @@ generator that returns TestInstance objects. See below for definition. global mininode_lock +def wait_until(predicate, attempts=float('inf'), timeout=float('inf')): + attempt = 0 + elapsed = 0 + + while attempt < attempts and elapsed < timeout: + with mininode_lock: + if predicate(): + return True + attempt += 1 + elapsed += 0.05 + time.sleep(0.05) + + return False + class TestNode(NodeConnCB): def __init__(self, block_store, tx_store): @@ -43,6 +57,10 @@ class TestNode(NodeConnCB): # a response self.pingMap = {} self.lastInv = [] + self.closed = False + + def on_close(self, conn): + self.closed = True def add_connection(self, conn): self.conn = conn @@ -104,19 +122,26 @@ class TestNode(NodeConnCB): # Instances of these are generated by the test generator, and fed into the # comptool. # -# "blocks_and_transactions" should be an array of [obj, True/False/None]: -# - obj is either a CBlock or a CTransaction, and +# "blocks_and_transactions" should be an array of +# [obj, True/False/None, hash/None]: +# - obj is either a CBlock, CBlockHeader, or a CTransaction, and # - the second value indicates whether the object should be accepted # into the blockchain or mempool (for tests where we expect a certain # answer), or "None" if we don't expect a certain answer and are just # comparing the behavior of the nodes being tested. +# - the third value is the hash to test the tip against (if None or omitted, +# use the hash of the block) +# - NOTE: if a block header, no test is performed; instead the header is +# just added to the block_store. This is to facilitate block delivery +# when communicating with headers-first clients (when withholding an +# intermediate block). # sync_every_block: if True, then each block will be inv'ed, synced, and # nodes will be tested based on the outcome for the block. If False, # then inv's accumulate until all blocks are processed (or max inv size # is reached) and then sent out in one inv message. Then the final block # will be synced across all connections, and the outcome of the final # block will be tested. -# sync_every_tx: analagous to behavior for sync_every_block, except if outcome +# sync_every_tx: analogous to behavior for sync_every_block, except if outcome # on the final tx is None, then contents of entire mempool are compared # across all connections. (If outcome of final tx is specified as true # or false, then only the last tx is tested against outcome.) @@ -132,6 +157,7 @@ class TestManager(object): def __init__(self, testgen, datadir): self.test_generator = testgen self.connections = [] + self.test_nodes = [] self.block_store = BlockStore(datadir) self.tx_store = TxStore(datadir) self.ping_counter = 1 @@ -139,57 +165,42 @@ class TestManager(object): def add_all_connections(self, nodes): for i in range(len(nodes)): # Create a p2p connection to each node - self.connections.append(NodeConn('127.0.0.1', p2p_port(i), - nodes[i], TestNode(self.block_store, self.tx_store))) + test_node = TestNode(self.block_store, self.tx_store) + self.test_nodes.append(test_node) + self.connections.append(NodeConn('127.0.0.1', p2p_port(i), nodes[i], test_node)) # Make sure the TestNode (callback class) has a reference to its # associated NodeConn - self.connections[-1].cb.add_connection(self.connections[-1]) + test_node.add_connection(self.connections[-1]) + + def wait_for_disconnections(self): + def disconnected(): + return all(node.closed for node in self.test_nodes) + return wait_until(disconnected, timeout=10) def wait_for_verack(self): - sleep_time = 0.05 - max_tries = 10 / sleep_time # Wait at most 10 seconds - while max_tries > 0: - done = True - with mininode_lock: - for c in self.connections: - if c.cb.verack_received is False: - done = False - break - if done: - break - time.sleep(sleep_time) + def veracked(): + return all(node.verack_received for node in self.test_nodes) + return wait_until(veracked, timeout=10) def wait_for_pings(self, counter): - received_pongs = False - while received_pongs is not True: - time.sleep(0.05) - received_pongs = True - with mininode_lock: - for c in self.connections: - if c.cb.received_ping_response(counter) is not True: - received_pongs = False - break + def received_pongs(): + return all(node.received_ping_response(counter) for node in self.test_nodes) + return wait_until(received_pongs) # sync_blocks: Wait for all connections to request the blockhash given # then send get_headers to find out the tip of each node, and synchronize # the response by using a ping (and waiting for pong with same nonce). def sync_blocks(self, blockhash, num_blocks): - # Wait for nodes to request block (50ms sleep * 20 tries * num_blocks) - max_tries = 20*num_blocks - while max_tries > 0: - with mininode_lock: - results = [ blockhash in c.cb.block_request_map and - c.cb.block_request_map[blockhash] for c in self.connections ] - if False not in results: - break - time.sleep(0.05) - max_tries -= 1 + def blocks_requested(): + return all( + blockhash in node.block_request_map and node.block_request_map[blockhash] + for node in self.test_nodes + ) # --> error if not requested - if max_tries == 0: + if not wait_until(blocks_requested, attempts=20*num_blocks): # print [ c.cb.block_request_map for c in self.connections ] raise AssertionError("Not all nodes requested block") - # --> Answer request (we did this inline!) # Send getheaders message [ c.cb.send_getheaders() for c in self.connections ] @@ -202,21 +213,16 @@ class TestManager(object): # Analogous to sync_block (see above) def sync_transaction(self, txhash, num_events): # Wait for nodes to request transaction (50ms sleep * 20 tries * num_events) - max_tries = 20*num_events - while max_tries > 0: - with mininode_lock: - results = [ txhash in c.cb.tx_request_map and - c.cb.tx_request_map[txhash] for c in self.connections ] - if False not in results: - break - time.sleep(0.05) - max_tries -= 1 + def transaction_requested(): + return all( + txhash in node.tx_request_map and node.tx_request_map[txhash] + for node in self.test_nodes + ) # --> error if not requested - if max_tries == 0: + if not wait_until(transaction_requested, attempts=20*num_events): # print [ c.cb.tx_request_map for c in self.connections ] raise AssertionError("Not all nodes requested transaction") - # --> Answer request (we did this inline!) # Get the mempool [ c.cb.send_mempool() for c in self.connections ] @@ -271,29 +277,55 @@ class TestManager(object): # We use these variables to keep track of the last block # and last transaction in the tests, which are used # if we're not syncing on every block or every tx. - [ block, block_outcome ] = [ None, None ] + [ block, block_outcome, tip ] = [ None, None, None ] [ tx, tx_outcome ] = [ None, None ] invqueue = [] - for b_or_t, outcome in test_instance.blocks_and_transactions: + for test_obj in test_instance.blocks_and_transactions: + b_or_t = test_obj[0] + outcome = test_obj[1] # Determine if we're dealing with a block or tx if isinstance(b_or_t, CBlock): # Block test runner block = b_or_t block_outcome = outcome + tip = block.sha256 + # each test_obj can have an optional third argument + # to specify the tip we should compare with + # (default is to use the block being tested) + if len(test_obj) >= 3: + tip = test_obj[2] + # Add to shared block_store, set as current block + # If there was an open getdata request for the block + # previously, and we didn't have an entry in the + # block_store, then immediately deliver, because the + # node wouldn't send another getdata request while + # the earlier one is outstanding. + first_block_with_hash = True + if self.block_store.get(block.sha256) is not None: + first_block_with_hash = False with mininode_lock: self.block_store.add_block(block) for c in self.connections: - c.cb.block_request_map[block.sha256] = False + if first_block_with_hash and block.sha256 in c.cb.block_request_map and c.cb.block_request_map[block.sha256] == True: + # There was a previous request for this block hash + # Most likely, we delivered a header for this block + # but never had the block to respond to the getdata + c.send_message(msg_block(block)) + else: + c.cb.block_request_map[block.sha256] = False # Either send inv's to each node and sync, or add # to invqueue for later inv'ing. if (test_instance.sync_every_block): [ c.cb.send_inv(block) for c in self.connections ] self.sync_blocks(block.sha256, 1) - if (not self.check_results(block.sha256, outcome)): + if (not self.check_results(tip, outcome)): raise AssertionError("Test failed at test %d" % test_number) else: invqueue.append(CInv(2, block.sha256)) + elif isinstance(b_or_t, CBlockHeader): + block_header = b_or_t + self.block_store.add_header(block_header) else: # Tx test runner assert(isinstance(b_or_t, CTransaction)) tx = b_or_t @@ -321,9 +353,8 @@ class TestManager(object): if len(invqueue) > 0: [ c.send_message(msg_inv(invqueue)) for c in self.connections ] invqueue = [] - self.sync_blocks(block.sha256, - len(test_instance.blocks_and_transactions)) - if (not self.check_results(block.sha256, block_outcome)): + self.sync_blocks(block.sha256, len(test_instance.blocks_and_transactions)) + if (not self.check_results(tip, block_outcome)): raise AssertionError("Block test failed at test %d" % test_number) if (not test_instance.sync_every_tx and tx is not None): if len(invqueue) > 0: @@ -336,6 +367,7 @@ class TestManager(object): print "Test %d: PASS" % test_number, [ c.rpc.getblockcount() for c in self.connections ] test_number += 1 + [ c.disconnect_node() for c in self.connections ] + self.wait_for_disconnections() self.block_store.close() self.tx_store.close() - [ c.disconnect_node() for c in self.connections ] diff --git a/qa/rpc-tests/test_framework/key.py b/qa/rpc-tests/test_framework/key.py new file mode 100644 index 0000000000..ba3038fe04 --- /dev/null +++ b/qa/rpc-tests/test_framework/key.py @@ -0,0 +1,215 @@ +# Copyright (c) 2011 Sam Rushing +# +# key.py - OpenSSL wrapper +# +# This file is modified from python-bitcoinlib. +# + +"""ECC secp256k1 crypto routines + +WARNING: This module does not mlock() secrets; your private keys may end up on +disk in swap! Use with caution! +""" + +import ctypes +import ctypes.util +import hashlib +import sys + +ssl = ctypes.cdll.LoadLibrary(ctypes.util.find_library ('ssl') or 'libeay32') + +ssl.BN_new.restype = ctypes.c_void_p +ssl.BN_new.argtypes = [] + +ssl.BN_bin2bn.restype = ctypes.c_void_p +ssl.BN_bin2bn.argtypes = [ctypes.c_char_p, ctypes.c_int, ctypes.c_void_p] + +ssl.BN_CTX_free.restype = None +ssl.BN_CTX_free.argtypes = [ctypes.c_void_p] + +ssl.BN_CTX_new.restype = ctypes.c_void_p +ssl.BN_CTX_new.argtypes = [] + +ssl.ECDH_compute_key.restype = ctypes.c_int +ssl.ECDH_compute_key.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p] + +ssl.ECDSA_sign.restype = ctypes.c_int +ssl.ECDSA_sign.argtypes = [ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] + +ssl.ECDSA_verify.restype = ctypes.c_int +ssl.ECDSA_verify.argtypes = [ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p] + +ssl.EC_KEY_free.restype = None +ssl.EC_KEY_free.argtypes = [ctypes.c_void_p] + +ssl.EC_KEY_new_by_curve_name.restype = ctypes.c_void_p +ssl.EC_KEY_new_by_curve_name.argtypes = [ctypes.c_int] + +ssl.EC_KEY_get0_group.restype = ctypes.c_void_p +ssl.EC_KEY_get0_group.argtypes = [ctypes.c_void_p] + +ssl.EC_KEY_get0_public_key.restype = ctypes.c_void_p +ssl.EC_KEY_get0_public_key.argtypes = [ctypes.c_void_p] + +ssl.EC_KEY_set_private_key.restype = ctypes.c_int +ssl.EC_KEY_set_private_key.argtypes = [ctypes.c_void_p, ctypes.c_void_p] + +ssl.EC_KEY_set_conv_form.restype = None +ssl.EC_KEY_set_conv_form.argtypes = [ctypes.c_void_p, ctypes.c_int] + +ssl.EC_KEY_set_public_key.restype = ctypes.c_int +ssl.EC_KEY_set_public_key.argtypes = [ctypes.c_void_p, ctypes.c_void_p] + +ssl.i2o_ECPublicKey.restype = ctypes.c_void_p +ssl.i2o_ECPublicKey.argtypes = [ctypes.c_void_p, ctypes.c_void_p] + +ssl.EC_POINT_new.restype = ctypes.c_void_p +ssl.EC_POINT_new.argtypes = [ctypes.c_void_p] + +ssl.EC_POINT_free.restype = None +ssl.EC_POINT_free.argtypes = [ctypes.c_void_p] + +ssl.EC_POINT_mul.restype = ctypes.c_int +ssl.EC_POINT_mul.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] + +# this specifies the curve used with ECDSA. +NID_secp256k1 = 714 # from openssl/obj_mac.h + +# Thx to Sam Devlin for the ctypes magic 64-bit fix. +def _check_result(val, func, args): + if val == 0: + raise ValueError + else: + return ctypes.c_void_p (val) + +ssl.EC_KEY_new_by_curve_name.restype = ctypes.c_void_p +ssl.EC_KEY_new_by_curve_name.errcheck = _check_result + +class CECKey(object): + """Wrapper around OpenSSL's EC_KEY""" + + POINT_CONVERSION_COMPRESSED = 2 + POINT_CONVERSION_UNCOMPRESSED = 4 + + def __init__(self): + self.k = ssl.EC_KEY_new_by_curve_name(NID_secp256k1) + + def __del__(self): + if ssl: + ssl.EC_KEY_free(self.k) + self.k = None + + def set_secretbytes(self, secret): + priv_key = ssl.BN_bin2bn(secret, 32, ssl.BN_new()) + group = ssl.EC_KEY_get0_group(self.k) + pub_key = ssl.EC_POINT_new(group) + ctx = ssl.BN_CTX_new() + if not ssl.EC_POINT_mul(group, pub_key, priv_key, None, None, ctx): + raise ValueError("Could not derive public key from the supplied secret.") + ssl.EC_POINT_mul(group, pub_key, priv_key, None, None, ctx) + ssl.EC_KEY_set_private_key(self.k, priv_key) + ssl.EC_KEY_set_public_key(self.k, pub_key) + ssl.EC_POINT_free(pub_key) + ssl.BN_CTX_free(ctx) + return self.k + + def set_privkey(self, key): + self.mb = ctypes.create_string_buffer(key) + return ssl.d2i_ECPrivateKey(ctypes.byref(self.k), ctypes.byref(ctypes.pointer(self.mb)), len(key)) + + def set_pubkey(self, key): + self.mb = ctypes.create_string_buffer(key) + return ssl.o2i_ECPublicKey(ctypes.byref(self.k), ctypes.byref(ctypes.pointer(self.mb)), len(key)) + + def get_privkey(self): + size = ssl.i2d_ECPrivateKey(self.k, 0) + mb_pri = ctypes.create_string_buffer(size) + ssl.i2d_ECPrivateKey(self.k, ctypes.byref(ctypes.pointer(mb_pri))) + return mb_pri.raw + + def get_pubkey(self): + size = ssl.i2o_ECPublicKey(self.k, 0) + mb = ctypes.create_string_buffer(size) + ssl.i2o_ECPublicKey(self.k, ctypes.byref(ctypes.pointer(mb))) + return mb.raw + + def get_raw_ecdh_key(self, other_pubkey): + ecdh_keybuffer = ctypes.create_string_buffer(32) + r = ssl.ECDH_compute_key(ctypes.pointer(ecdh_keybuffer), 32, + ssl.EC_KEY_get0_public_key(other_pubkey.k), + self.k, 0) + if r != 32: + raise Exception('CKey.get_ecdh_key(): ECDH_compute_key() failed') + return ecdh_keybuffer.raw + + def get_ecdh_key(self, other_pubkey, kdf=lambda k: hashlib.sha256(k).digest()): + # FIXME: be warned it's not clear what the kdf should be as a default + r = self.get_raw_ecdh_key(other_pubkey) + return kdf(r) + + def sign(self, hash): + # FIXME: need unit tests for below cases + if not isinstance(hash, bytes): + raise TypeError('Hash must be bytes instance; got %r' % hash.__class__) + if len(hash) != 32: + raise ValueError('Hash must be exactly 32 bytes long') + + sig_size0 = ctypes.c_uint32() + sig_size0.value = ssl.ECDSA_size(self.k) + mb_sig = ctypes.create_string_buffer(sig_size0.value) + result = ssl.ECDSA_sign(0, hash, len(hash), mb_sig, ctypes.byref(sig_size0), self.k) + assert 1 == result + return mb_sig.raw[:sig_size0.value] + + def verify(self, hash, sig): + """Verify a DER signature""" + return ssl.ECDSA_verify(0, hash, len(hash), sig, len(sig), self.k) == 1 + + def set_compressed(self, compressed): + if compressed: + form = self.POINT_CONVERSION_COMPRESSED + else: + form = self.POINT_CONVERSION_UNCOMPRESSED + ssl.EC_KEY_set_conv_form(self.k, form) + + +class CPubKey(bytes): + """An encapsulated public key + + Attributes: + + is_valid - Corresponds to CPubKey.IsValid() + is_fullyvalid - Corresponds to CPubKey.IsFullyValid() + is_compressed - Corresponds to CPubKey.IsCompressed() + """ + + def __new__(cls, buf, _cec_key=None): + self = super(CPubKey, cls).__new__(cls, buf) + if _cec_key is None: + _cec_key = CECKey() + self._cec_key = _cec_key + self.is_fullyvalid = _cec_key.set_pubkey(self) != 0 + return self + + @property + def is_valid(self): + return len(self) > 0 + + @property + def is_compressed(self): + return len(self) == 33 + + def verify(self, hash, sig): + return self._cec_key.verify(hash, sig) + + def __str__(self): + return repr(self) + + def __repr__(self): + # Always have represent as b'<secret>' so test cases don't have to + # change for py2/3 + if sys.version > '3': + return '%s(%s)' % (self.__class__.__name__, super(CPubKey, self).__repr__()) + else: + return '%s(b%s)' % (self.__class__.__name__, super(CPubKey, self).__repr__()) + diff --git a/qa/rpc-tests/test_framework/script.py b/qa/rpc-tests/test_framework/script.py index e37ab5d45a..0a78cf6fb1 100644 --- a/qa/rpc-tests/test_framework/script.py +++ b/qa/rpc-tests/test_framework/script.py @@ -27,7 +27,7 @@ if sys.version > '3': import copy import struct -import test_framework.bignum +from test_framework.bignum import bn2vch MAX_SCRIPT_SIZE = 10000 MAX_SCRIPT_ELEMENT_SIZE = 520 @@ -664,7 +664,7 @@ class CScript(bytes): elif other == -1: other = bytes(bchr(OP_1NEGATE)) else: - other = CScriptOp.encode_op_pushdata(bignum.bn2vch(other)) + other = CScriptOp.encode_op_pushdata(bn2vch(other)) elif isinstance(other, (bytes, bytearray)): other = CScriptOp.encode_op_pushdata(other) return other diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index c236ec2602..3759cc8162 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -78,8 +78,17 @@ def initialize_chain(test_dir): bitcoind and bitcoin-cli must be in search path. """ - if not os.path.isdir(os.path.join("cache", "node0")): - devnull = open("/dev/null", "w+") + if (not os.path.isdir(os.path.join("cache","node0")) + or not os.path.isdir(os.path.join("cache","node1")) + or not os.path.isdir(os.path.join("cache","node2")) + or not os.path.isdir(os.path.join("cache","node3"))): + + #find and delete old cache directories if any exist + for i in range(4): + if os.path.isdir(os.path.join("cache","node"+str(i))): + shutil.rmtree(os.path.join("cache","node"+str(i))) + + devnull = open(os.devnull, "w") # Create cache directories, run bitcoinds: for i in range(4): datadir=initialize_datadir("cache", i) @@ -171,7 +180,7 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary= args = [ binary, "-datadir="+datadir, "-keypool=1", "-discover=0", "-rest" ] if extra_args is not None: args.extend(extra_args) bitcoind_processes[i] = subprocess.Popen(args) - devnull = open("/dev/null", "w+") + devnull = open(os.devnull, "w") if os.getenv("PYTHON_DEBUG", ""): print "start_node: bitcoind started, calling bitcoin-cli -rpcwait getblockcount" subprocess.check_call([ os.getenv("BITCOINCLI", "bitcoin-cli"), "-datadir="+datadir] + diff --git a/qa/rpc-tests/zmq_test.py b/qa/rpc-tests/zmq_test.py new file mode 100755 index 0000000000..fffaf677d6 --- /dev/null +++ b/qa/rpc-tests/zmq_test.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python2 +# Copyright (c) 2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Test ZMQ interface +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +import zmq +import binascii +from test_framework.mininode import hash256 + +try: + import http.client as httplib +except ImportError: + import httplib +try: + import urllib.parse as urlparse +except ImportError: + import urlparse + +class ZMQTest (BitcoinTestFramework): + + port = 28332 + + def setup_nodes(self): + self.zmqContext = zmq.Context() + self.zmqSubSocket = self.zmqContext.socket(zmq.SUB) + self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashblock") + self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashtx") + self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % self.port) + # Note: proxies are not used to connect to local nodes + # this is because the proxy to use is based on CService.GetNetwork(), which return NET_UNROUTABLE for localhost + return start_nodes(4, self.options.tmpdir, extra_args=[ + ['-zmqpubhashtx=tcp://127.0.0.1:'+str(self.port), '-zmqpubhashblock=tcp://127.0.0.1:'+str(self.port)], + [], + [], + [] + ]) + + def run_test(self): + self.sync_all() + + genhashes = self.nodes[0].generate(1); + self.sync_all() + + print "listen..." + msg = self.zmqSubSocket.recv_multipart() + topic = str(msg[0]) + body = msg[1] + + msg = self.zmqSubSocket.recv_multipart() + topic = str(msg[0]) + body = msg[1] + blkhash = binascii.hexlify(body) + + assert_equal(genhashes[0], blkhash) #blockhash from generate must be equal to the hash received over zmq + + n = 10 + genhashes = self.nodes[1].generate(n); + self.sync_all() + + zmqHashes = [] + for x in range(0,n*2): + msg = self.zmqSubSocket.recv_multipart() + topic = str(msg[0]) + body = msg[1] + if topic == "hashblock": + zmqHashes.append(binascii.hexlify(body)) + + for x in range(0,n): + assert_equal(genhashes[x], zmqHashes[x]) #blockhash from generate must be equal to the hash received over zmq + + #test tx from a second node + hashRPC = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.0) + self.sync_all() + + #now we should receive a zmq msg because the tx was broadcastet + msg = self.zmqSubSocket.recv_multipart() + topic = str(msg[0]) + body = msg[1] + hashZMQ = "" + if topic == "hashtx": + hashZMQ = binascii.hexlify(body) + + assert_equal(hashRPC, hashZMQ) #blockhash from generate must be equal to the hash received over zmq + + +if __name__ == '__main__': + ZMQTest ().main () diff --git a/share/pixmaps/addressbook16.bmp b/share/pixmaps/addressbook16.bmp Binary files differdeleted file mode 100644 index c5576910b1..0000000000 --- a/share/pixmaps/addressbook16.bmp +++ /dev/null diff --git a/share/pixmaps/addressbook16mask.bmp b/share/pixmaps/addressbook16mask.bmp Binary files differdeleted file mode 100644 index d3a478d1ad..0000000000 --- a/share/pixmaps/addressbook16mask.bmp +++ /dev/null diff --git a/share/pixmaps/addressbook20.bmp b/share/pixmaps/addressbook20.bmp Binary files differdeleted file mode 100644 index 2b33b228aa..0000000000 --- a/share/pixmaps/addressbook20.bmp +++ /dev/null diff --git a/share/pixmaps/addressbook20mask.bmp b/share/pixmaps/addressbook20mask.bmp Binary files differdeleted file mode 100644 index 56ce6125db..0000000000 --- a/share/pixmaps/addressbook20mask.bmp +++ /dev/null diff --git a/share/pixmaps/bitcoin-bc.ico b/share/pixmaps/bitcoin-bc.ico Binary files differdeleted file mode 100644 index 88cc240e2d..0000000000 --- a/share/pixmaps/bitcoin-bc.ico +++ /dev/null diff --git a/share/pixmaps/check.ico b/share/pixmaps/check.ico Binary files differdeleted file mode 100644 index 0c4e6e8147..0000000000 --- a/share/pixmaps/check.ico +++ /dev/null diff --git a/share/pixmaps/favicon.ico b/share/pixmaps/favicon.ico Binary files differdeleted file mode 100644 index 754eebc488..0000000000 --- a/share/pixmaps/favicon.ico +++ /dev/null diff --git a/share/pixmaps/send16.bmp b/share/pixmaps/send16.bmp Binary files differdeleted file mode 100644 index 676b5c4b49..0000000000 --- a/share/pixmaps/send16.bmp +++ /dev/null diff --git a/share/pixmaps/send16mask.bmp b/share/pixmaps/send16mask.bmp Binary files differdeleted file mode 100644 index 06c747f934..0000000000 --- a/share/pixmaps/send16mask.bmp +++ /dev/null diff --git a/share/pixmaps/send16masknoshadow.bmp b/share/pixmaps/send16masknoshadow.bmp Binary files differdeleted file mode 100644 index faf24e0d8a..0000000000 --- a/share/pixmaps/send16masknoshadow.bmp +++ /dev/null diff --git a/share/pixmaps/send20.bmp b/share/pixmaps/send20.bmp Binary files differdeleted file mode 100644 index 2b90422b38..0000000000 --- a/share/pixmaps/send20.bmp +++ /dev/null diff --git a/share/pixmaps/send20mask.bmp b/share/pixmaps/send20mask.bmp Binary files differdeleted file mode 100644 index f124d0da08..0000000000 --- a/share/pixmaps/send20mask.bmp +++ /dev/null diff --git a/share/qt/img/reload.png b/share/qt/img/reload.png Binary files differdeleted file mode 100644 index 9068db9a63..0000000000 --- a/share/qt/img/reload.png +++ /dev/null diff --git a/share/qt/img/reload.xcf b/share/qt/img/reload.xcf Binary files differdeleted file mode 100644 index dc8be62831..0000000000 --- a/share/qt/img/reload.xcf +++ /dev/null diff --git a/share/qt/make_spinner.py b/share/qt/make_spinner.py deleted file mode 100755 index bb19e91508..0000000000 --- a/share/qt/make_spinner.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python -# W.J. van der Laan, 2011 -# Make spinning animation from a .png -# Requires imagemagick 6.7+ -from __future__ import division -from os import path -from PIL import Image -from subprocess import Popen - -SRC='img/reload.png' -TMPDIR='../../src/qt/res/movies/' -TMPNAME='spinner-%03i.png' -NUMFRAMES=35 -FRAMERATE=10.0 -CONVERT='convert' -CLOCKWISE=True -DSIZE=(16,16) - -im_src = Image.open(SRC) - -if CLOCKWISE: - im_src = im_src.transpose(Image.FLIP_LEFT_RIGHT) - -def frame_to_filename(frame): - return path.join(TMPDIR, TMPNAME % frame) - -frame_files = [] -for frame in xrange(NUMFRAMES): - rotation = (frame + 0.5) / NUMFRAMES * 360.0 - if CLOCKWISE: - rotation = -rotation - im_new = im_src.rotate(rotation, Image.BICUBIC) - im_new.thumbnail(DSIZE, Image.ANTIALIAS) - outfile = frame_to_filename(frame) - im_new.save(outfile, 'png') - frame_files.append(outfile) - - diff --git a/share/ui.rc b/share/ui.rc deleted file mode 100644 index 063641cba2..0000000000 --- a/share/ui.rc +++ /dev/null @@ -1,15 +0,0 @@ -bitcoin ICON "pixmaps/bitcoin.ico"
-
-#include "wx/msw/wx.rc"
-
-check ICON "pixmaps/check.ico"
-send16 BITMAP "pixmaps/send16.bmp"
-send16mask BITMAP "pixmaps/send16mask.bmp"
-send16masknoshadow BITMAP "pixmaps/send16masknoshadow.bmp"
-send20 BITMAP "pixmaps/send20.bmp"
-send20mask BITMAP "pixmaps/send20mask.bmp"
-addressbook16 BITMAP "pixmaps/addressbook16.bmp"
-addressbook16mask BITMAP "pixmaps/addressbook16mask.bmp"
-addressbook20 BITMAP "pixmaps/addressbook20.bmp"
-addressbook20mask BITMAP "pixmaps/addressbook20mask.bmp"
-favicon ICON "pixmaps/favicon.ico"
diff --git a/src/Makefile.am b/src/Makefile.am index cc8dded413..7fdc766e1c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -48,6 +48,9 @@ if ENABLE_WALLET BITCOIN_INCLUDES += $(BDB_CPPFLAGS) EXTRA_LIBRARIES += libbitcoin_wallet.a endif +if ENABLE_ZMQ +EXTRA_LIBRARIES += libbitcoin_zmq.a +endif if BUILD_BITCOIN_LIBS lib_LTLIBRARIES = libbitcoinconsensus.la @@ -98,6 +101,8 @@ BITCOIN_CORE_H = \ eccryptoverify.h \ ecwrapper.h \ hash.h \ + httprpc.h \ + httpserver.h \ init.h \ key.h \ keystore.h \ @@ -119,6 +124,7 @@ BITCOIN_CORE_H = \ protocol.h \ pubkey.h \ random.h \ + reverselock.h \ rpcclient.h \ rpcprotocol.h \ rpcserver.h \ @@ -154,7 +160,12 @@ BITCOIN_CORE_H = \ wallet/db.h \ wallet/wallet.h \ wallet/wallet_ismine.h \ - wallet/walletdb.h + wallet/walletdb.h \ + zmq/zmqabstractnotifier.h \ + zmq/zmqconfig.h\ + zmq/zmqnotificationinterface.h \ + zmq/zmqpublishnotifier.h + obj/build.h: FORCE @$(MKDIR_P) $(builddir)/obj @@ -163,13 +174,15 @@ obj/build.h: FORCE libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h # server: shared between bitcoind and bitcoin-qt -libbitcoin_server_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) +libbitcoin_server_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS) libbitcoin_server_a_SOURCES = \ addrman.cpp \ alert.cpp \ bloom.cpp \ chain.cpp \ checkpoints.cpp \ + httprpc.cpp \ + httpserver.cpp \ init.cpp \ leveldbwrapper.cpp \ main.cpp \ @@ -194,6 +207,17 @@ libbitcoin_server_a_SOURCES = \ validationinterface.cpp \ $(BITCOIN_CORE_H) +if ENABLE_ZMQ +LIBBITCOIN_ZMQ=libbitcoin_zmq.a + +libbitcoin_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) +libbitcoin_zmq_a_SOURCES = \ + zmq/zmqabstractnotifier.cpp \ + zmq/zmqnotificationinterface.cpp \ + zmq/zmqpublishnotifier.cpp +endif + + # wallet: shared between bitcoind and bitcoin-qt, but only linked # when wallet enabled libbitcoin_wallet_a_CPPFLAGS = $(BITCOIN_INCLUDES) @@ -315,16 +339,19 @@ bitcoind_LDADD = \ $(LIBMEMENV) \ $(LIBSECP256K1) +if ENABLE_ZMQ +bitcoind_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) +endif + if ENABLE_WALLET bitcoind_LDADD += libbitcoin_wallet.a endif -bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) -# +bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) # bitcoin-cli binary # bitcoin_cli_SOURCES = bitcoin-cli.cpp -bitcoin_cli_CPPFLAGS = $(BITCOIN_INCLUDES) +bitcoin_cli_CPPFLAGS = $(BITCOIN_INCLUDES) $(EVENT_CFLAGS) bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) if TARGET_WINDOWS @@ -334,10 +361,9 @@ endif bitcoin_cli_LDADD = \ $(LIBBITCOIN_CLI) \ $(LIBBITCOIN_UNIVALUE) \ - $(LIBBITCOIN_UTIL) \ - $(LIBSECP256K1) + $(LIBBITCOIN_UTIL) -bitcoin_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) +bitcoin_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS) # # bitcoin-tx binary # diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 2ec3468e06..3330ed2890 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -87,7 +87,7 @@ QT_FORMS_UI = \ qt/forms/overviewpage.ui \ qt/forms/receivecoinsdialog.ui \ qt/forms/receiverequestdialog.ui \ - qt/forms/rpcconsole.ui \ + qt/forms/debugwindow.ui \ qt/forms/sendcoinsdialog.ui \ qt/forms/sendcoinsentry.ui \ qt/forms/signverifymessagedialog.ui \ @@ -97,6 +97,7 @@ QT_MOC_CPP = \ qt/moc_addressbookpage.cpp \ qt/moc_addresstablemodel.cpp \ qt/moc_askpassphrasedialog.cpp \ + qt/moc_bantablemodel.cpp \ qt/moc_bitcoinaddressvalidator.cpp \ qt/moc_bitcoinamountfield.cpp \ qt/moc_bitcoingui.cpp \ @@ -162,6 +163,7 @@ BITCOIN_QT_H = \ qt/addressbookpage.h \ qt/addresstablemodel.h \ qt/askpassphrasedialog.h \ + qt/bantablemodel.h \ qt/bitcoinaddressvalidator.h \ qt/bitcoinamountfield.h \ qt/bitcoingui.h \ @@ -185,13 +187,13 @@ BITCOIN_QT_H = \ qt/paymentrequestplus.h \ qt/paymentserver.h \ qt/peertablemodel.h \ + qt/platformstyle.h \ qt/qvalidatedlineedit.h \ qt/qvaluecombobox.h \ qt/receivecoinsdialog.h \ qt/receiverequestdialog.h \ qt/recentrequeststablemodel.h \ qt/rpcconsole.h \ - qt/scicon.h \ qt/sendcoinsdialog.h \ qt/sendcoinsentry.h \ qt/signverifymessagedialog.h \ @@ -260,6 +262,7 @@ RES_ICONS = \ qt/res/icons/verify.png BITCOIN_QT_CPP = \ + qt/bantablemodel.cpp \ qt/bitcoinaddressvalidator.cpp \ qt/bitcoinamountfield.cpp \ qt/bitcoingui.cpp \ @@ -273,10 +276,10 @@ BITCOIN_QT_CPP = \ qt/optionsdialog.cpp \ qt/optionsmodel.cpp \ qt/peertablemodel.cpp \ + qt/platformstyle.cpp \ qt/qvalidatedlineedit.cpp \ qt/qvaluecombobox.cpp \ qt/rpcconsole.cpp \ - qt/scicon.cpp \ qt/splashscreen.cpp \ qt/trafficgraphwidget.cpp \ qt/utilitydialog.cpp @@ -361,8 +364,12 @@ qt_bitcoin_qt_LDADD = qt/libbitcoinqt.a $(LIBBITCOIN_SERVER) if ENABLE_WALLET qt_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET) endif +if ENABLE_ZMQ +qt_bitcoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) +endif qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \ - $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) + $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ + $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) qt_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) qt_bitcoin_qt_LIBTOOLFLAGS = --tag CXX diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index c5392cf307..6554580bea 100644 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -30,9 +30,13 @@ qt_test_test_bitcoin_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN_SERVER) if ENABLE_WALLET qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET) endif +if ENABLE_ZMQ +qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) +endif qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) \ $(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \ - $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) + $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ + $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) qt_test_test_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) CLEAN_BITCOIN_QT_TEST = $(TEST_QT_MOC_CPP) qt/test/*.gcda qt/test/*.gcno diff --git a/src/Makefile.test.include b/src/Makefile.test.include index f9384a09a4..cee35926a5 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -15,6 +15,8 @@ EXTRA_DIST += \ test/data/tx394b54bb.hex \ test/data/txcreate1.hex \ test/data/txcreate2.hex \ + test/data/txcreatedata1.hex \ + test/data/txcreatedata2.hex \ test/data/txcreatesign.hex JSON_TEST_FILES = \ @@ -50,6 +52,7 @@ BITCOIN_TESTS =\ test/getarg_tests.cpp \ test/hash_tests.cpp \ test/key_tests.cpp \ + test/limitedmap_tests.cpp \ test/main_tests.cpp \ test/mempool_tests.cpp \ test/miner_tests.cpp \ @@ -59,6 +62,7 @@ BITCOIN_TESTS =\ test/pmt_tests.cpp \ test/policyestimator_tests.cpp \ test/pow_tests.cpp \ + test/reverselock_tests.cpp \ test/rpc_tests.cpp \ test/sanity_tests.cpp \ test/scheduler_tests.cpp \ @@ -96,6 +100,10 @@ endif test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static +if ENABLE_ZMQ +test_test_bitcoin_LDADD += $(ZMQ_LIBS) +endif + nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES) $(BITCOIN_TESTS): $(GENERATED_TEST_FILES) diff --git a/src/addrman.cpp b/src/addrman.cpp index b605f4351d..ff1f7e9187 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -341,8 +341,10 @@ CAddrInfo CAddrMan::Select_() while (1) { int nKBucket = GetRandInt(ADDRMAN_TRIED_BUCKET_COUNT); int nKBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE); - if (vvTried[nKBucket][nKBucketPos] == -1) - continue; + while (vvTried[nKBucket][nKBucketPos] == -1) { + nKBucket = (nKBucket + insecure_rand()) % ADDRMAN_TRIED_BUCKET_COUNT; + nKBucketPos = (nKBucketPos + insecure_rand()) % ADDRMAN_BUCKET_SIZE; + } int nId = vvTried[nKBucket][nKBucketPos]; assert(mapInfo.count(nId) == 1); CAddrInfo& info = mapInfo[nId]; @@ -356,8 +358,10 @@ CAddrInfo CAddrMan::Select_() while (1) { int nUBucket = GetRandInt(ADDRMAN_NEW_BUCKET_COUNT); int nUBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE); - if (vvNew[nUBucket][nUBucketPos] == -1) - continue; + while (vvNew[nUBucket][nUBucketPos] == -1) { + nUBucket = (nUBucket + insecure_rand()) % ADDRMAN_NEW_BUCKET_COUNT; + nUBucketPos = (nUBucketPos + insecure_rand()) % ADDRMAN_BUCKET_SIZE; + } int nId = vvNew[nUBucket][nUBucketPos]; assert(mapInfo.count(nId) == 1); CAddrInfo& info = mapInfo[nId]; diff --git a/src/addrman.h b/src/addrman.h index 2623d89809..384b6cfdb9 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -265,7 +265,7 @@ public: * Notice that vvTried, mapAddr and vVector are never encoded explicitly; * they are instead reconstructed from the other information. * - * vvNew is serialized, but only used if ADDRMAN_UNKOWN_BUCKET_COUNT didn't change, + * vvNew is serialized, but only used if ADDRMAN_UNKNOWN_BUCKET_COUNT didn't change, * otherwise it is reconstructed as well. * * This format is more complex, but significantly smaller (at most 1.5 MiB), and supports diff --git a/src/amount.cpp b/src/amount.cpp index 0a394c96fc..b469181984 100644 --- a/src/amount.cpp +++ b/src/amount.cpp @@ -7,6 +7,8 @@ #include "tinyformat.h" +const std::string CURRENCY_UNIT = "BTC"; + CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nSize) { if (nSize > 0) @@ -27,5 +29,5 @@ CAmount CFeeRate::GetFee(size_t nSize) const std::string CFeeRate::ToString() const { - return strprintf("%d.%08d BTC/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN); + return strprintf("%d.%08d %s/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN, CURRENCY_UNIT); } diff --git a/src/amount.h b/src/amount.h index 7dc62edac4..90e6b5aa8e 100644 --- a/src/amount.h +++ b/src/amount.h @@ -16,6 +16,8 @@ typedef int64_t CAmount; static const CAmount COIN = 100000000; static const CAmount CENT = 1000000; +extern const std::string CURRENCY_UNIT; + /** No amount larger than this (in satoshi) is valid. * * Note that this constant is *not* the total money supply, which in Bitcoin diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 1c5a312874..7839b3b6b4 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -11,11 +11,19 @@ #include "utilstrencodings.h" #include <boost/filesystem/operations.hpp> +#include <stdio.h> + +#include <event2/event.h> +#include <event2/http.h> +#include <event2/buffer.h> +#include <event2/keyvalq_struct.h> #include "univalue/univalue.h" using namespace std; +static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900; + std::string HelpMessageCli() { string strUsage; @@ -31,9 +39,7 @@ std::string HelpMessageCli() strUsage += HelpMessageOpt("-rpcwait", _("Wait for RPC server to start")); strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections")); strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections")); - - strUsage += HelpMessageGroup(_("SSL options: (see the Bitcoin Wiki for SSL setup instructions)")); - strUsage += HelpMessageOpt("-rpcssl", _("Use OpenSSL (https) for JSON-RPC connections")); + strUsage += HelpMessageOpt("-rpcclienttimeout=<n>", strprintf(_("Timeout during HTTP requests (default: %d)"), DEFAULT_HTTP_CLIENT_TIMEOUT)); return strUsage; } @@ -92,32 +98,75 @@ static bool AppInitRPC(int argc, char* argv[]) fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n"); return false; } + if (GetBoolArg("-rpcssl", false)) + { + fprintf(stderr, "Error: SSL mode for RPC (-rpcssl) is no longer supported.\n"); + return false; + } return true; } -UniValue CallRPC(const string& strMethod, const UniValue& params) + +/** Reply structure for request_done to fill in */ +struct HTTPReply { - // Connect to localhost - bool fUseSSL = GetBoolArg("-rpcssl", false); - boost::asio::io_service io_service; - boost::asio::ssl::context context(io_service, boost::asio::ssl::context::sslv23); - context.set_options(boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::no_sslv3); - boost::asio::ssl::stream<boost::asio::ip::tcp::socket> sslStream(io_service, context); - SSLIOStreamDevice<boost::asio::ip::tcp> d(sslStream, fUseSSL); - boost::iostreams::stream< SSLIOStreamDevice<boost::asio::ip::tcp> > stream(d); - - const bool fConnected = d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(BaseParams().RPCPort()))); - if (!fConnected) - throw CConnectionFailed("couldn't connect to server"); + int status; + std::string body; +}; + +static void http_request_done(struct evhttp_request *req, void *ctx) +{ + HTTPReply *reply = static_cast<HTTPReply*>(ctx); + + if (req == NULL) { + /* If req is NULL, it means an error occurred while connecting, but + * I'm not sure how to find out which one. We also don't really care. + */ + reply->status = 0; + return; + } - // Find credentials to use + reply->status = evhttp_request_get_response_code(req); + + struct evbuffer *buf = evhttp_request_get_input_buffer(req); + if (buf) + { + size_t size = evbuffer_get_length(buf); + const char *data = (const char*)evbuffer_pullup(buf, size); + if (data) + reply->body = std::string(data, size); + evbuffer_drain(buf, size); + } +} + +UniValue CallRPC(const string& strMethod, const UniValue& params) +{ + std::string host = GetArg("-rpcconnect", "127.0.0.1"); + int port = GetArg("-rpcport", BaseParams().RPCPort()); + + // Create event base + struct event_base *base = event_base_new(); // TODO RAII + if (!base) + throw runtime_error("cannot create event_base"); + + // Synchronously look up hostname + struct evhttp_connection *evcon = evhttp_connection_base_new(base, NULL, host.c_str(), port); // TODO RAII + if (evcon == NULL) + throw runtime_error("create connection failed"); + evhttp_connection_set_timeout(evcon, GetArg("-rpcclienttimeout", DEFAULT_HTTP_CLIENT_TIMEOUT)); + + HTTPReply response; + struct evhttp_request *req = evhttp_request_new(http_request_done, (void*)&response); // TODO RAII + if (req == NULL) + throw runtime_error("create http request failed"); + + // Get credentials std::string strRPCUserColonPass; if (mapArgs["-rpcpassword"] == "") { // Try fall back to cookie-based authentication if no password is provided if (!GetAuthCookie(&strRPCUserColonPass)) { throw runtime_error(strprintf( - _("You must set rpcpassword=<password> in the configuration file:\n%s\n" - "If the file does not exist, create it with owner-readable-only file permissions."), + _("Could not locate RPC credentials. No authentication cookie could be found, and no rpcpassword is set in the configuration file (%s)"), GetConfigFile().string().c_str())); } @@ -125,34 +174,41 @@ UniValue CallRPC(const string& strMethod, const UniValue& params) strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; } - // HTTP basic authentication - map<string, string> mapRequestHeaders; - mapRequestHeaders["Authorization"] = string("Basic ") + EncodeBase64(strRPCUserColonPass); - - // Send request - string strRequest = JSONRPCRequest(strMethod, params, 1); - string strPost = HTTPPost(strRequest, mapRequestHeaders); - stream << strPost << std::flush; - - // Receive HTTP reply status - int nProto = 0; - int nStatus = ReadHTTPStatus(stream, nProto); + struct evkeyvalq *output_headers = evhttp_request_get_output_headers(req); + assert(output_headers); + evhttp_add_header(output_headers, "Host", host.c_str()); + evhttp_add_header(output_headers, "Connection", "close"); + evhttp_add_header(output_headers, "Authorization", (std::string("Basic ") + EncodeBase64(strRPCUserColonPass)).c_str()); + + // Attach request data + std::string strRequest = JSONRPCRequest(strMethod, params, 1); + struct evbuffer * output_buffer = evhttp_request_get_output_buffer(req); + assert(output_buffer); + evbuffer_add(output_buffer, strRequest.data(), strRequest.size()); + + int r = evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/"); + if (r != 0) { + evhttp_connection_free(evcon); + event_base_free(base); + throw CConnectionFailed("send http request failed"); + } - // Receive HTTP reply message headers and body - map<string, string> mapHeaders; - string strReply; - ReadHTTPMessage(stream, mapHeaders, strReply, nProto, std::numeric_limits<size_t>::max()); + event_base_dispatch(base); + evhttp_connection_free(evcon); + event_base_free(base); - if (nStatus == HTTP_UNAUTHORIZED) + if (response.status == 0) + throw CConnectionFailed("couldn't connect to server"); + else if (response.status == HTTP_UNAUTHORIZED) throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)"); - else if (nStatus >= 400 && nStatus != HTTP_BAD_REQUEST && nStatus != HTTP_NOT_FOUND && nStatus != HTTP_INTERNAL_SERVER_ERROR) - throw runtime_error(strprintf("server returned HTTP error %d", nStatus)); - else if (strReply.empty()) + else if (response.status >= 400 && response.status != HTTP_BAD_REQUEST && response.status != HTTP_NOT_FOUND && response.status != HTTP_INTERNAL_SERVER_ERROR) + throw runtime_error(strprintf("server returned HTTP error %d", response.status)); + else if (response.body.empty()) throw runtime_error("no response from server"); // Parse reply UniValue valReply(UniValue::VSTR); - if (!valReply.read(strReply)) + if (!valReply.read(response.body)) throw runtime_error("couldn't parse reply from server"); const UniValue& reply = valReply.get_obj(); if (reply.empty()) @@ -248,6 +304,10 @@ int CommandLineRPC(int argc, char *argv[]) int main(int argc, char* argv[]) { SetupEnvironment(); + if (!SetupNetworking()) { + fprintf(stderr, "Error: Initializing networking failed\n"); + exit(1); + } try { if(!AppInitRPC(argc, argv)) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index e389d51a73..5beab265bc 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -70,6 +70,7 @@ static bool AppInitRawTx(int argc, char* argv[]) strUsage += HelpMessageOpt("locktime=N", _("Set TX lock time to N")); strUsage += HelpMessageOpt("nversion=N", _("Set TX version to N")); strUsage += HelpMessageOpt("outaddr=VALUE:ADDRESS", _("Add address-based output to TX")); + strUsage += HelpMessageOpt("outdata=[VALUE:]DATA", _("Add data-based output to TX")); strUsage += HelpMessageOpt("outscript=VALUE:SCRIPT", _("Add raw script output to TX")); strUsage += HelpMessageOpt("sign=SIGHASH-FLAGS", _("Add zero or more signatures to transaction") + ". " + _("This command requires JSON registers:") + @@ -231,6 +232,35 @@ static void MutateTxAddOutAddr(CMutableTransaction& tx, const string& strInput) tx.vout.push_back(txout); } +static void MutateTxAddOutData(CMutableTransaction& tx, const string& strInput) +{ + CAmount value = 0; + + // separate [VALUE:]DATA in string + size_t pos = strInput.find(':'); + + if (pos==0) + throw runtime_error("TX output value not specified"); + + if (pos != string::npos) { + // extract and validate VALUE + string strValue = strInput.substr(0, pos); + if (!ParseMoney(strValue, value)) + throw runtime_error("invalid TX output value"); + } + + // extract and validate DATA + string strData = strInput.substr(pos + 1, string::npos); + + if (!IsHex(strData)) + throw runtime_error("invalid TX output data"); + + std::vector<unsigned char> data = ParseHex(strData); + + CTxOut txout(value, CScript() << OP_RETURN << data); + tx.vout.push_back(txout); +} + static void MutateTxAddOutScript(CMutableTransaction& tx, const string& strInput) { // separate VALUE:SCRIPT in string @@ -387,8 +417,8 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) CCoinsModifier coins = view.ModifyCoins(txid); if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) { string err("Previous output scriptPubKey mismatch:\n"); - err = err + coins->vout[nOut].scriptPubKey.ToString() + "\nvs:\n"+ - scriptPubKey.ToString(); + err = err + ScriptToAsmStr(coins->vout[nOut].scriptPubKey) + "\nvs:\n"+ + ScriptToAsmStr(scriptPubKey); throw runtime_error(err); } if ((unsigned int)nOut >= coins->vout.size()) @@ -470,6 +500,8 @@ static void MutateTx(CMutableTransaction& tx, const string& command, MutateTxDelOutput(tx, commandVal); else if (command == "outaddr") MutateTxAddOutAddr(tx, commandVal); + else if (command == "outdata") + MutateTxAddOutData(tx, commandVal); else if (command == "outscript") MutateTxAddOutScript(tx, commandVal); diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 39bb301f44..b512f74c22 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -10,11 +10,16 @@ #include "noui.h" #include "scheduler.h" #include "util.h" +#include "httpserver.h" +#include "httprpc.h" +#include "rpcserver.h" #include <boost/algorithm/string/predicate.hpp> #include <boost/filesystem.hpp> #include <boost/thread.hpp> +#include <stdio.h> + /* Introduction text for doxygen: */ /*! \mainpage Developer documentation @@ -44,7 +49,7 @@ void WaitForShutdown(boost::thread_group* threadGroup) } if (threadGroup) { - threadGroup->interrupt_all(); + Interrupt(*threadGroup); threadGroup->join_all(); } } @@ -154,7 +159,7 @@ bool AppInit(int argc, char* argv[]) if (!fRet) { - threadGroup.interrupt_all(); + Interrupt(threadGroup); // threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of // the startup-failure cases to make sure they don't result in a hang due to some // thread-blocking-waiting-for-another-thread-during-startup case diff --git a/src/bloom.cpp b/src/bloom.cpp index 36cba491c4..de87206592 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -8,6 +8,7 @@ #include "hash.h" #include "script/script.h" #include "script/standard.h" +#include "random.h" #include "streams.h" #include <math.h> @@ -121,6 +122,12 @@ void CBloomFilter::clear() isEmpty = true; } +void CBloomFilter::reset(unsigned int nNewTweak) +{ + clear(); + nTweak = nNewTweak; +} + bool CBloomFilter::IsWithinSizeConstraints() const { return vData.size() <= MAX_BLOOM_FILTER_SIZE && nHashFuncs <= MAX_HASH_FUNCS; @@ -209,15 +216,17 @@ void CBloomFilter::UpdateEmptyFull() isEmpty = empty; } -CRollingBloomFilter::CRollingBloomFilter(unsigned int nElements, double fpRate, unsigned int nTweak) : - b1(nElements * 2, fpRate, nTweak), b2(nElements * 2, fpRate, nTweak) +CRollingBloomFilter::CRollingBloomFilter(unsigned int nElements, double fpRate) : + b1(nElements * 2, fpRate, 0), b2(nElements * 2, fpRate, 0) { // Implemented using two bloom filters of 2 * nElements each. // We fill them up, and clear them, staggered, every nElements // inserted, so at least one always contains the last nElements // inserted. - nBloomSize = nElements * 2; nInsertions = 0; + nBloomSize = nElements * 2; + + reset(); } void CRollingBloomFilter::insert(const std::vector<unsigned char>& vKey) @@ -234,6 +243,12 @@ void CRollingBloomFilter::insert(const std::vector<unsigned char>& vKey) } } +void CRollingBloomFilter::insert(const uint256& hash) +{ + vector<unsigned char> data(hash.begin(), hash.end()); + insert(data); +} + bool CRollingBloomFilter::contains(const std::vector<unsigned char>& vKey) const { if (nInsertions < nBloomSize / 2) { @@ -242,9 +257,16 @@ bool CRollingBloomFilter::contains(const std::vector<unsigned char>& vKey) const return b1.contains(vKey); } -void CRollingBloomFilter::clear() +bool CRollingBloomFilter::contains(const uint256& hash) const +{ + vector<unsigned char> data(hash.begin(), hash.end()); + return contains(data); +} + +void CRollingBloomFilter::reset() { - b1.clear(); - b2.clear(); + unsigned int nNewTweak = GetRand(std::numeric_limits<unsigned int>::max()); + b1.reset(nNewTweak); + b2.reset(nNewTweak); nInsertions = 0; } diff --git a/src/bloom.h b/src/bloom.h index bb17f59c86..a4dba8cb4f 100644 --- a/src/bloom.h +++ b/src/bloom.h @@ -89,6 +89,7 @@ public: bool contains(const uint256& hash) const; void clear(); + void reset(unsigned int nNewTweak); //! True if the size is <= MAX_BLOOM_FILTER_SIZE and the number of hash functions is <= MAX_HASH_FUNCS //! (catch a filter which was just deserialized which was too big) @@ -103,7 +104,11 @@ public: /** * RollingBloomFilter is a probabilistic "keep track of most recently inserted" set. - * Construct it with the number of items to keep track of, and a false-positive rate. + * Construct it with the number of items to keep track of, and a false-positive + * rate. Unlike CBloomFilter, by default nTweak is set to a cryptographically + * secure random value for you. Similarly rather than clear() the method + * reset() is provided, which also changes nTweak to decrease the impact of + * false-positives. * * contains(item) will always return true if item was one of the last N things * insert()'ed ... but may also return true for items that were not inserted. @@ -111,12 +116,17 @@ public: class CRollingBloomFilter { public: - CRollingBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweak); + // A random bloom filter calls GetRand() at creation time. + // Don't create global CRollingBloomFilter objects, as they may be + // constructed before the randomizer is properly initialized. + CRollingBloomFilter(unsigned int nElements, double nFPRate); void insert(const std::vector<unsigned char>& vKey); + void insert(const uint256& hash); bool contains(const std::vector<unsigned char>& vKey) const; + bool contains(const uint256& hash) const; - void clear(); + void reset(); private: unsigned int nBloomSize; diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 08303d61ca..430b75683b 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -12,8 +12,6 @@ #include <boost/assign/list_of.hpp> -using namespace std; - #include "chainparamsseeds.h" static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) @@ -22,7 +20,7 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesi txNew.nVersion = 1; txNew.vin.resize(1); txNew.vout.resize(1); - txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << std::vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); txNew.vout[0].nValue = genesisReward; txNew.vout[0].scriptPubKey = genesisOutputScript; @@ -33,7 +31,7 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesi genesis.nVersion = nVersion; genesis.vtx.push_back(txNew); genesis.hashPrevBlock.SetNull(); - genesis.hashMerkleRoot = genesis.BuildMerkleTree(); + genesis.hashMerkleRoot = genesis.ComputeMerkleRoot(); return genesis; } @@ -118,7 +116,7 @@ public: fMineBlocksOnDemand = false; fTestnetToBeDeprecatedFieldRPC = false; - checkpointData = (Checkpoints::CCheckpointData) { + checkpointData = (CCheckpointData) { boost::assign::map_list_of ( 11111, uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")) ( 33333, uint256S("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")) @@ -192,7 +190,7 @@ public: fMineBlocksOnDemand = false; fTestnetToBeDeprecatedFieldRPC = true; - checkpointData = (Checkpoints::CCheckpointData) { + checkpointData = (CCheckpointData) { boost::assign::map_list_of ( 546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")), 1337966069, @@ -242,7 +240,7 @@ public: fMineBlocksOnDemand = true; fTestnetToBeDeprecatedFieldRPC = false; - checkpointData = (Checkpoints::CCheckpointData){ + checkpointData = (CCheckpointData){ boost::assign::map_list_of ( 0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")), 0, diff --git a/src/chainparams.h b/src/chainparams.h index 465e6a61a8..342bccb12f 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -7,7 +7,6 @@ #define BITCOIN_CHAINPARAMS_H #include "chainparamsbase.h" -#include "checkpoints.h" #include "consensus/params.h" #include "primitives/block.h" #include "protocol.h" @@ -24,6 +23,14 @@ struct SeedSpec6 { uint16_t port; }; +typedef std::map<int, uint256> MapCheckpoints; + +struct CCheckpointData { + MapCheckpoints mapCheckpoints; + int64_t nTimeLastCheckpoint; + int64_t nTransactionsLastCheckpoint; + double fTransactionsPerDay; +}; /** * CChainParams defines various tweakable parameters of a given instance of the @@ -68,7 +75,7 @@ public: const std::vector<CDNSSeedData>& DNSSeeds() const { return vSeeds; } const std::vector<unsigned char>& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; } const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; } - const Checkpoints::CCheckpointData& Checkpoints() const { return checkpointData; } + const CCheckpointData& Checkpoints() const { return checkpointData; } protected: CChainParams() {} @@ -89,7 +96,7 @@ protected: bool fRequireStandard; bool fMineBlocksOnDemand; bool fTestnetToBeDeprecatedFieldRPC; - Checkpoints::CCheckpointData checkpointData; + CCheckpointData checkpointData; }; /** diff --git a/src/checkpoints.h b/src/checkpoints.h index 001e3cc801..5fce6fa81e 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -10,6 +10,7 @@ #include <map> class CBlockIndex; +struct CCheckpointData; /** * Block-chain checkpoints are compiled-in sanity checks. @@ -17,14 +18,6 @@ class CBlockIndex; */ namespace Checkpoints { -typedef std::map<int, uint256> MapCheckpoints; - -struct CCheckpointData { - MapCheckpoints mapCheckpoints; - int64_t nTimeLastCheckpoint; - int64_t nTransactionsLastCheckpoint; - double fTransactionsPerDay; -}; //! Return conservative estimate of total number of blocks, 0 if unknown int GetTotalBlocksEstimate(const CCheckpointData& data); diff --git a/src/coincontrol.h b/src/coincontrol.h index 3e8de83c39..bc965f9e19 100644 --- a/src/coincontrol.h +++ b/src/coincontrol.h @@ -14,6 +14,8 @@ public: CTxDestination destChange; //! If false, allows unselected inputs, but requires all selected inputs be used bool fAllowOtherInputs; + //! Includes watch only addresses which match the ISMINE_WATCH_SOLVABLE criteria + bool fAllowWatchOnly; CCoinControl() { @@ -24,6 +26,7 @@ public: { destChange = CNoDestination(); fAllowOtherInputs = false; + fAllowWatchOnly = false; setSelected.clear(); } diff --git a/src/consensus/validation.h b/src/consensus/validation.h index a97d983a31..d6051edc38 100644 --- a/src/consensus/validation.h +++ b/src/consensus/validation.h @@ -28,16 +28,19 @@ private: } mode; int nDoS; std::string strRejectReason; - unsigned char chRejectCode; + unsigned int chRejectCode; bool corruptionPossible; + std::string strDebugMessage; public: CValidationState() : mode(MODE_VALID), nDoS(0), chRejectCode(0), corruptionPossible(false) {} bool DoS(int level, bool ret = false, - unsigned char chRejectCodeIn=0, std::string strRejectReasonIn="", - bool corruptionIn=false) { + unsigned int chRejectCodeIn=0, const std::string &strRejectReasonIn="", + bool corruptionIn=false, + const std::string &strDebugMessageIn="") { chRejectCode = chRejectCodeIn; strRejectReason = strRejectReasonIn; corruptionPossible = corruptionIn; + strDebugMessage = strDebugMessageIn; if (mode == MODE_ERROR) return ret; nDoS += level; @@ -45,8 +48,9 @@ public: return ret; } bool Invalid(bool ret = false, - unsigned char _chRejectCode=0, std::string _strRejectReason="") { - return DoS(0, ret, _chRejectCode, _strRejectReason); + unsigned int _chRejectCode=0, const std::string &_strRejectReason="", + const std::string &_strDebugMessage="") { + return DoS(0, ret, _chRejectCode, _strRejectReason, false, _strDebugMessage); } bool Error(const std::string& strRejectReasonIn) { if (mode == MODE_VALID) @@ -73,8 +77,9 @@ public: bool CorruptionPossible() const { return corruptionPossible; } - unsigned char GetRejectCode() const { return chRejectCode; } + unsigned int GetRejectCode() const { return chRejectCode; } std::string GetRejectReason() const { return strRejectReason; } + std::string GetDebugMessage() const { return strDebugMessage; } }; #endif // BITCOIN_CONSENSUS_VALIDATION_H diff --git a/src/core_io.h b/src/core_io.h index 115e3199dc..ba5b4e6487 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -16,6 +16,7 @@ class UniValue; // core_read.cpp extern CScript ParseScript(const std::string& s); +extern std::string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode = false); extern bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx); extern bool DecodeHexBlk(CBlock&, const std::string& strHexBlk); extern uint256 ParseHashUV(const UniValue& v, const std::string& strName); @@ -25,8 +26,7 @@ extern std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::strin // core_write.cpp extern std::string FormatScript(const CScript& script); extern std::string EncodeHexTx(const CTransaction& tx); -extern void ScriptPubKeyToUniv(const CScript& scriptPubKey, - UniValue& out, bool fIncludeHex); +extern void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); extern void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry); #endif // BITCOIN_CORE_IO_H diff --git a/src/core_memusage.h b/src/core_memusage.h index 711135bb44..a05f59ee0c 100644 --- a/src/core_memusage.h +++ b/src/core_memusage.h @@ -48,7 +48,7 @@ static inline size_t RecursiveDynamicUsage(const CMutableTransaction& tx) { } static inline size_t RecursiveDynamicUsage(const CBlock& block) { - size_t mem = memusage::DynamicUsage(block.vtx) + memusage::DynamicUsage(block.vMerkleTree); + size_t mem = memusage::DynamicUsage(block.vtx); for (std::vector<CTransaction>::const_iterator it = block.vtx.begin(); it != block.vtx.end(); it++) { mem += RecursiveDynamicUsage(*it); } diff --git a/src/core_write.cpp b/src/core_write.cpp index c3babec2fc..2ad42baddf 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -15,6 +15,7 @@ #include "utilmoneystr.h" #include "utilstrencodings.h" +#include <boost/assign/list_of.hpp> #include <boost/foreach.hpp> using namespace std; @@ -54,6 +55,67 @@ string FormatScript(const CScript& script) return ret.substr(0, ret.size() - 1); } +const map<unsigned char, string> mapSigHashTypes = + boost::assign::map_list_of + (static_cast<unsigned char>(SIGHASH_ALL), string("ALL")) + (static_cast<unsigned char>(SIGHASH_ALL|SIGHASH_ANYONECANPAY), string("ALL|ANYONECANPAY")) + (static_cast<unsigned char>(SIGHASH_NONE), string("NONE")) + (static_cast<unsigned char>(SIGHASH_NONE|SIGHASH_ANYONECANPAY), string("NONE|ANYONECANPAY")) + (static_cast<unsigned char>(SIGHASH_SINGLE), string("SINGLE")) + (static_cast<unsigned char>(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY), string("SINGLE|ANYONECANPAY")) + ; + +/** + * Create the assembly string representation of a CScript object. + * @param[in] script CScript object to convert into the asm string representation. + * @param[in] fAttemptSighashDecode Whether to attempt to decode sighash types on data within the script that matches the format + * of a signature. Only pass true for scripts you believe could contain signatures. For example, + * pass false, or omit the this argument (defaults to false), for scriptPubKeys. + */ +string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode) +{ + string str; + opcodetype opcode; + vector<unsigned char> vch; + CScript::const_iterator pc = script.begin(); + while (pc < script.end()) { + if (!str.empty()) { + str += " "; + } + if (!script.GetOp(pc, opcode, vch)) { + str += "[error]"; + return str; + } + if (0 <= opcode && opcode <= OP_PUSHDATA4) { + if (vch.size() <= static_cast<vector<unsigned char>::size_type>(4)) { + str += strprintf("%d", CScriptNum(vch, false).getint()); + } else { + // the IsUnspendable check makes sure not to try to decode OP_RETURN data that may match the format of a signature + if (fAttemptSighashDecode && !script.IsUnspendable()) { + string strSigHashDecode; + // goal: only attempt to decode a defined sighash type from data that looks like a signature within a scriptSig. + // this won't decode correctly formatted public keys in Pubkey or Multisig scripts due to + // the restrictions on the pubkey formats (see IsCompressedOrUncompressedPubKey) being incongruous with the + // checks in CheckSignatureEncoding. + if (CheckSignatureEncoding(vch, SCRIPT_VERIFY_STRICTENC, NULL)) { + const unsigned char chSigHashType = vch.back(); + if (mapSigHashTypes.count(chSigHashType)) { + strSigHashDecode = "[" + mapSigHashTypes.find(chSigHashType)->second + "]"; + vch.pop_back(); // remove the sighash type byte. it will be replaced by the decode. + } + } + str += HexStr(vch) + strSigHashDecode; + } else { + str += HexStr(vch); + } + } + } else { + str += GetOpName(opcode); + } + } + return str; +} + string EncodeHexTx(const CTransaction& tx) { CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); @@ -68,7 +130,7 @@ void ScriptPubKeyToUniv(const CScript& scriptPubKey, vector<CTxDestination> addresses; int nRequired; - out.pushKV("asm", scriptPubKey.ToString()); + out.pushKV("asm", ScriptToAsmStr(scriptPubKey)); if (fIncludeHex) out.pushKV("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())); @@ -101,7 +163,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry) in.pushKV("txid", txin.prevout.hash.GetHex()); in.pushKV("vout", (int64_t)txin.prevout.n); UniValue o(UniValue::VOBJ); - o.pushKV("asm", txin.scriptSig.ToString()); + o.pushKV("asm", ScriptToAsmStr(txin.scriptSig, true)); o.pushKV("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())); in.pushKV("scriptSig", o); } diff --git a/src/ecwrapper.cpp b/src/ecwrapper.cpp index 5e3aec25ba..f94bc954fd 100644 --- a/src/ecwrapper.cpp +++ b/src/ecwrapper.cpp @@ -13,6 +13,29 @@ namespace { +class ecgroup_order +{ +public: + static const EC_GROUP* get() + { + static const ecgroup_order wrapper; + return wrapper.pgroup; + } + +private: + ecgroup_order() + : pgroup(EC_GROUP_new_by_curve_name(NID_secp256k1)) + { + } + + ~ecgroup_order() + { + EC_GROUP_free(pgroup); + } + + EC_GROUP* pgroup; +}; + /** * Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields * recid selects which key is recovered @@ -92,8 +115,10 @@ err: } // anon namespace CECKey::CECKey() { - pkey = EC_KEY_new_by_curve_name(NID_secp256k1); + pkey = EC_KEY_new(); assert(pkey != NULL); + int result = EC_KEY_set_group(pkey, ecgroup_order::get()); + assert(result); } CECKey::~CECKey() { @@ -185,11 +210,9 @@ bool CECKey::TweakPublic(const unsigned char vchTweak[32]) { bool CECKey::SanityCheck() { - EC_KEY *pkey = EC_KEY_new_by_curve_name(NID_secp256k1); - if(pkey == NULL) + const EC_GROUP *pgroup = ecgroup_order::get(); + if(pgroup == NULL) return false; - EC_KEY_free(pkey); - // TODO Is there more EC functionality that could be missing? return true; } diff --git a/src/httprpc.cpp b/src/httprpc.cpp new file mode 100644 index 0000000000..98ac750bb1 --- /dev/null +++ b/src/httprpc.cpp @@ -0,0 +1,193 @@ +#include "httprpc.h" + +#include "base58.h" +#include "chainparams.h" +#include "httpserver.h" +#include "rpcprotocol.h" +#include "rpcserver.h" +#include "random.h" +#include "sync.h" +#include "util.h" +#include "utilstrencodings.h" +#include "ui_interface.h" + +#include <boost/algorithm/string.hpp> // boost::trim + +/** Simple one-shot callback timer to be used by the RPC mechanism to e.g. + * re-lock the wellet. + */ +class HTTPRPCTimer : public RPCTimerBase +{ +public: + HTTPRPCTimer(struct event_base* eventBase, boost::function<void(void)>& func, int64_t millis) : + ev(eventBase, false, func) + { + struct timeval tv; + tv.tv_sec = millis/1000; + tv.tv_usec = (millis%1000)*1000; + ev.trigger(&tv); + } +private: + HTTPEvent ev; +}; + +class HTTPRPCTimerInterface : public RPCTimerInterface +{ +public: + HTTPRPCTimerInterface(struct event_base* base) : base(base) + { + } + const char* Name() + { + return "HTTP"; + } + RPCTimerBase* NewTimer(boost::function<void(void)>& func, int64_t millis) + { + return new HTTPRPCTimer(base, func, millis); + } +private: + struct event_base* base; +}; + + +/* Pre-base64-encoded authentication token */ +static std::string strRPCUserColonPass; +/* Stored RPC timer interface (for unregistration) */ +static HTTPRPCTimerInterface* httpRPCTimerInterface = 0; + +static void JSONErrorReply(HTTPRequest* req, const UniValue& objError, const UniValue& id) +{ + // Send error reply from json-rpc error object + int nStatus = HTTP_INTERNAL_SERVER_ERROR; + int code = find_value(objError, "code").get_int(); + + if (code == RPC_INVALID_REQUEST) + nStatus = HTTP_BAD_REQUEST; + else if (code == RPC_METHOD_NOT_FOUND) + nStatus = HTTP_NOT_FOUND; + + std::string strReply = JSONRPCReply(NullUniValue, objError, id); + + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(nStatus, strReply); +} + +static bool RPCAuthorized(const std::string& strAuth) +{ + if (strRPCUserColonPass.empty()) // Belt-and-suspenders measure if InitRPCAuthentication was not called + return false; + if (strAuth.substr(0, 6) != "Basic ") + return false; + std::string strUserPass64 = strAuth.substr(6); + boost::trim(strUserPass64); + std::string strUserPass = DecodeBase64(strUserPass64); + return TimingResistantEqual(strUserPass, strRPCUserColonPass); +} + +static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &) +{ + // JSONRPC handles only POST + if (req->GetRequestMethod() != HTTPRequest::POST) { + req->WriteReply(HTTP_BAD_METHOD, "JSONRPC server handles only POST requests"); + return false; + } + // Check authorization + std::pair<bool, std::string> authHeader = req->GetHeader("authorization"); + if (!authHeader.first) { + req->WriteReply(HTTP_UNAUTHORIZED); + return false; + } + + if (!RPCAuthorized(authHeader.second)) { + LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", req->GetPeer().ToString()); + + /* Deter brute-forcing + If this results in a DoS the user really + shouldn't have their RPC port exposed. */ + MilliSleep(250); + + req->WriteReply(HTTP_UNAUTHORIZED); + return false; + } + + JSONRequest jreq; + try { + // Parse request + UniValue valRequest; + if (!valRequest.read(req->ReadBody())) + throw JSONRPCError(RPC_PARSE_ERROR, "Parse error"); + + std::string strReply; + // singleton request + if (valRequest.isObject()) { + jreq.parse(valRequest); + + UniValue result = tableRPC.execute(jreq.strMethod, jreq.params); + + // Send reply + strReply = JSONRPCReply(result, NullUniValue, jreq.id); + + // array of requests + } else if (valRequest.isArray()) + strReply = JSONRPCExecBatch(valRequest.get_array()); + else + throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error"); + + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strReply); + } catch (const UniValue& objError) { + JSONErrorReply(req, objError, jreq.id); + return false; + } catch (const std::exception& e) { + JSONErrorReply(req, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); + return false; + } + return true; +} + +static bool InitRPCAuthentication() +{ + if (mapArgs["-rpcpassword"] == "") + { + LogPrintf("No rpcpassword set - using random cookie authentication\n"); + if (!GenerateAuthCookie(&strRPCUserColonPass)) { + uiInterface.ThreadSafeMessageBox( + _("Error: A fatal internal error occurred, see debug.log for details"), // Same message as AbortNode + "", CClientUIInterface::MSG_ERROR); + return false; + } + } else { + strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; + } + return true; +} + +bool StartHTTPRPC() +{ + LogPrint("rpc", "Starting HTTP RPC server\n"); + if (!InitRPCAuthentication()) + return false; + + RegisterHTTPHandler("/", true, HTTPReq_JSONRPC); + + assert(EventBase()); + httpRPCTimerInterface = new HTTPRPCTimerInterface(EventBase()); + RPCRegisterTimerInterface(httpRPCTimerInterface); + return true; +} + +void InterruptHTTPRPC() +{ + LogPrint("rpc", "Interrupting HTTP RPC server\n"); +} + +void StopHTTPRPC() +{ + LogPrint("rpc", "Stopping HTTP RPC server\n"); + UnregisterHTTPHandler("/", true); + if (httpRPCTimerInterface) { + RPCUnregisterTimerInterface(httpRPCTimerInterface); + delete httpRPCTimerInterface; + httpRPCTimerInterface = 0; + } +} diff --git a/src/httprpc.h b/src/httprpc.h new file mode 100644 index 0000000000..d354457188 --- /dev/null +++ b/src/httprpc.h @@ -0,0 +1,37 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_HTTPRPC_H +#define BITCOIN_HTTPRPC_H + +#include <string> +#include <map> + +class HTTPRequest; + +/** Start HTTP RPC subsystem. + * Precondition; HTTP and RPC has been started. + */ +bool StartHTTPRPC(); +/** Interrupt HTTP RPC subsystem. + */ +void InterruptHTTPRPC(); +/** Stop HTTP RPC subsystem. + * Precondition; HTTP and RPC has been stopped. + */ +void StopHTTPRPC(); + +/** Start HTTP REST subsystem. + * Precondition; HTTP and RPC has been started. + */ +bool StartREST(); +/** Interrupt RPC REST subsystem. + */ +void InterruptREST(); +/** Stop HTTP REST subsystem. + * Precondition; HTTP and RPC has been stopped. + */ +void StopREST(); + +#endif diff --git a/src/httpserver.cpp b/src/httpserver.cpp new file mode 100644 index 0000000000..0a7f903e9f --- /dev/null +++ b/src/httpserver.cpp @@ -0,0 +1,650 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "httpserver.h" + +#include "chainparamsbase.h" +#include "compat.h" +#include "util.h" +#include "netbase.h" +#include "rpcprotocol.h" // For HTTP status codes +#include "sync.h" +#include "ui_interface.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <signal.h> + +#include <event2/event.h> +#include <event2/http.h> +#include <event2/thread.h> +#include <event2/buffer.h> +#include <event2/util.h> +#include <event2/keyvalq_struct.h> + +#ifdef EVENT__HAVE_NETINET_IN_H +#include <netinet/in.h> +#ifdef _XOPEN_SOURCE_EXTENDED +#include <arpa/inet.h> +#endif +#endif + +#include <boost/algorithm/string/case_conv.hpp> // for to_lower() +#include <boost/foreach.hpp> +#include <boost/scoped_ptr.hpp> + +/** HTTP request work item */ +class HTTPWorkItem : public HTTPClosure +{ +public: + HTTPWorkItem(HTTPRequest* req, const std::string &path, const HTTPRequestHandler& func): + req(req), path(path), func(func) + { + } + void operator()() + { + func(req.get(), path); + } + + boost::scoped_ptr<HTTPRequest> req; + +private: + std::string path; + HTTPRequestHandler func; +}; + +/** Simple work queue for distributing work over multiple threads. + * Work items are simply callable objects. + */ +template <typename WorkItem> +class WorkQueue +{ +private: + /** Mutex protects entire object */ + CWaitableCriticalSection cs; + CConditionVariable cond; + /* XXX in C++11 we can use std::unique_ptr here and avoid manual cleanup */ + std::deque<WorkItem*> queue; + bool running; + size_t maxDepth; + int numThreads; + + /** RAII object to keep track of number of running worker threads */ + class ThreadCounter + { + public: + WorkQueue &wq; + ThreadCounter(WorkQueue &w): wq(w) + { + boost::lock_guard<boost::mutex> lock(wq.cs); + wq.numThreads += 1; + } + ~ThreadCounter() + { + boost::lock_guard<boost::mutex> lock(wq.cs); + wq.numThreads -= 1; + wq.cond.notify_all(); + } + }; + +public: + WorkQueue(size_t maxDepth) : running(true), + maxDepth(maxDepth), + numThreads(0) + { + } + /*( Precondition: worker threads have all stopped + * (call WaitExit) + */ + ~WorkQueue() + { + while (!queue.empty()) { + delete queue.front(); + queue.pop_front(); + } + } + /** Enqueue a work item */ + bool Enqueue(WorkItem* item) + { + boost::unique_lock<boost::mutex> lock(cs); + if (queue.size() >= maxDepth) { + return false; + } + queue.push_back(item); + cond.notify_one(); + return true; + } + /** Thread function */ + void Run() + { + ThreadCounter count(*this); + while (running) { + WorkItem* i = 0; + { + boost::unique_lock<boost::mutex> lock(cs); + while (running && queue.empty()) + cond.wait(lock); + if (!running) + break; + i = queue.front(); + queue.pop_front(); + } + (*i)(); + delete i; + } + } + /** Interrupt and exit loops */ + void Interrupt() + { + boost::unique_lock<boost::mutex> lock(cs); + running = false; + cond.notify_all(); + } + /** Wait for worker threads to exit */ + void WaitExit() + { + boost::unique_lock<boost::mutex> lock(cs); + while (numThreads > 0) + cond.wait(lock); + } + + /** Return current depth of queue */ + size_t Depth() + { + boost::unique_lock<boost::mutex> lock(cs); + return queue.size(); + } +}; + +struct HTTPPathHandler +{ + HTTPPathHandler() {} + HTTPPathHandler(std::string prefix, bool exactMatch, HTTPRequestHandler handler): + prefix(prefix), exactMatch(exactMatch), handler(handler) + { + } + std::string prefix; + bool exactMatch; + HTTPRequestHandler handler; +}; + +/** HTTP module state */ + +//! libevent event loop +static struct event_base* eventBase = 0; +//! HTTP server +struct evhttp* eventHTTP = 0; +//! List of subnets to allow RPC connections from +static std::vector<CSubNet> rpc_allow_subnets; +//! Work queue for handling longer requests off the event loop thread +static WorkQueue<HTTPClosure>* workQueue = 0; +//! Handlers for (sub)paths +std::vector<HTTPPathHandler> pathHandlers; +//! Bound listening sockets +std::vector<evhttp_bound_socket *> boundSockets; + +/** Check if a network address is allowed to access the HTTP server */ +static bool ClientAllowed(const CNetAddr& netaddr) +{ + if (!netaddr.IsValid()) + return false; + BOOST_FOREACH (const CSubNet& subnet, rpc_allow_subnets) + if (subnet.Match(netaddr)) + return true; + return false; +} + +/** Initialize ACL list for HTTP server */ +static bool InitHTTPAllowList() +{ + rpc_allow_subnets.clear(); + rpc_allow_subnets.push_back(CSubNet("127.0.0.0/8")); // always allow IPv4 local subnet + rpc_allow_subnets.push_back(CSubNet("::1")); // always allow IPv6 localhost + if (mapMultiArgs.count("-rpcallowip")) { + const std::vector<std::string>& vAllow = mapMultiArgs["-rpcallowip"]; + BOOST_FOREACH (std::string strAllow, vAllow) { + CSubNet subnet(strAllow); + if (!subnet.IsValid()) { + uiInterface.ThreadSafeMessageBox( + strprintf("Invalid -rpcallowip subnet specification: %s. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).", strAllow), + "", CClientUIInterface::MSG_ERROR); + return false; + } + rpc_allow_subnets.push_back(subnet); + } + } + std::string strAllowed; + BOOST_FOREACH (const CSubNet& subnet, rpc_allow_subnets) + strAllowed += subnet.ToString() + " "; + LogPrint("http", "Allowing HTTP connections from: %s\n", strAllowed); + return true; +} + +/** HTTP request method as string - use for logging only */ +static std::string RequestMethodString(HTTPRequest::RequestMethod m) +{ + switch (m) { + case HTTPRequest::GET: + return "GET"; + break; + case HTTPRequest::POST: + return "POST"; + break; + case HTTPRequest::HEAD: + return "HEAD"; + break; + case HTTPRequest::PUT: + return "PUT"; + break; + default: + return "unknown"; + } +} + +/** HTTP request callback */ +static void http_request_cb(struct evhttp_request* req, void* arg) +{ + std::auto_ptr<HTTPRequest> hreq(new HTTPRequest(req)); + + LogPrint("http", "Received a %s request for %s from %s\n", + RequestMethodString(hreq->GetRequestMethod()), hreq->GetURI(), hreq->GetPeer().ToString()); + + // Early address-based allow check + if (!ClientAllowed(hreq->GetPeer())) { + hreq->WriteReply(HTTP_FORBIDDEN); + return; + } + + // Early reject unknown HTTP methods + if (hreq->GetRequestMethod() == HTTPRequest::UNKNOWN) { + hreq->WriteReply(HTTP_BADMETHOD); + return; + } + + // Find registered handler for prefix + std::string strURI = hreq->GetURI(); + std::string path; + std::vector<HTTPPathHandler>::const_iterator i = pathHandlers.begin(); + std::vector<HTTPPathHandler>::const_iterator iend = pathHandlers.end(); + for (; i != iend; ++i) { + bool match = false; + if (i->exactMatch) + match = (strURI == i->prefix); + else + match = (strURI.substr(0, i->prefix.size()) == i->prefix); + if (match) { + path = strURI.substr(i->prefix.size()); + break; + } + } + + // Dispatch to worker thread + if (i != iend) { + std::auto_ptr<HTTPWorkItem> item(new HTTPWorkItem(hreq.release(), path, i->handler)); + assert(workQueue); + if (workQueue->Enqueue(item.get())) + item.release(); /* if true, queue took ownership */ + else + item->req->WriteReply(HTTP_INTERNAL, "Work queue depth exceeded"); + } else { + hreq->WriteReply(HTTP_NOTFOUND); + } +} + +/** Callback to reject HTTP requests after shutdown. */ +static void http_reject_request_cb(struct evhttp_request* req, void*) +{ + LogPrint("http", "Rejecting request while shutting down\n"); + evhttp_send_error(req, HTTP_SERVUNAVAIL, NULL); +} + +/** Event dispatcher thread */ +static void ThreadHTTP(struct event_base* base, struct evhttp* http) +{ + RenameThread("bitcoin-http"); + LogPrint("http", "Entering http event loop\n"); + event_base_dispatch(base); + // Event loop will be interrupted by InterruptHTTPServer() + LogPrint("http", "Exited http event loop\n"); +} + +/** Bind HTTP server to specified addresses */ +static bool HTTPBindAddresses(struct evhttp* http) +{ + int defaultPort = GetArg("-rpcport", BaseParams().RPCPort()); + std::vector<std::pair<std::string, uint16_t> > endpoints; + + // Determine what addresses to bind to + if (!mapArgs.count("-rpcallowip")) { // Default to loopback if not allowing external IPs + endpoints.push_back(std::make_pair("::1", defaultPort)); + endpoints.push_back(std::make_pair("127.0.0.1", defaultPort)); + if (mapArgs.count("-rpcbind")) { + LogPrintf("WARNING: option -rpcbind was ignored because -rpcallowip was not specified, refusing to allow everyone to connect\n"); + } + } else if (mapArgs.count("-rpcbind")) { // Specific bind address + const std::vector<std::string>& vbind = mapMultiArgs["-rpcbind"]; + for (std::vector<std::string>::const_iterator i = vbind.begin(); i != vbind.end(); ++i) { + int port = defaultPort; + std::string host; + SplitHostPort(*i, port, host); + endpoints.push_back(std::make_pair(host, port)); + } + } else { // No specific bind address specified, bind to any + endpoints.push_back(std::make_pair("::", defaultPort)); + endpoints.push_back(std::make_pair("0.0.0.0", defaultPort)); + } + + // Bind addresses + for (std::vector<std::pair<std::string, uint16_t> >::iterator i = endpoints.begin(); i != endpoints.end(); ++i) { + LogPrint("http", "Binding RPC on address %s port %i\n", i->first, i->second); + evhttp_bound_socket *bind_handle = evhttp_bind_socket_with_handle(http, i->first.empty() ? NULL : i->first.c_str(), i->second); + if (bind_handle) { + boundSockets.push_back(bind_handle); + } else { + LogPrintf("Binding RPC on address %s port %i failed.\n", i->first, i->second); + } + } + return !boundSockets.empty(); +} + +/** Simple wrapper to set thread name and run work queue */ +static void HTTPWorkQueueRun(WorkQueue<HTTPClosure>* queue) +{ + RenameThread("bitcoin-httpworker"); + queue->Run(); +} + +/** libevent event log callback */ +static void libevent_log_cb(int severity, const char *msg) +{ + if (severity >= EVENT_LOG_WARN) // Log warn messages and higher without debug category + LogPrintf("libevent: %s\n", msg); + else + LogPrint("libevent", "libevent: %s\n", msg); +} + +bool InitHTTPServer() +{ + struct evhttp* http = 0; + struct event_base* base = 0; + + if (!InitHTTPAllowList()) + return false; + + if (GetBoolArg("-rpcssl", false)) { + uiInterface.ThreadSafeMessageBox( + "SSL mode for RPC (-rpcssl) is no longer supported.", + "", CClientUIInterface::MSG_ERROR); + return false; + } + + // Redirect libevent's logging to our own log + event_set_log_callback(&libevent_log_cb); +#if LIBEVENT_VERSION_NUMBER >= 0x02010100 + // If -debug=libevent, set full libevent debugging. + // Otherwise, disable all libevent debugging. + if (LogAcceptCategory("libevent")) + event_enable_debug_logging(EVENT_DBG_ALL); + else + event_enable_debug_logging(EVENT_DBG_NONE); +#endif +#ifdef WIN32 + evthread_use_windows_threads(); +#else + evthread_use_pthreads(); +#endif + + base = event_base_new(); // XXX RAII + if (!base) { + LogPrintf("Couldn't create an event_base: exiting\n"); + return false; + } + + /* Create a new evhttp object to handle requests. */ + http = evhttp_new(base); // XXX RAII + if (!http) { + LogPrintf("couldn't create evhttp. Exiting.\n"); + event_base_free(base); + return false; + } + + evhttp_set_timeout(http, GetArg("-rpcservertimeout", DEFAULT_HTTP_SERVER_TIMEOUT)); + evhttp_set_max_body_size(http, MAX_SIZE); + evhttp_set_gencb(http, http_request_cb, NULL); + + if (!HTTPBindAddresses(http)) { + LogPrintf("Unable to bind any endpoint for RPC server\n"); + evhttp_free(http); + event_base_free(base); + return false; + } + + LogPrint("http", "Initialized HTTP server\n"); + int workQueueDepth = std::max((long)GetArg("-rpcworkqueue", DEFAULT_HTTP_WORKQUEUE), 1L); + LogPrintf("HTTP: creating work queue of depth %d\n", workQueueDepth); + + workQueue = new WorkQueue<HTTPClosure>(workQueueDepth); + eventBase = base; + eventHTTP = http; + return true; +} + +bool StartHTTPServer(boost::thread_group& threadGroup) +{ + LogPrint("http", "Starting HTTP server\n"); + int rpcThreads = std::max((long)GetArg("-rpcthreads", DEFAULT_HTTP_THREADS), 1L); + LogPrintf("HTTP: starting %d worker threads\n", rpcThreads); + threadGroup.create_thread(boost::bind(&ThreadHTTP, eventBase, eventHTTP)); + + for (int i = 0; i < rpcThreads; i++) + threadGroup.create_thread(boost::bind(&HTTPWorkQueueRun, workQueue)); + return true; +} + +void InterruptHTTPServer() +{ + LogPrint("http", "Interrupting HTTP server\n"); + if (eventHTTP) { + // Unlisten sockets + BOOST_FOREACH (evhttp_bound_socket *socket, boundSockets) { + evhttp_del_accept_socket(eventHTTP, socket); + } + // Reject requests on current connections + evhttp_set_gencb(eventHTTP, http_reject_request_cb, NULL); + } + if (eventBase) { + // Force-exit event loop after predefined time + struct timeval tv; + tv.tv_sec = 10; + tv.tv_usec = 0; + event_base_loopexit(eventBase, &tv); + } + if (workQueue) + workQueue->Interrupt(); +} + +void StopHTTPServer() +{ + LogPrint("http", "Stopping HTTP server\n"); + if (workQueue) { + LogPrint("http", "Waiting for HTTP worker threads to exit\n"); + workQueue->WaitExit(); + delete workQueue; + } + if (eventHTTP) { + evhttp_free(eventHTTP); + eventHTTP = 0; + } + if (eventBase) { + event_base_free(eventBase); + eventBase = 0; + } +} + +struct event_base* EventBase() +{ + return eventBase; +} + +static void httpevent_callback_fn(evutil_socket_t, short, void* data) +{ + // Static handler: simply call inner handler + HTTPEvent *self = ((HTTPEvent*)data); + self->handler(); + if (self->deleteWhenTriggered) + delete self; +} + +HTTPEvent::HTTPEvent(struct event_base* base, bool deleteWhenTriggered, const boost::function<void(void)>& handler): + deleteWhenTriggered(deleteWhenTriggered), handler(handler) +{ + ev = event_new(base, -1, 0, httpevent_callback_fn, this); + assert(ev); +} +HTTPEvent::~HTTPEvent() +{ + event_free(ev); +} +void HTTPEvent::trigger(struct timeval* tv) +{ + if (tv == NULL) + event_active(ev, 0, 0); // immediately trigger event in main thread + else + evtimer_add(ev, tv); // trigger after timeval passed +} +HTTPRequest::HTTPRequest(struct evhttp_request* req) : req(req), + replySent(false) +{ +} +HTTPRequest::~HTTPRequest() +{ + if (!replySent) { + // Keep track of whether reply was sent to avoid request leaks + LogPrintf("%s: Unhandled request\n", __func__); + WriteReply(HTTP_INTERNAL, "Unhandled request"); + } + // evhttpd cleans up the request, as long as a reply was sent. +} + +std::pair<bool, std::string> HTTPRequest::GetHeader(const std::string& hdr) +{ + const struct evkeyvalq* headers = evhttp_request_get_input_headers(req); + assert(headers); + const char* val = evhttp_find_header(headers, hdr.c_str()); + if (val) + return std::make_pair(true, val); + else + return std::make_pair(false, ""); +} + +std::string HTTPRequest::ReadBody() +{ + struct evbuffer* buf = evhttp_request_get_input_buffer(req); + if (!buf) + return ""; + size_t size = evbuffer_get_length(buf); + /** Trivial implementation: if this is ever a performance bottleneck, + * internal copying can be avoided in multi-segment buffers by using + * evbuffer_peek and an awkward loop. Though in that case, it'd be even + * better to not copy into an intermediate string but use a stream + * abstraction to consume the evbuffer on the fly in the parsing algorithm. + */ + const char* data = (const char*)evbuffer_pullup(buf, size); + if (!data) // returns NULL in case of empty buffer + return ""; + std::string rv(data, size); + evbuffer_drain(buf, size); + return rv; +} + +void HTTPRequest::WriteHeader(const std::string& hdr, const std::string& value) +{ + struct evkeyvalq* headers = evhttp_request_get_output_headers(req); + assert(headers); + evhttp_add_header(headers, hdr.c_str(), value.c_str()); +} + +/** Closure sent to main thread to request a reply to be sent to + * a HTTP request. + * Replies must be sent in the main loop in the main http thread, + * this cannot be done from worker threads. + */ +void HTTPRequest::WriteReply(int nStatus, const std::string& strReply) +{ + assert(!replySent && req); + // Send event to main http thread to send reply message + struct evbuffer* evb = evhttp_request_get_output_buffer(req); + assert(evb); + evbuffer_add(evb, strReply.data(), strReply.size()); + HTTPEvent* ev = new HTTPEvent(eventBase, true, + boost::bind(evhttp_send_reply, req, nStatus, (const char*)NULL, (struct evbuffer *)NULL)); + ev->trigger(0); + replySent = true; + req = 0; // transferred back to main thread +} + +CService HTTPRequest::GetPeer() +{ + evhttp_connection* con = evhttp_request_get_connection(req); + CService peer; + if (con) { + // evhttp retains ownership over returned address string + const char* address = ""; + uint16_t port = 0; + evhttp_connection_get_peer(con, (char**)&address, &port); + peer = CService(address, port); + } + return peer; +} + +std::string HTTPRequest::GetURI() +{ + return evhttp_request_get_uri(req); +} + +HTTPRequest::RequestMethod HTTPRequest::GetRequestMethod() +{ + switch (evhttp_request_get_command(req)) { + case EVHTTP_REQ_GET: + return GET; + break; + case EVHTTP_REQ_POST: + return POST; + break; + case EVHTTP_REQ_HEAD: + return HEAD; + break; + case EVHTTP_REQ_PUT: + return PUT; + break; + default: + return UNKNOWN; + break; + } +} + +void RegisterHTTPHandler(const std::string &prefix, bool exactMatch, const HTTPRequestHandler &handler) +{ + LogPrint("http", "Registering HTTP handler for %s (exactmatch %d)\n", prefix, exactMatch); + pathHandlers.push_back(HTTPPathHandler(prefix, exactMatch, handler)); +} + +void UnregisterHTTPHandler(const std::string &prefix, bool exactMatch) +{ + std::vector<HTTPPathHandler>::iterator i = pathHandlers.begin(); + std::vector<HTTPPathHandler>::iterator iend = pathHandlers.end(); + for (; i != iend; ++i) + if (i->prefix == prefix && i->exactMatch == exactMatch) + break; + if (i != iend) + { + LogPrint("http", "Unregistering HTTP handler for %s (exactmatch %d)\n", prefix, exactMatch); + pathHandlers.erase(i); + } +} + diff --git a/src/httpserver.h b/src/httpserver.h new file mode 100644 index 0000000000..b377dc19fc --- /dev/null +++ b/src/httpserver.h @@ -0,0 +1,149 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_HTTPSERVER_H +#define BITCOIN_HTTPSERVER_H + +#include <string> +#include <stdint.h> +#include <boost/thread.hpp> +#include <boost/scoped_ptr.hpp> +#include <boost/function.hpp> + +static const int DEFAULT_HTTP_THREADS=4; +static const int DEFAULT_HTTP_WORKQUEUE=16; +static const int DEFAULT_HTTP_SERVER_TIMEOUT=30; + +struct evhttp_request; +struct event_base; +class CService; +class HTTPRequest; + +/** Initialize HTTP server. + * Call this before RegisterHTTPHandler or EventBase(). + */ +bool InitHTTPServer(); +/** Start HTTP server. + * This is separate from InitHTTPServer to give users race-condition-free time + * to register their handlers between InitHTTPServer and StartHTTPServer. + */ +bool StartHTTPServer(boost::thread_group& threadGroup); +/** Interrupt HTTP server threads */ +void InterruptHTTPServer(); +/** Stop HTTP server */ +void StopHTTPServer(); + +/** Handler for requests to a certain HTTP path */ +typedef boost::function<void(HTTPRequest* req, const std::string &)> HTTPRequestHandler; +/** Register handler for prefix. + * If multiple handlers match a prefix, the first-registered one will + * be invoked. + */ +void RegisterHTTPHandler(const std::string &prefix, bool exactMatch, const HTTPRequestHandler &handler); +/** Unregister handler for prefix */ +void UnregisterHTTPHandler(const std::string &prefix, bool exactMatch); + +/** Return evhttp event base. This can be used by submodules to + * queue timers or custom events. + */ +struct event_base* EventBase(); + +/** In-flight HTTP request. + * Thin C++ wrapper around evhttp_request. + */ +class HTTPRequest +{ +private: + struct evhttp_request* req; + bool replySent; + +public: + HTTPRequest(struct evhttp_request* req); + ~HTTPRequest(); + + enum RequestMethod { + UNKNOWN, + GET, + POST, + HEAD, + PUT + }; + + /** Get requested URI. + */ + std::string GetURI(); + + /** Get CService (address:ip) for the origin of the http request. + */ + CService GetPeer(); + + /** Get request method. + */ + RequestMethod GetRequestMethod(); + + /** + * Get the request header specified by hdr, or an empty string. + * Return an pair (isPresent,string). + */ + std::pair<bool, std::string> GetHeader(const std::string& hdr); + + /** + * Read request body. + * + * @note As this consumes the underlying buffer, call this only once. + * Repeated calls will return an empty string. + */ + std::string ReadBody(); + + /** + * Write output header. + * + * @note call this before calling WriteErrorReply or Reply. + */ + void WriteHeader(const std::string& hdr, const std::string& value); + + /** + * Write HTTP reply. + * nStatus is the HTTP status code to send. + * strReply is the body of the reply. Keep it empty to send a standard message. + * + * @note Can be called only once. As this will give the request back to the + * main thread, do not call any other HTTPRequest methods after calling this. + */ + void WriteReply(int nStatus, const std::string& strReply = ""); +}; + +/** Event handler closure. + */ +class HTTPClosure +{ +public: + virtual void operator()() = 0; + virtual ~HTTPClosure() {} +}; + +/** Event class. This can be used either as an cross-thread trigger or as a timer. + */ +class HTTPEvent +{ +public: + /** Create a new event. + * deleteWhenTriggered deletes this event object after the event is triggered (and the handler called) + * handler is the handler to call when the event is triggered. + */ + HTTPEvent(struct event_base* base, bool deleteWhenTriggered, const boost::function<void(void)>& handler); + ~HTTPEvent(); + + /** Trigger the event. If tv is 0, trigger it immediately. Otherwise trigger it after + * the given time has elapsed. + */ + void trigger(struct timeval* tv); + + bool deleteWhenTriggered; + boost::function<void(void)> handler; +private: + struct event* ev; +}; + +#endif // BITCOIN_HTTPSERVER_H diff --git a/src/init.cpp b/src/init.cpp index 365bd30714..a079dce5bc 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -16,6 +16,8 @@ #include "checkpoints.h" #include "compat/sanity.h" #include "consensus/validation.h" +#include "httpserver.h" +#include "httprpc.h" #include "key.h" #include "main.h" #include "miner.h" @@ -36,7 +38,6 @@ #include "wallet/wallet.h" #include "wallet/walletdb.h" #endif - #include <stdint.h> #include <stdio.h> @@ -53,6 +54,10 @@ #include <boost/thread.hpp> #include <openssl/crypto.h> +#if ENABLE_ZMQ +#include "zmq/zmqnotificationinterface.h" +#endif + using namespace std; #ifdef ENABLE_WALLET @@ -60,6 +65,10 @@ CWallet* pwalletMain = NULL; #endif bool fFeeEstimatesInitialized = false; +#if ENABLE_ZMQ +static CZMQNotificationInterface* pzmqNotificationInterface = NULL; +#endif + #ifdef WIN32 // Win32 LevelDB doesn't use filedescriptors, and the ones used for // accessing block files don't count towards the fd_set size limit @@ -144,6 +153,15 @@ public: static CCoinsViewDB *pcoinsdbview = NULL; static CCoinsViewErrorCatcher *pcoinscatcher = NULL; +void Interrupt(boost::thread_group& threadGroup) +{ + InterruptHTTPServer(); + InterruptHTTPRPC(); + InterruptRPC(); + InterruptREST(); + threadGroup.interrupt_all(); +} + void Shutdown() { LogPrintf("%s: In progress...\n", __func__); @@ -158,7 +176,11 @@ void Shutdown() /// module was initialized. RenameThread("bitcoin-shutoff"); mempool.AddTransactionsUpdated(1); - StopRPCThreads(); + + StopHTTPRPC(); + StopREST(); + StopRPC(); + StopHTTPServer(); #ifdef ENABLE_WALLET if (pwalletMain) pwalletMain->Flush(false); @@ -196,6 +218,16 @@ void Shutdown() if (pwalletMain) pwalletMain->Flush(true); #endif + +#if ENABLE_ZMQ + if (pzmqNotificationInterface) { + UnregisterValidationInterface(pzmqNotificationInterface); + pzmqNotificationInterface->Shutdown(); + delete pzmqNotificationInterface; + pzmqNotificationInterface = NULL; + } +#endif + #ifndef WIN32 try { boost::filesystem::remove(GetPidFile()); @@ -280,7 +312,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf")); if (mode == HMM_BITCOIND) { -#if !defined(WIN32) +#ifndef WIN32 strUsage += HelpMessageOpt("-daemon", _("Run in the background as a daemon and accept commands")); #endif } @@ -293,11 +325,11 @@ std::string HelpMessage(HelpMessageMode mode) #ifndef WIN32 strUsage += HelpMessageOpt("-pid=<file>", strprintf(_("Specify pid file (default: %s)"), "bitcoind.pid")); #endif - strUsage += HelpMessageOpt("-prune=<n>", strprintf(_("Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. " + strUsage += HelpMessageOpt("-prune=<n>", strprintf(_("Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. " "Warning: Reverting this setting requires re-downloading the entire blockchain. " "(default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)"), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024)); strUsage += HelpMessageOpt("-reindex", _("Rebuild block chain index from current blk000??.dat files on startup")); -#if !defined(WIN32) +#ifndef WIN32 strUsage += HelpMessageOpt("-sysperms", _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)")); #endif strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0)); @@ -314,7 +346,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-externalip=<ip>", _("Specify your own public address")); strUsage += HelpMessageOpt("-forcednsseed", strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), 0)); strUsage += HelpMessageOpt("-listen", _("Accept connections from outside (default: 1 if no -proxy or -connect)")); - strUsage += HelpMessageOpt("-maxconnections=<n>", strprintf(_("Maintain at most <n> connections to peers (default: %u)"), 125)); + strUsage += HelpMessageOpt("-maxconnections=<n>", strprintf(_("Maintain at most <n> connections to peers (default: %u)"), DEFAULT_MAX_PEER_CONNECTIONS)); strUsage += HelpMessageOpt("-maxreceivebuffer=<n>", strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), 5000)); strUsage += HelpMessageOpt("-maxsendbuffer=<n>", strprintf(_("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"), 1000)); strUsage += HelpMessageOpt("-onion=<ip:port>", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy")); @@ -335,23 +367,23 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-whitebind=<addr>", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6")); strUsage += HelpMessageOpt("-whitelist=<netmask>", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") + " " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway")); - strUsage += HelpMessageOpt("-whiteconnections=<n>", strprintf(_("Reserve this many inbound connections for whitelisted peers (default: %d)"), 0)); #ifdef ENABLE_WALLET strUsage += HelpMessageGroup(_("Wallet options:")); strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls")); strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), 100)); if (showDebug) - strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf("Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)", - FormatMoney(CWallet::minTxFee.GetFeePerK()))); - strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in BTC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK()))); + strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)", + CURRENCY_UNIT, FormatMoney(CWallet::minTxFee.GetFeePerK()))); + strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), + CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup")); strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup")); strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0)); strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1)); strUsage += HelpMessageOpt("-txconfirmtarget=<n>", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); - strUsage += HelpMessageOpt("-maxtxfee=<amt>", strprintf(_("Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)"), - FormatMoney(maxTxFee))); + strUsage += HelpMessageOpt("-maxtxfee=<amt>", strprintf(_("Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)"), + CURRENCY_UNIT, FormatMoney(maxTxFee))); strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format") + " " + _("on startup")); strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat")); strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), true)); @@ -360,6 +392,14 @@ std::string HelpMessage(HelpMessageMode mode) " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)")); #endif +#if ENABLE_ZMQ + strUsage += HelpMessageGroup(_("ZeroMQ notification options:")); + strUsage += HelpMessageOpt("-zmqpubhashblock=<address>", _("Enable publish hash block in <address>")); + strUsage += HelpMessageOpt("-zmqpubhashtransaction=<address>", _("Enable publish hash transaction in <address>")); + strUsage += HelpMessageOpt("-zmqpubrawblock=<address>", _("Enable publish raw block in <address>")); + strUsage += HelpMessageOpt("-zmqpubrawtransaction=<address>", _("Enable publish raw transaction in <address>")); +#endif + strUsage += HelpMessageGroup(_("Debugging/Testing options:")); if (showDebug) { @@ -371,8 +411,12 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-fuzzmessagestest=<n>", "Randomly fuzz 1 of every <n> network messages"); strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", 1)); strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", 0)); + strUsage += HelpMessageOpt("-limitancestorcount=<n>", strprintf("Do not accept transactions if number of in-mempool ancestors is <n> or more (default: %u)", DEFAULT_ANCESTOR_LIMIT)); + strUsage += HelpMessageOpt("-limitancestorsize=<n>", strprintf("Do not accept transactions whose size with all in-mempool ancestors exceeds <n> kilobytes (default: %u)", DEFAULT_ANCESTOR_SIZE_LIMIT)); + strUsage += HelpMessageOpt("-limitdescendantcount=<n>", strprintf("Do not accept transactions if any ancestor would have <n> or more in-mempool descendants (default: %u)", DEFAULT_DESCENDANT_LIMIT)); + strUsage += HelpMessageOpt("-limitdescendantsize=<n>", strprintf("Do not accept transactions if any ancestor would have more than <n> kilobytes of in-mempool descendants (default: %u).", DEFAULT_DESCENDANT_SIZE_LIMIT)); } - string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net, proxy, prune"; // Don't translate these and qt below + string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, mempoolrej, net, proxy, prune, http, libevent"; // Don't translate these and qt below if (mode == HMM_BITCOIN_QT) debugCategories += ", qt"; strUsage += HelpMessageOpt("-debug=<category>", strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + ". " + @@ -388,7 +432,8 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-relaypriority", strprintf("Require high priority for relaying free or low-fee transactions (default: %u)", 1)); strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf("Limit size of signature cache to <n> entries (default: %u)", 50000)); } - strUsage += HelpMessageOpt("-minrelaytxfee=<amt>", strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK()))); + strUsage += HelpMessageOpt("-minrelaytxfee=<amt>", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for relaying (default: %s)"), + CURRENCY_UNIT, FormatMoney(::minRelayTxFee.GetFeePerK()))); strUsage += HelpMessageOpt("-printtoconsole", _("Send trace/debug info to console instead of debug.log file")); if (showDebug) { @@ -421,14 +466,11 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections")); strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), 8332, 18332)); strUsage += HelpMessageOpt("-rpcallowip=<ip>", _("Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times")); - strUsage += HelpMessageOpt("-rpcthreads=<n>", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4)); - strUsage += HelpMessageOpt("-rpckeepalive", strprintf(_("RPC support for HTTP persistent connections (default: %d)"), 1)); - - strUsage += HelpMessageGroup(_("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)")); - strUsage += HelpMessageOpt("-rpcssl", _("Use OpenSSL (https) for JSON-RPC connections")); - strUsage += HelpMessageOpt("-rpcsslcertificatechainfile=<file.cert>", strprintf(_("Server certificate file (default: %s)"), "server.cert")); - strUsage += HelpMessageOpt("-rpcsslprivatekeyfile=<file.pem>", strprintf(_("Server private key (default: %s)"), "server.pem")); - strUsage += HelpMessageOpt("-rpcsslciphers=<ciphers>", strprintf(_("Acceptable ciphers (default: %s)"), "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH")); + strUsage += HelpMessageOpt("-rpcthreads=<n>", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), DEFAULT_HTTP_THREADS)); + if (showDebug) { + strUsage += HelpMessageOpt("-rpcworkqueue=<n>", strprintf("Set the depth of the work queue to service RPC calls (default: %d)", DEFAULT_HTTP_WORKQUEUE)); + strUsage += HelpMessageOpt("-rpcservertimeout=<n>", strprintf("Timeout during HTTP requests (default: %d)", DEFAULT_HTTP_SERVER_TIMEOUT)); + } if (mode == HMM_BITCOIN_QT) { @@ -441,6 +483,9 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-min", _("Start minimized")); strUsage += HelpMessageOpt("-rootcertificates=<file>", _("Set SSL root certificates for payment request (default: -system-)")); strUsage += HelpMessageOpt("-splash", _("Show splash screen on startup (default: 1)")); + if (showDebug) { + strUsage += HelpMessageOpt("-uiplatform", "Select platform to customize UI for (one of windows, macosx, other; default: platform compiled on)"); + } } return strUsage; @@ -597,6 +642,23 @@ bool InitSanityCheck(void) return true; } +bool AppInitServers(boost::thread_group& threadGroup) +{ + RPCServer::OnStopped(&OnRPCStopped); + RPCServer::OnPreCommand(&OnRPCPreCommand); + if (!InitHTTPServer()) + return false; + if (!StartRPC()) + return false; + if (!StartHTTPRPC()) + return false; + if (GetBoolArg("-rest", false) && !StartREST()) + return false; + if (!StartHTTPServer(threadGroup)) + return false; + return true; +} + /** Initialize bitcoin. * @pre Parameters should be parsed and config file should be read. */ @@ -624,17 +686,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) typedef BOOL (WINAPI *PSETPROCDEPPOL)(DWORD); PSETPROCDEPPOL setProcDEPPol = (PSETPROCDEPPOL)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetProcessDEPPolicy"); if (setProcDEPPol != NULL) setProcDEPPol(PROCESS_DEP_ENABLE); - - // Initialize Windows Sockets - WSADATA wsadata; - int ret = WSAStartup(MAKEWORD(2,2), &wsadata); - if (ret != NO_ERROR || LOBYTE(wsadata.wVersion ) != 2 || HIBYTE(wsadata.wVersion) != 2) - { - return InitError(strprintf("Error: Winsock library failed to start (WSAStartup returned error %d)", ret)); - } #endif -#ifndef WIN32 + if (!SetupNetworking()) + return InitError("Error: Initializing networking failed"); + +#ifndef WIN32 if (GetBoolArg("-sysperms", false)) { #ifdef ENABLE_WALLET if (!GetBoolArg("-disablewallet", false)) @@ -659,11 +716,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) sa_hup.sa_flags = 0; sigaction(SIGHUP, &sa_hup, NULL); -#if defined (__SVR4) && defined (__sun) - // ignore SIGPIPE on Solaris + // Ignore SIGPIPE, otherwise it will bring the daemon down if the client closes unexpectedly signal(SIGPIPE, SIG_IGN); #endif -#endif // ********************************************************* Step 2: parameter interactions const CChainParams& chainparams = Params(); @@ -747,27 +802,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // Make sure enough file descriptors are available int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1); - int nUserMaxConnections = GetArg("-maxconnections", 125); + int nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS); nMaxConnections = std::max(nUserMaxConnections, 0); - int nUserWhiteConnections = GetArg("-whiteconnections", 0); - nWhiteConnections = std::max(nUserWhiteConnections, 0); - - if ((mapArgs.count("-whitelist")) || (mapArgs.count("-whitebind"))) { - if (!(mapArgs.count("-maxconnections"))) { - // User is using whitelist feature, - // but did not specify -maxconnections parameter. - // Silently increase the default to compensate, - // so that the whitelist connection reservation feature - // does not inadvertently reduce the default - // inbound connection capacity of the network. - nMaxConnections += nWhiteConnections; - } - } else { - // User not using whitelist feature. - // Silently disable connection reservation, - // for the same reason as above. - nWhiteConnections = 0; - } // Trim requested connection counts, to fit into system limitations nMaxConnections = std::max(std::min(nMaxConnections, (int)(FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS)), 0); @@ -779,13 +815,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (nMaxConnections < nUserMaxConnections) InitWarning(strprintf(_("Reducing -maxconnections from %d to %d, because of system limitations."), nUserMaxConnections, nMaxConnections)); - // Connection capacity is prioritized in this order: - // outbound connections (hardcoded to 8), - // then whitelisted connections, - // then non-whitelisted connections get whatever's left (if any). - if ((nWhiteConnections > 0) && (nWhiteConnections >= (nMaxConnections - 8))) - InitWarning(strprintf(_("All non-whitelisted incoming connections will be dropped, because -whiteconnections is %d and -maxconnections is only %d."), nWhiteConnections, nMaxConnections)); - // ********************************************************* Step 3: parameter-to-internal-flags fDebug = !mapMultiArgs["-debug"].empty(); @@ -823,7 +852,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) fServer = GetBoolArg("-server", false); - // block pruning; get the amount of disk space (in MB) to allot for block & undo files + // block pruning; get the amount of disk space (in MiB) to allot for block & undo files int64_t nSignedPruneTarget = GetArg("-prune", 0) * 1024 * 1024; if (nSignedPruneTarget < 0) { return InitError(_("Prune cannot be configured with a negative value.")); @@ -831,7 +860,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) nPruneTarget = (uint64_t) nSignedPruneTarget; if (nPruneTarget) { if (nPruneTarget < MIN_DISK_SPACE_FOR_BLOCK_FILES) { - return InitError(strprintf(_("Prune configured below the minimum of %d MB. Please use a higher number."), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024)); + return InitError(strprintf(_("Prune configured below the minimum of %d MiB. Please use a higher number."), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024)); } LogPrintf("Prune configured to target %uMiB on disk for block and undo files.\n", nPruneTarget / 1024 / 1024); fPruneMode = true; @@ -916,6 +945,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // Option to startup with mocktime set (used for regression testing): SetMockTime(GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op + if (GetBoolArg("-peerbloomfilters", true)) + nLocalServices |= NODE_BLOOM; + // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log // Initialize elliptic curve code @@ -963,8 +995,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("Using data directory %s\n", strDataDir); LogPrintf("Using config file %s\n", GetConfigFile().string()); LogPrintf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD); - if (nWhiteConnections > 0) - LogPrintf("Reserving %i of these connections for whitelisted inbound peers\n", nWhiteConnections); std::ostringstream strErrors; LogPrintf("Using %u threads for script verification\n", nScriptCheckThreads); @@ -985,9 +1015,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (fServer) { uiInterface.InitMessage.connect(SetRPCWarmupStatus); - RPCServer::OnStopped(&OnRPCStopped); - RPCServer::OnPreCommand(&OnRPCPreCommand); - StartRPCThreads(); + if (!AppInitServers(threadGroup)) + return InitError(_("Unable to start HTTP server. See debug log for details.")); } int64_t nStart; @@ -1007,7 +1036,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (!warningString.empty()) InitWarning(warningString); if (!errorString.empty()) - return InitError(warningString); + return InitError(errorString); } // (!fDisableWallet) #endif // ENABLE_WALLET @@ -1015,6 +1044,20 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) RegisterNodeSignals(GetNodeSignals()); + // sanitize comments per BIP-0014, format user agent and check total size + std::vector<string> uacomments; + BOOST_FOREACH(string cmt, mapMultiArgs["-uacomment"]) + { + if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT)) + return InitError(strprintf("User Agent comment (%s) contains unsafe characters.", cmt)); + uacomments.push_back(SanitizeString(cmt, SAFE_CHARS_UA_COMMENT)); + } + strSubVersion = FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, uacomments); + if (strSubVersion.size() > MAX_SUBVERSION_LENGTH) { + return InitError(strprintf("Total length of network version string %i exceeds maximum of %i characters. Reduce the number and/or size of uacomments.", + strSubVersion.size(), MAX_SUBVERSION_LENGTH)); + } + if (mapArgs.count("-onlynet")) { std::set<enum Network> nets; BOOST_FOREACH(const std::string& snet, mapMultiArgs["-onlynet"]) { @@ -1116,6 +1159,15 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) BOOST_FOREACH(const std::string& strDest, mapMultiArgs["-seednode"]) AddOneShot(strDest); +#if ENABLE_ZMQ + pzmqNotificationInterface = CZMQNotificationInterface::CreateWithArguments(mapArgs); + + if (pzmqNotificationInterface) { + pzmqNotificationInterface->Initialize(); + RegisterValidationInterface(pzmqNotificationInterface); + } +#endif + // ********************************************************* Step 7: load block chain fReindex = GetBoolArg("-reindex", false); @@ -1225,6 +1277,18 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("Prune: pruned datadir may not have more than %d blocks; -checkblocks=%d may fail\n", MIN_BLOCKS_TO_KEEP, GetArg("-checkblocks", 288)); } + + { + LOCK(cs_main); + CBlockIndex* tip = chainActive.Tip(); + if (tip && tip->nTime > GetAdjustedTime() + 2 * 60 * 60) { + strLoadError = _("The block database contains a block which appears to be from the future. " + "This may be due to your computer's date and time being set incorrectly. " + "Only rebuild the block database if you are sure that your computer's date and time are correct"); + break; + } + } + if (!CVerifyDB().VerifyDB(pcoinsdbview, GetArg("-checklevel", 3), GetArg("-checkblocks", 288))) { strLoadError = _("Corrupted block database detected"); @@ -1275,15 +1339,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) mempool.ReadFeeEstimates(est_filein); fFeeEstimatesInitialized = true; - // if prune mode, unset NODE_NETWORK and prune block files - if (fPruneMode) { - LogPrintf("Unsetting NODE_NETWORK on prune mode\n"); - nLocalServices &= ~NODE_NETWORK; - if (!fReindex) { - PruneAndFlush(); - } - } - // ********************************************************* Step 8: load wallet #ifdef ENABLE_WALLET if (fDisableWallet) { @@ -1437,7 +1492,21 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) #else // ENABLE_WALLET LogPrintf("No wallet support compiled in!\n"); #endif // !ENABLE_WALLET - // ********************************************************* Step 9: import blocks + + // ********************************************************* Step 9: data directory maintenance + + // if pruning, unset the service bit and perform the initial blockstore prune + // after any wallet rescanning has taken place. + if (fPruneMode) { + uiInterface.InitMessage(_("Pruning blockstore...")); + LogPrintf("Unsetting NODE_NETWORK on prune mode\n"); + nLocalServices &= ~NODE_NETWORK; + if (!fReindex) { + PruneAndFlush(); + } + } + + // ********************************************************* Step 10: import blocks if (mapArgs.count("-blocknotify")) uiInterface.NotifyBlockTip.connect(BlockNotifyCallback); @@ -1461,7 +1530,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) MilliSleep(10); } - // ********************************************************* Step 10: start node + // ********************************************************* Step 11: start node if (!CheckDiskSpace()) return false; @@ -1491,7 +1560,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // Generate coins in the background GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 1), Params()); - // ********************************************************* Step 11: finished + // ********************************************************* Step 12: finished SetRPCWarmupFinished(); uiInterface.InitMessage(_("Done loading")); diff --git a/src/init.h b/src/init.h index dcb2b29360..8cd51b0286 100644 --- a/src/init.h +++ b/src/init.h @@ -20,6 +20,8 @@ extern CWallet* pwalletMain; void StartShutdown(); bool ShutdownRequested(); +/** Interrupt threads */ +void Interrupt(boost::thread_group& threadGroup); void Shutdown(); bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler); diff --git a/src/keystore.cpp b/src/keystore.cpp index 3bae24b7b9..cf49ba83ad 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -6,23 +6,30 @@ #include "keystore.h" #include "key.h" +#include "pubkey.h" #include "util.h" #include <boost/foreach.hpp> -bool CKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const +bool CKeyStore::AddKey(const CKey &key) { + return AddKeyPubKey(key, key.GetPubKey()); +} + +bool CBasicKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const { CKey key; - if (!GetKey(address, key)) + if (!GetKey(address, key)) { + WatchKeyMap::const_iterator it = mapWatchKeys.find(address); + if (it != mapWatchKeys.end()) { + vchPubKeyOut = it->second; + return true; + } return false; + } vchPubKeyOut = key.GetPubKey(); return true; } -bool CKeyStore::AddKey(const CKey &key) { - return AddKeyPubKey(key, key.GetPubKey()); -} - bool CBasicKeyStore::AddKeyPubKey(const CKey& key, const CPubKey &pubkey) { LOCK(cs_KeyStore); @@ -58,10 +65,29 @@ bool CBasicKeyStore::GetCScript(const CScriptID &hash, CScript& redeemScriptOut) return false; } +static bool ExtractPubKey(const CScript &dest, CPubKey& pubKeyOut) +{ + //TODO: Use Solver to extract this? + CScript::const_iterator pc = dest.begin(); + opcodetype opcode; + std::vector<unsigned char> vch; + if (!dest.GetOp(pc, opcode, vch) || vch.size() < 33 || vch.size() > 65) + return false; + pubKeyOut = CPubKey(vch); + if (!pubKeyOut.IsFullyValid()) + return false; + if (!dest.GetOp(pc, opcode, vch) || opcode != OP_CHECKSIG || dest.GetOp(pc, opcode, vch)) + return false; + return true; +} + bool CBasicKeyStore::AddWatchOnly(const CScript &dest) { LOCK(cs_KeyStore); setWatchOnly.insert(dest); + CPubKey pubKey; + if (ExtractPubKey(dest, pubKey)) + mapWatchKeys[pubKey.GetID()] = pubKey; return true; } @@ -69,6 +95,9 @@ bool CBasicKeyStore::RemoveWatchOnly(const CScript &dest) { LOCK(cs_KeyStore); setWatchOnly.erase(dest); + CPubKey pubKey; + if (ExtractPubKey(dest, pubKey)) + mapWatchKeys.erase(pubKey.GetID()); return true; } diff --git a/src/keystore.h b/src/keystore.h index 4a4b6d20af..b917bf20b4 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -32,7 +32,7 @@ public: virtual bool HaveKey(const CKeyID &address) const =0; virtual bool GetKey(const CKeyID &address, CKey& keyOut) const =0; virtual void GetKeys(std::set<CKeyID> &setAddress) const =0; - virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const; + virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const =0; //! Support for BIP 0013 : see https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki virtual bool AddCScript(const CScript& redeemScript) =0; @@ -47,6 +47,7 @@ public: }; typedef std::map<CKeyID, CKey> KeyMap; +typedef std::map<CKeyID, CPubKey> WatchKeyMap; typedef std::map<CScriptID, CScript > ScriptMap; typedef std::set<CScript> WatchOnlySet; @@ -55,11 +56,13 @@ class CBasicKeyStore : public CKeyStore { protected: KeyMap mapKeys; + WatchKeyMap mapWatchKeys; ScriptMap mapScripts; WatchOnlySet setWatchOnly; public: bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey); + bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const; bool HaveKey(const CKeyID &address) const { bool result; diff --git a/src/leveldbwrapper.cpp b/src/leveldbwrapper.cpp index c353dfa6d9..26cacf95ae 100644 --- a/src/leveldbwrapper.cpp +++ b/src/leveldbwrapper.cpp @@ -58,7 +58,8 @@ CLevelDBWrapper::CLevelDBWrapper(const boost::filesystem::path& path, size_t nCa } else { if (fWipe) { LogPrintf("Wiping LevelDB in %s\n", path.string()); - leveldb::DestroyDB(path.string(), options); + leveldb::Status result = leveldb::DestroyDB(path.string(), options); + HandleError(result); } TryCreateDirectory(path); LogPrintf("Opening LevelDB in %s\n", path.string()); diff --git a/src/limitedmap.h b/src/limitedmap.h index e8ea549653..5456dfc7c4 100644 --- a/src/limitedmap.h +++ b/src/limitedmap.h @@ -27,7 +27,11 @@ protected: size_type nMaxSize; public: - limitedmap(size_type nMaxSizeIn = 0) { nMaxSize = nMaxSizeIn; } + limitedmap(size_type nMaxSizeIn) + { + assert(nMaxSizeIn > 0); + nMaxSize = nMaxSizeIn; + } const_iterator begin() const { return map.begin(); } const_iterator end() const { return map.end(); } size_type size() const { return map.size(); } @@ -38,13 +42,12 @@ public: { std::pair<iterator, bool> ret = map.insert(x); if (ret.second) { - if (nMaxSize && map.size() == nMaxSize) { + if (map.size() > nMaxSize) { map.erase(rmap.begin()->second); rmap.erase(rmap.begin()); } rmap.insert(make_pair(x.second, ret.first)); } - return; } void erase(const key_type& k) { @@ -81,11 +84,11 @@ public: size_type max_size() const { return nMaxSize; } size_type max_size(size_type s) { - if (s) - while (map.size() > s) { - map.erase(rmap.begin()->second); - rmap.erase(rmap.begin()); - } + assert(s > 0); + while (map.size() > s) { + map.erase(rmap.begin()->second); + rmap.erase(rmap.begin()); + } nMaxSize = s; return nMaxSize; } diff --git a/src/main.cpp b/src/main.cpp index 8da2a80bb0..5cfb05b0d2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -162,6 +162,29 @@ namespace { */ map<uint256, NodeId> mapBlockSource; + /** + * Filter for transactions that were recently rejected by + * AcceptToMemoryPool. These are not rerequested until the chain tip + * changes, at which point the entire filter is reset. Protected by + * cs_main. + * + * Without this filter we'd be re-requesting txs from each of our peers, + * increasing bandwidth consumption considerably. For instance, with 100 + * peers, half of which relay a tx we don't accept, that might be a 50x + * bandwidth increase. A flooding attacker attempting to roll-over the + * filter using minimum-sized, 60byte, transactions might manage to send + * 1000/sec if we have fast peers, so we pick 120,000 to give our peers a + * two minute window to send invs to us. + * + * Decreasing the false positive rate is fairly cheap, so we pick one in a + * million to make it highly unlikely for users to have issues with this + * filter. + * + * Memory used: 1.7MB + */ + boost::scoped_ptr<CRollingBloomFilter> recentRejects; + uint256 hashRecentRejectsChainTip; + /** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */ struct QueuedBlock { uint256 hash; @@ -673,30 +696,24 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) { // Basic checks that don't depend on any context if (tx.vin.empty()) - return state.DoS(10, error("CheckTransaction(): vin empty"), - REJECT_INVALID, "bad-txns-vin-empty"); + return state.DoS(10, false, REJECT_INVALID, "bad-txns-vin-empty"); if (tx.vout.empty()) - return state.DoS(10, error("CheckTransaction(): vout empty"), - REJECT_INVALID, "bad-txns-vout-empty"); + return state.DoS(10, false, REJECT_INVALID, "bad-txns-vout-empty"); // Size limits if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) - return state.DoS(100, error("CheckTransaction(): size limits failed"), - REJECT_INVALID, "bad-txns-oversize"); + return state.DoS(100, false, REJECT_INVALID, "bad-txns-oversize"); // Check for negative or overflow output values CAmount nValueOut = 0; BOOST_FOREACH(const CTxOut& txout, tx.vout) { if (txout.nValue < 0) - return state.DoS(100, error("CheckTransaction(): txout.nValue negative"), - REJECT_INVALID, "bad-txns-vout-negative"); + return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-negative"); if (txout.nValue > MAX_MONEY) - return state.DoS(100, error("CheckTransaction(): txout.nValue too high"), - REJECT_INVALID, "bad-txns-vout-toolarge"); + return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-toolarge"); nValueOut += txout.nValue; if (!MoneyRange(nValueOut)) - return state.DoS(100, error("CheckTransaction(): txout total out of range"), - REJECT_INVALID, "bad-txns-txouttotal-toolarge"); + return state.DoS(100, false, REJECT_INVALID, "bad-txns-txouttotal-toolarge"); } // Check for duplicate inputs @@ -704,23 +721,20 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) BOOST_FOREACH(const CTxIn& txin, tx.vin) { if (vInOutPoints.count(txin.prevout)) - return state.DoS(100, error("CheckTransaction(): duplicate inputs"), - REJECT_INVALID, "bad-txns-inputs-duplicate"); + return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-duplicate"); vInOutPoints.insert(txin.prevout); } if (tx.IsCoinBase()) { if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100) - return state.DoS(100, error("CheckTransaction(): coinbase script size"), - REJECT_INVALID, "bad-cb-length"); + return state.DoS(100, false, REJECT_INVALID, "bad-cb-length"); } else { BOOST_FOREACH(const CTxIn& txin, tx.vin) if (txin.prevout.IsNull()) - return state.DoS(10, error("CheckTransaction(): prevout is null"), - REJECT_INVALID, "bad-txns-prevout-null"); + return state.DoS(10, false, REJECT_INVALID, "bad-txns-prevout-null"); } return true; @@ -755,6 +769,14 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF return nMinFee; } +/** Convert CValidationState to a human-readable message for logging */ +static std::string FormatStateMessage(const CValidationState &state) +{ + return strprintf("%s%s (code %i)", + state.GetRejectReason(), + state.GetDebugMessage().empty() ? "" : ", "+state.GetDebugMessage(), + state.GetRejectCode()); +} bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, bool* pfMissingInputs, bool fRejectAbsurdFee) @@ -764,31 +786,27 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa *pfMissingInputs = false; if (!CheckTransaction(tx, state)) - return error("AcceptToMemoryPool: CheckTransaction failed"); + return false; // Coinbase is only valid in a block, not as a loose transaction if (tx.IsCoinBase()) - return state.DoS(100, error("AcceptToMemoryPool: coinbase as individual tx"), - REJECT_INVALID, "coinbase"); + return state.DoS(100, false, REJECT_INVALID, "coinbase"); // Rather not work on nonstandard transactions (unless -testnet/-regtest) string reason; if (fRequireStandard && !IsStandardTx(tx, reason)) - return state.DoS(0, - error("AcceptToMemoryPool: nonstandard transaction: %s", reason), - REJECT_NONSTANDARD, reason); + return state.DoS(0, false, REJECT_NONSTANDARD, reason); // Only accept nLockTime-using transactions that can be mined in the next // block; we don't want our mempool filled up with transactions that can't // be mined yet. if (!CheckFinalTx(tx)) - return state.DoS(0, error("AcceptToMemoryPool: non-final"), - REJECT_NONSTANDARD, "non-final"); + return state.DoS(0, false, REJECT_NONSTANDARD, "non-final"); // is it already in the memory pool? uint256 hash = tx.GetHash(); if (pool.exists(hash)) - return false; + return state.Invalid(false, REJECT_ALREADY_KNOWN, "txn-already-in-mempool"); // Check for conflicts with in-memory transactions { @@ -799,7 +817,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa if (pool.mapNextTx.count(outpoint)) { // Disable replacement feature for now - return false; + return state.Invalid(false, REJECT_CONFLICT, "txn-mempool-conflict"); } } } @@ -816,7 +834,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // do we already have it? if (view.HaveCoins(hash)) - return false; + return state.Invalid(false, REJECT_ALREADY_KNOWN, "txn-already-known"); // do all inputs exist? // Note that this does not check for the presence of actual outputs (see the next check for that), @@ -825,14 +843,13 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa if (!view.HaveCoins(txin.prevout.hash)) { if (pfMissingInputs) *pfMissingInputs = true; - return false; + return false; // fMissingInputs and !state.IsInvalid() is used to detect this condition, don't set state.Invalid() } } // are the actual inputs available? if (!view.HaveInputs(tx)) - return state.Invalid(error("AcceptToMemoryPool: inputs already spent"), - REJECT_DUPLICATE, "bad-txns-inputs-spent"); + return state.Invalid(false, REJECT_DUPLICATE, "bad-txns-inputs-spent"); // Bring the best block into scope view.GetBestBlock(); @@ -845,7 +862,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // Check for non-standard pay-to-script-hash in inputs if (fRequireStandard && !AreInputsStandard(tx, view)) - return error("AcceptToMemoryPool: nonstandard transaction input"); + return state.Invalid(false, REJECT_NONSTANDARD, "bad-txns-nonstandard-inputs"); // Check that the transaction doesn't have an excessive number of // sigops, making it impossible to mine. Since the coinbase transaction @@ -855,10 +872,8 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa unsigned int nSigOps = GetLegacySigOpCount(tx); nSigOps += GetP2SHSigOpCount(tx, view); if (nSigOps > MAX_STANDARD_TX_SIGOPS) - return state.DoS(0, - error("AcceptToMemoryPool: too many sigops %s, %d > %d", - hash.ToString(), nSigOps, MAX_STANDARD_TX_SIGOPS), - REJECT_NONSTANDARD, "bad-txns-too-many-sigops"); + return state.DoS(0, false, REJECT_NONSTANDARD, "bad-txns-too-many-sigops", false, + strprintf("%d > %d", nSigOps, MAX_STANDARD_TX_SIGOPS)); CAmount nValueOut = tx.GetValueOut(); CAmount nFees = nValueIn-nValueOut; @@ -870,9 +885,8 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // Don't accept it if it can't get into a block CAmount txMinFee = GetMinRelayFee(tx, nSize, true); if (fLimitFree && nFees < txMinFee) - return state.DoS(0, error("AcceptToMemoryPool: not enough fees %s, %d < %d", - hash.ToString(), nFees, txMinFee), - REJECT_INSUFFICIENTFEE, "insufficient fee"); + return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient fee", false, + strprintf("%d < %d", nFees, txMinFee)); // Require that free transactions have sufficient priority to be mined in the next block. if (GetBoolArg("-relaypriority", true) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) { @@ -897,23 +911,31 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // -limitfreerelay unit is thousand-bytes-per-minute // At default rate it would take over a month to fill 1GB if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000) - return state.DoS(0, error("AcceptToMemoryPool: free transaction rejected by rate limiter"), - REJECT_INSUFFICIENTFEE, "rate limited free transaction"); + return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "rate limited free transaction"); LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize); dFreeCount += nSize; } if (fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000) - return error("AcceptToMemoryPool: absurdly high fees %s, %d > %d", - hash.ToString(), - nFees, ::minRelayTxFee.GetFee(nSize) * 10000); + return state.Invalid(false, + REJECT_HIGHFEE, "absurdly-high-fee", + strprintf("%d > %d", nFees, ::minRelayTxFee.GetFee(nSize) * 10000)); + + // Calculate in-mempool ancestors, up to a limit. + CTxMemPool::setEntries setAncestors; + size_t nLimitAncestors = GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT); + size_t nLimitAncestorSize = GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000; + size_t nLimitDescendants = GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT); + size_t nLimitDescendantSize = GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT)*1000; + std::string errString; + if (!pool.CalculateMemPoolAncestors(entry, setAncestors, nLimitAncestors, nLimitAncestorSize, nLimitDescendants, nLimitDescendantSize, errString)) { + return state.DoS(0, false, REJECT_NONSTANDARD, "too-long-mempool-chain", false, errString); + } // Check against previous transactions // This is done last to help prevent CPU exhaustion denial-of-service attacks. if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true)) - { - return error("AcceptToMemoryPool: ConnectInputs failed %s", hash.ToString()); - } + return false; // Check again against just the consensus-critical mandatory script // verification flags, in case of bugs in the standard flags that cause @@ -926,11 +948,12 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // can be exploited as a DoS attack. if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true)) { - return error("AcceptToMemoryPool: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString()); + return error("%s: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s, %s", + __func__, hash.ToString(), FormatStateMessage(state)); } // Store transaction in memory - pool.addUnchecked(hash, entry, !IsInitialBlockDownload()); + pool.addUnchecked(hash, entry, setAncestors, !IsInitialBlockDownload()); } SyncWithWallets(tx, NULL); @@ -942,47 +965,45 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow) { CBlockIndex *pindexSlow = NULL; + + LOCK(cs_main); + + if (mempool.lookup(hash, txOut)) { - LOCK(cs_main); - { - if (mempool.lookup(hash, txOut)) - { - return true; - } - } + return true; + } - if (fTxIndex) { - CDiskTxPos postx; - if (pblocktree->ReadTxIndex(hash, postx)) { - CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION); - if (file.IsNull()) - return error("%s: OpenBlockFile failed", __func__); - CBlockHeader header; - try { - file >> header; - fseek(file.Get(), postx.nTxOffset, SEEK_CUR); - file >> txOut; - } catch (const std::exception& e) { - return error("%s: Deserialize or I/O error - %s", __func__, e.what()); - } - hashBlock = header.GetHash(); - if (txOut.GetHash() != hash) - return error("%s: txid mismatch", __func__); - return true; + if (fTxIndex) { + CDiskTxPos postx; + if (pblocktree->ReadTxIndex(hash, postx)) { + CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION); + if (file.IsNull()) + return error("%s: OpenBlockFile failed", __func__); + CBlockHeader header; + try { + file >> header; + fseek(file.Get(), postx.nTxOffset, SEEK_CUR); + file >> txOut; + } catch (const std::exception& e) { + return error("%s: Deserialize or I/O error - %s", __func__, e.what()); } + hashBlock = header.GetHash(); + if (txOut.GetHash() != hash) + return error("%s: txid mismatch", __func__); + return true; } + } - if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it - int nHeight = -1; - { - CCoinsViewCache &view = *pcoinsTip; - const CCoins* coins = view.AccessCoins(hash); - if (coins) - nHeight = coins->nHeight; - } - if (nHeight > 0) - pindexSlow = chainActive[nHeight]; + if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it + int nHeight = -1; + { + CCoinsViewCache &view = *pcoinsTip; + const CCoins* coins = view.AccessCoins(hash); + if (coins) + nHeight = coins->nHeight; } + if (nHeight > 0) + pindexSlow = chainActive[nHeight]; } if (pindexSlow) { @@ -1011,7 +1032,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock // CBlock and CBlockIndex // -bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart) +bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart) { // Open history file to append CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION); @@ -1204,9 +1225,11 @@ void static InvalidChainFound(CBlockIndex* pindexNew) pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexNew->GetBlockTime())); + CBlockIndex *tip = chainActive.Tip(); + assert (tip); LogPrintf("%s: current best=%s height=%d log2_work=%.8g date=%s\n", __func__, - chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), - DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime())); + tip->GetBlockHash().ToString(), chainActive.Height(), log(tip->nChainWork.getdouble())/log(2.0), + DateTimeStrFormat("%Y-%m-%d %H:%M:%S", tip->GetBlockTime())); CheckForkWarningConditions(); } @@ -1215,7 +1238,8 @@ void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state if (state.IsInvalid(nDoS)) { std::map<uint256, NodeId>::iterator it = mapBlockSource.find(pindex->GetBlockHash()); if (it != mapBlockSource.end() && State(it->second)) { - CBlockReject reject = {state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), pindex->GetBlockHash()}; + assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes + CBlockReject reject = {(unsigned char)state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), pindex->GetBlockHash()}; State(it->second)->rejects.push_back(reject); if (nDoS > 0) Misbehaving(it->second, nDoS); @@ -1265,7 +1289,7 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach bool CScriptCheck::operator()() { const CScript &scriptSig = ptxTo->vin[nIn].scriptSig; if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, cacheStore), &error)) { - return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error)); + return false; } return true; } @@ -1283,7 +1307,7 @@ bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoins // This doesn't trigger the DoS code on purpose; if it did, it would make it easier // for an attacker to attempt to split the network. if (!inputs.HaveInputs(tx)) - return state.Invalid(error("CheckInputs(): %s inputs unavailable", tx.GetHash().ToString())); + return state.Invalid(false, 0, "", "Inputs unavailable"); CAmount nValueIn = 0; CAmount nFees = 0; @@ -1296,33 +1320,29 @@ bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoins // If prev is coinbase, check that it's matured if (coins->IsCoinBase()) { if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) - return state.Invalid( - error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight), - REJECT_INVALID, "bad-txns-premature-spend-of-coinbase"); + return state.Invalid(false, + REJECT_INVALID, "bad-txns-premature-spend-of-coinbase", + strprintf("tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight)); } // Check for negative or overflow input values nValueIn += coins->vout[prevout.n].nValue; if (!MoneyRange(coins->vout[prevout.n].nValue) || !MoneyRange(nValueIn)) - return state.DoS(100, error("CheckInputs(): txin values out of range"), - REJECT_INVALID, "bad-txns-inputvalues-outofrange"); + return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputvalues-outofrange"); } if (nValueIn < tx.GetValueOut()) - return state.DoS(100, error("CheckInputs(): %s value in (%s) < value out (%s)", - tx.GetHash().ToString(), FormatMoney(nValueIn), FormatMoney(tx.GetValueOut())), - REJECT_INVALID, "bad-txns-in-belowout"); + return state.DoS(100, false, REJECT_INVALID, "bad-txns-in-belowout", false, + strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(tx.GetValueOut()))); // Tally transaction fees CAmount nTxFee = nValueIn - tx.GetValueOut(); if (nTxFee < 0) - return state.DoS(100, error("CheckInputs(): %s nTxFee < 0", tx.GetHash().ToString()), - REJECT_INVALID, "bad-txns-fee-negative"); + return state.DoS(100, false, REJECT_INVALID, "bad-txns-fee-negative"); nFees += nTxFee; if (!MoneyRange(nFees)) - return state.DoS(100, error("CheckInputs(): nFees out of range"), - REJECT_INVALID, "bad-txns-fee-outofrange"); + return state.DoS(100, false, REJECT_INVALID, "bad-txns-fee-outofrange"); return true; } }// namespace Consensus @@ -1446,7 +1466,7 @@ bool AbortNode(const std::string& strMessage, const std::string& userMessage="") strMiscWarning = strMessage; LogPrintf("*** %s\n", strMessage); uiInterface.ThreadSafeMessageBox( - userMessage.empty() ? _("Error: A fatal internal error occured, see debug.log for details") : userMessage, + userMessage.empty() ? _("Error: A fatal internal error occurred, see debug.log for details") : userMessage, "", CClientUIInterface::MSG_ERROR); StartShutdown(); return false; @@ -1493,7 +1513,7 @@ static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const CO return fClean; } -bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean) +bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean) { assert(pindex->GetBlockHash() == view.GetBestBlock()); @@ -1768,7 +1788,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin std::vector<CScriptCheck> vChecks; if (!CheckInputs(tx, state, view, fScriptChecks, flags, false, nScriptCheckThreads ? &vChecks : NULL)) - return false; + return error("ConnectBlock(): CheckInputs on %s failed with %s", + tx.GetHash().ToString(), FormatStateMessage(state)); control.Add(vChecks); } @@ -2021,13 +2042,23 @@ bool static DisconnectTip(CValidationState &state) { if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED)) return false; // Resurrect mempool transactions from the disconnected block. + std::vector<uint256> vHashUpdate; BOOST_FOREACH(const CTransaction &tx, block.vtx) { // ignore validation errors in resurrected transactions list<CTransaction> removed; CValidationState stateDummy; - if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL)) + if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL)) { mempool.remove(tx, removed, true); + } else if (mempool.exists(tx.GetHash())) { + vHashUpdate.push_back(tx.GetHash()); + } } + // AcceptToMemoryPool/addUnchecked all assume that new mempool entries have + // no in-mempool children, which is generally not true when adding + // previously-confirmed transactions back to the mempool. + // UpdateTransactionsFromBlock finds descendants of any transactions in this + // block that were added back and cleans up the mempool state. + mempool.UpdateTransactionsFromBlock(vHashUpdate); mempool.removeCoinbaseSpends(pcoinsTip, pindexDelete->nHeight); mempool.check(pcoinsTip); // Update chainActive and related variables. @@ -2050,7 +2081,7 @@ static int64_t nTimePostConnect = 0; * Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock * corresponding to pindexNew, to bypass loading it again from disk. */ -bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *pblock) { +bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, const CBlock *pblock) { assert(pindexNew->pprev == chainActive.Tip()); mempool.check(pcoinsTip); // Read block from disk. @@ -2182,7 +2213,7 @@ static void PruneBlockIndexCandidates() { * Try to make some progress towards making pindexMostWork the active block. * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork. */ -static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, CBlock *pblock) { +static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, const CBlock *pblock) { AssertLockHeld(cs_main); bool fInvalidFound = false; const CBlockIndex *pindexOldTip = chainActive.Tip(); @@ -2251,7 +2282,7 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo * or an activated best chain. pblock is either NULL or a pointer to a block * that is already loaded (to avoid loading it again from disk). */ -bool ActivateBestChain(CValidationState &state, CBlock *pblock) { +bool ActivateBestChain(CValidationState &state, const CBlock *pblock) { CBlockIndex *pindexNewTip = NULL; CBlockIndex *pindexMostWork = NULL; const CChainParams& chainParams = Params(); @@ -2282,15 +2313,14 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) { int nBlockEstimate = 0; if (fCheckpointsEnabled) nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()); - // Don't relay blocks if pruning -- could cause a peer to try to download, resulting - // in a stalled download if the block file is pruned before the request. - if (nLocalServices & NODE_NETWORK) { + { LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip)); } // Notify external listeners about the new tip. + GetMainSignals().UpdatedBlockTip(pindexNewTip); uiInterface.NotifyBlockTip(hashNewTip); } } while(pindexMostWork != chainActive.Tip()); @@ -2553,6 +2583,9 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo { // These are checks that are independent of context. + if (block.fChecked) + return true; + // Check that the header is valid (particularly PoW). This is mostly // redundant with the call in AcceptBlockHeader. if (!CheckBlockHeader(block, state, fCheckPOW)) @@ -2561,7 +2594,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo // Check the merkle root. if (fCheckMerkleRoot) { bool mutated; - uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated); + uint256 hashMerkleRoot2 = block.ComputeMerkleRoot(&mutated); if (block.hashMerkleRoot != hashMerkleRoot2) return state.DoS(100, error("CheckBlock(): hashMerkleRoot mismatch"), REJECT_INVALID, "bad-txnmrklroot", true); @@ -2595,7 +2628,9 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo // Check transactions BOOST_FOREACH(const CTransaction& tx, block.vtx) if (!CheckTransaction(tx, state)) - return error("CheckBlock(): CheckTransaction failed"); + return error("CheckBlock(): CheckTransaction of %s failed with %s", + tx.GetHash().ToString(), + FormatStateMessage(state)); unsigned int nSigOps = 0; BOOST_FOREACH(const CTransaction& tx, block.vtx) @@ -2606,6 +2641,9 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo return state.DoS(100, error("CheckBlock(): out-of-bounds SigOpCount"), REJECT_INVALID, "bad-blk-sigops", true); + if (fCheckPOW && fCheckMerkleRoot) + block.fChecked = true; + return true; } @@ -2722,7 +2760,7 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc return true; } -bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp) +bool AcceptBlock(const CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp) { const CChainParams& chainparams = Params(); AssertLockHeld(cs_main); @@ -2799,7 +2837,7 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned } -bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp) +bool ProcessNewBlock(CValidationState &state, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp) { // Preliminary checks bool checked = CheckBlock(*pblock, state); @@ -3248,6 +3286,7 @@ void UnloadBlockIndex() setDirtyBlockIndex.clear(); setDirtyFileInfo.clear(); mapNodeState.clear(); + recentRejects.reset(NULL); BOOST_FOREACH(BlockMap::value_type& entry, mapBlockIndex) { delete entry.second; @@ -3268,6 +3307,10 @@ bool LoadBlockIndex() bool InitBlockIndex() { const CChainParams& chainparams = Params(); LOCK(cs_main); + + // Initialize global variables that cannot be constructed at startup. + recentRejects.reset(new CRollingBloomFilter(120000, 0.000001)); + // Check whether we're already initialized if (chainActive.Genesis() != NULL) return true; @@ -3398,7 +3441,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) } } } catch (const std::exception& e) { - LogPrintf("%s: Deserialize or I/O error - %s", __func__, e.what()); + LogPrintf("%s: Deserialize or I/O error - %s\n", __func__, e.what()); } } } catch (const std::runtime_error& e) { @@ -3670,10 +3713,21 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { case MSG_TX: { - bool txInMap = false; - txInMap = mempool.exists(inv.hash); - return txInMap || mapOrphanTransactions.count(inv.hash) || - pcoinsTip->HaveCoins(inv.hash); + assert(recentRejects); + if (chainActive.Tip()->GetBlockHash() != hashRecentRejectsChainTip) + { + // If the chain tip has changed previously rejected transactions + // might be now valid, e.g. due to a nLockTime'd tx becoming valid, + // or a double-spend. Reset the rejects filter and give those + // txs a second chance. + hashRecentRejectsChainTip = chainActive.Tip()->GetBlockHash(); + recentRejects->reset(); + } + + return recentRejects->contains(inv.hash) || + mempool.exists(inv.hash) || + mapOrphanTransactions.count(inv.hash) || + pcoinsTip->HaveCoins(inv.hash); } case MSG_BLOCK: return mapBlockIndex.count(inv.hash); @@ -3859,7 +3913,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (!vRecv.empty()) vRecv >> addrFrom >> nNonce; if (!vRecv.empty()) { - vRecv >> LIMITED_STRING(pfrom->strSubVer, 256); + vRecv >> LIMITED_STRING(pfrom->strSubVer, MAX_SUBVERSION_LENGTH); pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer); } if (!vRecv.empty()) @@ -4146,6 +4200,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LogPrint("net", " getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); break; } + // If pruning, don't inv blocks unless we have on disk and are likely to still have + // for some reasonable time window (1 hour) that block relay might require. + const int nPrunedBlocksLikelyToHave = MIN_BLOCKS_TO_KEEP - 3600 / chainparams.GetConsensus().nPowTargetSpacing; + if (fPruneMode && (!(pindex->nStatus & BLOCK_HAVE_DATA) || pindex->nHeight <= chainActive.Tip()->nHeight - nPrunedBlocksLikelyToHave)) + { + LogPrint("net", " getblocks stopping, pruned or too old block at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); + break; + } pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash())); if (--nLimit <= 0) { @@ -4218,16 +4280,20 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, mapAlreadyAskedFor.erase(inv); + // Check for recently rejected (and do other quick existence checks) + if (AlreadyHave(inv)) + return true; + if (AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs)) { mempool.check(pcoinsTip); RelayTransaction(tx); vWorkQueue.push_back(inv.hash); - LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s: accepted %s (poolsz %u)\n", - pfrom->id, pfrom->cleanSubVer, + LogPrint("mempool", "AcceptToMemoryPool: peer=%d: accepted %s (poolsz %u)\n", + pfrom->id, tx.GetHash().ToString(), - mempool.mapTx.size()); + mempool.size()); // Recursively process any orphan transactions that depended on this one set<NodeId> setMisbehaving; @@ -4273,6 +4339,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Probably non-standard or insufficient fee/priority LogPrint("mempool", " removed orphan tx %s\n", orphanHash.ToString()); vEraseQueue.push_back(orphanHash); + assert(recentRejects); + recentRejects->insert(orphanHash); } mempool.check(pcoinsTip); } @@ -4290,20 +4358,30 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx); if (nEvicted > 0) LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted); - } else if (pfrom->fWhitelisted) { - // Always relay transactions received from whitelisted peers, even - // if they are already in the mempool (allowing the node to function - // as a gateway for nodes hidden behind it). - RelayTransaction(tx); + } else { + assert(recentRejects); + recentRejects->insert(tx.GetHash()); + + if (pfrom->fWhitelisted) { + // Always relay transactions received from whitelisted peers, even + // if they were rejected from the mempool, allowing the node to + // function as a gateway for nodes hidden behind it. + // + // FIXME: This includes invalid transactions, which means a + // whitelisted peer could get us banned! We may want to change + // that. + RelayTransaction(tx); + } } int nDoS = 0; if (state.IsInvalid(nDoS)) { - LogPrint("mempool", "%s from peer=%d %s was not accepted into the memory pool: %s\n", tx.GetHash().ToString(), - pfrom->id, pfrom->cleanSubVer, - state.GetRejectReason()); - pfrom->PushMessage("reject", strCommand, state.GetRejectCode(), - state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); + LogPrint("mempoolrej", "%s from peer=%d was not accepted: %s\n", tx.GetHash().ToString(), + pfrom->id, + FormatStateMessage(state)); + if (state.GetRejectCode() < REJECT_INTERNAL) // Never send AcceptToMemoryPool's internal codes over P2P + pfrom->PushMessage("reject", strCommand, state.GetRejectCode(), + state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); if (nDoS > 0) Misbehaving(pfrom->GetId(), nDoS); } @@ -4383,6 +4461,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, ProcessNewBlock(state, pfrom, &block, forceProcessing, NULL); int nDoS; if (state.IsInvalid(nDoS)) { + assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes pfrom->PushMessage("reject", strCommand, state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); if (nDoS > 0) { @@ -4475,6 +4554,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (pingUsecTime > 0) { // Successful ping time measurement, replace previous pfrom->nPingUsecTime = pingUsecTime; + pfrom->nMinPingUsecTime = std::min(pfrom->nMinPingUsecTime, pingUsecTime); } else { // This should never happen sProblem = "Timing mishap"; @@ -4498,9 +4578,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } if (!(sProblem.empty())) { - LogPrint("net", "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n", + LogPrint("net", "pong peer=%d: %s, %x expected, %x received, %u bytes\n", pfrom->id, - pfrom->cleanSubVer, sProblem, pfrom->nPingNonceSent, nonce, @@ -4543,6 +4622,21 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } + else if (!(nLocalServices & NODE_BLOOM) && + (strCommand == "filterload" || + strCommand == "filteradd" || + strCommand == "filterclear") && + //TODO: Remove this line after reasonable network upgrade + pfrom->nVersion >= NO_BLOOM_VERSION) + { + if (pfrom->nVersion >= NO_BLOOM_VERSION) + Misbehaving(pfrom->GetId(), 100); + //TODO: Enable this after reasonable network upgrade + //else + // pfrom->fDisconnect = true; + } + + else if (strCommand == "filterload") { CBloomFilter filter; @@ -4797,7 +4891,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) { // Periodically clear addrKnown to allow refresh broadcasts if (nLastRebroadcast) - pnode->addrKnown.clear(); + pnode->addrKnown.reset(); // Rebroadcast our address AdvertizeLocal(pnode); diff --git a/src/main.h b/src/main.h index 96ad54cda6..a6001eed8f 100644 --- a/src/main.h +++ b/src/main.h @@ -43,6 +43,14 @@ struct CNodeStateStats; static const bool DEFAULT_ALERTS = true; /** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; +/** Default for -limitancestorcount, max number of in-mempool ancestors */ +static const unsigned int DEFAULT_ANCESTOR_LIMIT = 100; +/** Default for -limitancestorsize, maximum kilobytes of tx + all in-mempool ancestors */ +static const unsigned int DEFAULT_ANCESTOR_SIZE_LIMIT = 900; +/** Default for -limitdescendantcount, max number of in-mempool descendants */ +static const unsigned int DEFAULT_DESCENDANT_LIMIT = 1000; +/** Default for -limitdescendantsize, maximum kilobytes of in-mempool descendants */ +static const unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT = 2500; /** The maximum size of a blk?????.dat file (since 0.8) */ static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB /** The pre-allocation chunk size for blk?????.dat files (since 0.8) */ @@ -142,7 +150,7 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals); * @param[out] dbp If pblock is stored to disk (or already there), this will be set to its location. * @return True if state.IsValid() */ -bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp); +bool ProcessNewBlock(CValidationState &state, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp); /** Check whether enough disk space is available for an incoming block */ bool CheckDiskSpace(uint64_t nAdditionalBytes = 0); /** Open a block file (blk?????.dat) */ @@ -179,7 +187,7 @@ std::string GetWarnings(const std::string& strFor); /** Retrieve a transaction (from memory pool, or from disk, if possible) */ bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, bool fAllowSlow = false); /** Find the best known block, and make it the tip of the block chain */ -bool ActivateBestChain(CValidationState &state, CBlock *pblock = NULL); +bool ActivateBestChain(CValidationState &state, const CBlock *pblock = NULL); CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams); /** @@ -335,7 +343,7 @@ public: /** Functions for disk access for blocks */ -bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart); +bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart); bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos); bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex); @@ -346,7 +354,7 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex); * In case pfClean is provided, operation will try to be tolerant about errors, and *pfClean * will be true if no problems were found. Otherwise, the return value will be false in case * of problems. Note that in any case, coins may be modified. */ -bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool* pfClean = NULL); +bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockIndex* pindex, CCoinsViewCache& coins, bool* pfClean = NULL); /** Apply the effects of this block (with given index) on the UTXO set represented by coins */ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false); @@ -363,7 +371,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex *pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true); /** Store block on disk. If dbp is non-NULL, the file is known to already reside on disk */ -bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex **pindex, bool fRequested, CDiskBlockPos* dbp); +bool AcceptBlock(const CBlock& block, CValidationState& state, CBlockIndex **pindex, bool fRequested, CDiskBlockPos* dbp); bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL); @@ -455,4 +463,16 @@ extern CBlockTreeDB *pblocktree; */ int GetSpendHeight(const CCoinsViewCache& inputs); +/** Reject codes greater or equal to this can be returned by AcceptToMemPool + * for transactions, to signal internal conditions. They cannot and should not + * be sent over the P2P network. + */ +static const unsigned int REJECT_INTERNAL = 0x100; +/** Too high fee. Can not be triggered by P2P transactions */ +static const unsigned int REJECT_HIGHFEE = 0x100; +/** Transaction is already known (either in mempool or blockchain) */ +static const unsigned int REJECT_ALREADY_KNOWN = 0x101; +/** Transaction conflicts with a transaction already known */ +static const unsigned int REJECT_CONFLICT = 0x102; + #endif // BITCOIN_MAIN_H diff --git a/src/memusage.h b/src/memusage.h index be3964df1b..b475c3313b 100644 --- a/src/memusage.h +++ b/src/memusage.h @@ -74,18 +74,30 @@ static inline size_t DynamicUsage(const std::vector<X>& v) return MallocUsage(v.capacity() * sizeof(X)); } -template<typename X> -static inline size_t DynamicUsage(const std::set<X>& s) +template<typename X, typename Y> +static inline size_t DynamicUsage(const std::set<X, Y>& s) { return MallocUsage(sizeof(stl_tree_node<X>)) * s.size(); } template<typename X, typename Y> -static inline size_t DynamicUsage(const std::map<X, Y>& m) +static inline size_t IncrementalDynamicUsage(const std::set<X, Y>& s) +{ + return MallocUsage(sizeof(stl_tree_node<X>)); +} + +template<typename X, typename Y, typename Z> +static inline size_t DynamicUsage(const std::map<X, Y, Z>& m) { return MallocUsage(sizeof(stl_tree_node<std::pair<const X, Y> >)) * m.size(); } +template<typename X, typename Y, typename Z> +static inline size_t IncrementalDynamicUsage(const std::map<X, Y, Z>& m) +{ + return MallocUsage(sizeof(stl_tree_node<std::pair<const X, Y> >)); +} + // Boost data structures template<typename X> diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index 4d90fd8cd7..f8e877df25 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -168,7 +168,7 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) { // traverse the partial tree unsigned int nBitsUsed = 0, nHashUsed = 0; uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch); - // verify that no problems occured during the tree traversal + // verify that no problems occurred during the tree traversal if (fBad) return uint256(); // verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence) diff --git a/src/miner.cpp b/src/miner.cpp index e44f3392c8..42c8bb970b 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -84,13 +84,19 @@ public: } }; -void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev) +int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev) { - pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); + int64_t nOldTime = pblock->nTime; + int64_t nNewTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); + + if (nOldTime < nNewTime) + pblock->nTime = nNewTime; // Updating time can change work required on testnet: if (consensusParams.fPowAllowMinDifficultyBlocks) pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams); + + return nNewTime - nOldTime; } CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) @@ -152,10 +158,10 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) // This vector will be sorted into a priority queue: vector<TxPriority> vecPriority; vecPriority.reserve(mempool.mapTx.size()); - for (map<uint256, CTxMemPoolEntry>::iterator mi = mempool.mapTx.begin(); + for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi) { - const CTransaction& tx = mi->second.GetTx(); + const CTransaction& tx = mi->GetTx(); if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight, pblock->nTime)) continue; @@ -190,7 +196,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) } mapDependers[txin.prevout.hash].push_back(porphan); porphan->setDependsOn.insert(txin.prevout.hash); - nTotalIn += mempool.mapTx[txin.prevout.hash].GetTx().vout[txin.prevout.n].nValue; + nTotalIn += mempool.mapTx.find(txin.prevout.hash)->GetTx().vout[txin.prevout.n].nValue; continue; } const CCoins* coins = view.AccessCoins(txin.prevout.hash); @@ -220,7 +226,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) porphan->feeRate = feeRate; } else - vecPriority.push_back(TxPriority(dPriority, feeRate, &mi->second.GetTx())); + vecPriority.push_back(TxPriority(dPriority, feeRate, &(mi->GetTx()))); } // Collect transactions into block @@ -346,7 +352,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) return pblocktemplate.release(); } -void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce) +void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce) { // Update nExtraNonce static uint256 hashPrevBlock; @@ -362,7 +368,7 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& assert(txCoinbase.vin[0].scriptSig.size() <= 100); pblock->vtx[0] = txCoinbase; - pblock->hashMerkleRoot = pblock->BuildMerkleTree(); + pblock->hashMerkleRoot = pblock->ComputeMerkleRoot(); } ////////////////////////////////////////////////////////////////////////////// @@ -403,7 +409,7 @@ bool static ScanHash(const CBlockHeader *pblock, uint32_t& nNonce, uint256 *phas } } -static bool ProcessBlockFound(CBlock* pblock, const CChainParams& chainparams) +static bool ProcessBlockFound(const CBlock* pblock, const CChainParams& chainparams) { LogPrintf("%s\n", pblock->ToString()); LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue)); @@ -438,8 +444,10 @@ void static BitcoinMiner(const CChainParams& chainparams) GetMainSignals().ScriptForMining(coinbaseScript); try { - //throw an error if no script was provided - if (!coinbaseScript->reserveScript.size()) + // Throw an error if no script was provided. This can happen + // due to some internal error but also if the keypool is empty. + // In the latter case, already the pointer is NULL. + if (!coinbaseScript || coinbaseScript->reserveScript.empty()) throw std::runtime_error("No coinbase script available (mining requires a wallet)"); while (true) { @@ -521,7 +529,9 @@ void static BitcoinMiner(const CChainParams& chainparams) break; // Update nTime every few seconds - UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); + if (UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev) < 0) + break; // Recreate the block if the clock has run backwards, + // so that we can use the correct time. if (chainparams.GetConsensus().fPowAllowMinDifficultyBlocks) { // Changing pblock->nTime can change work required on testnet: diff --git a/src/miner.h b/src/miner.h index 777a091967..7e0e58d540 100644 --- a/src/miner.h +++ b/src/miner.h @@ -29,7 +29,7 @@ void GenerateBitcoins(bool fGenerate, int nThreads, const CChainParams& chainpar /** Generate a new block, without valid proof-of-work */ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn); /** Modify the extranonce in a block */ -void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); -void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev); +void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce); +int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev); #endif // BITCOIN_MINER_H diff --git a/src/net.cpp b/src/net.cpp index 3cece520de..87c4f0af0a 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -80,9 +80,9 @@ static CNode* pnodeLocalHost = NULL; uint64_t nLocalHostNonce = 0; static std::vector<ListenSocket> vhListenSocket; CAddrMan addrman; -int nMaxConnections = 125; -int nWhiteConnections = 0; +int nMaxConnections = DEFAULT_MAX_PEER_CONNECTIONS; bool fAddressesInitialized = false; +std::string strSubVersion; vector<CNode*> vNodes; CCriticalSection cs_vNodes; @@ -445,7 +445,7 @@ void CNode::PushVersion() else LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), id); PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, - nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight, true); + nLocalHostNonce, strSubVersion, nBestHeight, true); } @@ -628,6 +628,7 @@ void CNode::copyStats(CNodeStats &stats) // Raw ping time is in microseconds, but show it to user as whole seconds (Bitcoin users should be well used to small numbers with many decimal places by now :) stats.dPingTime = (((double)nPingUsecTime) / 1e6); + stats.dPingMin = (((double)nMinPingUsecTime) / 1e6); stats.dPingWait = (((double)nPingUsecWait) / 1e6); // Leave string empty if addrLocal invalid (not filled in yet) @@ -658,7 +659,7 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes) return false; if (msg.in_data && msg.hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) { - LogPrint("net", "Oversized message from peer=%i, disconnecting", GetId()); + LogPrint("net", "Oversized message from peer=%i, disconnecting\n", GetId()); return false; } @@ -775,6 +776,222 @@ void SocketSendData(CNode *pnode) static list<CNode*> vNodesDisconnected; +class CNodeRef { +public: + CNodeRef(CNode *pnode) : _pnode(pnode) { + LOCK(cs_vNodes); + _pnode->AddRef(); + } + + ~CNodeRef() { + LOCK(cs_vNodes); + _pnode->Release(); + } + + CNode& operator *() const {return *_pnode;}; + CNode* operator ->() const {return _pnode;}; + + CNodeRef& operator =(const CNodeRef& other) + { + if (this != &other) { + LOCK(cs_vNodes); + + _pnode->Release(); + _pnode = other._pnode; + _pnode->AddRef(); + } + return *this; + } + + CNodeRef(const CNodeRef& other): + _pnode(other._pnode) + { + LOCK(cs_vNodes); + _pnode->AddRef(); + } +private: + CNode *_pnode; +}; + +static bool ReverseCompareNodeMinPingTime(const CNodeRef &a, const CNodeRef &b) +{ + return a->nMinPingUsecTime > b->nMinPingUsecTime; +} + +static bool ReverseCompareNodeTimeConnected(const CNodeRef &a, const CNodeRef &b) +{ + return a->nTimeConnected > b->nTimeConnected; +} + +class CompareNetGroupKeyed +{ + std::vector<unsigned char> vchSecretKey; +public: + CompareNetGroupKeyed() + { + vchSecretKey.resize(32, 0); + GetRandBytes(vchSecretKey.data(), vchSecretKey.size()); + } + + bool operator()(const CNodeRef &a, const CNodeRef &b) + { + std::vector<unsigned char> vchGroupA, vchGroupB; + CSHA256 hashA, hashB; + std::vector<unsigned char> vchA(32), vchB(32); + + vchGroupA = a->addr.GetGroup(); + vchGroupB = b->addr.GetGroup(); + + hashA.Write(begin_ptr(vchGroupA), vchGroupA.size()); + hashB.Write(begin_ptr(vchGroupB), vchGroupB.size()); + + hashA.Write(begin_ptr(vchSecretKey), vchSecretKey.size()); + hashB.Write(begin_ptr(vchSecretKey), vchSecretKey.size()); + + hashA.Finalize(begin_ptr(vchA)); + hashB.Finalize(begin_ptr(vchB)); + + return vchA < vchB; + } +}; + +static bool AttemptToEvictConnection(bool fPreferNewConnection) { + std::vector<CNodeRef> vEvictionCandidates; + { + LOCK(cs_vNodes); + + BOOST_FOREACH(CNode *node, vNodes) { + if (node->fWhitelisted) + continue; + if (!node->fInbound) + continue; + if (node->fDisconnect) + continue; + if (node->addr.IsLocal()) + continue; + vEvictionCandidates.push_back(CNodeRef(node)); + } + } + + if (vEvictionCandidates.empty()) return false; + + // Protect connections with certain characteristics + + // Deterministically select 4 peers to protect by netgroup. + // An attacker cannot predict which netgroups will be protected. + static CompareNetGroupKeyed comparerNetGroupKeyed; + std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), comparerNetGroupKeyed); + vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end()); + + if (vEvictionCandidates.empty()) return false; + + // Protect the 8 nodes with the best ping times. + // An attacker cannot manipulate this metric without physically moving nodes closer to the target. + std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeMinPingTime); + vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(8, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end()); + + if (vEvictionCandidates.empty()) return false; + + // Protect the half of the remaining nodes which have been connected the longest. + // This replicates the existing implicit behavior. + std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected); + vEvictionCandidates.erase(vEvictionCandidates.end() - static_cast<int>(vEvictionCandidates.size() / 2), vEvictionCandidates.end()); + + if (vEvictionCandidates.empty()) return false; + + // Identify the network group with the most connections + std::vector<unsigned char> naMostConnections; + unsigned int nMostConnections = 0; + std::map<std::vector<unsigned char>, std::vector<CNodeRef> > mapAddrCounts; + BOOST_FOREACH(const CNodeRef &node, vEvictionCandidates) { + mapAddrCounts[node->addr.GetGroup()].push_back(node); + + if (mapAddrCounts[node->addr.GetGroup()].size() > nMostConnections) { + nMostConnections = mapAddrCounts[node->addr.GetGroup()].size(); + naMostConnections = node->addr.GetGroup(); + } + } + + // Reduce to the network group with the most connections + vEvictionCandidates = mapAddrCounts[naMostConnections]; + + // Do not disconnect peers if there is only 1 connection from their network group + if (vEvictionCandidates.size() <= 1) + // unless we prefer the new connection (for whitelisted peers) + if (!fPreferNewConnection) + return false; + + // Disconnect the most recent connection from the network group with the most connections + std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected); + vEvictionCandidates[0]->fDisconnect = true; + + return true; +} + +static void AcceptConnection(const ListenSocket& hListenSocket) { + struct sockaddr_storage sockaddr; + socklen_t len = sizeof(sockaddr); + SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len); + CAddress addr; + int nInbound = 0; + int nMaxInbound = nMaxConnections - MAX_OUTBOUND_CONNECTIONS; + + if (hSocket != INVALID_SOCKET) + if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr)) + LogPrintf("Warning: Unknown socket family\n"); + + bool whitelisted = hListenSocket.whitelisted || CNode::IsWhitelistedRange(addr); + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + if (pnode->fInbound) + nInbound++; + } + + if (hSocket == INVALID_SOCKET) + { + int nErr = WSAGetLastError(); + if (nErr != WSAEWOULDBLOCK) + LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr)); + return; + } + + if (!IsSelectableSocket(hSocket)) + { + LogPrintf("connection from %s dropped: non-selectable socket\n", addr.ToString()); + CloseSocket(hSocket); + return; + } + + if (CNode::IsBanned(addr) && !whitelisted) + { + LogPrintf("connection from %s dropped (banned)\n", addr.ToString()); + CloseSocket(hSocket); + return; + } + + if (nInbound >= nMaxInbound) + { + if (!AttemptToEvictConnection(whitelisted)) { + // No connection to evict, disconnect the new connection + LogPrint("net", "failed to find an eviction candidate - connection dropped (full)\n"); + CloseSocket(hSocket); + return; + } + } + + CNode* pnode = new CNode(hSocket, addr, "", true); + pnode->AddRef(); + pnode->fWhitelisted = whitelisted; + + LogPrint("net", "connection from %s accepted\n", addr.ToString()); + + { + LOCK(cs_vNodes); + vNodes.push_back(pnode); + } +} + void ThreadSocketHandler() { unsigned int nPrevNodeCount = 0; @@ -932,64 +1149,7 @@ void ThreadSocketHandler() { if (hListenSocket.socket != INVALID_SOCKET && FD_ISSET(hListenSocket.socket, &fdsetRecv)) { - struct sockaddr_storage sockaddr; - socklen_t len = sizeof(sockaddr); - SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len); - CAddress addr; - int nInbound = 0; - int nMaxInbound = nMaxConnections - MAX_OUTBOUND_CONNECTIONS; - - if (hSocket != INVALID_SOCKET) - if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr)) - LogPrintf("Warning: Unknown socket family\n"); - - bool whitelisted = hListenSocket.whitelisted || CNode::IsWhitelistedRange(addr); - { - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) - if (pnode->fInbound) - nInbound++; - } - - if (hSocket == INVALID_SOCKET) - { - int nErr = WSAGetLastError(); - if (nErr != WSAEWOULDBLOCK) - LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr)); - } - else if (!IsSelectableSocket(hSocket)) - { - LogPrintf("connection from %s dropped: non-selectable socket\n", addr.ToString()); - CloseSocket(hSocket); - } - else if (nInbound >= nMaxInbound) - { - LogPrint("net", "connection from %s dropped (full)\n", addr.ToString()); - CloseSocket(hSocket); - } - else if (!whitelisted && (nInbound >= (nMaxInbound - nWhiteConnections))) - { - LogPrint("net", "connection from %s dropped (non-whitelisted)\n", addr.ToString()); - CloseSocket(hSocket); - } - else if (CNode::IsBanned(addr) && !whitelisted) - { - LogPrintf("connection from %s dropped (banned)\n", addr.ToString()); - CloseSocket(hSocket); - } - else - { - CNode* pnode = new CNode(hSocket, addr, "", true); - pnode->AddRef(); - pnode->fWhitelisted = whitelisted; - - LogPrint("net", "connection from %s accepted\n", addr.ToString()); - - { - LOCK(cs_vNodes); - vNodes.push_back(pnode); - } - } + AcceptConnection(hListenSocket); } } @@ -1119,10 +1279,14 @@ void ThreadMapPort() #ifndef UPNPDISCOVER_SUCCESS /* miniupnpc 1.5 */ devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0); -#else +#elif MINIUPNPC_API_VERSION < 14 /* miniupnpc 1.6 */ int error = 0; devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error); +#else + /* miniupnpc 1.9.20150730 */ + int error = 0; + devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error); #endif struct UPNPUrls urls; @@ -1624,8 +1788,10 @@ bool BindListenPort(const CService &addrBind, string& strError, bool fWhiteliste setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int)); #endif // Allow binding if the port is still in TIME_WAIT state after - // the program was closed and restarted. Not an issue on windows! + // the program was closed and restarted. setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int)); +#else + setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&nOne, sizeof(int)); #endif // Set to non-blocking, incoming connections will also inherit this @@ -2060,7 +2226,7 @@ unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); } CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), - addrKnown(5000, 0.001, insecure_rand()), + addrKnown(5000, 0.001), setInventoryKnown(SendBufferSize() / 1000) { nServices = 0; @@ -2095,6 +2261,7 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa nPingUsecStart = 0; nPingUsecTime = 0; fPingQueued = false; + nMinPingUsecTime = std::numeric_limits<int64_t>::max(); { LOCK(cs_nLastNodeId); @@ -2318,7 +2485,7 @@ void DumpBanlist() { int64_t nStart = GetTimeMillis(); - CNode::SweepBanned(); //clean unused entires (if bantime has expired) + CNode::SweepBanned(); //clean unused entries (if bantime has expired) CBanDB bandb; banmap_t banmap; @@ -46,6 +46,8 @@ static const unsigned int MAX_INV_SZ = 50000; static const unsigned int MAX_ADDR_TO_SEND = 1000; /** Maximum length of incoming protocol messages (no message over 2 MiB is currently acceptable). */ static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 2 * 1024 * 1024; +/** Maximum length of strSubVer in `version` message */ +static const unsigned int MAX_SUBVERSION_LENGTH = 256; /** -listen default */ static const bool DEFAULT_LISTEN = true; /** -upnp default */ @@ -56,6 +58,8 @@ static const bool DEFAULT_UPNP = false; #endif /** The maximum number of entries in mapAskFor */ static const size_t MAPASKFOR_MAX_SZ = MAX_INV_SZ; +/** The maximum number of peer connections to maintain. */ +static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125; unsigned int ReceiveFloodSize(); unsigned int SendBufferSize(); @@ -139,19 +143,8 @@ extern uint64_t nLocalServices; extern uint64_t nLocalHostNonce; extern CAddrMan addrman; -// The allocation of connections against the maximum allowed (nMaxConnections) -// is prioritized as follows: -// 1st: Outbound connections (MAX_OUTBOUND_CONNECTIONS) -// 2nd: Inbound connections from whitelisted peers (nWhiteConnections) -// 3rd: Inbound connections from non-whitelisted peers -// Thus, the number of connection slots for the general public to use is: -// nMaxConnections - (MAX_OUTBOUND_CONNECTIONS + nWhiteConnections) -// Any additional inbound connections beyond limits will be immediately closed - /** Maximum number of connections to simultaneously allow (aka connection slots) */ extern int nMaxConnections; -/** Number of connection slots to reserve for inbound from whitelisted peers */ -extern int nWhiteConnections; extern std::vector<CNode*> vNodes; extern CCriticalSection cs_vNodes; @@ -166,6 +159,9 @@ extern CCriticalSection cs_vAddedNodes; extern NodeId nLastNodeId; extern CCriticalSection cs_nLastNodeId; +/** Subversion as sent to the P2P network in `version` messages */ +extern std::string strSubVersion; + struct LocalServiceInfo { int nScore; int nPort; @@ -193,6 +189,7 @@ public: bool fWhitelisted; double dPingTime; double dPingWait; + double dPingMin; std::string addrLocal; }; @@ -388,6 +385,8 @@ public: int64_t nPingUsecStart; // Last measured round-trip time. int64_t nPingUsecTime; + // Best measured round-trip time. + int64_t nMinPingUsecTime; // Whether a ping is requested. bool fPingQueued; @@ -688,7 +687,7 @@ public: static bool BannedSetIsDirty(); //!set the "dirty" flag for the banlist static void SetBannedSetDirty(bool dirty=true); - //!clean unused entires (if bantime has expired) + //!clean unused entries (if bantime has expired) static void SweepBanned(); void copyStats(CNodeStats &stats); diff --git a/src/netbase.cpp b/src/netbase.cpp index b7e2e57917..c3d56d9184 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -349,7 +349,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials } if (pchRetA[0] != 0x01 || pchRetA[1] != 0x00) { CloseSocket(hSocket); - return error("Proxy authentication unsuccesful"); + return error("Proxy authentication unsuccessful"); } } else if (pchRet1[1] == 0x00) { // Perform no authentication @@ -983,7 +983,7 @@ std::vector<unsigned char> CNetAddr::GetGroup() const nBits -= 8; } if (nBits > 0) - vchRet.push_back(GetByte(15 - nStartByte) | ((1 << nBits) - 1)); + vchRet.push_back(GetByte(15 - nStartByte) | ((1 << (8 - nBits)) - 1)); return vchRet; } @@ -1311,17 +1311,57 @@ bool CSubNet::Match(const CNetAddr &addr) const return true; } +static inline int NetmaskBits(uint8_t x) +{ + switch(x) { + case 0x00: return 0; break; + case 0x80: return 1; break; + case 0xc0: return 2; break; + case 0xe0: return 3; break; + case 0xf0: return 4; break; + case 0xf8: return 5; break; + case 0xfc: return 6; break; + case 0xfe: return 7; break; + case 0xff: return 8; break; + default: return -1; break; + } +} + std::string CSubNet::ToString() const { + /* Parse binary 1{n}0{N-n} to see if mask can be represented as /n */ + int cidr = 0; + bool valid_cidr = true; + int n = network.IsIPv4() ? 12 : 0; + for (; n < 16 && netmask[n] == 0xff; ++n) + cidr += 8; + if (n < 16) { + int bits = NetmaskBits(netmask[n]); + if (bits < 0) + valid_cidr = false; + else + cidr += bits; + ++n; + } + for (; n < 16 && valid_cidr; ++n) + if (netmask[n] != 0x00) + valid_cidr = false; + + /* Format output */ std::string strNetmask; - if (network.IsIPv4()) - strNetmask = strprintf("%u.%u.%u.%u", netmask[12], netmask[13], netmask[14], netmask[15]); - else - strNetmask = strprintf("%x:%x:%x:%x:%x:%x:%x:%x", - netmask[0] << 8 | netmask[1], netmask[2] << 8 | netmask[3], - netmask[4] << 8 | netmask[5], netmask[6] << 8 | netmask[7], - netmask[8] << 8 | netmask[9], netmask[10] << 8 | netmask[11], - netmask[12] << 8 | netmask[13], netmask[14] << 8 | netmask[15]); + if (valid_cidr) { + strNetmask = strprintf("%u", cidr); + } else { + if (network.IsIPv4()) + strNetmask = strprintf("%u.%u.%u.%u", netmask[12], netmask[13], netmask[14], netmask[15]); + else + strNetmask = strprintf("%x:%x:%x:%x:%x:%x:%x:%x", + netmask[0] << 8 | netmask[1], netmask[2] << 8 | netmask[3], + netmask[4] << 8 | netmask[5], netmask[6] << 8 | netmask[7], + netmask[8] << 8 | netmask[9], netmask[10] << 8 | netmask[11], + netmask[12] << 8 | netmask[13], netmask[14] << 8 | netmask[15]); + } + return network.ToString() + "/" + strNetmask; } diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index b1491cec01..ffe31d1942 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -249,7 +249,7 @@ unsigned int TxConfirmStats::NewTx(unsigned int nBlockHeight, double val) unsigned int bucketindex = bucketMap.lower_bound(val)->second; unsigned int blockIndex = nBlockHeight % unconfTxs.size(); unconfTxs[blockIndex][bucketindex]++; - LogPrint("estimatefee", "adding to %s\n", dataTypeString); + LogPrint("estimatefee", "adding to %s", dataTypeString); return bucketindex; } @@ -261,7 +261,7 @@ void TxConfirmStats::removeTx(unsigned int entryHeight, unsigned int nBestSeenHe blocksAgo = 0; if (blocksAgo < 0) { LogPrint("estimatefee", "Blockpolicy error, blocks ago is negative for mempool tx\n"); - return; //This can't happen becasue we call this with our best seen height, no entries can have higher + return; //This can't happen because we call this with our best seen height, no entries can have higher } if (blocksAgo >= (int)unconfTxs.size()) { @@ -390,8 +390,9 @@ void CBlockPolicyEstimator::processTransaction(const CTxMemPoolEntry& entry, boo mapMemPoolTxs[hash].bucketIndex = feeStats.NewTx(txHeight, (double)feeRate.GetFeePerK()); } else { - LogPrint("estimatefee", "not adding\n"); + LogPrint("estimatefee", "not adding"); } + LogPrint("estimatefee", "\n"); } void CBlockPolicyEstimator::processBlockTx(unsigned int nBlockHeight, const CTxMemPoolEntry& entry) diff --git a/src/policy/fees.h b/src/policy/fees.h index ce4d782566..15577d128a 100644 --- a/src/policy/fees.h +++ b/src/policy/fees.h @@ -118,7 +118,7 @@ public: /** * Initialize the data structures. This is called by BlockPolicyEstimator's * constructor with default values. - * @param defaultBuckets contains the upper limits for the bucket boundries + * @param defaultBuckets contains the upper limits for the bucket boundaries * @param maxConfirms max number of confirms to track * @param decay how much to decay the historical moving average per block * @param dataTypeString for logging purposes diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index 5b9c13d870..7a58074d24 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -15,7 +15,7 @@ uint256 CBlockHeader::GetHash() const return SerializeHash(*this); } -uint256 CBlock::BuildMerkleTree(bool* fMutated) const +uint256 CBlock::ComputeMerkleRoot(bool* fMutated) const { /* WARNING! If you're reading this because you're learning about crypto and/or designing a new system that will use merkle trees, keep in mind @@ -52,7 +52,7 @@ uint256 CBlock::BuildMerkleTree(bool* fMutated) const known ways of changing the transactions without affecting the merkle root. */ - vMerkleTree.clear(); + std::vector<uint256> vMerkleTree; vMerkleTree.reserve(vtx.size() * 2 + 16); // Safe upper bound for the number of total nodes. for (std::vector<CTransaction>::const_iterator it(vtx.begin()); it != vtx.end(); ++it) vMerkleTree.push_back(it->GetHash()); @@ -78,37 +78,6 @@ uint256 CBlock::BuildMerkleTree(bool* fMutated) const return (vMerkleTree.empty() ? uint256() : vMerkleTree.back()); } -std::vector<uint256> CBlock::GetMerkleBranch(int nIndex) const -{ - if (vMerkleTree.empty()) - BuildMerkleTree(); - std::vector<uint256> vMerkleBranch; - int j = 0; - for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) - { - int i = std::min(nIndex^1, nSize-1); - vMerkleBranch.push_back(vMerkleTree[j+i]); - nIndex >>= 1; - j += nSize; - } - return vMerkleBranch; -} - -uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex) -{ - if (nIndex == -1) - return uint256(); - for (std::vector<uint256>::const_iterator it(vMerkleBranch.begin()); it != vMerkleBranch.end(); ++it) - { - if (nIndex & 1) - hash = Hash(BEGIN(*it), END(*it), BEGIN(hash), END(hash)); - else - hash = Hash(BEGIN(hash), END(hash), BEGIN(*it), END(*it)); - nIndex >>= 1; - } - return hash; -} - std::string CBlock::ToString() const { std::stringstream s; @@ -123,9 +92,5 @@ std::string CBlock::ToString() const { s << " " << vtx[i].ToString() << "\n"; } - s << " vMerkleTree: "; - for (unsigned int i = 0; i < vMerkleTree.size(); i++) - s << " " << vMerkleTree[i].ToString(); - s << "\n"; return s.str(); } diff --git a/src/primitives/block.h b/src/primitives/block.h index 59f46deb1c..86106098f5 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -78,7 +78,7 @@ public: std::vector<CTransaction> vtx; // memory only - mutable std::vector<uint256> vMerkleTree; + mutable bool fChecked; CBlock() { @@ -103,7 +103,7 @@ public: { CBlockHeader::SetNull(); vtx.clear(); - vMerkleTree.clear(); + fChecked = false; } CBlockHeader GetBlockHeader() const @@ -118,14 +118,12 @@ public: return block; } - // Build the in-memory merkle tree for this block and return the merkle root. + // Build the merkle tree for this block and return the merkle root. // If non-NULL, *mutated is set to whether mutation was detected in the merkle // tree (a duplication of transactions in the block leading to an identical // merkle root). - uint256 BuildMerkleTree(bool* mutated = NULL) const; + uint256 ComputeMerkleRoot(bool* mutated = NULL) const; - std::vector<uint256> GetMerkleBranch(int nIndex) const; - static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex); std::string ToString() const; }; diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 606dbea798..46d3cbbe2e 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -36,7 +36,7 @@ std::string CTxIn::ToString() const if (prevout.IsNull()) str += strprintf(", coinbase %s", HexStr(scriptSig)); else - str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24)); + str += strprintf(", scriptSig=%s", HexStr(scriptSig).substr(0, 24)); if (nSequence != std::numeric_limits<unsigned int>::max()) str += strprintf(", nSequence=%u", nSequence); str += ")"; @@ -56,7 +56,7 @@ uint256 CTxOut::GetHash() const std::string CTxOut::ToString() const { - return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30)); + return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, HexStr(scriptPubKey).substr(0, 30)); } CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {} diff --git a/src/protocol.h b/src/protocol.h index b5e65032a2..50aeaf44ba 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -75,6 +75,10 @@ enum { // Bitcoin Core does not support this but a patch set called Bitcoin XT does. // See BIP 64 for details on how this is implemented. NODE_GETUTXO = (1 << 1), + // NODE_BLOOM means the node is capable and willing to handle bloom-filtered connections. + // Bitcoin Core nodes used to support this by default, without advertising this bit, + // but no longer do as of protocol version 70011 (= NO_BLOOM_VERSION) + NODE_BLOOM = (1 << 2), // Bits 24-31 are reserved for temporary experiments. Just pick a bit that // isn't getting used, or one not being used much, and notify the diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index af6801919c..8bd1586446 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -14,14 +14,14 @@ #include "csvmodelwriter.h" #include "editaddressdialog.h" #include "guiutil.h" -#include "scicon.h" +#include "platformstyle.h" #include <QIcon> #include <QMenu> #include <QMessageBox> #include <QSortFilterProxyModel> -AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : +AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode mode, Tabs tab, QWidget *parent) : QDialog(parent), ui(new Ui::AddressBookPage), model(0), @@ -30,17 +30,17 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : { ui->setupUi(this); -#ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac - ui->newAddress->setIcon(QIcon()); - ui->copyAddress->setIcon(QIcon()); - ui->deleteAddress->setIcon(QIcon()); - ui->exportButton->setIcon(QIcon()); -#else - ui->newAddress->setIcon(SingleColorIcon(":/icons/add")); - ui->copyAddress->setIcon(SingleColorIcon(":/icons/editcopy")); - ui->deleteAddress->setIcon(SingleColorIcon(":/icons/remove")); - ui->exportButton->setIcon(SingleColorIcon(":/icons/export")); -#endif + if (!platformStyle->getImagesOnButtons()) { + ui->newAddress->setIcon(QIcon()); + ui->copyAddress->setIcon(QIcon()); + ui->deleteAddress->setIcon(QIcon()); + ui->exportButton->setIcon(QIcon()); + } else { + ui->newAddress->setIcon(platformStyle->SingleColorIcon(":/icons/add")); + ui->copyAddress->setIcon(platformStyle->SingleColorIcon(":/icons/editcopy")); + ui->deleteAddress->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); + ui->exportButton->setIcon(platformStyle->SingleColorIcon(":/icons/export")); + } switch(mode) { diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h index 09634ce336..92e6cab9ac 100644 --- a/src/qt/addressbookpage.h +++ b/src/qt/addressbookpage.h @@ -9,6 +9,7 @@ class AddressTableModel; class OptionsModel; +class PlatformStyle; namespace Ui { class AddressBookPage; @@ -39,7 +40,7 @@ public: ForEditing /**< Open address book for editing */ }; - explicit AddressBookPage(Mode mode, Tabs tab, QWidget *parent); + explicit AddressBookPage(const PlatformStyle *platformStyle, Mode mode, Tabs tab, QWidget *parent); ~AddressBookPage(); void setModel(AddressTableModel *model); diff --git a/src/qt/bantablemodel.cpp b/src/qt/bantablemodel.cpp new file mode 100644 index 0000000000..33792af5ba --- /dev/null +++ b/src/qt/bantablemodel.cpp @@ -0,0 +1,181 @@ +// Copyright (c) 2011-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "bantablemodel.h" + +#include "clientmodel.h" +#include "guiconstants.h" +#include "guiutil.h" + +#include "sync.h" +#include "utiltime.h" + +#include <QDebug> +#include <QList> + +bool BannedNodeLessThan::operator()(const CCombinedBan& left, const CCombinedBan& right) const +{ + const CCombinedBan* pLeft = &left; + const CCombinedBan* pRight = &right; + + if (order == Qt::DescendingOrder) + std::swap(pLeft, pRight); + + switch(column) + { + case BanTableModel::Address: + return pLeft->subnet.ToString().compare(pRight->subnet.ToString()) < 0; + case BanTableModel::Bantime: + return pLeft->banEntry.nBanUntil < pRight->banEntry.nBanUntil; + } + + return false; +} + +// private implementation +class BanTablePriv +{ +public: + /** Local cache of peer information */ + QList<CCombinedBan> cachedBanlist; + /** Column to sort nodes by */ + int sortColumn; + /** Order (ascending or descending) to sort nodes by */ + Qt::SortOrder sortOrder; + + /** Pull a full list of banned nodes from CNode into our cache */ + void refreshBanlist() + { + banmap_t banMap; + CNode::GetBanned(banMap); + + cachedBanlist.clear(); +#if QT_VERSION >= 0x040700 + cachedBanlist.reserve(banMap.size()); +#endif + for (banmap_t::iterator it = banMap.begin(); it != banMap.end(); it++) + { + CCombinedBan banEntry; + banEntry.subnet = (*it).first; + banEntry.banEntry = (*it).second; + cachedBanlist.append(banEntry); + } + + if (sortColumn >= 0) + // sort cachedBanlist (use stable sort to prevent rows jumping around unneceesarily) + qStableSort(cachedBanlist.begin(), cachedBanlist.end(), BannedNodeLessThan(sortColumn, sortOrder)); + } + + int size() const + { + return cachedBanlist.size(); + } + + CCombinedBan *index(int idx) + { + if (idx >= 0 && idx < cachedBanlist.size()) + return &cachedBanlist[idx]; + + return 0; + } +}; + +BanTableModel::BanTableModel(ClientModel *parent) : + QAbstractTableModel(parent), + clientModel(parent) +{ + columns << tr("IP/Netmask") << tr("Banned Until"); + priv = new BanTablePriv(); + // default to unsorted + priv->sortColumn = -1; + + // load initial data + refresh(); +} + +int BanTableModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return priv->size(); +} + +int BanTableModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return columns.length();; +} + +QVariant BanTableModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + return QVariant(); + + CCombinedBan *rec = static_cast<CCombinedBan*>(index.internalPointer()); + + if (role == Qt::DisplayRole) { + switch(index.column()) + { + case Address: + return QString::fromStdString(rec->subnet.ToString()); + case Bantime: + QDateTime date = QDateTime::fromMSecsSinceEpoch(0); + date = date.addSecs(rec->banEntry.nBanUntil); + return date.toString(Qt::SystemLocaleLongDate); + } + } + + return QVariant(); +} + +QVariant BanTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(orientation == Qt::Horizontal) + { + if(role == Qt::DisplayRole && section < columns.size()) + { + return columns[section]; + } + } + return QVariant(); +} + +Qt::ItemFlags BanTableModel::flags(const QModelIndex &index) const +{ + if(!index.isValid()) + return 0; + + Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled; + return retval; +} + +QModelIndex BanTableModel::index(int row, int column, const QModelIndex &parent) const +{ + Q_UNUSED(parent); + CCombinedBan *data = priv->index(row); + + if (data) + return createIndex(row, column, data); + return QModelIndex(); +} + +void BanTableModel::refresh() +{ + Q_EMIT layoutAboutToBeChanged(); + priv->refreshBanlist(); + Q_EMIT layoutChanged(); +} + +void BanTableModel::sort(int column, Qt::SortOrder order) +{ + priv->sortColumn = column; + priv->sortOrder = order; + refresh(); +} + +bool BanTableModel::shouldShow() +{ + if (priv->size() > 0) + return true; + return false; +}
\ No newline at end of file diff --git a/src/qt/bantablemodel.h b/src/qt/bantablemodel.h new file mode 100644 index 0000000000..c21dd04e31 --- /dev/null +++ b/src/qt/bantablemodel.h @@ -0,0 +1,72 @@ +// Copyright (c) 2011-2013 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_QT_BANTABLEMODEL_H +#define BITCOIN_QT_BANTABLEMODEL_H + +#include "net.h" + +#include <QAbstractTableModel> +#include <QStringList> + +class ClientModel; +class BanTablePriv; + +struct CCombinedBan { + CSubNet subnet; + CBanEntry banEntry; +}; + +class BannedNodeLessThan +{ +public: + BannedNodeLessThan(int nColumn, Qt::SortOrder fOrder) : + column(nColumn), order(fOrder) {} + bool operator()(const CCombinedBan& left, const CCombinedBan& right) const; + +private: + int column; + Qt::SortOrder order; +}; + +/** + Qt model providing information about connected peers, similar to the + "getpeerinfo" RPC call. Used by the rpc console UI. + */ +class BanTableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit BanTableModel(ClientModel *parent = 0); + void startAutoRefresh(); + void stopAutoRefresh(); + + enum ColumnIndex { + Address = 0, + Bantime = 1 + }; + + /** @name Methods overridden from QAbstractTableModel + @{*/ + int rowCount(const QModelIndex &parent) const; + int columnCount(const QModelIndex &parent) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + QModelIndex index(int row, int column, const QModelIndex &parent) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + void sort(int column, Qt::SortOrder order); + bool shouldShow(); + /*@}*/ + +public Q_SLOTS: + void refresh(); + +private: + ClientModel *clientModel; + QStringList columns; + BanTablePriv *priv; +}; + +#endif // BITCOIN_QT_BANTABLEMODEL_H diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index b8aec0c268..ea7f86d18e 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -15,6 +15,7 @@ #include "intro.h" #include "networkstyle.h" #include "optionsmodel.h" +#include "platformstyle.h" #include "splashscreen.h" #include "utilitydialog.h" #include "winshutdownmonitor.h" @@ -241,6 +242,7 @@ private: WalletModel *walletModel; #endif int returnValue; + const PlatformStyle *platformStyle; void startThread(); }; @@ -264,13 +266,6 @@ void BitcoinCore::initialize() { qDebug() << __func__ << ": Running AppInit2 in thread"; int rv = AppInit2(threadGroup, scheduler); - if(rv) - { - /* Start a dummy RPC thread if no RPC thread is active yet - * to handle timeouts. - */ - StartDummyRPCThread(); - } Q_EMIT initializeResult(rv); } catch (const std::exception& e) { handleRunawayException(&e); @@ -284,7 +279,7 @@ void BitcoinCore::shutdown() try { qDebug() << __func__ << ": Running Shutdown in thread"; - threadGroup.interrupt_all(); + Interrupt(threadGroup); threadGroup.join_all(); Shutdown(); qDebug() << __func__ << ": Shutdown finished"; @@ -310,6 +305,22 @@ BitcoinApplication::BitcoinApplication(int &argc, char **argv): returnValue(0) { setQuitOnLastWindowClosed(false); + + // UI per-platform customization + // This must be done inside the BitcoinApplication constructor, or after it, because + // PlatformStyle::instantiate requires a QApplication +#if defined(Q_OS_MAC) + std::string platformName = "macosx"; +#elif defined(Q_OS_WIN) + std::string platformName = "windows"; +#else + std::string platformName = "other"; +#endif + platformName = GetArg("-uiplatform", platformName); + platformStyle = PlatformStyle::instantiate(QString::fromStdString(platformName)); + if (!platformStyle) // Fall back to "other" if specified name not found + platformStyle = PlatformStyle::instantiate("other"); + assert(platformStyle); } BitcoinApplication::~BitcoinApplication() @@ -330,6 +341,8 @@ BitcoinApplication::~BitcoinApplication() #endif delete optionsModel; optionsModel = 0; + delete platformStyle; + platformStyle = 0; } #ifdef ENABLE_WALLET @@ -346,7 +359,7 @@ void BitcoinApplication::createOptionsModel() void BitcoinApplication::createWindow(const NetworkStyle *networkStyle) { - window = new BitcoinGUI(networkStyle, 0); + window = new BitcoinGUI(platformStyle, networkStyle, 0); pollShutdownTimer = new QTimer(window); connect(pollShutdownTimer, SIGNAL(timeout()), window, SLOT(detectShutdown())); @@ -421,6 +434,8 @@ void BitcoinApplication::initializeResult(int retval) returnValue = retval ? 0 : 1; if(retval) { + // Log this only after AppInit2 finishes, as then logging setup is guaranteed complete + qWarning() << "Platform customization:" << platformStyle->getName(); #ifdef ENABLE_WALLET PaymentServer::LoadRootCAs(); paymentServer->setOptionsModel(optionsModel); @@ -432,7 +447,7 @@ void BitcoinApplication::initializeResult(int retval) #ifdef ENABLE_WALLET if(pwalletMain) { - walletModel = new WalletModel(pwalletMain, optionsModel); + walletModel = new WalletModel(platformStyle, pwalletMain, optionsModel); window->addWallet(BitcoinGUI::DEFAULT_WALLET, walletModel); window->setCurrentWallet(BitcoinGUI::DEFAULT_WALLET); diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 396435f12b..d930d15953 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -13,8 +13,8 @@ #include "openuridialog.h" #include "optionsdialog.h" #include "optionsmodel.h" +#include "platformstyle.h" #include "rpcconsole.h" -#include "scicon.h" #include "utilitydialog.h" #ifdef ENABLE_WALLET @@ -60,7 +60,7 @@ const QString BitcoinGUI::DEFAULT_WALLET = "~Default"; -BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) : +BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent) : QMainWindow(parent), clientModel(0), walletFrame(0), @@ -97,8 +97,10 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) : trayIconMenu(0), notificator(0), rpcConsole(0), + helpMessageDialog(0), prevBlocks(0), - spinnerFrame(0) + spinnerFrame(0), + platformStyle(platformStyle) { GUIUtil::restoreWindowGeometry("nWindow", QSize(850, 550), this); @@ -130,12 +132,13 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) : setUnifiedTitleAndToolBarOnMac(true); #endif - rpcConsole = new RPCConsole(0); + rpcConsole = new RPCConsole(platformStyle, 0); + helpMessageDialog = new HelpMessageDialog(this, false); #ifdef ENABLE_WALLET if(enableWallet) { /** Create wallet frame and make it the central widget */ - walletFrame = new WalletFrame(this); + walletFrame = new WalletFrame(platformStyle, this); setCentralWidget(walletFrame); } else #endif // ENABLE_WALLET @@ -175,7 +178,7 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) : QHBoxLayout *frameBlocksLayout = new QHBoxLayout(frameBlocks); frameBlocksLayout->setContentsMargins(3,0,3,0); frameBlocksLayout->setSpacing(3); - unitDisplayControl = new UnitDisplayStatusBarControl(); + unitDisplayControl = new UnitDisplayStatusBarControl(platformStyle); labelEncryptionIcon = new QLabel(); labelConnectionsIcon = new QLabel(); labelBlocksIcon = new QLabel(); @@ -212,11 +215,6 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) : statusBar()->addWidget(progressBar); statusBar()->addPermanentWidget(frameBlocks); - connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show())); - - // prevents an open debug window from becoming stuck/unusable on client shutdown - connect(quitAction, SIGNAL(triggered()), rpcConsole, SLOT(hide())); - // Install event filter to be able to catch status tip events (QEvent::StatusTip) this->installEventFilter(this); @@ -247,36 +245,36 @@ void BitcoinGUI::createActions() { QActionGroup *tabGroup = new QActionGroup(this); - overviewAction = new QAction(SingleColorIcon(":/icons/overview"), tr("&Overview"), this); + overviewAction = new QAction(platformStyle->SingleColorIcon(":/icons/overview"), tr("&Overview"), this); overviewAction->setStatusTip(tr("Show general overview of wallet")); overviewAction->setToolTip(overviewAction->statusTip()); overviewAction->setCheckable(true); overviewAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_1)); tabGroup->addAction(overviewAction); - sendCoinsAction = new QAction(SingleColorIcon(":/icons/send"), tr("&Send"), this); + sendCoinsAction = new QAction(platformStyle->SingleColorIcon(":/icons/send"), tr("&Send"), this); sendCoinsAction->setStatusTip(tr("Send coins to a Bitcoin address")); sendCoinsAction->setToolTip(sendCoinsAction->statusTip()); sendCoinsAction->setCheckable(true); sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2)); tabGroup->addAction(sendCoinsAction); - sendCoinsMenuAction = new QAction(TextColorIcon(":/icons/send"), sendCoinsAction->text(), this); + sendCoinsMenuAction = new QAction(platformStyle->TextColorIcon(":/icons/send"), sendCoinsAction->text(), this); sendCoinsMenuAction->setStatusTip(sendCoinsAction->statusTip()); sendCoinsMenuAction->setToolTip(sendCoinsMenuAction->statusTip()); - receiveCoinsAction = new QAction(SingleColorIcon(":/icons/receiving_addresses"), tr("&Receive"), this); + receiveCoinsAction = new QAction(platformStyle->SingleColorIcon(":/icons/receiving_addresses"), tr("&Receive"), this); receiveCoinsAction->setStatusTip(tr("Request payments (generates QR codes and bitcoin: URIs)")); receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip()); receiveCoinsAction->setCheckable(true); receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3)); tabGroup->addAction(receiveCoinsAction); - receiveCoinsMenuAction = new QAction(TextColorIcon(":/icons/receiving_addresses"), receiveCoinsAction->text(), this); + receiveCoinsMenuAction = new QAction(platformStyle->TextColorIcon(":/icons/receiving_addresses"), receiveCoinsAction->text(), this); receiveCoinsMenuAction->setStatusTip(receiveCoinsAction->statusTip()); receiveCoinsMenuAction->setToolTip(receiveCoinsMenuAction->statusTip()); - historyAction = new QAction(SingleColorIcon(":/icons/history"), tr("&Transactions"), this); + historyAction = new QAction(platformStyle->SingleColorIcon(":/icons/history"), tr("&Transactions"), this); historyAction->setStatusTip(tr("Browse transaction history")); historyAction->setToolTip(historyAction->statusTip()); historyAction->setCheckable(true); @@ -300,46 +298,46 @@ void BitcoinGUI::createActions() connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage())); #endif // ENABLE_WALLET - quitAction = new QAction(TextColorIcon(":/icons/quit"), tr("E&xit"), this); + quitAction = new QAction(platformStyle->TextColorIcon(":/icons/quit"), tr("E&xit"), this); quitAction->setStatusTip(tr("Quit application")); quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q)); quitAction->setMenuRole(QAction::QuitRole); - aboutAction = new QAction(TextColorIcon(":/icons/about"), tr("&About Bitcoin Core"), this); + aboutAction = new QAction(platformStyle->TextColorIcon(":/icons/about"), tr("&About Bitcoin Core"), this); aboutAction->setStatusTip(tr("Show information about Bitcoin Core")); aboutAction->setMenuRole(QAction::AboutRole); - aboutQtAction = new QAction(TextColorIcon(":/icons/about_qt"), tr("About &Qt"), this); + aboutQtAction = new QAction(platformStyle->TextColorIcon(":/icons/about_qt"), tr("About &Qt"), this); aboutQtAction->setStatusTip(tr("Show information about Qt")); aboutQtAction->setMenuRole(QAction::AboutQtRole); - optionsAction = new QAction(TextColorIcon(":/icons/options"), tr("&Options..."), this); + optionsAction = new QAction(platformStyle->TextColorIcon(":/icons/options"), tr("&Options..."), this); optionsAction->setStatusTip(tr("Modify configuration options for Bitcoin Core")); optionsAction->setMenuRole(QAction::PreferencesRole); - toggleHideAction = new QAction(TextColorIcon(":/icons/about"), tr("&Show / Hide"), this); + toggleHideAction = new QAction(platformStyle->TextColorIcon(":/icons/about"), tr("&Show / Hide"), this); toggleHideAction->setStatusTip(tr("Show or hide the main Window")); - encryptWalletAction = new QAction(TextColorIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this); + encryptWalletAction = new QAction(platformStyle->TextColorIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this); encryptWalletAction->setStatusTip(tr("Encrypt the private keys that belong to your wallet")); encryptWalletAction->setCheckable(true); - backupWalletAction = new QAction(TextColorIcon(":/icons/filesave"), tr("&Backup Wallet..."), this); + backupWalletAction = new QAction(platformStyle->TextColorIcon(":/icons/filesave"), tr("&Backup Wallet..."), this); backupWalletAction->setStatusTip(tr("Backup wallet to another location")); - changePassphraseAction = new QAction(TextColorIcon(":/icons/key"), tr("&Change Passphrase..."), this); + changePassphraseAction = new QAction(platformStyle->TextColorIcon(":/icons/key"), tr("&Change Passphrase..."), this); changePassphraseAction->setStatusTip(tr("Change the passphrase used for wallet encryption")); - signMessageAction = new QAction(TextColorIcon(":/icons/edit"), tr("Sign &message..."), this); + signMessageAction = new QAction(platformStyle->TextColorIcon(":/icons/edit"), tr("Sign &message..."), this); signMessageAction->setStatusTip(tr("Sign messages with your Bitcoin addresses to prove you own them")); - verifyMessageAction = new QAction(TextColorIcon(":/icons/verify"), tr("&Verify message..."), this); + verifyMessageAction = new QAction(platformStyle->TextColorIcon(":/icons/verify"), tr("&Verify message..."), this); verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Bitcoin addresses")); - openRPCConsoleAction = new QAction(TextColorIcon(":/icons/debugwindow"), tr("&Debug window"), this); + openRPCConsoleAction = new QAction(platformStyle->TextColorIcon(":/icons/debugwindow"), tr("&Debug window"), this); openRPCConsoleAction->setStatusTip(tr("Open debugging and diagnostic console")); - usedSendingAddressesAction = new QAction(TextColorIcon(":/icons/address-book"), tr("&Sending addresses..."), this); + usedSendingAddressesAction = new QAction(platformStyle->TextColorIcon(":/icons/address-book"), tr("&Sending addresses..."), this); usedSendingAddressesAction->setStatusTip(tr("Show the list of used sending addresses and labels")); - usedReceivingAddressesAction = new QAction(TextColorIcon(":/icons/address-book"), tr("&Receiving addresses..."), this); + usedReceivingAddressesAction = new QAction(platformStyle->TextColorIcon(":/icons/address-book"), tr("&Receiving addresses..."), this); usedReceivingAddressesAction->setStatusTip(tr("Show the list of used receiving addresses and labels")); - openAction = new QAction(TextColorIcon(":/icons/open"), tr("Open &URI..."), this); + openAction = new QAction(platformStyle->TextColorIcon(":/icons/open"), tr("Open &URI..."), this); openAction->setStatusTip(tr("Open a bitcoin: URI or payment request")); - showHelpMessageAction = new QAction(TextColorIcon(":/icons/info"), tr("&Command-line options"), this); + showHelpMessageAction = new QAction(platformStyle->TextColorIcon(":/icons/info"), tr("&Command-line options"), this); showHelpMessageAction->setMenuRole(QAction::NoRole); showHelpMessageAction->setStatusTip(tr("Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options")); @@ -349,6 +347,10 @@ void BitcoinGUI::createActions() connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked())); connect(toggleHideAction, SIGNAL(triggered()), this, SLOT(toggleHidden())); connect(showHelpMessageAction, SIGNAL(triggered()), this, SLOT(showHelpMessageClicked())); + connect(openRPCConsoleAction, SIGNAL(triggered()), this, SLOT(showDebugWindow())); + // prevents an open debug window from becoming stuck/unusable on client shutdown + connect(quitAction, SIGNAL(triggered()), rpcConsole, SLOT(hide())); + #ifdef ENABLE_WALLET if(walletFrame) { @@ -587,11 +589,17 @@ void BitcoinGUI::aboutClicked() dlg.exec(); } +void BitcoinGUI::showDebugWindow() +{ + rpcConsole->showNormal(); + rpcConsole->show(); + rpcConsole->raise(); + rpcConsole->activateWindow(); +} + void BitcoinGUI::showHelpMessageClicked() { - HelpMessageDialog *help = new HelpMessageDialog(this, false); - help->setAttribute(Qt::WA_DeleteOnClose); - help->show(); + helpMessageDialog->show(); } #ifdef ENABLE_WALLET @@ -650,7 +658,7 @@ void BitcoinGUI::setNumConnections(int count) case 7: case 8: case 9: icon = ":/icons/connect_3"; break; default: icon = ":/icons/connect_4"; break; } - labelConnectionsIcon->setPixmap(SingleColorIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelConnectionsIcon->setPixmap(platformStyle->SingleColorIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Bitcoin network", "", count)); } @@ -691,7 +699,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate) if(secs < 90*60) { tooltip = tr("Up to date") + QString(".<br>") + tooltip; - labelBlocksIcon->setPixmap(SingleColorIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); + labelBlocksIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); #ifdef ENABLE_WALLET if(walletFrame) @@ -737,7 +745,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate) tooltip = tr("Catching up...") + QString("<br>") + tooltip; if(count != prevBlocks) { - labelBlocksIcon->setPixmap(SingleColorIcon(QString( + labelBlocksIcon->setPixmap(platformStyle->SingleColorIcon(QString( ":/movies/spinner-%1").arg(spinnerFrame, 3, 10, QChar('0'))) .pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); spinnerFrame = (spinnerFrame + 1) % SPINNER_FRAMES; @@ -931,7 +939,7 @@ void BitcoinGUI::setEncryptionStatus(int status) break; case WalletModel::Unlocked: labelEncryptionIcon->show(); - labelEncryptionIcon->setPixmap(SingleColorIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelEncryptionIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b>")); encryptWalletAction->setChecked(true); changePassphraseAction->setEnabled(true); @@ -939,7 +947,7 @@ void BitcoinGUI::setEncryptionStatus(int status) break; case WalletModel::Locked: labelEncryptionIcon->show(); - labelEncryptionIcon->setPixmap(SingleColorIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelEncryptionIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>locked</b>")); encryptWalletAction->setChecked(true); changePassphraseAction->setEnabled(true); @@ -1041,7 +1049,7 @@ void BitcoinGUI::unsubscribeFromCoreSignals() uiInterface.ThreadSafeMessageBox.disconnect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3)); } -UnitDisplayStatusBarControl::UnitDisplayStatusBarControl() : +UnitDisplayStatusBarControl::UnitDisplayStatusBarControl(const PlatformStyle *platformStyle) : optionsModel(0), menu(0) { @@ -1056,7 +1064,7 @@ UnitDisplayStatusBarControl::UnitDisplayStatusBarControl() : } setMinimumSize(max_width, 0); setAlignment(Qt::AlignRight | Qt::AlignVCenter); - setStyleSheet(QString("QLabel { color : %1 }").arg(SingleColor().name())); + setStyleSheet(QString("QLabel { color : %1 }").arg(platformStyle->SingleColor().name())); } /** So that it responds to button clicks */ diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 4e50b1712a..717f2bd12d 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -22,11 +22,13 @@ class ClientModel; class NetworkStyle; class Notificator; class OptionsModel; +class PlatformStyle; class RPCConsole; class SendCoinsRecipient; class UnitDisplayStatusBarControl; class WalletFrame; class WalletModel; +class HelpMessageDialog; class CWallet; @@ -47,7 +49,7 @@ class BitcoinGUI : public QMainWindow public: static const QString DEFAULT_WALLET; - explicit BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent = 0); + explicit BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent = 0); ~BitcoinGUI(); /** Set the client model. @@ -112,11 +114,14 @@ private: QMenu *trayIconMenu; Notificator *notificator; RPCConsole *rpcConsole; + HelpMessageDialog *helpMessageDialog; /** Keep track of previous number of blocks, to detect progress */ int prevBlocks; int spinnerFrame; + const PlatformStyle *platformStyle; + /** Create the main UI actions. */ void createActions(); /** Create the menu bar and sub-menus. */ @@ -191,6 +196,8 @@ private Q_SLOTS: void optionsClicked(); /** Show about dialog */ void aboutClicked(); + /** Show debug window */ + void showDebugWindow(); /** Show help message dialog */ void showHelpMessageClicked(); #ifndef Q_OS_MAC @@ -215,7 +222,7 @@ class UnitDisplayStatusBarControl : public QLabel Q_OBJECT public: - explicit UnitDisplayStatusBarControl(); + explicit UnitDisplayStatusBarControl(const PlatformStyle *platformStyle); /** Lets the control know about the Options Model (and its signals) */ void setOptionsModel(OptionsModel *optionsModel); diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index b259d038f2..3cde2657cf 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -17,9 +17,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or " "a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"An error occurred while setting up the RPC address %s port %u for listening: " -"%s"), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Bind to given address and always listen on it. Use [host]:port notation for " "IPv6"), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -33,9 +30,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Cannot obtain a lock on data directory %s. Bitcoin Core is probably already " "running."), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Continuously rate-limit free transactions to <n>*1000 bytes per minute " -"(default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Create new files with system default permissions, instead of umask 077 (only " "effective with disabled wallet functionality)"), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -48,9 +42,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Distributed under the MIT software license, see the accompanying file " "COPYING or <http://www.opensource.org/licenses/mit-license.php>."), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Enter regression test mode, which uses a special chain in which blocks can " -"be solved instantly."), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Error: Listening for incoming connections failed (listen returned error %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Error: Unsupported argument -socks found. Setting SOCKS version isn't " @@ -65,42 +56,40 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Execute command when the best block changes (%s in cmd is replaced by block " "hash)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Fees (in BTC/Kb) smaller than this are considered zero fee for relaying " +"Fees (in %s/kB) smaller than this are considered zero fee for relaying " "(default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Fees (in BTC/Kb) smaller than this are considered zero fee for transaction " -"creation (default: %s)"), -QT_TRANSLATE_NOOP("bitcoin-core", "" -"Flush database activity from memory pool to disk log every <n> megabytes " -"(default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "" "How thorough the block verification of -checkblocks is (0-4, default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"If <category> is not supplied or if <category> = 1, output all debugging " +"information."), +QT_TRANSLATE_NOOP("bitcoin-core", "" "If paytxfee is not set, include enough fee so transactions begin " "confirmation on average within n blocks (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"In this mode -genproclimit controls how many blocks are generated " -"immediately."), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay " "fee of %s to prevent stuck transactions)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Log transaction priority and fee per kB when mining blocks (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Maintain a full transaction index, used by the getrawtransaction rpc call " "(default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Maximum size of data in data carrier transactions we relay and mine " "(default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Maximum total fees to use in a single wallet transaction; setting this too " -"low may abort large transactions (default: %s)"), +"Maximum total fees (in %s) to use in a single wallet transaction; setting " +"this too low may abort large transactions (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Output debugging information (default: %u, supplying <category> is optional)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Prune configured below the minimum of %d MB. Please use a higher number."), +"Please check that your computer's date and time are correct! If your clock " +"is wrong Bitcoin Core will not work properly."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Prune configured below the minimum of %d MiB. Please use a higher number."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Prune: last wallet synchronisation goes beyond pruned data. You need to -" +"reindex (download the whole blockchain again in case of pruned node)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Query for peer addresses via DNS lookup, if low on addresses (default: 1 " "unless -connect)"), @@ -108,13 +97,13 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Randomize credentials for every proxy connection. This enables Tor stream " "isolation (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Reduce storage requirements by pruning (deleting) old blocks. This mode " -"disables wallet support and is incompatible with -txindex. Warning: " -"Reverting this setting requires re-downloading the entire blockchain. " -"(default: 0 = disable pruning blocks, >%u = target size in MiB to use for " -"block files)"), +"Reduce storage requirements by pruning (deleting) old blocks. This mode is " +"incompatible with -txindex and -rescan. Warning: Reverting this setting " +"requires re-downloading the entire blockchain. (default: 0 = disable pruning " +"blocks, >%u = target size in MiB to use for block files)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Require high priority for relaying free or low-fee transactions (default: %u)"), +"Rescans are not possible in pruned mode. You will need to use -reindex which " +"will download the whole blockchain again."), QT_TRANSLATE_NOOP("bitcoin-core", "" "Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -124,6 +113,11 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Set the number of threads for coin generation if enabled (-1 = all cores, " "default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"The block database contains a block which appears to be from the future. " +"This may be due to your computer's date and time being set incorrectly. Only " +"rebuild the block database if you are sure that your computer's date and " +"time are correct"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "The transaction amount is too small to send after the fee has been deducted"), QT_TRANSLATE_NOOP("bitcoin-core", "" "This is a pre-release test build - use at your own risk - do not use for " @@ -133,34 +127,26 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software " "written by Eric Young and UPnP software written by Thomas Bernard."), QT_TRANSLATE_NOOP("bitcoin-core", "" -"To use bitcoind, or the -server option to bitcoin-qt, you must set an " -"rpcpassword in the configuration file:\n" -"%s\n" -"It is recommended you use the following random password:\n" -"rpcuser=bitcoinrpc\n" -"rpcpassword=%s\n" -"(you do not need to remember this password)\n" -"The username and password MUST NOT be the same.\n" -"If the file does not exist, create it with owner-readable-only file " -"permissions.\n" -"It is also recommended to set alertnotify so you are notified of problems;\n" -"for example: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com\n"), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Unable to bind to %s on this computer. Bitcoin Core is probably already " "running."), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Use UPnP to map the listening port (default: 1 when listening and no -proxy)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: " "%s)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"WARNING: abnormally high number of blocks generated, %d blocks received in " +"the last %d hours (%d expected)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"WARNING: check your network connection, %d blocks received in the last %d " +"hours (%d expected)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "Warning: -maxtxfee is set very high! Fees this large could be paid on a " "single transaction."), QT_TRANSLATE_NOOP("bitcoin-core", "" "Warning: -paytxfee is set very high! This is the transaction fee you will " "pay if you send a transaction."), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Warning: Please check that your computer's date and time are correct! If " -"your clock is wrong Bitcoin Core will not work properly."), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Warning: The network does not appear to fully agree! Some miners appear to " "be experiencing issues."), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -189,15 +175,12 @@ QT_TRANSLATE_NOOP("bitcoin-core", "<category> can be:"), QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands"), QT_TRANSLATE_NOOP("bitcoin-core", "Accept connections from outside (default: 1 if no -proxy or -connect)"), QT_TRANSLATE_NOOP("bitcoin-core", "Accept public REST requests (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Acceptable ciphers (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Activating best chain..."), QT_TRANSLATE_NOOP("bitcoin-core", "Add a node to connect to and attempt to keep the connection open"), QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for -addnode, -seednode and -connect"), -QT_TRANSLATE_NOOP("bitcoin-core", "Allow self signed root certificates (default: 0)"), QT_TRANSLATE_NOOP("bitcoin-core", "Always query for peer addresses via DNS lookup (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Attempt to recover private keys from a corrupt wallet.dat"), QT_TRANSLATE_NOOP("bitcoin-core", "Block creation options:"), -QT_TRANSLATE_NOOP("bitcoin-core", "Can't run with a wallet in prune mode."), QT_TRANSLATE_NOOP("bitcoin-core", "Cannot downgrade wallet"), QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -bind address: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -externalip address: '%s'"), @@ -210,12 +193,14 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Connect to a node to retrieve peer addresses, QT_TRANSLATE_NOOP("bitcoin-core", "Connection options:"), QT_TRANSLATE_NOOP("bitcoin-core", "Copyright (C) 2009-%i The Bitcoin Core Developers"), QT_TRANSLATE_NOOP("bitcoin-core", "Corrupted block database detected"), -QT_TRANSLATE_NOOP("bitcoin-core", "Could not parse -rpcbind value %s as network address"), QT_TRANSLATE_NOOP("bitcoin-core", "Debugging/Testing options:"), -QT_TRANSLATE_NOOP("bitcoin-core", "Disable safemode, override a real safe mode event (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Do not load the wallet and disable wallet RPC calls"), QT_TRANSLATE_NOOP("bitcoin-core", "Do you want to rebuild the block database now?"), QT_TRANSLATE_NOOP("bitcoin-core", "Done loading"), +QT_TRANSLATE_NOOP("bitcoin-core", "Enable publish hash block in <address>"), +QT_TRANSLATE_NOOP("bitcoin-core", "Enable publish hash transaction in <address>"), +QT_TRANSLATE_NOOP("bitcoin-core", "Enable publish raw block in <address>"), +QT_TRANSLATE_NOOP("bitcoin-core", "Enable publish raw transaction in <address>"), QT_TRANSLATE_NOOP("bitcoin-core", "Error initializing block database"), QT_TRANSLATE_NOOP("bitcoin-core", "Error initializing wallet database environment %s!"), QT_TRANSLATE_NOOP("bitcoin-core", "Error loading block database"), @@ -225,15 +210,13 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet requires new QT_TRANSLATE_NOOP("bitcoin-core", "Error opening block database"), QT_TRANSLATE_NOOP("bitcoin-core", "Error reading from database, shutting down."), QT_TRANSLATE_NOOP("bitcoin-core", "Error"), -QT_TRANSLATE_NOOP("bitcoin-core", "Error: A fatal internal error occured, see debug.log for details"), +QT_TRANSLATE_NOOP("bitcoin-core", "Error: A fatal internal error occurred, see debug.log for details"), QT_TRANSLATE_NOOP("bitcoin-core", "Error: Disk space is low!"), QT_TRANSLATE_NOOP("bitcoin-core", "Error: Unsupported argument -tor found, use -onion."), QT_TRANSLATE_NOOP("bitcoin-core", "Failed to listen on any port. Use -listen=0 if you want this."), -QT_TRANSLATE_NOOP("bitcoin-core", "Fee (in BTC/kB) to add to transactions you send (default: %s)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Force safe mode (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Fee (in %s/kB) to add to transactions you send (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "How many blocks to check at startup (default: %u, 0 = all)"), -QT_TRANSLATE_NOOP("bitcoin-core", "If <category> is not supplied, output all debugging information."), QT_TRANSLATE_NOOP("bitcoin-core", "Importing..."), QT_TRANSLATE_NOOP("bitcoin-core", "Imports blocks from external blk000??.dat file"), QT_TRANSLATE_NOOP("bitcoin-core", "Include IP addresses in debug output (default: %u)"), @@ -250,7 +233,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s' ( QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Invalid netmask specified in -whitelist: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most <n> unconnectable transactions in memory (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Limit size of signature cache to <n> entries (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on <port> (default: %u or testnet: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."), @@ -263,29 +245,24 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, <n>*1000 QT_TRANSLATE_NOOP("bitcoin-core", "Need to specify a port with -whitebind: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Node relay options:"), QT_TRANSLATE_NOOP("bitcoin-core", "Not enough file descriptors available."), -QT_TRANSLATE_NOOP("bitcoin-core", "Only accept block chain matching built-in checkpoints (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network <net> (ipv4, ipv6 or onion)"), QT_TRANSLATE_NOOP("bitcoin-core", "Options:"), QT_TRANSLATE_NOOP("bitcoin-core", "Password for JSON-RPC connections"), QT_TRANSLATE_NOOP("bitcoin-core", "Prepend debug output with timestamp (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Prune cannot be configured with a negative value."), QT_TRANSLATE_NOOP("bitcoin-core", "Prune mode is incompatible with -txindex."), -QT_TRANSLATE_NOOP("bitcoin-core", "RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Pruning blockstore..."), QT_TRANSLATE_NOOP("bitcoin-core", "RPC server options:"), -QT_TRANSLATE_NOOP("bitcoin-core", "RPC support for HTTP persistent connections (default: %d)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Randomly drop 1 of every <n> network messages"), -QT_TRANSLATE_NOOP("bitcoin-core", "Randomly fuzz 1 of every <n> network messages"), QT_TRANSLATE_NOOP("bitcoin-core", "Rebuild block chain index from current blk000??.dat files on startup"), +QT_TRANSLATE_NOOP("bitcoin-core", "Receive and display P2P network alerts (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Reducing -maxconnections from %d to %d, because of system limitations."), QT_TRANSLATE_NOOP("bitcoin-core", "Relay and mine data carrier transactions (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Relay non-P2SH multisig (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Rescan the block chain for missing wallet transactions"), QT_TRANSLATE_NOOP("bitcoin-core", "Rescanning..."), -QT_TRANSLATE_NOOP("bitcoin-core", "Run a thread to flush wallet periodically (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Run in the background as a daemon and accept commands"), QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to console instead of debug.log file"), QT_TRANSLATE_NOOP("bitcoin-core", "Send transactions as zero-fee transactions if possible (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Server certificate file (default: %s)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Server private key (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set SSL root certificates for payment request (default: -system-)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set database cache size in megabytes (%d to %d, default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to <n> (default: %u)"), @@ -293,7 +270,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Set language, for example \"de_DE\" (default: QT_TRANSLATE_NOOP("bitcoin-core", "Set maximum block size in bytes (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set minimum block size in bytes (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set the number of threads to service RPC calls (default: %d)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Show all debugging options (usage: --help -help-debug)"), QT_TRANSLATE_NOOP("bitcoin-core", "Show splash screen on startup (default: 1)"), QT_TRANSLATE_NOOP("bitcoin-core", "Shrink debug.log file on client startup (default: 1 when no -debug)"), @@ -306,11 +282,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Specify wallet file (within data directory)") QT_TRANSLATE_NOOP("bitcoin-core", "Specify your own public address"), QT_TRANSLATE_NOOP("bitcoin-core", "Spend unconfirmed change when sending transactions (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Start minimized"), -QT_TRANSLATE_NOOP("bitcoin-core", "Stop running after importing blocks from disk (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "The transaction amount is too small to pay the fee"), QT_TRANSLATE_NOOP("bitcoin-core", "This help message"), QT_TRANSLATE_NOOP("bitcoin-core", "This is experimental software."), -QT_TRANSLATE_NOOP("bitcoin-core", "This is intended for regression testing tools and app development."), QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amount too small"), QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amounts must be positive"), @@ -318,11 +292,10 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large for fee policy"), QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large"), QT_TRANSLATE_NOOP("bitcoin-core", "UI Options:"), QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer (bind returned error %s)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Unable to start HTTP server. See debug log for details."), QT_TRANSLATE_NOOP("bitcoin-core", "Unknown network specified in -onlynet: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Upgrade wallet to latest format"), -QT_TRANSLATE_NOOP("bitcoin-core", "Use OpenSSL (https) for JSON-RPC connections"), QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: 1 when listening)"), QT_TRANSLATE_NOOP("bitcoin-core", "Use the test network"), QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections"), QT_TRANSLATE_NOOP("bitcoin-core", "Verifying blocks..."), @@ -336,6 +309,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Unsupported argument -benchmark igno QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Unsupported argument -debugnet ignored, use -debug=net."), QT_TRANSLATE_NOOP("bitcoin-core", "You need to rebuild the database using -reindex to change -txindex"), QT_TRANSLATE_NOOP("bitcoin-core", "Zapping all transactions from wallet..."), +QT_TRANSLATE_NOOP("bitcoin-core", "ZeroMQ notification options:"), QT_TRANSLATE_NOOP("bitcoin-core", "on startup"), QT_TRANSLATE_NOOP("bitcoin-core", "wallet.dat corrupt, salvage failed"), }; diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 41dc2ea77e..0900a35cc4 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -4,6 +4,7 @@ #include "clientmodel.h" +#include "bantablemodel.h" #include "guiconstants.h" #include "peertablemodel.h" @@ -26,6 +27,7 @@ ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) : QObject(parent), optionsModel(optionsModel), peerTableModel(0), + banTableModel(0), cachedNumBlocks(0), cachedBlockDate(QDateTime()), cachedReindexing(0), @@ -33,6 +35,7 @@ ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) : pollTimer(0) { peerTableModel = new PeerTableModel(this); + banTableModel = new BanTableModel(this); pollTimer = new QTimer(this); connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer())); pollTimer->start(MODEL_UPDATE_DELAY); @@ -176,11 +179,21 @@ PeerTableModel *ClientModel::getPeerTableModel() return peerTableModel; } +BanTableModel *ClientModel::getBanTableModel() +{ + return banTableModel; +} + QString ClientModel::formatFullVersion() const { return QString::fromStdString(FormatFullVersion()); } +QString ClientModel::formatSubVersion() const +{ + return QString::fromStdString(strSubVersion); +} + QString ClientModel::formatBuildDate() const { return QString::fromStdString(CLIENT_DATE); @@ -201,6 +214,11 @@ QString ClientModel::formatClientStartupTime() const return QDateTime::fromTime_t(nClientStartupTime).toString(); } +void ClientModel::updateBanlist() +{ + banTableModel->refresh(); +} + // Handlers for core signals static void ShowProgress(ClientModel *clientmodel, const std::string &title, int nProgress) { @@ -225,12 +243,19 @@ static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, Ch Q_ARG(int, status)); } +static void BannedListChanged(ClientModel *clientmodel) +{ + qDebug() << QString("%1: Requesting update for peer banlist").arg(__func__); + QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection); +} + void ClientModel::subscribeToCoreSignals() { // Connect signals to client uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2)); uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1)); uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this, _1, _2)); + uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this)); } void ClientModel::unsubscribeFromCoreSignals() @@ -239,4 +264,5 @@ void ClientModel::unsubscribeFromCoreSignals() uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2)); uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1)); uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this, _1, _2)); + uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this)); } diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 68434f404c..627bdf862d 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -9,6 +9,7 @@ #include <QDateTime> class AddressTableModel; +class BanTableModel; class OptionsModel; class PeerTableModel; class TransactionTableModel; @@ -44,6 +45,7 @@ public: OptionsModel *getOptionsModel(); PeerTableModel *getPeerTableModel(); + BanTableModel *getBanTableModel(); //! Return number of connections, default is in- and outbound (total) int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const; @@ -63,6 +65,7 @@ public: QString getStatusBarWarnings() const; QString formatFullVersion() const; + QString formatSubVersion() const; QString formatBuildDate() const; bool isReleaseVersion() const; QString clientName() const; @@ -71,6 +74,7 @@ public: private: OptionsModel *optionsModel; PeerTableModel *peerTableModel; + BanTableModel *banTableModel; int cachedNumBlocks; QDateTime cachedBlockDate; @@ -98,6 +102,7 @@ public Q_SLOTS: void updateTimer(); void updateNumConnections(int numConnections); void updateAlert(const QString &hash, int status); + void updateBanlist(); }; #endif // BITCOIN_QT_CLIENTMODEL_H diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 934d62d5f7..51008ad2de 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -9,7 +9,7 @@ #include "bitcoinunits.h" #include "guiutil.h" #include "optionsmodel.h" -#include "scicon.h" +#include "platformstyle.h" #include "txmempool.h" #include "walletmodel.h" @@ -35,10 +35,11 @@ QList<CAmount> CoinControlDialog::payAmounts; CCoinControl* CoinControlDialog::coinControl = new CCoinControl(); bool CoinControlDialog::fSubtractFeeFromAmount = false; -CoinControlDialog::CoinControlDialog(QWidget *parent) : +CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget *parent) : QDialog(parent), ui(new Ui::CoinControlDialog), - model(0) + model(0), + platformStyle(platformStyle) { ui->setupUi(this); @@ -280,7 +281,7 @@ void CoinControlDialog::lockCoin() COutPoint outpt(uint256S(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt()); model->lockCoin(outpt); contextMenuItem->setDisabled(true); - contextMenuItem->setIcon(COLUMN_CHECKBOX, SingleColorIcon(":/icons/lock_closed")); + contextMenuItem->setIcon(COLUMN_CHECKBOX, platformStyle->SingleColorIcon(":/icons/lock_closed")); updateLabelLocked(); } @@ -791,7 +792,7 @@ void CoinControlDialog::updateView() COutPoint outpt(txhash, out.i); coinControl->UnSelect(outpt); // just to be sure itemOutput->setDisabled(true); - itemOutput->setIcon(COLUMN_CHECKBOX, SingleColorIcon(":/icons/lock_closed")); + itemOutput->setIcon(COLUMN_CHECKBOX, platformStyle->SingleColorIcon(":/icons/lock_closed")); } // set checkbox diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index 0566b02c96..8ff1eac709 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -16,6 +16,7 @@ #include <QString> #include <QTreeWidgetItem> +class PlatformStyle; class WalletModel; class CCoinControl; @@ -32,7 +33,7 @@ class CoinControlDialog : public QDialog Q_OBJECT public: - explicit CoinControlDialog(QWidget *parent = 0); + explicit CoinControlDialog(const PlatformStyle *platformStyle, QWidget *parent = 0); ~CoinControlDialog(); void setModel(WalletModel *model); @@ -57,6 +58,8 @@ private: QAction *lockAction; QAction *unlockAction; + const PlatformStyle *platformStyle; + QString strPad(QString, int, QString); void sortView(int, Qt::SortOrder); void updateView(); diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/debugwindow.ui index 7ae8237476..4117da57f5 100644 --- a/src/qt/forms/rpcconsole.ui +++ b/src/qt/forms/debugwindow.ui @@ -87,6 +87,32 @@ </widget> </item> <item row="3" column="0"> + <widget class="QLabel" name="labelClientUserAgent"> + <property name="text"> + <string>User Agent</string> + </property> + <property name="indent"> + <number>10</number> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLabel" name="clientUserAgent"> + <property name="cursor"> + <cursorShape>IBeamCursor</cursorShape> + </property> + <property name="text"> + <string>N/A</string> + </property> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="4" column="0"> <widget class="QLabel" name="label_14"> <property name="text"> <string>Using OpenSSL version</string> @@ -96,7 +122,7 @@ </property> </widget> </item> - <item row="3" column="1"> + <item row="4" column="1"> <widget class="QLabel" name="openSSLVersion"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -112,7 +138,7 @@ </property> </widget> </item> - <item row="4" column="0"> + <item row="5" column="0"> <widget class="QLabel" name="label_berkeleyDBVersion"> <property name="text"> <string>Using BerkeleyDB version</string> @@ -122,7 +148,7 @@ </property> </widget> </item> - <item row="4" column="1"> + <item row="5" column="1"> <widget class="QLabel" name="berkeleyDBVersion"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -138,14 +164,14 @@ </property> </widget> </item> - <item row="5" column="0"> + <item row="6" column="0"> <widget class="QLabel" name="label_12"> <property name="text"> <string>Build date</string> </property> </widget> </item> - <item row="5" column="1"> + <item row="6" column="1"> <widget class="QLabel" name="buildDate"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -161,14 +187,14 @@ </property> </widget> </item> - <item row="6" column="0"> + <item row="7" column="0"> <widget class="QLabel" name="label_13"> <property name="text"> <string>Startup time</string> </property> </widget> </item> - <item row="6" column="1"> + <item row="7" column="1"> <widget class="QLabel" name="startupTime"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -184,7 +210,7 @@ </property> </widget> </item> - <item row="7" column="0"> + <item row="8" column="0"> <widget class="QLabel" name="label_11"> <property name="font"> <font> @@ -197,14 +223,14 @@ </property> </widget> </item> - <item row="8" column="0"> + <item row="9" column="0"> <widget class="QLabel" name="label_8"> <property name="text"> <string>Name</string> </property> </widget> </item> - <item row="8" column="1"> + <item row="9" column="1"> <widget class="QLabel" name="networkName"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -220,14 +246,14 @@ </property> </widget> </item> - <item row="9" column="0"> + <item row="10" column="0"> <widget class="QLabel" name="label_7"> <property name="text"> <string>Number of connections</string> </property> </widget> </item> - <item row="9" column="1"> + <item row="10" column="1"> <widget class="QLabel" name="numberOfConnections"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -243,7 +269,7 @@ </property> </widget> </item> - <item row="10" column="0"> + <item row="11" column="0"> <widget class="QLabel" name="label_10"> <property name="font"> <font> @@ -256,14 +282,14 @@ </property> </widget> </item> - <item row="11" column="0"> + <item row="12" column="0"> <widget class="QLabel" name="label_3"> <property name="text"> <string>Current number of blocks</string> </property> </widget> </item> - <item row="11" column="1"> + <item row="12" column="1"> <widget class="QLabel" name="numberOfBlocks"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -279,14 +305,14 @@ </property> </widget> </item> - <item row="12" column="0"> + <item row="13" column="0"> <widget class="QLabel" name="label_2"> <property name="text"> <string>Last block time</string> </property> </widget> </item> - <item row="12" column="1"> + <item row="13" column="1"> <widget class="QLabel" name="lastBlockTime"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -302,7 +328,7 @@ </property> </widget> </item> - <item row="13" column="0"> + <item row="14" column="0"> <spacer name="verticalSpacer_2"> <property name="orientation"> <enum>Qt::Vertical</enum> @@ -315,7 +341,7 @@ </property> </spacer> </item> - <item row="14" column="0"> + <item row="15" column="0"> <widget class="QLabel" name="labelDebugLogfile"> <property name="font"> <font> @@ -328,7 +354,7 @@ </property> </widget> </item> - <item row="15" column="0"> + <item row="16" column="0"> <widget class="QPushButton" name="openDebugLogfileButton"> <property name="toolTip"> <string>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</string> @@ -341,7 +367,7 @@ </property> </widget> </item> - <item row="16" column="0"> + <item row="17" column="0"> <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> @@ -687,17 +713,85 @@ </attribute> <layout class="QGridLayout" name="gridLayout_2"> <item row="0" column="0" rowspan="2"> - <widget class="QTableView" name="peerWidget"> - <property name="horizontalScrollBarPolicy"> - <enum>Qt::ScrollBarAsNeeded</enum> - </property> - <property name="sortingEnabled"> - <bool>true</bool> + <layout class="QVBoxLayout" name="verticalLayout_101"> + <property name="spacing"> + <number>0</number> </property> - <attribute name="horizontalHeaderHighlightSections"> - <bool>false</bool> - </attribute> - </widget> + <item> + <widget class="QTableView" name="peerWidget"> + <property name="horizontalScrollBarPolicy"> + <enum>Qt::ScrollBarAsNeeded</enum> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <attribute name="horizontalHeaderHighlightSections"> + <bool>false</bool> + </attribute> + </widget> + </item> + <item> + <widget class="QLabel" name="banHeading"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>300</width> + <height>32</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>32</height> + </size> + </property> + <property name="font"> + <font> + <pointsize>12</pointsize> + </font> + </property> + <property name="cursor"> + <cursorShape>IBeamCursor</cursorShape> + </property> + <property name="text"> + <string>Banned peers</string> + </property> + <property name="alignment"> + <set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::NoTextInteraction</set> + </property> + </widget> + </item> + <item> + <widget class="QTableView" name="banlistWidget"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="horizontalScrollBarPolicy"> + <enum>Qt::ScrollBarAsNeeded</enum> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <attribute name="horizontalHeaderHighlightSections"> + <bool>false</bool> + </attribute> + </widget> + </item> + </layout> </item> <item row="0" column="1"> <widget class="QLabel" name="peerHeading"> diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index 55c4f5ac58..22c67b8040 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>560</width> - <height>400</height> + <height>440</height> </rect> </property> <property name="windowTitle"> @@ -298,6 +298,193 @@ </layout> </item> <item> + <layout class="QHBoxLayout" name="horizontalLayout_2_Network"> + <item> + <widget class="QLabel" name="proxyActiveNets"> + <property name="text"> + <string>Used for reaching peers via:</string> + </property> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="proxyReachIPv4"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</string> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="proxyReachIPv4Label"> + <property name="text"> + <string>IPv4</string> + </property> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="proxyReachIPv6"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</string> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="proxyReachIPv6Label"> + <property name="text"> + <string>IPv6</string> + </property> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="proxyReachTor"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</string> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="proxyReachTorLabel"> + <property name="text"> + <string>Tor</string> + </property> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2_Network"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <widget class="QCheckBox" name="connectSocksTor"> + <property name="toolTip"> + <string>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</string> + </property> + <property name="text"> + <string>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3_Network"> + <item> + <widget class="QLabel" name="proxyIpTorLabel"> + <property name="text"> + <string>Proxy &IP:</string> + </property> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> + <property name="buddy"> + <cstring>proxyIpTor</cstring> + </property> + </widget> + </item> + <item> + <widget class="QValidatedLineEdit" name="proxyIpTor"> + <property name="minimumSize"> + <size> + <width>140</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>140</width> + <height>16777215</height> + </size> + </property> + <property name="toolTip"> + <string>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="proxyPortTorLabel"> + <property name="text"> + <string>&Port:</string> + </property> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> + <property name="buddy"> + <cstring>proxyPortTor</cstring> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="proxyPortTor"> + <property name="minimumSize"> + <size> + <width>55</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>55</width> + <height>16777215</height> + </size> + </property> + <property name="toolTip"> + <string>Port of the proxy (e.g. 9050)</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_4_Network"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> <spacer name="verticalSpacer_Network"> <property name="orientation"> <enum>Qt::Vertical</enum> diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h index a0a2993ea3..7d3e48ff32 100644 --- a/src/qt/guiconstants.h +++ b/src/qt/guiconstants.h @@ -42,7 +42,7 @@ static const int MAX_URI_LENGTH = 255; #define EXPORT_IMAGE_SIZE 256 /* Number of frames in spinner animation */ -#define SPINNER_FRAMES 35 +#define SPINNER_FRAMES 36 #define QAPP_ORG_NAME "Bitcoin" #define QAPP_ORG_DOMAIN "bitcoin.org" diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 550dbacf93..8917f77f22 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -404,7 +404,7 @@ void SubstituteFonts(const QString& language) { #if defined(Q_OS_MAC) // Background: -// OSX's default font changed in 10.9 and QT is unable to find it with its +// OSX's default font changed in 10.9 and Qt is unable to find it with its // usual fallback methods when building against the 10.7 sdk or lower. // The 10.8 SDK added a function to let it find the correct fallback font. // If this fallback is not properly loaded, some characters may fail to diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index 117969758c..4ab87e0f32 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -6,7 +6,6 @@ #include "ui_intro.h" #include "guiutil.h" -#include "scicon.h" #include "util.h" @@ -168,7 +167,7 @@ void Intro::pickDataDirectory() /* If current default data directory does not exist, let the user choose one */ Intro intro; intro.setDataDirectory(dataDir); - intro.setWindowIcon(SingleColorIcon(":icons/bitcoin")); + intro.setWindowIcon(QIcon(":icons/bitcoin")); while(true) { diff --git a/src/qt/locale/bitcoin_ach.ts b/src/qt/locale/bitcoin_ach.ts index 835ddb8eaa..ddb9fb85ce 100644 --- a/src/qt/locale/bitcoin_ach.ts +++ b/src/qt/locale/bitcoin_ach.ts @@ -1,4 +1,4 @@ -<TS language="ach" version="2.1"> +<TS language="ach" version="2.0"> <context> <name>AddressBookPage</name> </context> diff --git a/src/qt/locale/bitcoin_af_ZA.ts b/src/qt/locale/bitcoin_af_ZA.ts index 5ef7d3fd37..3767a4c830 100644 --- a/src/qt/locale/bitcoin_af_ZA.ts +++ b/src/qt/locale/bitcoin_af_ZA.ts @@ -1,4 +1,4 @@ -<TS language="af_ZA" version="2.1"> +<TS language="af_ZA" version="2.0"> <context> <name>AddressBookPage</name> <message> diff --git a/src/qt/locale/bitcoin_ar.ts b/src/qt/locale/bitcoin_ar.ts index 235b22cd1f..e56083fa2c 100644 --- a/src/qt/locale/bitcoin_ar.ts +++ b/src/qt/locale/bitcoin_ar.ts @@ -1,4 +1,4 @@ -<TS language="ar" version="2.1"> +<TS language="ar" version="2.0"> <context> <name>AddressBookPage</name> <message> diff --git a/src/qt/locale/bitcoin_be_BY.ts b/src/qt/locale/bitcoin_be_BY.ts index b727b75566..5f7f6f89bf 100644 --- a/src/qt/locale/bitcoin_be_BY.ts +++ b/src/qt/locale/bitcoin_be_BY.ts @@ -1,4 +1,4 @@ -<TS language="be_BY" version="2.1"> +<TS language="be_BY" version="2.0"> <context> <name>AddressBookPage</name> <message> diff --git a/src/qt/locale/bitcoin_bg.ts b/src/qt/locale/bitcoin_bg.ts index c86fdd42dd..e2821dbdef 100644 --- a/src/qt/locale/bitcoin_bg.ts +++ b/src/qt/locale/bitcoin_bg.ts @@ -1,4 +1,4 @@ -<TS language="bg" version="2.1"> +<TS language="bg" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -1955,6 +1955,14 @@ <translation>Дебит</translation> </message> <message> + <source>Total debit</source> + <translation>Общ дълг</translation> + </message> + <message> + <source>Total credit</source> + <translation>Общ дълг</translation> + </message> + <message> <source>Transaction fee</source> <translation>Такса</translation> </message> @@ -1979,6 +1987,10 @@ <translation>Търговец</translation> </message> <message> + <source>Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source> + <translation>Генерираните монети трябва да отлежат %1 блока преди да могат да бъдат похарчени. Когато генерираш блока, той се разпространява в мрежата, за да се добави в блок-веригата. Ако не успее да се добави във веригата, неговия статус ще се стане "неприет" и няма да може да се похарчи. Това е възможно да се случи случайно, ако друг възел генерира блок няколко секунди след твоя.</translation> + </message> + <message> <source>Debug information</source> <translation>Информация за грешките</translation> </message> @@ -2029,6 +2041,10 @@ <translation>Тип</translation> </message> <message> + <source>Immature (%1 confirmations, will be available after %2)</source> + <translation>Неплатим (%1 потвърждения, ще бъде платим след %2)</translation> + </message> + <message> <source>Open until %1</source> <translation>Подлежи на промяна до %1</translation> </message> diff --git a/src/qt/locale/bitcoin_bs.ts b/src/qt/locale/bitcoin_bs.ts index fc5e6d270e..86526022fe 100644 --- a/src/qt/locale/bitcoin_bs.ts +++ b/src/qt/locale/bitcoin_bs.ts @@ -1,4 +1,4 @@ -<TS language="bs" version="2.1"> +<TS language="bs" version="2.0"> <context> <name>AddressBookPage</name> </context> diff --git a/src/qt/locale/bitcoin_ca.ts b/src/qt/locale/bitcoin_ca.ts index f7d97eb061..ceb71469cb 100644 --- a/src/qt/locale/bitcoin_ca.ts +++ b/src/qt/locale/bitcoin_ca.ts @@ -1,4 +1,4 @@ -<TS language="ca" version="2.1"> +<TS language="ca" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -168,6 +168,10 @@ <translation>Esteu segur que voleu encriptar el vostre moneder?</translation> </message> <message> + <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>Ara es tancarà el Bitcoin Core per finalitzar el procés d'encriptació. Tingueu present que encriptar el vostre moneder no garanteix que les vostres bitcoins no puguin ser robades per programari maliciós que infecti l'ordinador.</translation> + </message> + <message> <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source> <translation>IMPORTANT: Tota copia de seguretat que hàgiu realitzat hauria de ser reemplaçada pel, recentment generat, fitxer encriptat del moneder.</translation> </message> @@ -184,6 +188,10 @@ <translation>Introduïu la contrasenya nova al moneder.<br/>Utilitzeu una contrasenya de <b>deu o més caràcters aleatoris</b>, o <b>vuit o més paraules</b>.</translation> </message> <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Introduïu la contrasenya antiga i la contrasenya nova al moneder.</translation> + </message> + <message> <source>Wallet encryption failed</source> <translation>L'encriptació del moneder ha fallat</translation> </message> @@ -391,6 +399,10 @@ <translation>&Quant al Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Modifica les opcions de configuració del Bitcoin Core</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Mostra la llista d'adreces d'enviament i etiquetes utilitzades</translation> </message> @@ -419,6 +431,10 @@ <translation>No hi ha cap font de bloc disponible...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>S'han processat %n bloc de l'historial de transacció.</numerusform><numerusform>S'han processat %n blocs de l'historial de transacció.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n hora</numerusform><numerusform>%n hores</numerusform></translation> </message> @@ -471,6 +487,36 @@ <translation>S'està posant al dia ...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Data: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Import: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Tipus: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Etiqueta: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Adreça: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Transacció enviada</translation> </message> @@ -669,6 +715,18 @@ <translation>cap</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Aquesta etiqueta es torna en vermell si la transacció és superior a 1000 bytes.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Aquesta etiqueta es torna en vermell si la propietat és inferior que la «mitjana».</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Aquesta etiqueta es torna vermella si el destinatari rep un import inferior de %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Pot variar +/- %1 satoshi(s) per entrada.</translation> </message> @@ -919,6 +977,14 @@ <translation>Adreça IP del proxy (p. ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>Minimitza en comptes de sortir de l'aplicació quan la finestra es tanca. Quan s'habilita aquesta opció l'aplicació es tancara només quan se selecciona Surt del menú. </translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>La interfície d'usuari pot definir-se des d'aquí. El paràmetre tindrà efecte després de reiniciar el Bitcoin Core.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>URL de terceres parts (p. ex. explorador de blocs) que apareix en la pestanya de transaccions com elements del menú contextual. %s en l'URL es reemplaçat pel resum de la transacció. Diferents URL estan separades per una barra vertical |.</translation> </message> @@ -943,6 +1009,14 @@ <translation>&Xarxa</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Inicia el Bitcoin Core automàticament després d'iniciar una sessió en el sistema.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Inicia el Bitcoin Core en inciar el sistema</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = auto, <0 = deixa tants nuclis lliures)</translation> </message> @@ -1055,6 +1129,10 @@ <translation>Cal reiniciar el client per activar els canvis.</translation> </message> <message> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>S'aturarà el client. Voleu procedir?</translation> + </message> + <message> <source>This change would require a client restart.</source> <translation>Amb aquest canvi cal un reinici del client.</translation> </message> @@ -1189,10 +1267,18 @@ <translation>No es pot llegir el fitxer de la sol·licitud de pagament. Això pot ser causat per un fitxer de sol·licitud de pagament no vàlid.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>La sol·licitud de pagament ha vençut.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>No s'accepten sol·licituds de pagament no verificades a scripts de pagament personalitzats.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Sol·licitud de pagament no vàlida.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Reemborsament de %1</translation> </message> @@ -1232,6 +1318,10 @@ <translation>Agent d'usuari</translation> </message> <message> + <source>Node/Service</source> + <translation>Node/Servei</translation> + </message> + <message> <source>Ping Time</source> <translation>Temps de ping</translation> </message> @@ -1353,6 +1443,10 @@ <translation>Nombre de blocs actuals</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Obre el fitxer de registre de depuració del Bitcoin Core del directori de dades actual. Pot portar uns quants segons per a fitxers de registre grans.</translation> + </message> + <message> <source>Received</source> <translation>Rebut</translation> </message> @@ -1421,6 +1515,10 @@ <translation>Temps de ping</translation> </message> <message> + <source>Time Offset</source> + <translation>Diferència horària</translation> + </message> + <message> <source>Last block time</source> <translation>Últim temps de bloc</translation> </message> @@ -1465,6 +1563,10 @@ <translation>Neteja la consola</translation> </message> <message> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Us donem la benviguda a la consola RPC del Bitcoin Core.</translation> + </message> + <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Utilitza les fletxes d'amunt i avall per navegar per l'historial, i <b>Ctrl-L<\b> per netejar la pantalla.</translation> </message> @@ -1761,6 +1863,10 @@ <translation>Si la comissió personalitzada es defineix a 1000 satoshis i la transacció és de només 250 bytes, llavors «per kilobyte» només es paguen 250 satoshis en una comissió, mentre que amb la de «total com a mínim» es pagarien 1000 satoshis. Per a transaccions superiors al kilobyte, en tots dos casos es paga per kilobyte.</translation> </message> <message> + <source>Hide</source> + <translation>Amaga</translation> + </message> + <message> <source>total at least</source> <translation>total com a mínim</translation> </message> @@ -1901,10 +2007,30 @@ <translation>S'ha rebutjat la transacció! Això pot passar si alguna de les monedes del vostre moneder ja s'han gastat; per exemple, si heu fet servir una còpia de seguretat del fitxer wallet.dat i s'haguessin gastat monedes de la còpia però sense marcar-les-hi com a gastades.</translation> </message> <message> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>Una comissió superior a %1 es considera una comissió absurdament alta.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>La sol·licitud de pagament ha vençut.</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Estimat per començar la confirmació en %n bloc.</numerusform><numerusform>Estimat per començar la confirmació en %n blocs.</numerusform></translation> + </message> + <message> <source>Pay only the minimum fee of %1</source> <translation>Paga només la comissió mínima de %1</translation> </message> <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>L'adreça de destinatari no és vàlida. Torneu-la a comprovar.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>S'ha trobat una adreça duplicada: cal utilitzar les adreces només un cop cada vegada.</translation> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Avís: adreça Bitcoin no vàlida</translation> </message> @@ -1976,10 +2102,26 @@ <translation>Elimina aquesta entrada</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>La comissió es deduirà de l'import que s'enviarà. El destinatari rebrà menys bitcoins que les que introduïu al camp d'import. Si se seleccionen múltiples destinataris, la comissió es dividirà per igual.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>S&ubstreu la comissió de l'import</translation> + </message> + <message> <source>Message:</source> <translation>Missatge:</translation> </message> <message> + <source>This is an unauthenticated payment request.</source> + <translation>Aquesta és una sol·licitud de pagament no autenticada.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Aquesta és una sol·licitud de pagament autenticada.</translation> + </message> + <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>Introduïu una etiqueta per a aquesta adreça per afegir-la a la llista d'adreces utilitzades</translation> </message> @@ -2018,6 +2160,10 @@ <translation>&Signa el missatge</translation> </message> <message> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>Podeu signar missatges/acords amb les vostres adreces per provar que rebeu les bitcoins que s'hi envien. Aneu amb compte no signar res que sigui vague o aleatori, perquè en alguns atacs de suplantació es pot provar que hi signeu la vostra identitat. Només signeu aquelles declaracions completament detallades en què hi esteu d'acord. </translation> + </message> + <message> <source>The Bitcoin address to sign the message with</source> <translation>L'adreça Bitcoin amb què signar el missatge</translation> </message> @@ -2070,6 +2216,10 @@ <translation>&Verifica el missatge</translation> </message> <message> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Introduïu l'adreça del receptor, el missatge (assegureu-vos de copiar els salts de línia, espais, tabuladors, etc. exactament) i signatura de sota per verificar el missatge. Tingueu cura de no llegir més en la signatura del que està al missatge signat, per evitar ser enganyat per un atac d'home-en-el-mig. Tingueu en compte que això només demostra que la part que signa rep amb l'adreça, i no es pot provar l'enviament de qualsevol transacció!</translation> + </message> + <message> <source>The Bitcoin address the message was signed with</source> <translation>L'adreça Bitcoin amb què va ser signat el missatge</translation> </message> @@ -2421,6 +2571,10 @@ <translation>Si està implicada o no una adreça només de lectura en la transacció.</translation> </message> <message> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Intenció/propòsit de la transacció definida per l'usuari.</translation> + </message> + <message> <source>Amount removed from or added to balance.</source> <translation>Import extret o afegit del balanç.</translation> </message> @@ -2671,16 +2825,16 @@ <translation>Distribuït sota llicència de programari MIT. Vegeu el fitxer acompanyant COPYING o <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Entra en el mode de proves de regressió, que utilitza una cadena especial en què els blocs poden resoldre's al moment.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Executa una ordre quan una transacció del moneder canviï (%s en cmd es canvia per TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>En aquest mode -genproclimit controla quants blocs es generen immediatament.</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Comissions totals màximes que s'utilitzaran en una única transacció de moneder; si s'estableix un valor massa baix es poden interrompre transaccions grans (per defecte: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>Redueix els requeriments d'emmagatzemament podant (suprimint) els blocs antics. Aquest mode inhabilita l'ús de moneders i és incompatible amb -tindex. Avís: Revertir aquesta configuració comporta tornar a baixar la cadena de blocs sencera. (per defecte: 0 = inhabilita la poda de blocs, >%u = mida objectiu en MiB per utilitzar els fitxers de blocs)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2695,6 +2849,14 @@ <translation>No es pot enllaçar %s a aquest ordinador. El Bitcoin Core probablement ja estigui executant-s'hi.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>AVÍS: s'ha generat un nombre anòmalament alt de blocs, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>AVÍS: comproveu la vostra connexió a la xarxa, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Avís: el -paytxfee és molt elevat! Aquesta és la comissió de transacció que pagareu si envieu una transacció.</translation> </message> @@ -2811,6 +2973,14 @@ <translation>Només connecta als nodes de la xarxa <net> (ipv4, ipv6 o onion)</translation> </message> <message> + <source>Prune cannot be configured with a negative value.</source> + <translation>La poda no es pot configurar amb un valor negatiu.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>El mode de poda és incompatible amb -txindex.</translation> + </message> + <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation>Defineix la mida de la memòria cau de la base de dades en megabytes (%d a %d, per defecte: %d)</translation> </message> @@ -2823,10 +2993,6 @@ <translation>Especifica un fitxer de moneder (dins del directori de dades)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Això es així per a eines de proves de regressió per al desenvolupament d'aplicacions.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Utilitza UPnP per a mapejar el port d'escolta (per defecte: %u)</translation> </message> @@ -2847,6 +3013,10 @@ <translation>Opcions de moneder:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Avís: aquesta versió és obsoleta; cal actualitzar-la!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Cal que reconstruïu la base de dades fent servir -reindex per canviar -txindex</translation> </message> @@ -2875,6 +3045,10 @@ <translation>Crea fitxers nous amb els permisos per defecte del sistema, en comptes de l'umask 077 (només efectiu amb la funcionalitat de moneder inhabilitada)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Descobreix l'adreça IP pròpia (per defecte: 1 quan s'escolta i no -externalip o -proxy)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Error: ha fallat escoltar les connexions entrants (l'escoltament ha retornat l'error %s)</translation> </message> @@ -2891,10 +3065,6 @@ <translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la transmissió (per defecte: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la creació de la transacció (per defecte: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Si no s'especifica una paytxfee (comissió de transacció de pagament), inclogueu suficient comissió per tal que les transaccions comencin a confirmar-se en una mitja de n blocs (per defecte: %u)</translation> </message> @@ -2907,10 +3077,18 @@ <translation>Mida màxima de les dades en les transaccions de l'operador en què confiem i en les meves (per defecte: %u)</translation> </message> <message> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>Poda configurada per sota el mínim de %d MB. Feu servir un nombre superior.</translation> + </message> + <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Consulta a adreces d'iguals a través de DNS, si es troba baix en adreces (per defecte: 1 a menys que -connect)</translation> </message> <message> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Genera a l'atzar credencials per a cada connexió proxy. Això habilita l'aïllament del flux de Tor (per defecte: %u)</translation> + </message> + <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Defineix la mida màxima de transaccions d'alta prioritat / baixa comissió en bytes (per defecte: %d)</translation> </message> @@ -2919,6 +3097,10 @@ <translation>Defineix el nombre de fils per a la generació de moneda si està habilitat (-1 = tots els nuclis, per defecte: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>L'import de la transacció és massa petit per enviar-la després que se'n dedueixi la comissió</translation> + </message> + <message> <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source> <translation>Aquest producte inclou programari desenvolupat pel projecte OpenSSL per a ús a l'OpenSSL Toolkit <https://www.openssl.org/> i programari criptogràfic escrit per Eric Young i programari UPnP escrit per Thomas Bernard.</translation> </message> @@ -2958,10 +3140,26 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Els iguals en la llista blanca no poden ser bandejats per DoS i es transmetran sempre llurs transaccions, fins i tot si ja són a la mempool. Això és útil, p. ex., per a una passarel·la</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>Cal que torneu a construir la base de dades fent servir -reindex per tornar al mode no podat. Això tornarà a baixar la cadena de blocs sencera</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(per defecte: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>Accepta sol·licituds REST públiques (per defecte: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>S'està activant la millor cadena...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>No es pot executar amb un moneder en mode poda.</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>No es pot resoldre l'adreça -whitebind: «%s»</translation> </message> @@ -3050,12 +3248,12 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Suport RPC per a connexions HTTP persistents (per defecte: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Descarta a l'atzar 1 de cada <n> missatges de la xarxa</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Reconstrueix l'índex de la cadena de blocs dels fitxers blk000??.dat actuals a l'inici.</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Introdueix incertesa en 1 de cada <n> missatges de la xarxa</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Rep i mostra avisos de la xarxa P2P (per defecte: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3094,6 +3292,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Inicia minimitzat</translation> </message> <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>L'import de la transacció és massa petit per pagar-ne una comissió</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Això és programari experimental.</translation> </message> @@ -3114,6 +3316,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>La transacció és massa gran</translation> </message> <message> + <source>UI Options:</source> + <translation>Opcions d'interfície:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>No s'ha pogut vincular a %s en aquest ordinador (la vinculació ha retornat l'error %s)</translation> </message> @@ -3194,18 +3400,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>(1 = manté les metadades de les tx, p. ex., propietari del compte i informació de sol·licitud del pagament, 2 = prescindeix de les metadades de les tx)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Buida l'activitat de la base de dades de la memòria disponible al registre del disc cada <n> megabytes (per defecte: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Com d'exhaustiva és la verificació de blocs del -checkblocks (0-4, per defecte: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Enregistreu la prioritat de la transacció i la comissió per kB en minar blocs (per defecte: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Manté un índex complet de transaccions, utilitzat per la crida rpc getrawtransaction (per defecte: %u)</translation> </message> @@ -3234,18 +3432,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Demana sempre les adreces dels iguals a través de consultes DNS (per defecte: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Inhabilita el mode segur, sobreescriu un esdeveniment de mode segur real (per defecte: %u) </translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Error en carregar wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Força el mode segur (per defecte: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Genera monedes (per defecte: %u)</translation> </message> @@ -3262,10 +3452,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Adreça -proxy invalida: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Limita la mida de la cau de signatura a <n> entrades (per defecte: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Escolta les connexions JSON-RPC en <port> (per defecte: %u o testnet: %u)</translation> </message> @@ -3278,6 +3464,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Manté com a màxim <n> connexions a iguals (per defecte: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Fes que el moneder faci difusió de les transaccions</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Memòria intermèdia màxima de recepció per connexió, <n>*1000 bytes (per defecte: %u)</translation> </message> @@ -3286,10 +3476,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Memòria intermèdia màxima d'enviament per connexió, <n>*1000 bytes (per defecte: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Només accepta els punts de control integrats que coincideixen amb la cadena de blocs (per defecte: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Posa davant de la sortida de depuració una marca horària (per defecte: %u)</translation> </message> @@ -3302,10 +3488,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Retransmet multisig no P2SH (per defecte: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Executa un fil per buidar el moneder periòdicament (per defecte: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Fitxer de certificat del servidor (per defecte: %s)</translation> </message> @@ -3326,10 +3508,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Defineix el nombre de fils a crides de servei RPC (per defecte: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Defineix el senyalador DB_PRIVATE en l'entorn db del moneder (per defecte: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Especifica el fitxer de configuració (per defecte: %s)</translation> </message> @@ -3346,10 +3524,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Gasta el canvi no confirmat en enviar les transaccions (per defecte: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Atura l'execució després d'importar blocs del disc (per defecte: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Llindar per a desconnectar els iguals de comportament qüestionable (per defecte: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_ca@valencia.ts b/src/qt/locale/bitcoin_ca@valencia.ts index c68cfb686a..b77845cfb2 100644 --- a/src/qt/locale/bitcoin_ca@valencia.ts +++ b/src/qt/locale/bitcoin_ca@valencia.ts @@ -1,7 +1,11 @@ -<TS language="ca@valencia" version="2.1"> +<TS language="ca@valencia" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>Feu clic dret per a editar l'adreça o l'etiqueta</translation> + </message> + <message> <source>Create a new address</source> <translation>Crea una nova adreça</translation> </message> @@ -83,7 +87,7 @@ </message> <message> <source>Comma separated file (*.csv)</source> - <translation>Fitxer separat per comes (*.csv)</translation> + <translation>Fitxer de separació amb comes (*.csv)</translation> </message> <message> <source>Exporting Failed</source> @@ -164,6 +168,10 @@ <translation>Esteu segur que voleu encriptar el vostre moneder?</translation> </message> <message> + <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>Ara es tancarà el Bitcoin Core per finalitzar el procés d'encriptació. Tingueu present que encriptar el vostre moneder no garanteix que les vostres bitcoins no puguen ser robades per programari maliciós que infecti l'ordinador.</translation> + </message> + <message> <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source> <translation>IMPORTANT: Tota copia de seguretat que hàgeu realitzat hauria de ser reemplaçada pel, recentment generat, fitxer encriptat del moneder.</translation> </message> @@ -180,6 +188,10 @@ <translation>Introduïu la contrasenya nova al moneder.<br/>Utilitzeu una contrasenya de <b>deu o més caràcters aleatoris</b>, o <b>vuit o més paraules</b>.</translation> </message> <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Introduïu la contrasenya antiga i la contrasenya nova al moneder.</translation> + </message> + <message> <source>Wallet encryption failed</source> <translation>L'encriptació del moneder ha fallat</translation> </message> @@ -387,6 +399,10 @@ <translation>&Quant al Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Modifica les opcions de configuració del Bitcoin Core</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Mostra la llista d'adreces d'enviament i etiquetes utilitzades</translation> </message> @@ -406,14 +422,34 @@ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> <translation>Mostra el missatge d'ajuda del Bitcoin Core per obtindre una llista amb les possibles opcions de línia d'ordes de Bitcoin</translation> </message> + <message numerus="yes"> + <source>%n active connection(s) to Bitcoin network</source> + <translation><numerusform>%n connexió activa a la xarxa Bitcoin</numerusform><numerusform>%n connexions actives a la xarxa Bitcoin</numerusform></translation> + </message> <message> <source>No block source available...</source> <translation>No hi ha cap font de bloc disponible...</translation> </message> + <message numerus="yes"> + <source>%n hour(s)</source> + <translation><numerusform>%n hora</numerusform><numerusform>%n hores</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n day(s)</source> + <translation><numerusform>%n dia</numerusform><numerusform>%n dies</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n week(s)</source> + <translation><numerusform>%n setmana</numerusform><numerusform>%n setmanes</numerusform></translation> + </message> <message> <source>%1 and %2</source> <translation>%1 i %2</translation> </message> + <message numerus="yes"> + <source>%n year(s)</source> + <translation><numerusform>%n any</numerusform><numerusform>%n anys</numerusform></translation> + </message> <message> <source>%1 behind</source> <translation>%1 darrere</translation> @@ -436,7 +472,7 @@ </message> <message> <source>Information</source> - <translation>&Informació</translation> + <translation>Informació</translation> </message> <message> <source>Up to date</source> @@ -447,6 +483,36 @@ <translation>S'està posant al dia ...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Data: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Import: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Tipus: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Etiqueta: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Adreça: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Transacció enviada</translation> </message> @@ -473,6 +539,10 @@ <context> <name>CoinControlDialog</name> <message> + <source>Coin Selection</source> + <translation>Selecció de moneda</translation> + </message> + <message> <source>Quantity:</source> <translation>Quantitat:</translation> </message> @@ -490,7 +560,7 @@ </message> <message> <source>Fee:</source> - <translation>Comissió:</translation> + <translation>Comissió</translation> </message> <message> <source>Dust:</source> @@ -498,7 +568,7 @@ </message> <message> <source>After Fee:</source> - <translation>Quota posterior:</translation> + <translation>Comissió posterior:</translation> </message> <message> <source>Change:</source> @@ -518,7 +588,15 @@ </message> <message> <source>Amount</source> - <translation>Quantitat</translation> + <translation>Import</translation> + </message> + <message> + <source>Received with label</source> + <translation>Rebut amb l'etiqueta</translation> + </message> + <message> + <source>Received with address</source> + <translation>Rebut amb l'adreça</translation> </message> <message> <source>Date</source> @@ -538,11 +616,11 @@ </message> <message> <source>Copy address</source> - <translation>Copia l'adreça</translation> + <translation>Copiar adreça </translation> </message> <message> <source>Copy label</source> - <translation>Copia l'etiqueta</translation> + <translation>Copiar etiqueta</translation> </message> <message> <source>Copy amount</source> @@ -566,7 +644,7 @@ </message> <message> <source>Copy fee</source> - <translation>Copia la comissi</translation> + <translation>Copia la comissió</translation> </message> <message> <source>Copy after fee</source> @@ -633,6 +711,18 @@ <translation>cap</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Esta etiqueta es torna en roig si la transacció és superior a 1000 bytes.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Esta etiqueta es torna en roig si la propietat és inferior que la «mitjana».</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Esta etiqueta es torna roja si el destinatari rep un import inferior de %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Pot variar +/- %1 satoshi(s) per entrada.</translation> </message> @@ -646,7 +736,7 @@ </message> <message> <source>This means a fee of at least %1 per kB is required.</source> - <translation>Això comporta una comissi d'almenys %1 per kB.</translation> + <translation>Això comporta una comissió d'almenys %1 per kB.</translation> </message> <message> <source>Can vary +/- 1 byte per input.</source> @@ -673,7 +763,7 @@ <name>EditAddressDialog</name> <message> <source>Edit Address</source> - <translation>Editar Adreça</translation> + <translation>Edita l'adreça</translation> </message> <message> <source>&Label</source> @@ -816,7 +906,15 @@ <source>Error</source> <translation>Error</translation> </message> - </context> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n GB d'espai lliure disponible</numerusform><numerusform>%n GB d'espai lliure disponible</numerusform></translation> + </message> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(de %n GB necessari)</numerusform><numerusform>(de %n GB necessaris)</numerusform></translation> + </message> +</context> <context> <name>OpenURIDialog</name> <message> @@ -875,6 +973,14 @@ <translation>Adreça IP del proxy (p. ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>Minimitza en comptes d'eixir de l'aplicació quan la finestra es tanca. Quan s'habilita esta opció l'aplicació es tancara només quan se selecciona Ix del menú. </translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>La interfície d'usuari pot definir-se des d'ací. El paràmetre tindrà efecte després de reiniciar el Bitcoin Core.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>URL de terceres parts (p. ex. explorador de blocs) que apareix en la pestanya de transaccions com elements del menú contextual. %s en l'URL es reemplaçat pel resum de la transacció. Diferents URL estan separades per una barra vertical |.</translation> </message> @@ -899,6 +1005,14 @@ <translation>&Xarxa</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Inicia el Bitcoin Core automàticament després d'iniciar una sessió en el sistema.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Inicia el Bitcoin Core en inciar el sistema</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = auto, <0 = deixa tants nuclis lliures)</translation> </message> @@ -931,6 +1045,14 @@ <translation>Port obert amb &UPnP</translation> </message> <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>Connecta a la xarxa Bitcoin a través d'un proxy SOCKS5.</translation> + </message> + <message> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation>&Connecta a través d'un proxy SOCKS5 (proxy per defecte):</translation> + </message> + <message> <source>Proxy &IP:</source> <translation>&IP del proxy:</translation> </message> @@ -1003,6 +1125,10 @@ <translation>Cal reiniciar el client per activar els canvis.</translation> </message> <message> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Es pararà el client. Voleu procedir?</translation> + </message> + <message> <source>This change would require a client restart.</source> <translation>Amb este canvi cal un reinici del client.</translation> </message> @@ -1050,6 +1176,10 @@ <translation>Balanç minat que encara no ha madurat</translation> </message> <message> + <source>Balances</source> + <translation>Balances</translation> + </message> + <message> <source>Total:</source> <translation>Total:</translation> </message> @@ -1062,6 +1192,14 @@ <translation>El vostre balanç actual en adreces de només lectura</translation> </message> <message> + <source>Spendable:</source> + <translation>Que es pot gastar:</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>Transaccions recents</translation> + </message> + <message> <source>Unconfirmed transactions to watch-only addresses</source> <translation>Transaccions sense confirmar a adreces de només lectura</translation> </message> @@ -1125,14 +1263,30 @@ <translation>No es pot llegir el fitxer de la sol·licitud de pagament. Això pot ser causat per un fitxer de sol·licitud de pagament no vàlid.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>La sol·licitud de pagament ha vençut.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>No s'accepten sol·licituds de pagament no verificades a scripts de pagament personalitzats.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Sol·licitud de pagament no vàlida.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Reemborsament de %1</translation> </message> <message> + <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source> + <translation>La sol·licitud de pagament %1 és massa gran (%2 bytes, permés %3 bytes).</translation> + </message> + <message> + <source>Payment request DoS protection</source> + <translation>Protecció de DoS per a la sol·licitud de pagament</translation> + </message> + <message> <source>Error communicating with %1: %2</source> <translation>Error en comunicar amb %1: %2</translation> </message> @@ -1160,6 +1314,10 @@ <translation>Agent d'usuari</translation> </message> <message> + <source>Node/Service</source> + <translation>Node/Servei</translation> + </message> + <message> <source>Ping Time</source> <translation>Temps de ping</translation> </message> @@ -1168,7 +1326,7 @@ <name>QObject</name> <message> <source>Amount</source> - <translation>Quantitat</translation> + <translation>Import</translation> </message> <message> <source>Enter a Bitcoin address (e.g. %1)</source> @@ -1281,6 +1439,10 @@ <translation>Nombre de blocs actuals</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Obri el fitxer de registre de depuració del Bitcoin Core del directori de dades actual. Pot portar uns quants segons per a fitxers de registre grans.</translation> + </message> + <message> <source>Received</source> <translation>Rebut</translation> </message> @@ -1349,6 +1511,10 @@ <translation>Temps de ping</translation> </message> <message> + <source>Time Offset</source> + <translation>Diferència horària</translation> + </message> + <message> <source>Last block time</source> <translation>Últim temps de bloc</translation> </message> @@ -1393,6 +1559,10 @@ <translation>Neteja la consola</translation> </message> <message> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Vos donem la benviguda a la consola RPC del Bitcoin Core.</translation> + </message> + <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Utilitza les fletxes d'amunt i avall per navegar per l'historial, i <b>Ctrl-L<\b> per netejar la pantalla.</translation> </message> @@ -1560,7 +1730,7 @@ </message> <message> <source>Amount</source> - <translation>Quantitat</translation> + <translation>Import</translation> </message> <message> <source>Label</source> @@ -1595,7 +1765,7 @@ </message> <message> <source>Amount</source> - <translation>Quantitat</translation> + <translation>Import</translation> </message> <message> <source>(no label)</source> @@ -1654,7 +1824,7 @@ </message> <message> <source>After Fee:</source> - <translation>Quota posterior:</translation> + <translation>Comissió posterior:</translation> </message> <message> <source>Change:</source> @@ -1669,6 +1839,74 @@ <translation>Personalitza l'adreça de canvi</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Comissió de transacció</translation> + </message> + <message> + <source>Choose...</source> + <translation>Tria...</translation> + </message> + <message> + <source>collapse fee-settings</source> + <translation>redueix els paràmetres de comissió</translation> + </message> + <message> + <source>per kilobyte</source> + <translation>per kilobyte</translation> + </message> + <message> + <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> + <translation>Si la comissió personalitzada es defineix a 1000 satoshis i la transacció és de només 250 bytes, llavors «per kilobyte» només es paguen 250 satoshis en una comissió, mentre que amb la de «total com a mínim» es pagarien 1000 satoshis. Per a transaccions superiors al kilobyte, en tots dos casos es paga per kilobyte.</translation> + </message> + <message> + <source>Hide</source> + <translation>Amaga</translation> + </message> + <message> + <source>total at least</source> + <translation>total com a mínim</translation> + </message> + <message> + <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source> + <translation>No hi ha cap problema en pagar només la comissió mínima sempre que hi haja menys volum de transacció que espai en els blocs. Però tingueu present que això pot acabar en una transacció que mai es confirme una vegada hi haja més demanda de transaccions de bitcoins que la xarxa puga processar.</translation> + </message> + <message> + <source>(read the tooltip)</source> + <translation>(llegiu l'indicador de funció)</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Recomanada:</translation> + </message> + <message> + <source>Custom:</source> + <translation>Personalitzada:</translation> + </message> + <message> + <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source> + <translation>(No s'ha inicialitzat encara la comissió intel·ligent. Normalment pren uns pocs blocs...)</translation> + </message> + <message> + <source>Confirmation time:</source> + <translation>Temps de confirmació:</translation> + </message> + <message> + <source>normal</source> + <translation>normal</translation> + </message> + <message> + <source>fast</source> + <translation>ràpid</translation> + </message> + <message> + <source>Send as zero-fee transaction if possible</source> + <translation>Envia com a transacció de comissió zero si és possible</translation> + </message> + <message> + <source>(confirmation may take longer)</source> + <translation>(la confirmació pot trigar més temps)</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Envia a múltiples destinataris al mateix temps</translation> </message> @@ -1678,7 +1916,7 @@ </message> <message> <source>Clear all fields of the form.</source> - <translation>Esborra tots els camps del formuari.</translation> + <translation>Netejar tots els camps del formulari.</translation> </message> <message> <source>Dust:</source> @@ -1718,7 +1956,7 @@ </message> <message> <source>Copy fee</source> - <translation>Copia la comissi</translation> + <translation>Copia la comissió</translation> </message> <message> <source>Copy after fee</source> @@ -1754,7 +1992,7 @@ </message> <message> <source>The total exceeds your balance when the %1 transaction fee is included.</source> - <translation>El total excedeix el teu balanç quan s'afig la comisió a la transacció %1.</translation> + <translation>El total excedeix el teu balanç quan s'afig la comissió a la transacció %1.</translation> </message> <message> <source>Transaction creation failed!</source> @@ -1765,6 +2003,30 @@ <translation>S'ha rebutjat la transacció! Això pot passar si alguna de les monedes del vostre moneder ja s'han gastat; per exemple, si heu fet servir una còpia de seguretat del fitxer wallet.dat i s'hagueren gastat monedes de la còpia però sense marcar-les-hi com a gastades.</translation> </message> <message> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>Una comissió superior a %1 es considera una comissió absurdament alta.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>La sol·licitud de pagament ha vençut.</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Estimat per començar la confirmació en %n bloc.</numerusform><numerusform>Estimat per començar la confirmació en %n blocs.</numerusform></translation> + </message> + <message> + <source>Pay only the minimum fee of %1</source> + <translation>Paga només la comissió mínima de %1</translation> + </message> + <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>L'adreça de destinatari no és vàlida. Torneu-la a comprovar.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>S'ha trobat una adreça duplicada: cal utilitzar les adreces només un cop cada vegada.</translation> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Avís: adreça Bitcoin no vàlida</translation> </message> @@ -1836,10 +2098,26 @@ <translation>Elimina esta entrada</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>La comissió es deduirà de l'import que s'enviarà. El destinatari rebrà menys bitcoins que les que introduïu al camp d'import. Si se seleccionen múltiples destinataris, la comissió es dividirà per igual.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>S&ubstreu la comissió de l'import</translation> + </message> + <message> <source>Message:</source> <translation>Missatge:</translation> </message> <message> + <source>This is an unauthenticated payment request.</source> + <translation>Esta és una sol·licitud de pagament no autenticada.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Esta és una sol·licitud de pagament autenticada.</translation> + </message> + <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>Introduïu una etiqueta per a esta adreça per afegir-la a la llista d'adreces utilitzades</translation> </message> @@ -1878,20 +2156,24 @@ <translation>&Signa el missatge</translation> </message> <message> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>Podeu signar missatges/acords amb les vostres adreces per provar que rebeu les bitcoins que s'hi envien. Aneu amb compte no signar res que siga vague o aleatori, perquè en alguns atacs de suplantació es pot provar que hi signeu la vostra identitat. Només signeu aquelles declaracions completament detallades en què hi esteu d'acord. </translation> + </message> + <message> <source>The Bitcoin address to sign the message with</source> <translation>L'adreça Bitcoin amb què signar el missatge</translation> </message> <message> <source>Choose previously used address</source> - <translation>Trieu una adreça feta servir anteriorment</translation> + <translation>Tria les adreces fetes servir amb anterioritat</translation> </message> <message> <source>Alt+A</source> - <translation>Alta+A</translation> + <translation>Alt+A</translation> </message> <message> <source>Paste address from clipboard</source> - <translation>Apegar adreça del porta-retalls</translation> + <translation>Apega l'adreça del porta-retalls</translation> </message> <message> <source>Alt+P</source> @@ -1930,6 +2212,10 @@ <translation>&Verifica el missatge</translation> </message> <message> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Introduïu l'adreça del receptor, el missatge (assegureu-vos de copiar els salts de línia, espais, tabuladors, etc. exactament) i signatura de sota per verificar el missatge. Tingueu cura de no llegir més en la signatura del que està al missatge signat, per evitar ser enganyat per un atac d'home-en-el-mig. Tingueu en compte que això només demostra que la part que signa rep amb l'adreça, i no es pot provar l'enviament de qualsevol transacció!</translation> + </message> + <message> <source>The Bitcoin address the message was signed with</source> <translation>L'adreça Bitcoin amb què va ser signat el missatge</translation> </message> @@ -2002,7 +2288,7 @@ <name>SplashScreen</name> <message> <source>Bitcoin Core</source> - <translation>Nucli de Bitcoin</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>The Bitcoin Core developers</source> @@ -2046,6 +2332,10 @@ <source>Status</source> <translation>Estat</translation> </message> + <message numerus="yes"> + <source>, broadcast through %n node(s)</source> + <translation><numerusform>, difusió a través de %n node</numerusform><numerusform>, difusió a través de %n nodes</numerusform></translation> + </message> <message> <source>Date</source> <translation>Data</translation> @@ -2082,6 +2372,10 @@ <source>Credit</source> <translation>Crèdit</translation> </message> + <message numerus="yes"> + <source>matures in %n more block(s)</source> + <translation><numerusform>madura en %n bloc més</numerusform><numerusform>madura en %n blocs més</numerusform></translation> + </message> <message> <source>not accepted</source> <translation>no acceptat</translation> @@ -2140,7 +2434,7 @@ </message> <message> <source>Amount</source> - <translation>Quantitat</translation> + <translation>Import</translation> </message> <message> <source>true</source> @@ -2154,6 +2448,10 @@ <source>, has not been successfully broadcast yet</source> <translation>, encara no ha estat emés correctement</translation> </message> + <message numerus="yes"> + <source>Open for %n more block(s)</source> + <translation><numerusform>Obri per %n bloc més</numerusform><numerusform>Obri per %n blocs més</numerusform></translation> + </message> <message> <source>unknown</source> <translation>desconegut</translation> @@ -2184,6 +2482,10 @@ <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Immadur (%1 confirmacions, serà disponible després de %2)</translation> </message> + <message numerus="yes"> + <source>Open for %n more block(s)</source> + <translation><numerusform>Obri per %n bloc més</numerusform><numerusform>Obri per %n blocs més</numerusform></translation> + </message> <message> <source>Open until %1</source> <translation>Obert fins %1</translation> @@ -2261,6 +2563,14 @@ <translation>Tipus de transacció.</translation> </message> <message> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <translation>Si està implicada o no una adreça només de lectura en la transacció.</translation> + </message> + <message> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Intenció/propòsit de la transacció definida per l'usuari.</translation> + </message> + <message> <source>Amount removed from or added to balance.</source> <translation>Import extret o afegit del balanç.</translation> </message> @@ -2329,7 +2639,7 @@ </message> <message> <source>Copy label</source> - <translation>Copia l'etiqueta</translation> + <translation>Copiar etiqueta</translation> </message> <message> <source>Copy amount</source> @@ -2352,6 +2662,10 @@ <translation>Exporta l'historial de transacció</translation> </message> <message> + <source>Watch-only</source> + <translation>Només de lectura</translation> + </message> + <message> <source>Exporting Failed</source> <translation>L'exportació ha fallat</translation> </message> @@ -2503,16 +2817,20 @@ <translation>Elimina totes les transaccions del moneder i només recupera aquelles de la cadena de blocs a través de -rescan a l'inici</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Entra en el mode de proves de regressió, que utilitza una cadena especial en què els blocs poden resoldre's al moment.</translation> + <source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> + <translation>Distribuït sota llicència de programari MIT. Vegeu el fitxer acompanyant COPYING o <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Executa una orde quan una transacció del moneder canvie (%s en cmd es canvia per TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>En este mode -genproclimit controla quants blocs es generen immediatament.</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Comissions totals màximes que s'utilitzaran en una única transacció de moneder; si s'estableix un valor massa baix es poden interrompre transaccions grans (per defecte: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>Redueix els requeriments d'emmagatzemament podant (suprimint) els blocs antics. Este mode inhabilita l'ús de moneders i és incompatible amb -tindex. Avís: Revertir esta configuració comporta tornar a baixar la cadena de blocs sencera. (per defecte: 0 = inhabilita la poda de blocs, >%u = mida objectiu en MiB per utilitzar els fitxers de blocs)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2527,6 +2845,14 @@ <translation>No es pot enllaçar %s a este ordinador. El Bitcoin Core probablement ja estiga executant-s'hi.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>AVÍS: s'ha generat un nombre anòmalament alt de blocs, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>AVÍS: comproveu la vostra connexió a la xarxa, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Avís: el -paytxfee és molt elevat! Esta és la comissió de transacció que pagareu si envieu una transacció.</translation> </message> @@ -2547,6 +2873,10 @@ <translation>Avís: el fitxer wallet.dat és corrupte, dades rescatades! L'arxiu wallet.dat original ha estat guardat com wallet.{estampa_temporal}.bak al directori %s; si el teu balanç o transaccions son incorrectes hauries de restaurar-lo de un backup.</translation> </message> <message> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>Afig a la llista blanca els iguals que es connecten de la màscara de xarxa o adreça IP donada. Es pot especificar moltes vegades.</translation> + </message> + <message> <source>(default: 1)</source> <translation>(per defecte: 1)</translation> </message> @@ -2603,6 +2933,10 @@ <translation>Error en obrir la base de dades de blocs</translation> </message> <message> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation>Error: s'ha produït un error intern fatal. Consulteu debug.log per a més detalls</translation> + </message> + <message> <source>Error: Disk space is low!</source> <translation>Error: Espai al disc baix!</translation> </message> @@ -2631,6 +2965,18 @@ <translation>No hi ha suficient descriptors de fitxers disponibles.</translation> </message> <message> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <translation>Només connecta als nodes de la xarxa <net> (ipv4, ipv6 o onion)</translation> + </message> + <message> + <source>Prune cannot be configured with a negative value.</source> + <translation>La poda no es pot configurar amb un valor negatiu.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>El mode de poda és incompatible amb -txindex.</translation> + </message> + <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation>Defineix la mida de la memòria cau de la base de dades en megabytes (%d a %d, per defecte: %d)</translation> </message> @@ -2643,8 +2989,8 @@ <translation>Especifica un fitxer de moneder (dins del directori de dades)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Això s'així per a eines de proves de regressió per al desenvolupament d'aplicacions.</translation> + <source>Use UPnP to map the listening port (default: %u)</source> + <translation>Utilitza UPnP per a mapejar el port d'escolta (per defecte: %u)</translation> </message> <message> <source>Verifying blocks...</source> @@ -2663,6 +3009,10 @@ <translation>Opcions de moneder:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Avís: esta versió és obsoleta; cal actualitzar-la!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Cal que reconstruïu la base de dades fent servir -reindex per canviar -txindex</translation> </message> @@ -2691,6 +3041,10 @@ <translation>Crea fitxers nous amb els permisos per defecte del sistema, en comptes de l'umask 077 (només efectiu amb la funcionalitat de moneder inhabilitada)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Descobreix l'adreça IP pròpia (per defecte: 1 quan s'escolta i no -externalip o -proxy)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Error: ha fallat escoltar les connexions entrants (l'escoltament ha retornat l'error %s)</translation> </message> @@ -2707,22 +3061,73 @@ <translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la transmissió (per defecte: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la creació de la transacció (per defecte: %s)</translation> + <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> + <translation>Si no s'especifica una paytxfee (comissió de transacció de pagament), inclogueu suficient comissió per tal que les transaccions comencen a confirmar-se en una mitja de n blocs (per defecte: %u)</translation> + </message> + <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source> + <translation>Import no vàlid per a -maxtxfee=<amount>: '%s' (cal que siga com a mínim la comissió de minrelay de %s per evitar que les comissions s'encallin)</translation> + </message> + <message> + <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> + <translation>Mida màxima de les dades en les transaccions de l'operador en què confiem i en les meues (per defecte: %u)</translation> + </message> + <message> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>Poda configurada per sota el mínim de %d MB. Feu servir un nombre superior.</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Consulta a adreces d'iguals a través de DNS, si es troba baix en adreces (per defecte: 1 a menys que -connect)</translation> </message> <message> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Genera a l'atzar credencials per a cada connexió proxy. Això habilita l'aïllament del flux de Tor (per defecte: %u)</translation> + </message> + <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Defineix la mida màxima de transaccions d'alta prioritat / baixa comissió en bytes (per defecte: %d)</translation> </message> <message> + <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source> + <translation>Defineix el nombre de fils per a la generació de moneda si està habilitat (-1 = tots els nuclis, per defecte: %d)</translation> + </message> + <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>L'import de la transacció és massa petit per enviar-la després que se'n deduïsca la comissió</translation> + </message> + <message> <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source> <translation>Este producte inclou programari desenvolupat pel projecte OpenSSL per a ús a l'OpenSSL Toolkit <https://www.openssl.org/> i programari criptogràfic escrit per Eric Young i programari UPnP escrit per Thomas Bernard.</translation> </message> <message> + <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: +%s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +The username and password MUST NOT be the same. +If the file does not exist, create it with owner-readable-only file permissions. +It is also recommended to set alertnotify so you are notified of problems; +for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com +</source> + <translation>Per utilitzar bitcoind, o l'opció de serviddor de bitcoin-qt, heu de definir una rpcpassword en el fitxer de configuració: +%s +Es recomana que utilitzeu la contrasenya aleatòria següent: +rpcuser=bitcoinrpc +rpcpassword=%s +(no cal que recordeu la contrasenya) +El nom d'usuari i la contrasenya NO han de ser els mateixos. +Si el fitxer no existeix, creeu-ne un amb permisos de lectura només per al seu propietari. +Es recomana definir alertnotify per tal de ser notificat de qualsevol problema; +per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</translation> + </message> + <message> + <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> + <translation>Avís: s'ha especificat un -maxtxfee molt alt! Comissions tan grans podrien pagar-se en una única transacció.</translation> + </message> + <message> <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> <translation>Avís: comproveu que la data i hora del vostre ordinador siguen correctes! Si el vostre rellotge no és correcte, el Bitcoin Core no funcionarà correctament.</translation> </message> @@ -2731,6 +3136,26 @@ <translation>Els iguals en la llista blanca no poden ser bandejats per DoS i es transmetran sempre llurs transaccions, fins i tot si ja són a la mempool. Això és útil, p. ex., per a una passarel·la</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>Cal que torneu a construir la base de dades fent servir -reindex per tornar al mode no podat. Això tornarà a baixar la cadena de blocs sencera</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(per defecte: %u)</translation> + </message> + <message> + <source>Accept public REST requests (default: %u)</source> + <translation>Accepta sol·licituds REST públiques (per defecte: %u)</translation> + </message> + <message> + <source>Activating best chain...</source> + <translation>S'està activant la millor cadena...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>No es pot executar amb un moneder en mode poda.</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>No es pot resoldre l'adreça -whitebind: «%s»</translation> </message> @@ -2755,6 +3180,10 @@ <translation>Error en carregar wallet.dat: el moneder requereix una versió més nova del Bitcoin core</translation> </message> <message> + <source>Error reading from database, shutting down.</source> + <translation>Error en llegir la base de dades, tancant.</translation> + </message> + <message> <source>Error: Unsupported argument -tor found, use -onion.</source> <translation>Error: s'ha trobat un argument -tor no acceptat. Feu servir -onion.</translation> </message> @@ -2771,6 +3200,10 @@ <translation>Ha fallat la inicialització de la comprovació de validesa. El Bitcoin Core s'està parant.</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Import no vàlid per a -maxtxfee=<amount>: '%s'</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>Import no vàlid per a -minrelaytxfee=<amount>: «%s»</translation> </message> @@ -2787,6 +3220,10 @@ <translation>S'ha especificat una màscara de xarxa no vàlida a -whitelist: «%s»</translation> </message> <message> + <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> + <translation>Manté com a màxim <n> transaccions no connectables en memòria (per defecte: %u)</translation> + </message> + <message> <source>Need to specify a port with -whitebind: '%s'</source> <translation>Cal especificar un port amb -whitebind: «%s»</translation> </message> @@ -2803,24 +3240,32 @@ <translation>Opcions del servidor RPC:</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Descarta a l'atzar 1 de cada <n> missatges de la xarxa</translation> + <source>RPC support for HTTP persistent connections (default: %d)</source> + <translation>Suport RPC per a connexions HTTP persistents (per defecte: %d)</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Introdueix incertesa en 1 de cada <n> missatges de la xarxa</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Reconstrueix l'índex de la cadena de blocs dels fitxers blk000??.dat actuals a l'inici.</translation> + </message> + <message> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Rep i mostra avisos de la xarxa P2P (per defecte: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Envia informació de traça/depuració a la consola en comptes del fitxer debug.log</translation> </message> <message> + <source>Send transactions as zero-fee transactions if possible (default: %u)</source> + <translation>Envia les transaccions com a transaccions de comissió zero sempre que siga possible (per defecte: %u) </translation> + </message> + <message> <source>Set SSL root certificates for payment request (default: -system-)</source> <translation>Defineix certificats arrel SSL per a la sol·licitud de pagament (per defecte: -sistema-)</translation> </message> <message> <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Defineix un idioma, per exemple "de_DE" (per defecte: preferències locals de sistema)</translation> + <translation>Defineix un idioma, per exemple «de_DE» (per defecte: preferències locals de sistema)</translation> </message> <message> <source>Show all debugging options (usage: --help -help-debug)</source> @@ -2843,6 +3288,10 @@ <translation>Inicia minimitzat</translation> </message> <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>L'import de la transacció és massa petit per pagar-ne una comissió</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Això és programari experimental.</translation> </message> @@ -2855,10 +3304,18 @@ <translation>Els imports de les transaccions han de ser positius</translation> </message> <message> + <source>Transaction too large for fee policy</source> + <translation>Transacció massa gran per a la política de comissions</translation> + </message> + <message> <source>Transaction too large</source> <translation>La transacció és massa gran</translation> </message> <message> + <source>UI Options:</source> + <translation>Opcions d'interfície:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>No s'ha pogut vincular a %s en este ordinador (la vinculació ha retornat l'error %s)</translation> </message> @@ -2935,14 +3392,138 @@ <translation>Error en carregar wallet.dat: Moneder corrupte</translation> </message> <message> + <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source> + <translation>(1 = manté les metadades de les tx, p. ex., propietari del compte i informació de sol·licitud del pagament, 2 = prescindeix de les metadades de les tx)</translation> + </message> + <message> + <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> + <translation>Com d'exhaustiva és la verificació de blocs del -checkblocks (0-4, per defecte: %u)</translation> + </message> + <message> + <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> + <translation>Manté un índex complet de transaccions, utilitzat per la crida rpc getrawtransaction (per defecte: %u)</translation> + </message> + <message> + <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source> + <translation>Nombre de segons necessaris perquè els iguals de comportament qüestionable puguen tornar a connectar-se (per defecte: %u)</translation> + </message> + <message> + <source>Output debugging information (default: %u, supplying <category> is optional)</source> + <translation>Informació d'eixida de la depuració (per defecte: %u, proporcionar <category> és opcional)</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation>Utilitza un proxy SOCKS4 apart per a arribar als iguals a través de serveis ocults de Tor (per defecte: %s)</translation> + </message> + <message> + <source>(default: %s)</source> + <translation>(per defecte: %s)</translation> + </message> + <message> + <source>Acceptable ciphers (default: %s)</source> + <translation>Xifrats acceptables (per defecte: %s)</translation> + </message> + <message> + <source>Always query for peer addresses via DNS lookup (default: %u)</source> + <translation>Demana sempre les adreces dels iguals a través de consultes DNS (per defecte: %u)</translation> + </message> + <message> <source>Error loading wallet.dat</source> <translation>Error en carregar wallet.dat</translation> </message> <message> + <source>Generate coins (default: %u)</source> + <translation>Genera monedes (per defecte: %u)</translation> + </message> + <message> + <source>How many blocks to check at startup (default: %u, 0 = all)</source> + <translation>Quants blocs per comprovar a l'inici (per defecte: %u, 0 = tots)</translation> + </message> + <message> + <source>Include IP addresses in debug output (default: %u)</source> + <translation>Inclou l'adreça IP a l'eixida de depuració (per defecte: %u)</translation> + </message> + <message> <source>Invalid -proxy address: '%s'</source> <translation>Adreça -proxy invalida: '%s'</translation> </message> <message> + <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> + <translation>Escolta les connexions JSON-RPC en <port> (per defecte: %u o testnet: %u)</translation> + </message> + <message> + <source>Listen for connections on <port> (default: %u or testnet: %u)</source> + <translation>Escolta les connexions en <port> (per defecte: %u o testnet: %u)</translation> + </message> + <message> + <source>Maintain at most <n> connections to peers (default: %u)</source> + <translation>Manté com a màxim <n> connexions a iguals (per defecte: %u)</translation> + </message> + <message> + <source>Make the wallet broadcast transactions</source> + <translation>Fes que el moneder faça difusió de les transaccions</translation> + </message> + <message> + <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> + <translation>Memòria intermèdia màxima de recepció per connexió, <n>*1000 bytes (per defecte: %u)</translation> + </message> + <message> + <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source> + <translation>Memòria intermèdia màxima d'enviament per connexió, <n>*1000 bytes (per defecte: %u)</translation> + </message> + <message> + <source>Prepend debug output with timestamp (default: %u)</source> + <translation>Posa davant de l'eixida de depuració una marca horària (per defecte: %u)</translation> + </message> + <message> + <source>Relay and mine data carrier transactions (default: %u)</source> + <translation>Retransmet i mina les transaccions de l'operador (per defecte: %u)</translation> + </message> + <message> + <source>Relay non-P2SH multisig (default: %u)</source> + <translation>Retransmet multisig no P2SH (per defecte: %u)</translation> + </message> + <message> + <source>Server certificate file (default: %s)</source> + <translation>Fitxer de certificat del servidor (per defecte: %s)</translation> + </message> + <message> + <source>Server private key (default: %s)</source> + <translation>Clau privada del servidor (per defecte: %s)</translation> + </message> + <message> + <source>Set key pool size to <n> (default: %u)</source> + <translation>Defineix la mida clau disponible a <n> (per defecte: %u)</translation> + </message> + <message> + <source>Set minimum block size in bytes (default: %u)</source> + <translation>Defineix la mida de bloc mínima en bytes (per defecte: %u)</translation> + </message> + <message> + <source>Set the number of threads to service RPC calls (default: %d)</source> + <translation>Defineix el nombre de fils a crides de servei RPC (per defecte: %d)</translation> + </message> + <message> + <source>Specify configuration file (default: %s)</source> + <translation>Especifica el fitxer de configuració (per defecte: %s)</translation> + </message> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Especifica el temps d'espera de la connexió en milisegons (mínim: 1, per defecte: %d)</translation> + </message> + <message> + <source>Specify pid file (default: %s)</source> + <translation>Especifica el fitxer pid (per defecte: %s)</translation> + </message> + <message> + <source>Spend unconfirmed change when sending transactions (default: %u)</source> + <translation>Gasta el canvi no confirmat en enviar les transaccions (per defecte: %u)</translation> + </message> + <message> + <source>Threshold for disconnecting misbehaving peers (default: %u)</source> + <translation>Llindar per a desconnectar els iguals de comportament qüestionable (per defecte: %u)</translation> + </message> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Xarxa desconeguda especificada a -onlynet: '%s'</translation> </message> diff --git a/src/qt/locale/bitcoin_ca_ES.ts b/src/qt/locale/bitcoin_ca_ES.ts index cd6aa96d34..898b7f33b3 100644 --- a/src/qt/locale/bitcoin_ca_ES.ts +++ b/src/qt/locale/bitcoin_ca_ES.ts @@ -1,4 +1,4 @@ -<TS language="ca_ES" version="2.1"> +<TS language="ca_ES" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -168,6 +168,10 @@ <translation>Esteu segur que voleu encriptar el vostre moneder?</translation> </message> <message> + <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>Ara es tancarà el Bitcoin Core per finalitzar el procés d'encriptació. Tingueu present que encriptar el vostre moneder no garanteix que les vostres bitcoins no puguin ser robades per programari maliciós que infecti l'ordinador.</translation> + </message> + <message> <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source> <translation>IMPORTANT: Tota copia de seguretat que hàgiu realitzat hauria de ser reemplaçada pel, recentment generat, fitxer encriptat del moneder.</translation> </message> @@ -184,6 +188,10 @@ <translation>Introduïu la contrasenya nova al moneder.<br/>Utilitzeu una contrasenya de <b>deu o més caràcters aleatoris</b>, o <b>vuit o més paraules</b>.</translation> </message> <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Introduïu la contrasenya antiga i la contrasenya nova al moneder.</translation> + </message> + <message> <source>Wallet encryption failed</source> <translation>L'encriptació del moneder ha fallat</translation> </message> @@ -391,6 +399,10 @@ <translation>&Quant al Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Modifica les opcions de configuració del Bitcoin Core</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Mostra la llista d'adreces d'enviament i etiquetes utilitzades</translation> </message> @@ -419,6 +431,10 @@ <translation>No hi ha cap font de bloc disponible...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>S'han processat %n bloc de l'historial de transacció.</numerusform><numerusform>S'han processat %n blocs de l'historial de transacció.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n hora</numerusform><numerusform>%n hores</numerusform></translation> </message> @@ -471,6 +487,36 @@ <translation>S'està posant al dia ...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Data: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Import: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Tipus: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Etiqueta: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Adreça: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Transacció enviada</translation> </message> @@ -669,6 +715,18 @@ <translation>cap</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Aquesta etiqueta es torna en vermell si la transacció és superior a 1000 bytes.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Aquesta etiqueta es torna en vermell si la propietat és inferior que la «mitjana».</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Aquesta etiqueta es torna vermella si el destinatari rep un import inferior de %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Pot variar +/- %1 satoshi(s) per entrada.</translation> </message> @@ -919,6 +977,14 @@ <translation>Adreça IP del proxy (p. ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>Minimitza en comptes de sortir de l'aplicació quan la finestra es tanca. Quan s'habilita aquesta opció l'aplicació es tancara només quan se selecciona Surt del menú. </translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>La interfície d'usuari pot definir-se des d'aquí. El paràmetre tindrà efecte després de reiniciar el Bitcoin Core.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>URL de terceres parts (p. ex. explorador de blocs) que apareix en la pestanya de transaccions com elements del menú contextual. %s en l'URL es reemplaçat pel resum de la transacció. Diferents URL estan separades per una barra vertical |.</translation> </message> @@ -943,6 +1009,14 @@ <translation>&Xarxa</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Inicia el Bitcoin Core automàticament després d'iniciar una sessió en el sistema.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Inicia el Bitcoin Core en inciar el sistema</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = auto, <0 = deixa tants nuclis lliures)</translation> </message> @@ -1055,6 +1129,10 @@ <translation>Cal reiniciar el client per activar els canvis.</translation> </message> <message> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>S'aturarà el client. Voleu procedir?</translation> + </message> + <message> <source>This change would require a client restart.</source> <translation>Amb aquest canvi cal un reinici del client.</translation> </message> @@ -1189,10 +1267,18 @@ <translation>No es pot llegir el fitxer de la sol·licitud de pagament. Això pot ser causat per un fitxer de sol·licitud de pagament no vàlid.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>La sol·licitud de pagament ha vençut.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>No s'accepten sol·licituds de pagament no verificades a scripts de pagament personalitzats.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Sol·licitud de pagament no vàlida.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Reemborsament de %1</translation> </message> @@ -1232,6 +1318,10 @@ <translation>Agent d'usuari</translation> </message> <message> + <source>Node/Service</source> + <translation>Node/Servei</translation> + </message> + <message> <source>Ping Time</source> <translation>Temps de ping</translation> </message> @@ -1353,6 +1443,10 @@ <translation>Nombre de blocs actuals</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Obre el fitxer de registre de depuració del Bitcoin Core del directori de dades actual. Pot portar uns quants segons per a fitxers de registre grans.</translation> + </message> + <message> <source>Received</source> <translation>Rebut</translation> </message> @@ -1421,6 +1515,10 @@ <translation>Temps de ping</translation> </message> <message> + <source>Time Offset</source> + <translation>Diferència horària</translation> + </message> + <message> <source>Last block time</source> <translation>Últim temps de bloc</translation> </message> @@ -1465,6 +1563,10 @@ <translation>Neteja la consola</translation> </message> <message> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Us donem la benviguda a la consola RPC del Bitcoin Core.</translation> + </message> + <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Utilitza les fletxes d'amunt i avall per navegar per l'historial, i <b>Ctrl-L<\b> per netejar la pantalla.</translation> </message> @@ -1761,6 +1863,10 @@ <translation>Si la comissió personalitzada es defineix a 1000 satoshis i la transacció és de només 250 bytes, llavors «per kilobyte» només es paguen 250 satoshis en una comissió, mentre que amb la de «total com a mínim» es pagarien 1000 satoshis. Per a transaccions superiors al kilobyte, en tots dos casos es paga per kilobyte.</translation> </message> <message> + <source>Hide</source> + <translation>Amaga</translation> + </message> + <message> <source>total at least</source> <translation>total com a mínim</translation> </message> @@ -1901,10 +2007,30 @@ <translation>S'ha rebutjat la transacció! Això pot passar si alguna de les monedes del vostre moneder ja s'han gastat; per exemple, si heu fet servir una còpia de seguretat del fitxer wallet.dat i s'haguessin gastat monedes de la còpia però sense marcar-les-hi com a gastades.</translation> </message> <message> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>Una comissió superior a %1 es considera una comissió absurdament alta.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>La sol·licitud de pagament ha vençut.</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Estimat per començar la confirmació en %n bloc.</numerusform><numerusform>Estimat per començar la confirmació en %n blocs.</numerusform></translation> + </message> + <message> <source>Pay only the minimum fee of %1</source> <translation>Paga només la comissió mínima de %1</translation> </message> <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>L'adreça de destinatari no és vàlida. Torneu-la a comprovar.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>S'ha trobat una adreça duplicada: cal utilitzar les adreces només un cop cada vegada.</translation> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Avís: adreça Bitcoin no vàlida</translation> </message> @@ -1976,10 +2102,26 @@ <translation>Elimina aquesta entrada</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>La comissió es deduirà de l'import que s'enviarà. El destinatari rebrà menys bitcoins que les que introduïu al camp d'import. Si se seleccionen múltiples destinataris, la comissió es dividirà per igual.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>S&ubstreu la comissió de l'import</translation> + </message> + <message> <source>Message:</source> <translation>Missatge:</translation> </message> <message> + <source>This is an unauthenticated payment request.</source> + <translation>Aquesta és una sol·licitud de pagament no autenticada.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Aquesta és una sol·licitud de pagament autenticada.</translation> + </message> + <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>Introduïu una etiqueta per a aquesta adreça per afegir-la a la llista d'adreces utilitzades</translation> </message> @@ -2018,6 +2160,10 @@ <translation>&Signa el missatge</translation> </message> <message> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>Podeu signar missatges/acords amb les vostres adreces per provar que rebeu les bitcoins que s'hi envien. Aneu amb compte no signar res que sigui vague o aleatori, perquè en alguns atacs de suplantació es pot provar que hi signeu la vostra identitat. Només signeu aquelles declaracions completament detallades en què hi esteu d'acord. </translation> + </message> + <message> <source>The Bitcoin address to sign the message with</source> <translation>L'adreça Bitcoin amb què signar el missatge</translation> </message> @@ -2070,6 +2216,10 @@ <translation>&Verifica el missatge</translation> </message> <message> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Introduïu l'adreça del receptor, el missatge (assegureu-vos de copiar els salts de línia, espais, tabuladors, etc. exactament) i signatura de sota per verificar el missatge. Tingueu cura de no llegir més en la signatura del que està al missatge signat, per evitar ser enganyat per un atac d'home-en-el-mig. Tingueu en compte que això només demostra que la part que signa rep amb l'adreça, i no es pot provar l'enviament de qualsevol transacció!</translation> + </message> + <message> <source>The Bitcoin address the message was signed with</source> <translation>L'adreça Bitcoin amb què va ser signat el missatge</translation> </message> @@ -2421,6 +2571,10 @@ <translation>Si està implicada o no una adreça només de lectura en la transacció.</translation> </message> <message> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Intenció/propòsit de la transacció definida per l'usuari.</translation> + </message> + <message> <source>Amount removed from or added to balance.</source> <translation>Import extret o afegit del balanç.</translation> </message> @@ -2671,16 +2825,16 @@ <translation>Distribuït sota llicència de programari MIT. Vegeu el fitxer acompanyant COPYING o <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Entra en el mode de proves de regressió, que utilitza una cadena especial en què els blocs poden resoldre's al moment.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Executa una ordre quan una transacció del moneder canviï (%s en cmd es canvia per TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>En aquest mode -genproclimit controla quants blocs es generen immediatament.</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Comissions totals màximes que s'utilitzaran en una única transacció de moneder; si s'estableix un valor massa baix es poden interrompre transaccions grans (per defecte: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>Redueix els requeriments d'emmagatzemament podant (suprimint) els blocs antics. Aquest mode inhabilita l'ús de moneders i és incompatible amb -tindex. Avís: Revertir aquesta configuració comporta tornar a baixar la cadena de blocs sencera. (per defecte: 0 = inhabilita la poda de blocs, >%u = mida objectiu en MiB per utilitzar els fitxers de blocs)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2695,6 +2849,14 @@ <translation>No es pot enllaçar %s a aquest ordinador. El Bitcoin Core probablement ja estigui executant-s'hi.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>AVÍS: s'ha generat un nombre anòmalament alt de blocs, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>AVÍS: comproveu la vostra connexió a la xarxa, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Avís: el -paytxfee és molt elevat! Aquesta és la comissió de transacció que pagareu si envieu una transacció.</translation> </message> @@ -2811,6 +2973,14 @@ <translation>Només connecta als nodes de la xarxa <net> (ipv4, ipv6 o onion)</translation> </message> <message> + <source>Prune cannot be configured with a negative value.</source> + <translation>La poda no es pot configurar amb un valor negatiu.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>El mode de poda és incompatible amb -txindex.</translation> + </message> + <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation>Defineix la mida de la memòria cau de la base de dades en megabytes (%d a %d, per defecte: %d)</translation> </message> @@ -2823,10 +2993,6 @@ <translation>Especifica un fitxer de moneder (dins del directori de dades)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Això es així per a eines de proves de regressió per al desenvolupament d'aplicacions.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Utilitza UPnP per a mapejar el port d'escolta (per defecte: %u)</translation> </message> @@ -2847,6 +3013,10 @@ <translation>Opcions de moneder:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Avís: aquesta versió és obsoleta; cal actualitzar-la!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Cal que reconstruïu la base de dades fent servir -reindex per canviar -txindex</translation> </message> @@ -2875,6 +3045,10 @@ <translation>Crea fitxers nous amb els permisos per defecte del sistema, en comptes de l'umask 077 (només efectiu amb la funcionalitat de moneder inhabilitada)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Descobreix l'adreça IP pròpia (per defecte: 1 quan s'escolta i no -externalip o -proxy)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Error: ha fallat escoltar les connexions entrants (l'escoltament ha retornat l'error %s)</translation> </message> @@ -2891,10 +3065,6 @@ <translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la transmissió (per defecte: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la creació de la transacció (per defecte: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Si no s'especifica una paytxfee (comissió de transacció de pagament), inclogueu suficient comissió per tal que les transaccions comencin a confirmar-se en una mitja de n blocs (per defecte: %u)</translation> </message> @@ -2907,10 +3077,18 @@ <translation>Mida màxima de les dades en les transaccions de l'operador en què confiem i en les meves (per defecte: %u)</translation> </message> <message> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>Poda configurada per sota el mínim de %d MB. Feu servir un nombre superior.</translation> + </message> + <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Consulta a adreces d'iguals a través de DNS, si es troba baix en adreces (per defecte: 1 a menys que -connect)</translation> </message> <message> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Genera a l'atzar credencials per a cada connexió proxy. Això habilita l'aïllament del flux de Tor (per defecte: %u)</translation> + </message> + <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Defineix la mida màxima de transaccions d'alta prioritat / baixa comissió en bytes (per defecte: %d)</translation> </message> @@ -2919,6 +3097,10 @@ <translation>Defineix el nombre de fils per a la generació de moneda si està habilitat (-1 = tots els nuclis, per defecte: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>L'import de la transacció és massa petit per enviar-la després que se'n dedueixi la comissió</translation> + </message> + <message> <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source> <translation>Aquest producte inclou programari desenvolupat pel projecte OpenSSL per a ús a l'OpenSSL Toolkit <https://www.openssl.org/> i programari criptogràfic escrit per Eric Young i programari UPnP escrit per Thomas Bernard.</translation> </message> @@ -2958,10 +3140,26 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Els iguals en la llista blanca no poden ser bandejats per DoS i es transmetran sempre llurs transaccions, fins i tot si ja són a la mempool. Això és útil, p. ex., per a una passarel·la</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>Cal que torneu a construir la base de dades fent servir -reindex per tornar al mode no podat. Això tornarà a baixar la cadena de blocs sencera</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(per defecte: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>Accepta sol·licituds REST públiques (per defecte: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>S'està activant la millor cadena...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>No es pot executar amb un moneder en mode poda.</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>No es pot resoldre l'adreça -whitebind: «%s»</translation> </message> @@ -3050,12 +3248,12 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Suport RPC per a connexions HTTP persistents (per defecte: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Descarta a l'atzar 1 de cada <n> missatges de la xarxa</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Reconstrueix l'índex de la cadena de blocs dels fitxers blk000??.dat actuals a l'inici.</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Introdueix incertesa en 1 de cada <n> missatges de la xarxa</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Rep i mostra avisos de la xarxa P2P (per defecte: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3094,6 +3292,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Inicia minimitzat</translation> </message> <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>L'import de la transacció és massa petit per pagar-ne una comissió</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Això és programari experimental.</translation> </message> @@ -3114,6 +3316,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>La transacció és massa gran</translation> </message> <message> + <source>UI Options:</source> + <translation>Opcions d'interfície:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>No s'ha pogut vincular a %s en aquest ordinador (la vinculació ha retornat l'error %s)</translation> </message> @@ -3194,18 +3400,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>(1 = manté les metadades de les tx, p. ex., propietari del compte i informació de sol·licitud del pagament, 2 = prescindeix de les metadades de les tx)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Buida l'activitat de la base de dades de la memòria disponible al registre del disc cada <n> megabytes (per defecte: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Com d'exhaustiva és la verificació de blocs del -checkblocks (0-4, per defecte: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Enregistreu la prioritat de la transacció i la comissió per kB en minar blocs (per defecte: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Manté un índex complet de transaccions, utilitzat per la crida rpc getrawtransaction (per defecte: %u)</translation> </message> @@ -3234,18 +3432,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Demana sempre les adreces dels iguals a través de consultes DNS (per defecte: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Inhabilita el mode segur, sobreescriu un esdeveniment de mode segur real (per defecte: %u) </translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Error en carregar wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Força el mode segur (per defecte: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Genera monedes (per defecte: %u)</translation> </message> @@ -3262,10 +3452,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Adreça -proxy invalida: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Limita la mida de la cau de signatura a <n> entrades (per defecte: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Escolta les connexions JSON-RPC en <port> (per defecte: %u o testnet: %u)</translation> </message> @@ -3278,6 +3464,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Manté com a màxim <n> connexions a iguals (per defecte: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Fes que el moneder faci difusió de les transaccions</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Memòria intermèdia màxima de recepció per connexió, <n>*1000 bytes (per defecte: %u)</translation> </message> @@ -3286,10 +3476,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Memòria intermèdia màxima d'enviament per connexió, <n>*1000 bytes (per defecte: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Només accepta els punts de control integrats que coincideixen amb la cadena de blocs (per defecte: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Posa davant de la sortida de depuració una marca horària (per defecte: %u)</translation> </message> @@ -3302,10 +3488,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Retransmet multisig no P2SH (per defecte: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Executa un fil per buidar el moneder periòdicament (per defecte: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Fitxer de certificat del servidor (per defecte: %s)</translation> </message> @@ -3326,10 +3508,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Defineix el nombre de fils a crides de servei RPC (per defecte: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Defineix el senyalador DB_PRIVATE en l'entorn db del moneder (per defecte: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Especifica el fitxer de configuració (per defecte: %s)</translation> </message> @@ -3346,10 +3524,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Gasta el canvi no confirmat en enviar les transaccions (per defecte: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Atura l'execució després d'importar blocs del disc (per defecte: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Llindar per a desconnectar els iguals de comportament qüestionable (per defecte: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_cmn.ts b/src/qt/locale/bitcoin_cmn.ts index 3286f12698..37c937b864 100644 --- a/src/qt/locale/bitcoin_cmn.ts +++ b/src/qt/locale/bitcoin_cmn.ts @@ -1,6 +1,10 @@ -<TS language="cmn" version="2.1"> +<TS language="cmn" version="2.0"> <context> <name>AddressBookPage</name> + <message> + <source>Create a new address</source> + <translation>创建新地址</translation> + </message> </context> <context> <name>AddressTableModel</name> diff --git a/src/qt/locale/bitcoin_cs.ts b/src/qt/locale/bitcoin_cs.ts index 47464b7a53..6e7ffec27f 100644 --- a/src/qt/locale/bitcoin_cs.ts +++ b/src/qt/locale/bitcoin_cs.ts @@ -1,4 +1,4 @@ -<TS language="cs" version="2.1"> +<TS language="cs" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -168,6 +168,10 @@ <translation>Jsi si jistý, že chceš peněženku zašifrovat?</translation> </message> <message> + <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>Bitcoin Core se teď ukončí, aby dokončil zašifrování. Pamatuj však, že pouhé zašifrování peněženky nemůže zabránit krádeži tvých bitcoinů malwarem, kterým se může počítač nakazit.</translation> + </message> + <message> <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source> <translation>DŮLEŽITÉ: Všechny předchozí zálohy peněženky by měly být nahrazeny nově vygenerovanou, zašifrovanou peněženkou. Z bezpečnostních důvodů budou předchozí zálohy nešifrované peněženky nepoužitelné, jakmile začneš používat novou zašifrovanou peněženku.</translation> </message> @@ -184,6 +188,10 @@ <translation>Zadej nové heslo k peněžence.<br/>Použij <b>alespoň deset náhodných znaků</b> nebo <b>alespoň osm slov</b>.</translation> </message> <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Zadej staré a nové heslo k peněžence.</translation> + </message> + <message> <source>Wallet encryption failed</source> <translation>Zašifrování peněženky selhalo</translation> </message> @@ -391,6 +399,10 @@ <translation>O &Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Uprav nastavení Bitcoin Core</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Ukaž seznam použitých odesílacích adres a jejich označení</translation> </message> @@ -419,6 +431,10 @@ <translation>Není dostupný žádný zdroj bloků...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Zpracován %n blok transakční historie.</numerusform><numerusform>Zpracovány %n bloky transakční historie.</numerusform><numerusform>Zpracováno %n bloků transakční historie.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n hodinu</numerusform><numerusform>%n hodiny</numerusform><numerusform>%n hodin</numerusform></translation> </message> @@ -471,6 +487,36 @@ <translation>Stahuji...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Datum: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Částka: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Typ: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Označení: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Adresa: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Odeslané transakce</translation> </message> @@ -669,6 +715,18 @@ <translation>žádná</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Popisek zčervená, pokud je velikost transakce větší než 1000 bajtů.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Popisek zčervená, pokud je priorita menší než „střední“.</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Popisek zčervená, pokud má některý příjemce obdržet částku menší než %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Může se lišit o +/– %1 satoshi na každý vstup.</translation> </message> @@ -919,6 +977,14 @@ <translation>IP adresa proxy (např. IPv4: 127.0.0.1/IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>Zavřením se aplikace minimalizuje. Pokud je tato volba zaškrtnuta, tak se aplikace ukončí pouze zvolením Konec v menu.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>Tady lze nastavit jazyk uživatelského rozhraní. Nastavení se projeví až po restartování Bitcoin Core.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>URL třetích stran (např. block exploreru), které se zobrazí v kontextovém menu v záložce Transakce. %s v URL se nahradí hashem transakce. Více URL odděl svislítkem |.</translation> </message> @@ -943,6 +1009,14 @@ <translation>&Síť</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Automaticky spustí Bitcoin Core po přihlášení do systému.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>S&pustit Bitcoin Core po přihlášení do systému</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = automaticky, <0 = nechat daný počet jader volný, výchozí: 0)</translation> </message> @@ -1055,6 +1129,10 @@ <translation>K aktivaci změn je potřeba restartovat klienta.</translation> </message> <message> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Klient se vypne, chceš pokračovat?</translation> + </message> + <message> <source>This change would require a client restart.</source> <translation>Tahle změna bude chtít restartovat klienta.</translation> </message> @@ -1189,10 +1267,18 @@ <translation>Soubor platebního požadavku nejde přečíst nebo zpracovat! Příčinou může být špatný soubor platebního požadavku.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Platební požadavek vypršel.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Neověřené platební požadavky k uživatelským platebním skriptům nejsou podporované.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Neplatný platební požadavek.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Vrácení peněz od %1</translation> </message> @@ -1232,6 +1318,10 @@ <translation>Typ klienta</translation> </message> <message> + <source>Node/Service</source> + <translation>Uzel/Služba</translation> + </message> + <message> <source>Ping Time</source> <translation>Odezva</translation> </message> @@ -1353,6 +1443,10 @@ <translation>Aktuální počet bloků</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Otevři soubor s ladicími záznamy Bitcoin Core z aktuálního datového adresáře. U velkých logů to může pár vteřin zabrat.</translation> + </message> + <message> <source>Received</source> <translation>Přijato</translation> </message> @@ -1421,6 +1515,10 @@ <translation>Odezva</translation> </message> <message> + <source>Time Offset</source> + <translation>Časový posun</translation> + </message> + <message> <source>Last block time</source> <translation>Čas posledního bloku</translation> </message> @@ -1465,6 +1563,10 @@ <translation>Vyčistit konzoli</translation> </message> <message> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Vítej v RPC konzoli Bitcoin Core.</translation> + </message> + <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>V historii se pohybuješ šipkami nahoru a dolů a pomocí <b>Ctrl-L</b> čistíš obrazovku.</translation> </message> @@ -1761,6 +1863,10 @@ <translation>Pokud je vlastní poplatek nastavený na 1000 satoshi a transakce má pouze 250 bajtů, tak „za kilobajt“ zaplatí poplatek jen 250 satoshi, zatímco „přinejmenším“ zaplatí 1000 satoshi. Pro transakce větší než kilobajt obě možnosti platí za kilobajt.</translation> </message> <message> + <source>Hide</source> + <translation>Skryj</translation> + </message> + <message> <source>total at least</source> <translation>přinejmenším</translation> </message> @@ -1901,10 +2007,30 @@ <translation>Transakce byla odmítnuta! Tohle může nastat, pokud nějaké mince z tvé peněženky už jednou byly utraceny, například pokud používáš kopii souboru wallet.dat a mince byly utraceny v druhé kopii, ale nebyly označeny jako utracené v této.</translation> </message> <message> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>Poplatek vyšší než %1 je považován za absurdně vysoký.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Platební požadavek vypršel.</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Potvrzování by podle odhadu mělo začít během %n bloku.</numerusform><numerusform>Potvrzování by podle odhadu mělo začít během %n bloků.</numerusform><numerusform>Potvrzování by podle odhadu mělo začít během %n bloků.</numerusform></translation> + </message> + <message> <source>Pay only the minimum fee of %1</source> <translation>Zaplatit pouze minimální poplatek %1</translation> </message> <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Adresa příjemce je neplatná – překontroluj ji prosím.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Zaznamenána duplicitní adresa: každá adresa by ale měla být použita vždy jen jednou.</translation> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Upozornění: Neplatná Bitcoinová adresa</translation> </message> @@ -1976,10 +2102,26 @@ <translation>Smaž tento záznam</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>Poplatek se odečte od posílané částky. Příjemce tak dostane méně bitcoinů, než zadáš do pole Částka. Pokud vybereš více příjemců, tak se poplatek rovnoměrně rozloží.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>&Odečíst poplatek od částky</translation> + </message> + <message> <source>Message:</source> <translation>Zpráva:</translation> </message> <message> + <source>This is an unauthenticated payment request.</source> + <translation>Tohle je neověřený platební požadavek.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Tohle je ověřený platební požadavek.</translation> + </message> + <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>Zadej označení této adresy; obojí se ti pak uloží do adresáře</translation> </message> @@ -2018,6 +2160,10 @@ <translation>&Podepiš zprávu</translation> </message> <message> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>Podepsáním zprávy/smlouvy svými adresami můžeš prokázat, že jsi na ně schopen přijmout bitcoiny. Buď opatrný a nepodepisuj nic vágního nebo náhodného; například při phishingových útocích můžeš být lákán, abys něco takového podepsal. Podepisuj pouze naprosto úplná a detailní prohlášení, se kterými souhlasíš.</translation> + </message> + <message> <source>The Bitcoin address to sign the message with</source> <translation>Bitcoinová adresa, kterou se zpráva podepíše</translation> </message> @@ -2070,6 +2216,10 @@ <translation>&Ověř zprávu</translation> </message> <message> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>K ověření podpisu zprávy zadej adresu příjemce, zprávu (ověř si, že správně kopíruješ zalomení řádků, mezery, tabulátory apod.) a podpis. Dávej pozor na to, abys nezkopíroval do podpisu víc, než co je v samotné podepsané zprávě, abys nebyl napálen man-in-the-middle útokem. Poznamenejme však, že takto lze pouze prokázat, že podepisující je schopný na dané adrese přijmout platbu, ale není možnéprokázat, že odeslal jakoukoli transakci!</translation> + </message> + <message> <source>The Bitcoin address the message was signed with</source> <translation>Bitcoinová adresa, kterou je zpráva podepsána</translation> </message> @@ -2421,6 +2571,10 @@ <translation>Zda tato transakce zahrnuje i některou sledovanou adresu.</translation> </message> <message> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Uživatelsky určený účel transakce.</translation> + </message> + <message> <source>Amount removed from or added to balance.</source> <translation>Částka odečtená z nebo přičtená k účtu.</translation> </message> @@ -2640,7 +2794,7 @@ </message> <message> <source>Specify your own public address</source> - <translation>Specifikuj svou veřejnou adresu</translation> + <translation>Udej svou veřejnou adresu</translation> </message> <message> <source>Accept command line and JSON-RPC commands</source> @@ -2671,16 +2825,16 @@ <translation>Šířen pod softwarovou licencí MIT, viz přiložený soubor COPYING nebo <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Přepnout do módu testování regresí, který používá speciální řetězec, ve kterém mohou být bloky okamžitě vyřešeny.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Spustit příkaz, když se objeví transakce týkající se peněženky (%s se v příkazu nahradí za TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>V tomto módu -genproclimit určuje, kolik bloků je vygenerováno okamžitě.</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Horní hranice pro celkový poplatek za jednu transakci z peněženky; příliš nízká hodnota může zmařit velké transakce (výchozí: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>Omezit nároky na úložný prostor prořezáváním (mazáním) starých bloků. V tomto režimu chybí peněženka a rovněž tento režim není slučitelný s -txindex. Upozornění: opětovná změna tohoto nastavení bude vyžadovat nové stažení celého řetězce bloků. (výchozí: 0 = bloky neprořezávat, >%u = cílová velikost souborů s bloky, v MiB)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2695,6 +2849,14 @@ <translation>Nedaří se mi připojit na %s na tomhle počítači. Bitcoin Core už pravděpodobně jednou běží.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>UPOZORNĚNÍ: vygenerováno nezvykle mnoho bloků – přijato %d bloků jen za posledních %d hodin (očekáváno %d)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>UPOZORNĚNÍ: zkontroluj své spojení do sítě – bylo přijato %d bloků za posledních %d hodin (očekáváno %d)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Upozornění: -paytxfee je nastaveno velmi vysoko! Toto je transakční poplatek, který zaplatíš za každou poslanou transakci.</translation> </message> @@ -2732,7 +2894,7 @@ </message> <message> <source>Block creation options:</source> - <translation>Možnosti vytvoření bloku:</translation> + <translation>Možnosti vytváření bloku:</translation> </message> <message> <source>Connect only to the specified node(s)</source> @@ -2811,6 +2973,14 @@ <translation>Připojovat se pouze k uzlům v <net> síti (ipv4, ipv6 nebo onion)</translation> </message> <message> + <source>Prune cannot be configured with a negative value.</source> + <translation>Prořezávání nemůže být zkonfigurováno s negativní hodnotou.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>Prořezávací režim není kompatibilní s -txindex.</translation> + </message> + <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation>Nastavit velikost databázové vyrovnávací paměti v megabajtech (%d až %d, výchozí: %d)</translation> </message> @@ -2823,16 +2993,12 @@ <translation>Udej název souboru s peněženkou (v rámci datového adresáře)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Tohle je určeno pro nástroje na regresní testování a vyvíjení aplikací.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Použít UPnP k namapování naslouchacího portu (výchozí: %u)</translation> </message> <message> <source>Verifying blocks...</source> - <translation>Ověřuji bloky... </translation> + <translation>Ověřuji bloky...</translation> </message> <message> <source>Verifying wallet...</source> @@ -2847,6 +3013,10 @@ <translation>Možnosti peněženky:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Upozornění: tahle verze je zastaralá, měl bys ji aktualizovat!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Je třeba přestavět databázi použitím -reindex, aby bylo možné změnit -txindex</translation> </message> @@ -2879,6 +3049,10 @@ <translation>Vytvářet nové soubory s výchozími systémovými právy namísto umask 077 (uplatní se, pouze pokud je vypnutá funkce peněženky)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Zjistit vlastní IP adresu (výchozí: 1, pokud naslouchá a není zadáno -externalip nebo -proxy)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Chyba: Nelze naslouchat příchozí spojení (listen vrátil chybu %s)</translation> </message> @@ -2892,25 +3066,33 @@ </message> <message> <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> - <translation>Poplatky (v BTC/Kb) menší než tato hodnota jsou považovány za nulové pro účely přeposílání transakcí (výchozí: %s)</translation> + <translation>Poplatky (v BTC/kB) menší než tato hodnota jsou považovány za nulové pro účely přeposílání transakcí (výchozí: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Poplatky (v BTC/Kb) menší než tato hodnota jsou považovány za nulové pro účely vytváření transakcí (výchozí: %s)</translation> + <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> + <translation>Pokud paytxfee není nastaveno, platit dostatečný poplatek na to, aby začaly být transakce potvrzovány v průměru během n bloků (výchozí: %u)</translation> </message> <message> - <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> - <translation>Pokud paytxfee není nastaveno, platit dostatečný poplatek na to, aby byly transakce potvrzeny v průměru během n bloků (výchozí: %u)</translation> + <source>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source> + <translation>Neplatná částka pro -maxtxfee=<amount>: '%s' (musí být alespoň jako poplatek minrelay %s, aby transakce nezůstávaly trčet)</translation> </message> <message> <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> <translation>Maximální velikost dat v transakcích nesoucích data, se kterou jsme ochotni je ještě přeposílat a těžit (výchozí: %u)</translation> </message> <message> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>Prořezávání je nastaveno pod minimum %d MB. Použij prosím nějaké vyšší číslo.</translation> + </message> + <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Při nedostatku adres získat další protějšky z DNS (výchozí: 1, pokud není použito -connect)</translation> </message> <message> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Použít náhodné údaje pro každé proxy spojení. To umožní izolovat nesouvisející datové toky v Toru (výchozí: %u)</translation> + </message> + <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Nastavit maximální velikost prioritních/nízkopoplatkových transakcí v bajtech (výchozí: %d)</translation> </message> @@ -2919,10 +3101,42 @@ <translation>Nastavení počtu vláken pro těžení, je-li zapnuté (-1 = všechna jádra, výchozí: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>Částka v transakci po odečtení poplatku je příliš malá na odeslání</translation> + </message> + <message> <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source> <translation>Tento produkt zahrnuje programy vyvinuté OpenSSL Projektem pro použití v OpenSSL Toolkitu <https://www.openssl.org/> a kryptografický program od Erika Younga a program UPnP od Thomase Bernarda.</translation> </message> <message> + <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: +%s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +The username and password MUST NOT be the same. +If the file does not exist, create it with owner-readable-only file permissions. +It is also recommended to set alertnotify so you are notified of problems; +for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com +</source> + <translation>K používání bitcoind nebo volby -server u bitcoin-qt musíš nastavit rpcpassword v konfiguračním souboru: +%s +Je vhodné použít následující náhodné heslo: +rpcuser=bitcoinrpc +rpcpassword=%s +(není potřeba si ho pamatovat) +rpcuser a rpcpassword NESMÍ být stejné. +Pokud konfigurační soubor ještě neexistuje, vytvoř ho tak, aby ho mohl číst pouze vlastník. +Je také doporučeno si nastavit alertnotify, abys byl upozorněn na případné problémy; +například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com +</translation> + </message> + <message> + <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> + <translation>Upozornění: -maxtxfee je nastaveno velmi vysoko! Takto vysoký poplatek může být zaplacen v jednotlivé transakci.</translation> + </message> + <message> <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> <translation>Upozornění: Zkontroluj, že máš v počítači správně nastavený datum a čas! Pokud jsou nastaveny špatně, Bitcoin Core nebude fungovat správně.</translation> </message> @@ -2931,6 +3145,26 @@ <translation>Na protějšky na bílé listině se nevztahuje DoS klatba a jejich transakce jsou vždy přeposílány, i když už třeba jsou v mempoolu, což je užitečné např. pro bránu</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>K návratu k neprořezávacímu režimu je potřeba přestavět databázi použitím -reindex. Také se znovu stáhne celý řetězec bloků</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(výchozí: %u)</translation> + </message> + <message> + <source>Accept public REST requests (default: %u)</source> + <translation>Přijímat veřejné REST požadavky (výchozí: %u)</translation> + </message> + <message> + <source>Activating best chain...</source> + <translation>Aktivuji nejlepší řetězec...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>V prořezávacím režimu se s pěněženkou nemůžu spustit.</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Nemohu přeložit -whitebind adresu: '%s'</translation> </message> @@ -2975,6 +3209,10 @@ <translation>Selhala úvodní zevrubná prověrka. Bitcoin Core se ukončuje.</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Neplatná částka pro -maxtxfee=<amount>: '%s'</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>Neplatná částka pro -minrelaytxfee=<částka>: '%s'</translation> </message> @@ -3011,12 +3249,16 @@ <translation>Možnosti RPC serveru:</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Náhodně zahazovat jednu z každých <n> síťových zpráv</translation> + <source>RPC support for HTTP persistent connections (default: %d)</source> + <translation>Podpora RPC pro perzistentní HTTP spojení (výchozí: %d)</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Náhodně pozměňovat jednu z každých <n> síťových zpráv</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Při startu znovu vytvořit index řetězce bloků z aktuálních blk000??.dat souborů</translation> + </message> + <message> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Přijímat a zobrazovat poplachy z P2P sítě (výchozí: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3032,7 +3274,7 @@ </message> <message> <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Nastavit jazyk, například "de_DE" (výchozí: systémové nastavení)</translation> + <translation>Nastavit jazyk, například „de_DE“ (výchozí: systémové nastavení)</translation> </message> <message> <source>Show all debugging options (usage: --help -help-debug)</source> @@ -3055,6 +3297,10 @@ <translation>Nastartovat minimalizovaně</translation> </message> <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>Částka v transakci je příliš malá na pokrytí poplatku</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Tohle je experimentální program.</translation> </message> @@ -3075,6 +3321,10 @@ <translation>Transakce je příliš velká</translation> </message> <message> + <source>UI Options:</source> + <translation>Možnosti UI:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Nedaří se mi připojit na %s na tomhle počítači (operace bind vrátila chybu %s)</translation> </message> @@ -3155,18 +3405,10 @@ <translation>(1 = ukládat transakční metadata, např. majitele účtu a informace o platebním požadavku, 2 = mazat transakční metadata)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Promítnout databázovou aktivitu z paměťového prostoru do záznamu na disku každých <n> megabajtů (výchozí: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Jak moc důkladná má být verifikace bloků -checkblocks (0-4, výchozí: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Zaznamenávat během těžení bloků prioritu transakce a poplatek za kB (výchozí: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Spravovat úplný index transakcí, který je využíván rpc voláním getrawtransaction (výchozí: %u)</translation> </message> @@ -3195,18 +3437,10 @@ <translation>Vždy získávat adresy dalších protějšků přes DNS (výchozí: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Vypnout bezpečný režim (safemode), překrýt skutečnou událost bezpečného režimu (výchozí: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Chyba při načítání wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Vynutit bezpečný mód (výchozí: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Těžit (výchozí: %u)</translation> </message> @@ -3223,10 +3457,6 @@ <translation>Neplatná -proxy adresa: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Omezit velikost vyrovnávací paměti pro podpisy na <n> položek (výchozí: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Čekat na JSON-RPC spojení na <portu> (výchozí: %u nebo testnet: %u)</translation> </message> @@ -3239,6 +3469,10 @@ <translation>Povolit nejvýše <n> protějšků (výchozí: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Transakce z peněženky rozesílat</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Maximální velikost přijímacího bufferu pro každé spojení, <n>*1000 bajtů (výchozí: %u)</translation> </message> @@ -3247,10 +3481,6 @@ <translation>Maximální velikost odesílacího bufferu pro každé spojení, <n>*1000 bajtů (výchozí: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Uznávat pouze řetězec bloků, který odpovídá vnitřním kontrolním bodům (výchozí: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Připojit před ladicí výstup časové razítko (výchozí: %u)</translation> </message> @@ -3263,10 +3493,6 @@ <translation>Přeposílat ne-P2SH multisig (výchozí: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Spustit vlákno pročišťující periodicky peněženku (výchozí: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Soubor se serverovým certifikátem (výchozí: %s)</translation> </message> @@ -3287,10 +3513,6 @@ <translation>Nastavení počtu vláken pro servisní RPC volání (výchozí: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Nastavit příznak DB_PRIVATE v databázovém prostředí peněženky (výchozí: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Konfigurační soubor (výchozí: %s)</translation> </message> @@ -3303,10 +3525,6 @@ <translation>Utrácet i ještě nepotvrzené drobné při posílání transakcí (výchozí: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Ukončit se po importu bloků z disku (výchozí: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Práh pro odpojování zlobivých protějšků (výchozí: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_cy.ts b/src/qt/locale/bitcoin_cy.ts index 9867375fb2..1b8eb3dc41 100644 --- a/src/qt/locale/bitcoin_cy.ts +++ b/src/qt/locale/bitcoin_cy.ts @@ -1,4 +1,4 @@ -<TS language="cy" version="2.1"> +<TS language="cy" version="2.0"> <context> <name>AddressBookPage</name> <message> diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts index 1467791047..60b8925e8c 100644 --- a/src/qt/locale/bitcoin_da.ts +++ b/src/qt/locale/bitcoin_da.ts @@ -1,4 +1,4 @@ -<TS language="da" version="2.1"> +<TS language="da" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -2813,10 +2813,6 @@ <translation>Tildel til den givne adresse og lyt altid på den. Brug [vært]:port-notation for IPv6</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)</source> - <translation>Begræns hyppigheden af gratis transaktioner løbende til <n>*1000 byte pr. minut (standard: %u)</translation> - </message> - <message> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <translation>Slet alle transaktioner i tegnebogen og genskab kun disse dele af blokkæden gennem -rescan under opstart</translation> </message> @@ -2825,18 +2821,10 @@ <translation>Distribueret under MIT-softwarelicensen; se den vedlagte fil COPYING eller <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Start regressionstesttilstand, som bruger en speciel kæde, hvor blokke kan løses med det samme.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Udfør kommando, når en transaktion i tegnebogen ændres (%s i kommandoen erstattes med TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>I denne tilstand styrer -genproclimit hvor mange blokke, der genereres med det samme.</translation> - </message> - <message> <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> <translation>Maksimalt totalt gebyr der kan bruges i en enkelt tegnebogstransaktion. For lav en værdi kan afbryde store transaktioner (standard: %s)</translation> </message> @@ -2857,6 +2845,14 @@ <translation>Ikke i stand til at tildele til %s på denne computer. Bitcoin Core kører sansynligvis allerede.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>ADVARSEL: unormalt mange blokke er genereret; %d blokke er modtaget i løbet af de seneste %d timer (%d forventet)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>ADVARSEL: tjek din netværksforbindelse; %d blokke er modtaget i løbet af de seneste %d timer (%d forventet)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Advarsel: -paytxfee er sat meget højt! Dette er det gebyr du vil betale, hvis du sender en transaktion.</translation> </message> @@ -2993,10 +2989,6 @@ <translation>Angiv tegnebogsfil (inden for datamappe)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>This is intended for regression testing tools and app development.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Brug UPnP til at konfigurere den lyttende port (standard: %u)</translation> </message> @@ -3073,10 +3065,6 @@ <translation>Gebyrer (i BTC/Kb) mindre end dette opfattes som nulgebyr for videresendelse (standard: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Gebyrer (i BTC/Kb) mindre end dette opfattes som nulgebyr for oprettelse af transaktion (standard: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Hvis paytxfee ikke er sat, inkluderes nok gebyr til at transaktioner begynder at blive bekræftet ingen for gennemsnitligt n blokke (standard: %u)</translation> </message> @@ -3101,10 +3089,6 @@ <translation>Brug tilfældige akkreditiver for hver proxy-forbindelse. Dette tillader strømisolation med Tor (standard: %u)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default: %u)</source> - <translation>Kræv høj prioritet for at videresende transaktioner uden eller med lavt gebyr (standard: %u)</translation> - </message> - <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Sæt maksimumstørrelse for højprioritet/lavgebyr-transaktioner i byte (standard: %d)</translation> </message> @@ -3173,10 +3157,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Aktiverer bedste kæde …</translation> </message> <message> - <source>Allow self signed root certificates (default: 0)</source> - <translation>Tillad selvsignerede rodcertifikater (standard: 0)</translation> - </message> - <message> <source>Can't run with a wallet in prune mode.</source> <translation>Kan ikke køre med en tegnebog i beskåret tilstand.</translation> </message> @@ -3269,18 +3249,14 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>RPC-understøttelse for HTTP-persistente forbindelser (standard: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Drop tilfældigt 1 ud af hver <n> netværksbeskeder</translation> - </message> - <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Slør tilfældigt 1 ud af hver <n> netværksbeskeder</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>Genopbyg blokkædeindeks fra nuværende blk000??.dat-filer ved opstart</translation> </message> <message> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Modtag og vis P2P-netværksadvarsler (standard: %u)</translation> + </message> + <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Send sporings-/fejlsøgningsinformation til konsollen i stedet for debug.log filen</translation> </message> @@ -3425,18 +3401,10 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(1 = behold metadata for transaktion, fx kontoindehaver og information om betalingsanmodning, 2 = drop metadata for transaktion)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Flyt databaseaktivitet fra hukommelsespulje til disklog hver <n> megabyte (standard: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Hvor gennemarbejdet blokverificeringen for -checkblocks er (0-4; standard: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Prioritet for transaktionslog og gebyr pr. kB under udvinding af blokke (standard: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Vedligehold et komplet transaktionsindeks, der bruges af rpc-kaldet getrawtransaction (standard: %u)</translation> </message> @@ -3465,18 +3433,10 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Forespørg altid adresser på andre knuder via DNS-opslag (default: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Slå sikker tilstand fra, tilsidesæt hændelser fra sikker tilstand (standard: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Fejl ved indlæsning af wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Gennemtving sikker tilstand (standard: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Generér bitcoins (standard: %u)</translation> </message> @@ -3493,10 +3453,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ugyldig -proxy adresse: "%s"</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Begræns størrelsen på signaturcache til <n> indgange (standard: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Lyt efter JSON-RPC-forbindelser på <port> (standard: %u eller testnet: %u)</translation> </message> @@ -3521,10 +3477,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Maksimum for afsendelsesbuffer pr. forbindelse, <n>*1000 byte (standard: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Acceptér kun indbyggede kontrolposter, der matcher blokkæden (standard: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Føj tidsstempel foran fejlsøgningsoutput (standard: %u)</translation> </message> @@ -3537,10 +3489,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Videresend ikke-P2SH multisig (standard: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Kør en tråd for periodisk at rydde tegnebog (standard: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Servercertifikat-fil (standard: %s) </translation> @@ -3563,10 +3511,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Angiv antallet af tråde til at håndtere RPC-kald (standard: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Sætter DB_PRIVATE-flaget i tegnebogens db-miljø (standard: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Angiv konfigurationsfil (standard: %s)</translation> </message> @@ -3583,10 +3527,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Brug ubekræftede byttepenge under afsendelse af transaktioner (standard: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Stop kørsel efter import af blokke fra disk (standard: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Grænse for afbrydelse af forbindelse til knuder, der opfører sig upassende (standard: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts index ab0367dbab..a50a6e60cb 100644 --- a/src/qt/locale/bitcoin_de.ts +++ b/src/qt/locale/bitcoin_de.ts @@ -1,4 +1,4 @@ -<TS language="de" version="2.1"> +<TS language="de" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -2817,10 +2817,6 @@ <translation>An die angegebene Adresse binden und immer abhören. Für IPv6 "[Host]:Port"-Notation verwenden</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)</source> - <translation>Durchgehend die Anzahl freier Transaktionen auf <n> * 1000 Byte pro Minute begrenzen (Standard: %u)</translation> - </message> - <message> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <translation>Alle Wallet-Transaktionen löschen und nur diese Teilbereiche der Blockkette durch -rescan beim Starten wiederherstellen</translation> </message> @@ -2829,18 +2825,10 @@ <translation>Veröffentlicht unter der MIT-Softwarelizenz, siehe beiligende Datei COPYING oder <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Regressionstest-Modus aktivieren, der eine spezielle Blockkette nutzt, in der Blöcke sofort gelöst werden können.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Befehl ausführen wenn sich eine Wallet-Transaktion verändert (%s im Befehl wird durch die Transaktions-ID ersetzt)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>In diesem Modus legt -genproclimit fest, wie viele Blöcke sofort erzeugt werden.</translation> - </message> - <message> <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> <translation>Maximale Gesamtgebühren je Wallet-Transaktion, ein zu niedriger Wert kann große Transaktionen abbrechen (Standard: %s)</translation> </message> @@ -2861,6 +2849,14 @@ <translation>Kann auf diesem Computer nicht an %s binden, da Bitcoin Core wahrscheinlich bereits gestartet wurde.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>Warnung: Es wurde eine ungewöhnlich hohe Anzahl Blöcke erzeugt, %d Blöcke wurden in den letzten %d Stunden empfangen (%d wurden erwartet).</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>Warnung: Überprüpfen Sie ihre Netzwerkverbindung, %d Blöcke wurden in den letzten %d Stunden empfangen (%d wurden erwartet).</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Warnung: -paytxfee ist auf einen sehr hohen Wert festgelegt! Dies ist die Gebühr die beim Senden einer Transaktion fällig wird.</translation> </message> @@ -2997,10 +2993,6 @@ <translation>Wallet-Datei angeben (innerhalb des Datenverzeichnisses)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Dies ist für Regressionstest-Tools und Anwendungsentwicklung gedacht.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>UPnP verwenden, um eine Portweiterleitung einzurichten (Standard: %u)</translation> </message> @@ -3077,10 +3069,6 @@ <translation>Niedrigere Gebühren (in BTC/Kb) als diese werden bei der Weiterleitung als gebührenfrei angesehen (Standard: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Niedrigere Gebühren (in BTC/Kb) als diese werden bei der Transaktionserstellung als gebührenfrei angesehen (Standard: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Wenn -paytxfee nicht festgelegt wurde Gebühren einschließen, so dass mit der Bestätigung von Transaktionen im Schnitt innerhalb von n Blöcken begonnen wird (Standard: %u)</translation> </message> @@ -3105,10 +3093,6 @@ <translation>Zufällige Anmeldedaten für jede Proxyverbindung verwenden. Dies aktiviert Tor-Datenflussisolation (Standard: %u)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default: %u)</source> - <translation>Hohe Priorität zum Weiterleiten von freien bzw. Transaktionen mit niedrigen Gebühren voraussetzen (Standard: %u)</translation> - </message> - <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Maximale Größe in Byte von "high-priority/low-fee"-Transaktionen festlegen (Standard: %d)</translation> </message> @@ -3177,10 +3161,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Aktiviere beste Blockkette...</translation> </message> <message> - <source>Allow self signed root certificates (default: 0)</source> - <translation>Selbstunterschriebene Stammzertifikate erlauben (Standard: 0)</translation> - </message> - <message> <source>Can't run with a wallet in prune mode.</source> <translation>Eine Wallet kann im Kürzungsmodus nicht verwendet werden.</translation> </message> @@ -3273,18 +3253,14 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Unterstützung für persistente HTTP-Verbindungen bei RPC (Standard: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Zufällig eine von <n> Netzwerknachrichten verwerfen</translation> - </message> - <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Zufällig eine von <n> Netzwerknachrichten verwürfeln</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>Blockkettenindex aus aktuellen Dateien blk000??.dat beim Starten wiederaufbauen</translation> </message> <message> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>P2P-Netzwerk-Alarme empfangen und anzeigen (Standard: %u)</translation> + </message> + <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Rückverfolgungs- und Debuginformationen an die Konsole senden, anstatt sie in debug.log zu schreiben</translation> </message> @@ -3429,18 +3405,10 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(1 = TX-Metadaten wie z.B. Accountbesitzer und Zahlungsanforderungsinformationen behalten, 2 = TX-Metadaten verwerfen)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Datenbankaktivitäten vom Arbeitsspeicher-Pool alle <n> Megabyte auf den Datenträger schreiben (Standard: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Legt fest, wie gründlich die Blockverifikation von -checkblocks ist (0-4, Standard: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Transaktionspriorität und Gebühr pro kB beim Erzeugen von Blöcken protokollieren (Standard: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Einen vollständigen Transaktionsindex führen, der vom RPC-Befehl "getrawtransaction" genutzt wird (Standard: %u)</translation> </message> @@ -3469,18 +3437,10 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Adressen von Gegenstellen immer über DNS-Namensauflösung abfragen (Standard: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Sicherheitsmodus deaktivieren, übergeht ein echtes Sicherheitsmodusereignis (Standard: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Fehler beim Laden von wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Sicherheitsmodus erzwingen (Standard: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Bitcoins erzeugen (Standard: %u)</translation> </message> @@ -3497,10 +3457,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ungültige Adresse in -proxy: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Größe des Signaturcaches auf <n> Einträge begrenzen (Standard: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation><port> nach JSON-RPC-Verbindungen abhören (Standard: %u oder Testnetz: %u)</translation> </message> @@ -3521,10 +3477,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Maximale Größe des Sendepuffers pro Verbindung, <n> * 1000 Byte (Standard: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Blockkette nur als gültig ansehen, wenn sie mit den integrierten Prüfpunkten übereinstimmt (Standard: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Debugausgaben einen Zeitstempel voranstellen (Standard: %u)</translation> </message> @@ -3537,10 +3489,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Nicht-"P2SH-Multisig" weiterleiten (Standard: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Einen Thread starten, der periodisch die Wallet sicher auf den Datenträger schreibt (Standard: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Serverzertifikat (Standard: %s)</translation> </message> @@ -3561,10 +3509,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Maximale Anzahl an Threads zur Verarbeitung von RPC-Anfragen festlegen (Standard: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>"DB_PRIVATE"-Flag in der Wallet-Datenbankumgebung setzen (Standard: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Konfigurationsdatei festlegen (Standard: %s)</translation> </message> @@ -3581,10 +3525,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Unbestätigtes Wechselgeld darf beim Senden von Transaktionen ausgegeben werden (Standard: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Beenden, nachdem Blöcke vom Datenträger importiert wurden (Standard: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Schwellenwert, um Verbindungen zu sich nicht konform verhaltenden Gegenstellen zu beenden (Standard: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_el_GR.ts b/src/qt/locale/bitcoin_el_GR.ts index a4c95857ba..8a0958a7bd 100644 --- a/src/qt/locale/bitcoin_el_GR.ts +++ b/src/qt/locale/bitcoin_el_GR.ts @@ -1,4 +1,4 @@ -<TS language="el_GR" version="2.1"> +<TS language="el_GR" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -2494,10 +2494,6 @@ <translation>Αποθηκευση σε συγκεκριμένη διεύθυνση. Χρησιμοποιήστε τα πλήκτρα [Host] : συμβολισμός θύρα για IPv6</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Εισαγωγή δοκιμαστικής λειτουργίας παλινδρόμησης, που χρησιμοποιεί μια ειδική αλυσίδα στην οποία τα μπλοκ επιλύονται στιγμιαία.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Εκτέλεσε την εντολή όταν το καλύτερο μπλοκ αλλάξει(%s στην εντολή αντικαθίσταται από το hash του μπλοκ)</translation> </message> @@ -2594,10 +2590,6 @@ <translation>Επιλέξτε αρχείο πορτοφολιού (μέσα απο κατάλογο δεδομένων)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Αυτό προορίζεται για εργαλεία δοκιμών παλινδρόμησης και την ανάπτυξη εφαρμογών.</translation> - </message> - <message> <source>Verifying blocks...</source> <translation>Επαλήθευση των μπλοκ... </translation> </message> @@ -2802,10 +2794,6 @@ <translation>Σφάλμα φόρτωσης αρχείου wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Επιβολή ασφαλής λειτουργίας (προεπιλογή: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Δημιουργία νομισμάτων (προκαθορισμος: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index 90a13feaca..3ebb4d0bf6 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -104,7 +104,7 @@ <translation>&Edit</translation> </message> <message> - <location line="+194"/> + <location line="+193"/> <source>Export Address List</source> <translation type="unfinished"></translation> </message> @@ -284,29 +284,42 @@ </message> </context> <context> + <name>BanTableModel</name> + <message> + <location filename="../bantablemodel.cpp" line="+88"/> + <source>IP/Netmask</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+0"/> + <source>Banned Until</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> - <location filename="../bitcoingui.cpp" line="+326"/> + <location filename="../bitcoingui.cpp" line="+324"/> <source>Sign &message...</source> <translation>Sign &message...</translation> </message> <message> - <location line="+342"/> + <location line="+353"/> <source>Synchronizing with network...</source> <translation>Synchronizing with network...</translation> </message> <message> - <location line="-418"/> + <location line="-429"/> <source>&Overview</source> <translation>&Overview</translation> </message> <message> - <location line="-134"/> + <location line="-130"/> <source>Node</source> <translation type="unfinished"></translation> </message> <message> - <location line="+135"/> + <location line="+131"/> <source>Show general overview of wallet</source> <translation>Show general overview of wallet</translation> </message> @@ -376,12 +389,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+175"/> + <location line="+180"/> <source>Bitcoin Core client</source> <translation type="unfinished"></translation> </message> <message> - <location line="+157"/> + <location line="+163"/> <source>Importing blocks from disk...</source> <translation>Importing blocks from disk...</translation> </message> @@ -391,7 +404,7 @@ <translation>Reindexing blocks on disk...</translation> </message> <message> - <location line="-416"/> + <location line="-427"/> <source>Send coins to a Bitcoin address</source> <translation>Send coins to a Bitcoin address</translation> </message> @@ -421,17 +434,17 @@ <translation>&Verify message...</translation> </message> <message> - <location line="+439"/> + <location line="+450"/> <source>Bitcoin</source> <translation>Bitcoin</translation> </message> <message> - <location line="-653"/> + <location line="-660"/> <source>Wallet</source> <translation>Wallet</translation> </message> <message> - <location line="+143"/> + <location line="+139"/> <source>&Send</source> <translation>&Send</translation> </message> @@ -471,7 +484,7 @@ <translation>Verify messages to ensure they were signed with specified Bitcoin addresses</translation> </message> <message> - <location line="+49"/> + <location line="+53"/> <source>&File</source> <translation>&File</translation> </message> @@ -496,7 +509,7 @@ <translation type="unfinished">Bitcoin Core</translation> </message> <message> - <location line="+164"/> + <location line="+160"/> <source>Request payments (generates QR codes and bitcoin: URIs)</source> <translation type="unfinished"></translation> </message> @@ -536,7 +549,7 @@ <translation type="unfinished"></translation> </message> <message numerus="yes"> - <location line="+309"/> + <location line="+320"/> <source>%n active connection(s) to Bitcoin network</source> <translation> <numerusform>%n active connection to Bitcoin network</numerusform> @@ -688,7 +701,7 @@ <context> <name>ClientModel</name> <message> - <location filename="../clientmodel.cpp" line="+141"/> + <location filename="../clientmodel.cpp" line="+143"/> <source>Network Alert</source> <translation>Network Alert</translation> </message> @@ -791,7 +804,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../coincontroldialog.cpp" line="+46"/> + <location filename="../coincontroldialog.cpp" line="+47"/> <source>Copy address</source> <translation type="unfinished">Copy address</translation> </message> @@ -912,7 +925,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+161"/> + <location line="+160"/> <source>This label turns red if the transaction size is greater than 1000 bytes.</source> <translation type="unfinished"></translation> </message> @@ -958,8 +971,8 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+59"/> - <location line="+61"/> + <location line="+58"/> + <location line="+60"/> <source>(no label)</source> <translation type="unfinished">(no label)</translation> </message> @@ -1045,7 +1058,7 @@ <context> <name>FreespaceChecker</name> <message> - <location filename="../intro.cpp" line="+69"/> + <location filename="../intro.cpp" line="+68"/> <source>A new data directory will be created.</source> <translation>A new data directory will be created.</translation> </message> @@ -1240,6 +1253,7 @@ </message> <message> <location line="+44"/> + <location line="+187"/> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation type="unfinished"></translation> </message> @@ -1280,7 +1294,7 @@ <translation>&Reset Options</translation> </message> <message> - <location line="-317"/> + <location line="-504"/> <source>&Network</source> <translation>&Network</translation> </message> @@ -1346,21 +1360,61 @@ </message> <message> <location line="+9"/> + <location line="+187"/> <source>Proxy &IP:</source> <translation>Proxy &IP:</translation> </message> <message> - <location line="+32"/> + <location line="-155"/> + <location line="+187"/> <source>&Port:</source> <translation>&Port:</translation> </message> <message> - <location line="+25"/> + <location line="-162"/> + <location line="+187"/> <source>Port of the proxy (e.g. 9050)</source> <translation>Port of the proxy (e.g. 9050)</translation> </message> <message> - <location line="+36"/> + <location line="-163"/> + <source>Used for reaching peers via:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+13"/> + <location line="+23"/> + <location line="+23"/> + <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="-36"/> + <source>IPv4</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+23"/> + <source>IPv6</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+23"/> + <source>Tor</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+25"/> + <source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+102"/> <source>&Window</source> <translation>&Window</translation> </message> @@ -1400,12 +1454,12 @@ <translation>Choose the default subdivision unit to show in the interface and when sending coins.</translation> </message> <message> - <location line="-253"/> + <location line="-440"/> <source>Whether to show coin control features or not.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+415"/> + <location line="+602"/> <source>&OK</source> <translation>&OK</translation> </message> @@ -1415,7 +1469,7 @@ <translation>&Cancel</translation> </message> <message> - <location filename="../optionsdialog.cpp" line="+75"/> + <location filename="../optionsdialog.cpp" line="+83"/> <source>default</source> <translation>default</translation> </message> @@ -1425,28 +1479,28 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+76"/> + <location line="+83"/> <source>Confirm options reset</source> <translation>Confirm options reset</translation> </message> <message> <location line="+1"/> - <location line="+29"/> + <location line="+30"/> <source>Client restart required to activate changes.</source> <translation type="unfinished"></translation> </message> <message> - <location line="-29"/> + <location line="-30"/> <source>Client will be shut down. Do you want to proceed?</source> <translation type="unfinished"></translation> </message> <message> - <location line="+33"/> + <location line="+34"/> <source>This change would require a client restart.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+25"/> + <location line="+24"/> <source>The supplied proxy address is invalid.</source> <translation>The supplied proxy address is invalid.</translation> </message> @@ -1548,7 +1602,7 @@ <context> <name>PaymentServer</name> <message> - <location filename="../paymentserver.cpp" line="+434"/> + <location filename="../paymentserver.cpp" line="+432"/> <location line="+14"/> <location line="+7"/> <source>URI handling</source> @@ -1560,16 +1614,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+88"/> + <location line="+83"/> <location line="+9"/> <location line="+31"/> <location line="+10"/> <location line="+17"/> + <location line="+88"/> <source>Payment request rejected</source> <translation type="unfinished"></translation> </message> <message> - <location line="-67"/> + <location line="-155"/> <source>Payment request network doesn't match client network.</source> <translation type="unfinished"></translation> </message> @@ -1584,17 +1639,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-263"/> - <location line="+221"/> + <location line="-258"/> + <location line="+216"/> <location line="+42"/> - <location line="+114"/> + <location line="+113"/> <location line="+14"/> <location line="+18"/> <source>Payment request error</source> <translation type="unfinished"></translation> </message> <message> - <location line="-408"/> + <location line="-402"/> <source>Cannot start bitcoin: click-to-pay handler</source> <translation type="unfinished"></translation> </message> @@ -1619,7 +1674,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+75"/> + <location line="+70"/> <source>Payment request expired.</source> <translation type="unfinished"></translation> </message> @@ -1640,17 +1695,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+44"/> <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source> <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> - <source>Payment request DoS protection</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+5"/> + <location line="+9"/> <source>Error communicating with %1: %2</source> <translation type="unfinished"></translation> </message> @@ -1678,7 +1728,7 @@ <context> <name>PeerTableModel</name> <message> - <location filename="../peertablemodel.cpp" line="+118"/> + <location filename="../peertablemodel.cpp" line="+117"/> <source>User Agent</source> <translation type="unfinished"></translation> </message> @@ -1706,7 +1756,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+748"/> + <location line="+761"/> <source>%1 d</source> <translation type="unfinished"></translation> </message> @@ -1768,7 +1818,7 @@ <context> <name>RPCConsole</name> <message> - <location filename="../forms/rpcconsole.ui" line="+46"/> + <location filename="../forms/debugwindow.ui" line="+46"/> <source>Client name</source> <translation>Client name</translation> </message> @@ -1777,13 +1827,16 @@ <location line="+23"/> <location line="+26"/> <location line="+26"/> + <location line="+26"/> <location line="+23"/> <location line="+23"/> <location line="+36"/> <location line="+23"/> <location line="+36"/> <location line="+23"/> - <location line="+465"/> + <location line="+533"/> + <location line="+23"/> + <location line="+23"/> <location line="+23"/> <location line="+23"/> <location line="+23"/> @@ -1796,12 +1849,13 @@ <location line="+23"/> <location line="+23"/> <location line="+23"/> + <location line="+26"/> <location line="+23"/> <source>N/A</source> <translation>N/A</translation> </message> <message> - <location line="-990"/> + <location line="-1156"/> <source>Client version</source> <translation>Client version</translation> </message> @@ -1821,7 +1875,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+53"/> + <location line="+79"/> <source>Using OpenSSL version</source> <translation>Using OpenSSL version</translation> </message> @@ -1881,14 +1935,24 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+39"/> - <location filename="../rpcconsole.cpp" line="+238"/> - <location line="+326"/> + <location line="+50"/> + <source>Banned peers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+57"/> + <location filename="../rpcconsole.cpp" line="+281"/> + <location line="+560"/> <source>Select a peer to view detailed information.</source> <translation type="unfinished"></translation> </message> <message> <location line="+25"/> + <source>Whitelisted</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+23"/> <source>Direction</source> <translation type="unfinished"></translation> </message> @@ -1898,27 +1962,33 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+23"/> - <source>User Agent</source> + <location line="+69"/> + <source>Starting Block</source> <translation type="unfinished"></translation> </message> <message> <location line="+23"/> - <source>Services</source> + <source>Synced Headers</source> <translation type="unfinished"></translation> </message> <message> <location line="+23"/> - <source>Starting Height</source> + <source>Synced Blocks</source> <translation type="unfinished"></translation> </message> <message> - <location line="+23"/> - <source>Sync Height</source> + <location line="-913"/> + <location line="+821"/> + <source>User Agent</source> <translation type="unfinished"></translation> </message> <message> <location line="+23"/> + <source>Services</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+92"/> <source>Ban Score</source> <translation type="unfinished"></translation> </message> @@ -1954,11 +2024,21 @@ </message> <message> <location line="+23"/> + <source>The duration of a currently outstanding ping.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>Ping Wait</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+23"/> <source>Time Offset</source> <translation type="unfinished"></translation> </message> <message> - <location line="-764"/> + <location line="-904"/> <source>Last block time</source> <translation>Last block time</translation> </message> @@ -1988,7 +2068,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../rpcconsole.cpp" line="-164"/> + <location filename="../rpcconsole.cpp" line="-333"/> <source>In:</source> <translation type="unfinished"></translation> </message> @@ -1998,7 +2078,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../forms/rpcconsole.ui" line="-357"/> + <location filename="../forms/debugwindow.ui" line="-357"/> <source>Build date</source> <translation>Build date</translation> </message> @@ -2013,7 +2093,45 @@ <translation>Clear console</translation> </message> <message> - <location filename="../rpcconsole.cpp" line="-36"/> + <location filename="../rpcconsole.cpp" line="-150"/> + <source>&Disconnect Node</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <location line="+1"/> + <location line="+1"/> + <location line="+1"/> + <source>Ban Node for</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="-3"/> + <source>1 &hour</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>1 &day</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>1 &week</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>1 &year</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+46"/> + <source>&Unban Node</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+64"/> <source>Welcome to the Bitcoin Core RPC console.</source> <translation type="unfinished"></translation> </message> @@ -2048,7 +2166,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+95"/> + <location line="+88"/> + <source>(node id: %1)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> <source>via %1</source> <translation type="unfinished"></translation> </message> @@ -2059,7 +2182,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+9"/> <source>Inbound</source> <translation type="unfinished"></translation> </message> @@ -2069,14 +2192,19 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> - <source>Unknown</source> + <location line="+2"/> + <source>Yes</source> <translation type="unfinished"></translation> </message> <message> - <location line="+2"/> - <location line="+1"/> - <source>Fetching...</source> + <location line="+0"/> + <source>No</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+12"/> + <location line="+6"/> + <source>Unknown</source> <translation type="unfinished"></translation> </message> </context> @@ -2171,7 +2299,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../receivecoinsdialog.cpp" line="+45"/> + <location filename="../receivecoinsdialog.cpp" line="+46"/> <source>Copy label</source> <translation type="unfinished">Copy label</translation> </message> @@ -2296,7 +2424,7 @@ <name>SendCoinsDialog</name> <message> <location filename="../forms/sendcoinsdialog.ui" line="+14"/> - <location filename="../sendcoinsdialog.cpp" line="+543"/> + <location filename="../sendcoinsdialog.cpp" line="+545"/> <source>Send Coins</source> <translation>Send Coins</translation> </message> @@ -2541,12 +2669,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+244"/> - <source>Total Amount %1 (= %2)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+2"/> + <location line="+246"/> <source>or</source> <translation type="unfinished"></translation> </message> @@ -2599,7 +2722,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-114"/> + <location line="-309"/> + <source>Total Amount %1<span style='font-size:10pt;font-weight:normal;'><br />(=%2)</span></source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+195"/> <source>The recipient address is not valid. Please recheck.</source> <translation type="unfinished"></translation> </message> @@ -2614,7 +2742,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+20"/> + <location line="+19"/> <source>(no label)</source> <translation type="unfinished">(no label)</translation> </message> @@ -2624,7 +2752,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-692"/> + <location line="-691"/> <source>Copy dust</source> <translation type="unfinished"></translation> </message> @@ -2872,7 +3000,7 @@ <translation>Reset all verify message fields</translation> </message> <message> - <location filename="../signverifymessagedialog.cpp" line="+40"/> + <location filename="../signverifymessagedialog.cpp" line="+41"/> <source>Click "Sign Message" to generate signature</source> <translation>Click "Sign Message" to generate signature</translation> </message> @@ -2956,7 +3084,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../networkstyle.cpp" line="+20"/> + <location filename="../networkstyle.cpp" line="+19"/> <source>[testnet]</source> <translation>[testnet]</translation> </message> @@ -2972,7 +3100,7 @@ <context> <name>TransactionDesc</name> <message> - <location filename="../transactiondesc.cpp" line="+34"/> + <location filename="../transactiondesc.cpp" line="+32"/> <source>Open until %1</source> <translation>Open until %1</translation> </message> @@ -3196,7 +3324,7 @@ <context> <name>TransactionTableModel</name> <message> - <location filename="../transactiontablemodel.cpp" line="+230"/> + <location filename="../transactiontablemodel.cpp" line="+233"/> <source>Date</source> <translation>Date</translation> </message> @@ -3332,7 +3460,7 @@ <context> <name>TransactionView</name> <message> - <location filename="../transactionview.cpp" line="+68"/> + <location filename="../transactionview.cpp" line="+69"/> <location line="+16"/> <source>All</source> <translation>All</translation> @@ -3519,7 +3647,7 @@ <context> <name>WalletFrame</name> <message> - <location filename="../walletframe.cpp" line="+26"/> + <location filename="../walletframe.cpp" line="+27"/> <source>No wallet has been loaded.</source> <translation type="unfinished"></translation> </message> @@ -3535,7 +3663,7 @@ <context> <name>WalletView</name> <message> - <location filename="../walletview.cpp" line="+45"/> + <location filename="../walletview.cpp" line="+46"/> <source>&Export</source> <translation>&Export</translation> </message> @@ -3545,7 +3673,7 @@ <translation>Export the data in the current tab to a file</translation> </message> <message> - <location line="+189"/> + <location line="+194"/> <source>Backup Wallet</source> <translation>Backup Wallet</translation> </message> @@ -3578,57 +3706,112 @@ <context> <name>bitcoin-core</name> <message> - <location filename="../bitcoinstrings.cpp" line="+268"/> + <location filename="../bitcoinstrings.cpp" line="+249"/> <source>Options:</source> <translation>Options:</translation> </message> <message> - <location line="+35"/> + <location line="+30"/> <source>Specify data directory</source> <translation>Specify data directory</translation> </message> <message> - <location line="-94"/> + <location line="-87"/> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Connect to a node to retrieve peer addresses, and disconnect</translation> </message> <message> - <location line="+97"/> + <location line="+90"/> <source>Specify your own public address</source> <translation>Specify your own public address</translation> </message> <message> - <location line="-117"/> + <location line="-107"/> <source>Accept command line and JSON-RPC commands</source> <translation>Accept command line and JSON-RPC commands</translation> </message> <message> - <location line="+95"/> + <location line="-117"/> + <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying (default: %s)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+5"/> + <source>If <category> is not supplied or if <category> = 1, output all debugging information.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+15"/> + <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>Prune configured below the minimum of %d MiB. Please use a higher number.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+9"/> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+5"/> + <source>Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+109"/> + <source>Error: A fatal internal error occurred, see debug.log for details</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+37"/> + <source>Pruning blockstore...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+9"/> <source>Run in the background as a daemon and accept commands</source> <translation>Run in the background as a daemon and accept commands</translation> </message> <message> - <location line="+42"/> + <location line="+32"/> + <source>Unable to start HTTP server. See debug log for details.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> <source>Use the test network</source> <translation>Use the test network</translation> </message> <message> - <location line="-136"/> + <location line="-123"/> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>Accept connections from outside (default: 1 if no -proxy or -connect)</translation> </message> <message> - <location line="-168"/> + <location line="-157"/> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Bind to given address and always listen on it. Use [host]:port notation for IPv6</translation> </message> <message> - <location line="+13"/> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+6"/> + <location line="+16"/> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <translation type="unfinished"></translation> </message> @@ -3638,52 +3821,52 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation type="unfinished"></translation> - </message> - <message> <location line="+11"/> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</translation> </message> <message> - <location line="+20"/> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> + <location line="+57"/> + <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+14"/> - <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <location line="+6"/> + <source>The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct</source> <translation type="unfinished"></translation> </message> <message> - <location line="+15"/> - <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <location line="+7"/> + <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source> + <translation>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</translation> + </message> + <message> + <location line="+7"/> + <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+10"/> - <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> + <location line="+3"/> + <source>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> - <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source> - <translation>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</translation> + <location line="+5"/> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation type="unfinished"></translation> </message> <message> - <location line="+20"/> - <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source> + <location line="+3"/> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+6"/> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</translation> </message> <message> - <location line="+6"/> + <location line="+3"/> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</translation> </message> @@ -3718,7 +3901,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+10"/> + <location line="+8"/> <source>Attempt to recover private keys from a corrupt wallet.dat</source> <translation>Attempt to recover private keys from a corrupt wallet.dat</translation> </message> @@ -3728,7 +3911,7 @@ <translation>Block creation options:</translation> </message> <message> - <location line="+8"/> + <location line="+7"/> <source>Connect only to the specified node(s)</source> <translation>Connect only to the specified node(s)</translation> </message> @@ -3743,12 +3926,12 @@ <translation>Corrupted block database detected</translation> </message> <message> - <location line="+2"/> + <location line="+1"/> <source>Debugging/Testing options:</source> <translation type="unfinished"></translation> </message> <message> - <location line="+2"/> + <location line="+1"/> <source>Do not load the wallet and disable wallet RPC calls</source> <translation type="unfinished"></translation> </message> @@ -3759,6 +3942,26 @@ </message> <message> <location line="+2"/> + <source>Enable publish hash block in <address></source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Enable publish hash transaction in <address></source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Enable publish raw block in <address></source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Enable publish raw transaction in <address></source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> <source>Error initializing block database</source> <translation>Error initializing block database</translation> </message> @@ -3778,12 +3981,7 @@ <translation>Error opening block database</translation> </message> <message> - <location line="+3"/> - <source>Error: A fatal internal error occured, see debug.log for details</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+1"/> + <location line="+4"/> <source>Error: Disk space is low!</source> <translation>Error: Disk space is low!</translation> </message> @@ -3793,12 +3991,7 @@ <translation>Failed to listen on any port. Use -listen=0 if you want this.</translation> </message> <message> - <location line="+5"/> - <source>If <category> is not supplied, output all debugging information.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+1"/> + <location line="+4"/> <source>Importing...</source> <translation type="unfinished"></translation> </message> @@ -3813,12 +4006,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+21"/> + <location line="+20"/> <source>Not enough file descriptors available.</source> <translation>Not enough file descriptors available.</translation> </message> <message> - <location line="+2"/> + <location line="+1"/> <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> <translation type="unfinished"></translation> </message> @@ -3833,7 +4026,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+18"/> + <location line="+14"/> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation type="unfinished"></translation> </message> @@ -3843,22 +4036,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+12"/> + <location line="+11"/> <source>Specify wallet file (within data directory)</source> <translation>Specify wallet file (within data directory)</translation> </message> <message> - <location line="+8"/> - <source>This is intended for regression testing tools and app development.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+11"/> + <location line="+17"/> <source>Use UPnP to map the listening port (default: %u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+4"/> + <location line="+3"/> <source>Verifying blocks...</source> <translation>Verifying blocks...</translation> </message> @@ -3888,22 +4076,17 @@ <translation>You need to rebuild the database using -reindex to change -txindex</translation> </message> <message> - <location line="-99"/> + <location line="-89"/> <source>Imports blocks from external blk000??.dat file</source> <translation>Imports blocks from external blk000??.dat file</translation> </message> <message> - <location line="-223"/> + <location line="-206"/> <source>Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source> <translation type="unfinished"></translation> </message> <message> - <location line="+4"/> - <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+6"/> + <location line="+7"/> <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> <translation type="unfinished"></translation> </message> @@ -3918,7 +4101,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> + <location line="+3"/> <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> <translation type="unfinished"></translation> </message> @@ -3928,7 +4111,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+6"/> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation type="unfinished"></translation> </message> @@ -3943,37 +4126,22 @@ <translation>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</translation> </message> <message> - <location line="+9"/> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+3"/> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+8"/> + <location line="+17"/> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> + <location line="+3"/> <source>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+6"/> <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+10"/> - <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+2"/> + <location line="+18"/> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation type="unfinished"></translation> </message> @@ -3983,12 +4151,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> - <source>Require high priority for relaying free or low-fee transactions (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+2"/> + <location line="+11"/> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation type="unfinished"></translation> </message> @@ -3998,7 +4161,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> + <location line="+8"/> <source>The transaction amount is too small to send after the fee has been deducted</source> <translation type="unfinished"></translation> </message> @@ -4008,32 +4171,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+4"/> - <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+19"/> + <location line="+18"/> <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> - <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+19"/> + <location line="+22"/> <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source> <translation type="unfinished"></translation> </message> @@ -4053,22 +4196,12 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+2"/> + <location line="+1"/> <source>Activating best chain...</source> <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> - <source>Allow self signed root certificates (default: 0)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+4"/> - <source>Can't run with a wallet in prune mode.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+4"/> + <location line="+9"/> <source>Cannot resolve -whitebind address: '%s'</source> <translation type="unfinished"></translation> </message> @@ -4088,12 +4221,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+2"/> - <source>Could not parse -rpcbind value %s as network address</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+11"/> + <location line="+15"/> <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> <translation type="unfinished"></translation> </message> @@ -4108,11 +4236,6 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+2"/> - <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> - <translation type="unfinished"></translation> - </message> - <message> <location line="+9"/> <source>Information</source> <translation>Information</translation> @@ -4153,7 +4276,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+11"/> + <location line="+10"/> <source>Need to specify a port with -whitebind: '%s'</source> <translation type="unfinished"></translation> </message> @@ -4164,36 +4287,26 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <location line="+9"/> - <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+1"/> <source>RPC server options:</source> <translation type="unfinished"></translation> </message> <message> <location line="+1"/> - <source>RPC support for HTTP persistent connections (default: %d)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+1"/> - <source>Randomly drop 1 of every <n> network messages</source> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation type="unfinished"></translation> </message> <message> <location line="+1"/> - <source>Randomly fuzz 1 of every <n> network messages</source> + <source>Receive and display P2P network alerts (default: %u)</source> <translation type="unfinished"></translation> </message> <message> <location line="+1"/> - <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <source>Reducing -maxconnections from %d to %d, because of system limitations.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+7"/> + <location line="+6"/> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Send trace/debug info to console instead of debug.log file</translation> </message> @@ -4203,7 +4316,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> + <location line="+1"/> <source>Set SSL root certificates for payment request (default: -system-)</source> <translation type="unfinished"></translation> </message> @@ -4213,7 +4326,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished">Set language, for example "de_DE" (default: system locale)</translation> </message> <message> - <location line="+5"/> + <location line="+4"/> <source>Show all debugging options (usage: --help -help-debug)</source> <translation type="unfinished"></translation> </message> @@ -4238,7 +4351,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished">Start minimized</translation> </message> <message> - <location line="+2"/> + <location line="+1"/> <source>The transaction amount is too small to pay the fee</source> <translation type="unfinished"></translation> </message> @@ -4248,7 +4361,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> + <location line="+2"/> <source>Transaction amount too small</source> <translation>Transaction amount too small</translation> </message> @@ -4278,12 +4391,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> - <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>Use UPnP to map the listening port (default: 1 when listening)</translation> - </message> - <message> - <location line="+2"/> + <location line="+6"/> <source>Username for JSON-RPC connections</source> <translation>Username for JSON-RPC connections</translation> </message> @@ -4314,6 +4422,11 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <location line="+1"/> + <source>ZeroMQ notification options:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> <source>on startup</source> <translation type="unfinished"></translation> </message> @@ -4323,72 +4436,57 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>wallet.dat corrupt, salvage failed</translation> </message> <message> - <location line="-71"/> + <location line="-64"/> <source>Password for JSON-RPC connections</source> <translation>Password for JSON-RPC connections</translation> </message> <message> - <location line="-205"/> + <location line="-195"/> <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source> <translation>Execute command when the best block changes (%s in cmd is replaced by block hash)</translation> </message> <message> - <location line="+258"/> + <location line="+242"/> <source>Upgrade wallet to latest format</source> <translation>Upgrade wallet to latest format</translation> </message> <message> - <location line="-41"/> + <location line="-36"/> <source>Rescan the block chain for missing wallet transactions</source> <translation>Rescan the block chain for missing wallet transactions</translation> </message> <message> - <location line="+42"/> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Use OpenSSL (https) for JSON-RPC connections</translation> - </message> - <message> - <location line="-12"/> + <location line="+25"/> <source>This help message</source> <translation>This help message</translation> </message> <message> - <location line="-116"/> + <location line="-106"/> <source>Allow DNS lookups for -addnode, -seednode and -connect</source> <translation>Allow DNS lookups for -addnode, -seednode and -connect</translation> </message> <message> - <location line="+61"/> + <location line="+58"/> <source>Loading addresses...</source> <translation>Loading addresses...</translation> </message> <message> - <location line="-33"/> + <location line="-30"/> <source>Error loading wallet.dat: Wallet corrupted</source> <translation>Error loading wallet.dat: Wallet corrupted</translation> </message> <message> - <location line="-211"/> + <location line="-196"/> <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+61"/> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+3"/> + <location line="+49"/> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation type="unfinished"></translation> </message> <message> <location line="+11"/> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+2"/> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation type="unfinished"></translation> </message> @@ -4408,37 +4506,22 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+34"/> + <location line="+37"/> <source>(default: %s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+7"/> - <source>Acceptable ciphers (default: %s)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+5"/> + <location line="+10"/> <source>Always query for peer addresses via DNS lookup (default: %u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+18"/> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+7"/> + <location line="+26"/> <source>Error loading wallet.dat</source> <translation>Error loading wallet.dat</translation> </message> <message> <location line="+11"/> - <source>Force safe mode (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+1"/> <source>Generate coins (default: %u)</source> <translation type="unfinished"></translation> </message> @@ -4448,7 +4531,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+4"/> + <location line="+3"/> <source>Include IP addresses in debug output (default: %u)</source> <translation type="unfinished"></translation> </message> @@ -4459,11 +4542,6 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <location line="+8"/> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+1"/> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation type="unfinished"></translation> </message> @@ -4493,17 +4571,12 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+4"/> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+4"/> + <location line="+7"/> <source>Prepend debug output with timestamp (default: %u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+8"/> <source>Relay and mine data carrier transactions (default: %u)</source> <translation type="unfinished"></translation> </message> @@ -4513,22 +4586,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+4"/> - <source>Server certificate file (default: %s)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+1"/> - <source>Server private key (default: %s)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+3"/> + <location line="+8"/> <source>Set key pool size to <n> (default: %u)</source> <translation type="unfinished"></translation> </message> @@ -4543,11 +4601,6 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+1"/> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> <location line="+5"/> <source>Specify configuration file (default: %s)</source> <translation type="unfinished"></translation> @@ -4568,22 +4621,17 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+2"/> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation type="unfinished"></translation> - </message> - <message> <location line="+5"/> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+7"/> + <location line="+8"/> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Unknown network specified in -onlynet: '%s'</translation> </message> <message> - <location line="-119"/> + <location line="-111"/> <source>Cannot resolve -bind address: '%s'</source> <translation>Cannot resolve -bind address: '%s'</translation> </message> @@ -4603,22 +4651,22 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Insufficient funds</translation> </message> <message> - <location line="+14"/> + <location line="+13"/> <source>Loading block index...</source> <translation>Loading block index...</translation> </message> <message> - <location line="-63"/> + <location line="-60"/> <source>Add a node to connect to and attempt to keep the connection open</source> <translation>Add a node to connect to and attempt to keep the connection open</translation> </message> <message> - <location line="+64"/> + <location line="+61"/> <source>Loading wallet...</source> <translation>Loading wallet...</translation> </message> <message> - <location line="-57"/> + <location line="-56"/> <source>Cannot downgrade wallet</source> <translation>Cannot downgrade wallet</translation> </message> @@ -4628,17 +4676,17 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Cannot write default address</translation> </message> <message> - <location line="+77"/> + <location line="+74"/> <source>Rescanning...</source> <translation>Rescanning...</translation> </message> <message> - <location line="-64"/> + <location line="-63"/> <source>Done loading</source> <translation>Done loading</translation> </message> <message> - <location line="+9"/> + <location line="+13"/> <source>Error</source> <translation>Error</translation> </message> diff --git a/src/qt/locale/bitcoin_eo.ts b/src/qt/locale/bitcoin_eo.ts index 007acbc495..17ce494f91 100644 --- a/src/qt/locale/bitcoin_eo.ts +++ b/src/qt/locale/bitcoin_eo.ts @@ -1,7 +1,11 @@ -<TS language="eo" version="2.1"> +<TS language="eo" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>Dekstre-klaku por redakti adreson aŭ etikedon</translation> + </message> + <message> <source>Create a new address</source> <translation>Krei novan adreson</translation> </message> @@ -89,7 +93,11 @@ <source>Exporting Failed</source> <translation>ekspotado malsukcesinta</translation> </message> - </context> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>Okazis eraron dum konservo de adreslisto al %1. Bonvolu provi denove.</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -327,6 +335,10 @@ <translation>&Ricevi</translation> </message> <message> + <source>Show information about Bitcoin Core</source> + <translation>Vidigi informon pri Bitmona Kerno</translation> + </message> + <message> <source>&Show / Hide</source> <translation>&Montri / Kaŝi</translation> </message> @@ -477,6 +489,10 @@ <translation>Krompago:</translation> </message> <message> + <source>Dust:</source> + <translation>Polvo:</translation> + </message> + <message> <source>After Fee:</source> <translation>Post krompago:</translation> </message> @@ -501,6 +517,14 @@ <translation>Sumo</translation> </message> <message> + <source>Received with label</source> + <translation>Ricevita kun etikedo</translation> + </message> + <message> + <source>Received with address</source> + <translation>Ricevita kun adreso</translation> + </message> + <message> <source>Date</source> <translation>Dato</translation> </message> @@ -561,6 +585,10 @@ <translation>Kopii prioritaton</translation> </message> <message> + <source>Copy dust</source> + <translation>Kopii polvon</translation> + </message> + <message> <source>Copy change</source> <translation>Kopii restmonon</translation> </message> @@ -835,6 +863,10 @@ <translation>&Reto</translation> </message> <message> + <source>Expert</source> + <translation>Fakulo</translation> + </message> + <message> <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> <translation>Aŭtomate malfermi la kursilan pordon por Bitmono. Tio funkcias nur se via kursilo havas la UPnP-funkcion, kaj se tiu ĉi estas ŝaltita.</translation> </message> @@ -1089,6 +1121,10 @@ <translation>Aktuala nombro de blokoj</translation> </message> <message> + <source>Bytes Sent</source> + <translation>Bajtoj Senditaj:</translation> + </message> + <message> <source>Last block time</source> <translation>Horo de la lasta bloko</translation> </message> @@ -1353,6 +1389,10 @@ <translation>Malplenigi ĉiujn kampojn de la formularo.</translation> </message> <message> + <source>Dust:</source> + <translation>Polvo:</translation> + </message> + <message> <source>Clear &All</source> <translation>&Forigi Ĉion</translation> </message> @@ -1437,6 +1477,10 @@ <translation>(neniu etikedo)</translation> </message> <message> + <source>Copy dust</source> + <translation>Kopii polvon</translation> + </message> + <message> <source>Are you sure you want to send?</source> <translation>Ĉu vi certas, ke vi volas sendi?</translation> </message> diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts index 17ec4dca5d..de55496c09 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -1,9 +1,9 @@ -<TS language="es" version="2.1"> +<TS language="es" version="2.0"> <context> <name>AddressBookPage</name> <message> <source>Right-click to edit address or label</source> - <translation>Haz-clic para editar la dirección o etiqueta</translation> + <translation>Haz clic derecho para editar la dirección o etiqueta</translation> </message> <message> <source>Create a new address</source> @@ -47,11 +47,11 @@ </message> <message> <source>Choose the address to send coins to</source> - <translation>Elije la dirección para enviar monedas a</translation> + <translation>Elija la dirección para enviar monedas a</translation> </message> <message> <source>Choose the address to receive coins with</source> - <translation>Elije la dirección para recibir monedas con</translation> + <translation>Elija la dirección para recibir monedas con</translation> </message> <message> <source>C&hoose</source> @@ -75,7 +75,7 @@ </message> <message> <source>Copy &Label</source> - <translation>Copiar &etiqueta</translation> + <translation>Copiar &Etiqueta</translation> </message> <message> <source>&Edit</source> @@ -395,6 +395,10 @@ <translation>&Acerca de Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Modificar las opciones de configuración de Bitcoin</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Mostrar la lista de direcciones de envío y etiquetas</translation> </message> @@ -423,6 +427,10 @@ <translation>Ninguna fuente de bloques disponible ...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>%n bloque procesado del historial de transacciones.</numerusform><numerusform>%n bloques procesados del historial de transacciones.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n hora</numerusform><numerusform>%n horas</numerusform></translation> </message> @@ -481,6 +489,18 @@ </translation> </message> <message> + <source>Amount: %1 +</source> + <translation>Amount: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Tipo: %1 +</translation> + </message> + <message> <source>Label: %1 </source> <translation>Etiqueta: %1 @@ -699,6 +719,10 @@ <translation>Esta etiqueta se mostrará en rojo si la prioridad es menor a "media"</translation> </message> <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Esta etiqueta se vuelve roja si el cambio es menor que %1</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Puede variar en +/- %1 satoshi(s) por entrada.</translation> </message> @@ -949,6 +973,14 @@ <translation>Dirección IP del proxy (p. ej. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>Minimizar en lugar de salir de la aplicación cuando la ventana está cerrada. Cuando se activa esta opción, la aplicación sólo se cerrará después de seleccionar Salir en el menú.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>El idioma de la interfaz de usuario puede establecerse aquí. Este ajuste se aplicará cuando se reinicie Bitcoin.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>Identificadores URL de terceros (por ejemplo, un explorador de bloques) que aparecen en la pestaña de transacciones como elementos del menú contextual. El %s en la URL es reemplazado por el valor hash de la transacción. Se pueden separar URL múltiples por una barra vertical |.</translation> </message> @@ -1093,6 +1125,10 @@ <translation>Se necesita reiniciar el cliente para activar los cambios.</translation> </message> <message> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>El cliente se cerrará. ¿Desea continuar?</translation> + </message> + <message> <source>This change would require a client restart.</source> <translation>Este cambio exige el reinicio del cliente.</translation> </message> @@ -1403,6 +1439,10 @@ <translation>Número actual de bloques</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Abre el archivo de registro de depuración de Bitcoin desde el directorio de datos actual. Esto puede tardar unos segundos para ficheros de registro de gran tamaño.</translation> + </message> + <message> <source>Received</source> <translation>Recibido</translation> </message> @@ -1471,6 +1511,10 @@ <translation>Ping</translation> </message> <message> + <source>Time Offset</source> + <translation>Desplazamiento de tiempo</translation> + </message> + <message> <source>Last block time</source> <translation>Hora del último bloque</translation> </message> @@ -1962,11 +2006,23 @@ <source>Payment request expired.</source> <translation>Solicitud de pago caducada.</translation> </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Estimado para empezar la confirmación dentro de %n bloque.</numerusform><numerusform>Estimado para empezar la confirmación dentro de %n bloques.</numerusform></translation> + </message> <message> <source>Pay only the minimum fee of %1</source> <translation>Paga sólo la cuota mínima de %1</translation> </message> <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>La dirección del destinatario no es válida. Por favor, compruébela de nuevo.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Se ha encontrado una dirección duplicada. Solo se puede enviar a cada dirección una vez por operación de envío.</translation> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Alerta: Dirección de Bitcoin inválida</translation> </message> @@ -2038,6 +2094,10 @@ <translation>Eliminar esta transacción</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>La cuota será deducida de la cantidad que sea mandada. El destinatario recibirá menos bitcoins de los que entres en el </translation> + </message> + <message> <source>S&ubtract fee from amount</source> <translation>Restar comisiones a la cantidad</translation> </message> @@ -2092,6 +2152,10 @@ <translation>&Firmar mensaje</translation> </message> <message> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>Puede firmar los mensajes con sus direcciones para demostrar que las posee. Tenga cuidado de no firmar cualquier cosa de manera vaga o aleatoria, pues los ataques de phishing pueden tratar de engañarle firmando su identidad a través de ellos. Sólo firme declaraciones totalmente detalladas con las que usted esté de acuerdo.</translation> + </message> + <message> <source>The Bitcoin address to sign the message with</source> <translation>Dirección Bitcoin con la que firmar el mensaje</translation> </message> @@ -2144,6 +2208,10 @@ <translation>&Verificar mensaje</translation> </message> <message> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Introduzca la dirección para la firma, el mensaje (asegurándose de copiar tal cual los saltos de línea, espacios, tabulaciones, etc.) y la firma a continuación para verificar el mensaje. Tenga cuidado de no asumir más información de lo que dice el propio mensaje firmado para evitar fraudes basados en ataques de tipo man-in-the-middle. </translation> + </message> + <message> <source>The Bitcoin address the message was signed with</source> <translation>La dirección Bitcoin con la que se firmó el mensaje</translation> </message> @@ -2495,6 +2563,10 @@ <translation>Sea o no una dirección sólo está involucrada en esta transacción.</translation> </message> <message> + <source>User-defined intent/purpose of the transaction.</source> + <translation>intento/propósito de la transacción definido por el usuario.</translation> + </message> + <message> <source>Amount removed from or added to balance.</source> <translation>Cantidad retirada o añadida al saldo.</translation> </message> @@ -2749,16 +2821,16 @@ <translation>Distribuido bajo la licencia de software MIT, vea la copia del archivo adjunto o <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Ingresar en el modo de prueba de regresión, que utiliza una cadena especial en la que los bloques se pueden resolver instantáneamente.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Ejecutar comando cuando una transacción del monedero cambia (%s en cmd se remplazará por TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>En este modo -genproclimit controla cuántos bloques se generan de inmediato.</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Maximo Comisión totales para usar en una sola transacción billetera; establecer esta demasiado bajo puede abortar transacciones grandes (por defecto: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>Reducir los requerimientos de almacenamiento mediante la poda (borrado) bloquea viejos. Este modo desactiva el apoyo cartera y es incompatible con -txindex. Advertencia: Revertir esta configuración requiere volver a descargar toda la blockchain. (por defecto: 0 = desactivar bloques de poda, >%u = tamaño de destino en MiB de usar para los archivos de bloques)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2773,6 +2845,14 @@ <translation>No se ha podido acceder a %s en esta máquina. Probablemente ya se está ejecutando Bitcoin Core.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>ADVERTENCIA: anormalmente alto número de bloques generado, %d bloques recibidos en las últimas horas %d (%d espera)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>ADVERTENCIA: comprueba tu conexión de red, %d bloques recibidos en las últimas %d horas (%d esperados)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Aviso: ¡-paytxfee tiene un valor muy alto! Esta es la comisión que pagará si envía una transacción.</translation> </message> @@ -2889,6 +2969,14 @@ <translation>Sólo conectar a nodos en redes <net> (ipv4, ipv6 o onion)</translation> </message> <message> + <source>Prune cannot be configured with a negative value.</source> + <translation>Pode no se puede configurar con un valor negativo.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>El modo recorte es incompatible con -txindex.</translation> + </message> + <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation>Asignar tamaño de cache en megabytes (entre %d y %d; predeterminado: %d)</translation> </message> @@ -2901,10 +2989,6 @@ <translation>Especificar archivo de monedero (dentro del directorio de datos)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Esto afecta a las herramientas de prueba de regresión y al desarrollo informático de la aplicación.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Usar UPnP para asignar el puerto de escucha (predeterminado:: %u)</translation> </message> @@ -2961,6 +3045,10 @@ <translation>Crear nuevos archivos con permisos por defecto del sistema, en lugar de umask 077 (sólo efectivo con la funcionalidad de monedero desactivada)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Descubra direcciones IP propias (por defecto: 1 cuando se escucha y nadie -externalip o -proxy)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Error: la escucha para conexiones entrantes falló (la escucha regresó el error %s)</translation> </message> @@ -2977,10 +3065,6 @@ <translation>Tarifas (en BTC/Kb) más pequeños que esto se consideran cero cuota de reinstalación (por defecto: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Tarifas (en BTC/Kb) más pequeños que esto se consideran cero cuota para la creación de la transacción (por defecto: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Si el pago de comisión no está establecido, incluir la cuota suficiente para que las transacciones comiencen la confirmación en una media de n bloques ( por defecto :%u)</translation> </message> @@ -2989,10 +3073,18 @@ <translation>El tamaño máximo de los datos en las operaciones de transporte de datos que transmitimos y el mio (default: %u)</translation> </message> <message> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>Pode configurado por debajo del mínimo de %d MB. Por favor, use un número más alto.</translation> + </message> + <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Consulta de direcciones pares mediante búsqueda de DNS, si bajo en direcciones (por defecto: 1 a menos que - conectar)</translation> </message> <message> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Aleatorizar las credenciales para cada conexión proxy. Esto habilita la Tor stream isolation (por defecto: %u)</translation> + </message> + <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Establecer tamaño máximo de las transacciones de alta prioridad/baja comisión en bytes (predeterminado: %d)</translation> </message> @@ -3001,6 +3093,10 @@ <translation>Ajuste el número de hilos para la generación de moneda si está habilitado (-1 = all cores, default: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>Monto de transacción muy pequeña luego de la deducción por comisión</translation> + </message> + <message> <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source> <translation>Este producto incluye software desarrollado por el OpenSSL Project para su uso en OpenSSL Toolkit <https://www.openssl.org/>, software de cifrado escrito por Eric Young y software UPnP escrito por Thomas Bernard.</translation> </message> @@ -3041,10 +3137,26 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>A los equipos en lista blanca no se les pueden prohibir los ataques DoS y sus transacciones siempre son retransmitidas, incluso si ya están en el mempool, es útil por ejemplo para un gateway.</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>Necesitas reconstruir la base de datos utilizando -reindex para volver al modo sin recorte. Esto volverá a descargar toda la cadena de bloques</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(por defecto: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>Aceptar solicitudes públicas en FERIADOS (por defecto: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>Activando la mejor cadena...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>No se puede ejecutar con un monedero en modo recorte.</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>No se puede resolver -whitebind address: '%s'</translation> </message> @@ -3133,12 +3245,12 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Soporte RPC para conexiones HTTP persistentes (por defecto: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Ignorar 1 de cada <n> mensajes de red al azar</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Reconstruir el índice de la cadena de bloques en el arranque desde los actuales ficheros blk000??.dat</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Introducir datos fuzz en 1 de cada <n> mensajes de red al azar</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Recibir y mostrar alertas de red P2P (default: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3177,6 +3289,10 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Arrancar minimizado</translation> </message> <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>Cantidad de la transacción demasiado pequeña para pagar la comisión</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Este software es experimental.</translation> </message> @@ -3197,6 +3313,10 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Transacción demasiado grande</translation> </message> <message> + <source>UI Options:</source> + <translation>Opciones de interfaz de usuario</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>No es posible conectar con %s en este sistema (bind ha dado el error %s)</translation> </message> @@ -3281,18 +3401,10 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Volcar la actividad de la base de datos de memoria al registro en disco cada <n> megabytes (predeterminado: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Nivel de rigor en la verificación de bloques de -checkblocks (0-4; predeterminado: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Registrar prioridad de las transacciones y cuota por kB cuando se minen bloques (por defecto: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Mantener el índice completo de transacciones, usado por la llamada rpc de getrawtransaction (por defecto: %u)</translation> </message> @@ -3321,18 +3433,10 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Siempre consultar direcciones de otros equipos por medio de DNS lookup (por defecto: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Inhabilitar el modo seguro, no considerar un suceso real de modo seguro (predeterminado: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Error al cargar wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Forzar modo seguro (por defecto: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Generar monedas (por defecto: %u)</translation> </message> @@ -3349,10 +3453,6 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Dirección -proxy inválida: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Limitar tamaño de la cache de firmas a <n> entradas (predeterminado: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Escuchar conexiones JSON-RPC en <puerto> (predeterminado: %u o testnet: %u)</translation> </message> @@ -3365,6 +3465,10 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Mantener como máximo <n> conexiones a pares (predeterminado: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Realiza las operaciones de difusión del monedero</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Búfer de recepción máximo por conexión, <n>*1000 bytes (por defecto: %u)</translation> </message> @@ -3373,10 +3477,6 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Búfer de recepción máximo por conexión, , <n>*1000 bytes (por defecto: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Aceptar solamente cadena de bloques que concuerde con los puntos de control internos (predeterminado: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Anteponer marca temporal a la información de depuración (por defecto: %u)</translation> </message> @@ -3389,10 +3489,6 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Relay non-P2SH multisig (default: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Ejecutar un hilo para limpiar de la memoria el monedero periódicamente (predeterminado: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Archivo de certificado del servidor (por defecto: %s)</translation> </message> @@ -3413,10 +3509,6 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Establecer el número de procesos para llamadas del servicio RPC (por defecto: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Establece la opción DB_PRIVATE en el entorno de base de datos del monedero (predeterminado: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Especificar archivo de configuración (por defecto: %s)</translation> </message> @@ -3433,10 +3525,6 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Gastar cambio no confirmado al enviar transacciones (predeterminado: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Detener después de importar los bloques del disco (por defecto: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Umbral para la desconexión de pares con mal comportamiento (predeterminado: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_es_CL.ts b/src/qt/locale/bitcoin_es_CL.ts index f50aa49110..c35acf2c67 100644 --- a/src/qt/locale/bitcoin_es_CL.ts +++ b/src/qt/locale/bitcoin_es_CL.ts @@ -1,4 +1,4 @@ -<TS language="es_CL" version="2.1"> +<TS language="es_CL" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -204,7 +204,7 @@ </message> <message> <source>Show information about Qt</source> - <translation>Mostrar Información sobre QT</translation> + <translation>Mostrar Información sobre Qt</translation> </message> <message> <source>&Options...</source> diff --git a/src/qt/locale/bitcoin_es_DO.ts b/src/qt/locale/bitcoin_es_DO.ts index d2cdf87a0e..6071702989 100644 --- a/src/qt/locale/bitcoin_es_DO.ts +++ b/src/qt/locale/bitcoin_es_DO.ts @@ -1,4 +1,4 @@ -<TS language="es_DO" version="2.1"> +<TS language="es_DO" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -2271,10 +2271,6 @@ <translation>Opciones del sservidor RPC:</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Descartar aleatoriamente 1 de cada <n> mensajes de red</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Enviar información de trazas/depuración a la consola en lugar de al archivo debug.log</translation> </message> diff --git a/src/qt/locale/bitcoin_es_MX.ts b/src/qt/locale/bitcoin_es_MX.ts index 4238330105..258308598e 100644 --- a/src/qt/locale/bitcoin_es_MX.ts +++ b/src/qt/locale/bitcoin_es_MX.ts @@ -1,4 +1,4 @@ -<TS language="es_MX" version="2.1"> +<TS language="es_MX" version="2.0"> <context> <name>AddressBookPage</name> <message> diff --git a/src/qt/locale/bitcoin_es_UY.ts b/src/qt/locale/bitcoin_es_UY.ts index 48a6f35f92..bb99466619 100644 --- a/src/qt/locale/bitcoin_es_UY.ts +++ b/src/qt/locale/bitcoin_es_UY.ts @@ -1,4 +1,4 @@ -<TS language="es_UY" version="2.1"> +<TS language="es_UY" version="2.0"> <context> <name>AddressBookPage</name> <message> diff --git a/src/qt/locale/bitcoin_et.ts b/src/qt/locale/bitcoin_et.ts index 29a45960c9..c746107bc7 100644 --- a/src/qt/locale/bitcoin_et.ts +++ b/src/qt/locale/bitcoin_et.ts @@ -1,4 +1,4 @@ -<TS language="et" version="2.1"> +<TS language="et" version="2.0"> <context> <name>AddressBookPage</name> <message> diff --git a/src/qt/locale/bitcoin_eu_ES.ts b/src/qt/locale/bitcoin_eu_ES.ts index d68411d382..3de9ad5a2f 100644 --- a/src/qt/locale/bitcoin_eu_ES.ts +++ b/src/qt/locale/bitcoin_eu_ES.ts @@ -1,4 +1,4 @@ -<TS language="eu_ES" version="2.1"> +<TS language="eu_ES" version="2.0"> <context> <name>AddressBookPage</name> <message> diff --git a/src/qt/locale/bitcoin_fa.ts b/src/qt/locale/bitcoin_fa.ts index 33f43f0c2d..5eeea04684 100644 --- a/src/qt/locale/bitcoin_fa.ts +++ b/src/qt/locale/bitcoin_fa.ts @@ -1,4 +1,4 @@ -<TS language="fa" version="2.1"> +<TS language="fa" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -66,6 +66,10 @@ <translation>اینها نشانیهای بیتکوین شما برای ارسال وجود هستند. همیشه قبل از ارسال سکهها، نشانی دریافتکننده و مقدار ارسالی را بررسی کنید.</translation> </message> <message> + <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> + <translation>اینها نشانیهای بیتکوین شما برای دریافت وجوه هستند. توصیه میشود یک نشانی دریافت جدید برای هر تبادل استفاده کنید.</translation> + </message> + <message> <source>Copy &Label</source> <translation>کپی و برچسب&گذاری</translation> </message> @@ -85,7 +89,11 @@ <source>Exporting Failed</source> <translation>استخراج انجام نشد</translation> </message> - </context> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>خطایی هنگام تلاش برای ذخیرهٔ لیست آدرس ها در %1 رخ داد.</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -156,6 +164,10 @@ <translation>آیا مطمئن هستید که میخواهید کیف پول خود را رمزنگاری کنید؟</translation> </message> <message> + <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>هسته بیتکوین هم اکنون بسته میشود تا فرایند رمزگذاری را تمام کند. به خاطر داشته باشید که رمزگذاری کردن کیف پولتان نمیتواند به طور کامل بیتکوینهای شما را در برابر دزدیده شدن توسط بدافزارهایی که رایانهی شما را آلوده میکنند، محافظت نماید.</translation> + </message> + <message> <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source> <translation>مهم: هر نسخهٔ پشتیبانی که تا کنون از کیف پول خود تهیه کردهاید، باید با کیف پول رمزنگاری شدهٔ جدید جایگزین شود. به دلایل امنیتی، پروندهٔ قدیمی کیف پول بدون رمزنگاری، تا زمانی که از کیف پول رمزنگاریشدهٔ جدید استفاده نکنید، غیرقابل استفاده خواهد بود.</translation> </message> @@ -168,6 +180,14 @@ <translation>کیف پول رمزنگاری شد</translation> </message> <message> + <source>Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>.</source> + <translation>رمز جدید کیف پول خود را وارد کنید.<br/>از رمز عبوری استفاده کنید که<b> حداقل 10 کاراکتر تصادفی </b> و یا <b> حداقل 8 حرف داشته باشد.</b></translation> + </message> + <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>رمز عبور قدیمی و رمز عبور جدید کیف پول خود را وارد گنید.</translation> + </message> + <message> <source>Wallet encryption failed</source> <translation>رمزنگاری کیف پول با شکست مواجه شد</translation> </message> @@ -211,6 +231,10 @@ <translation>&بررسی اجمالی</translation> </message> <message> + <source>Node</source> + <translation>گره</translation> + </message> + <message> <source>Show general overview of wallet</source> <translation>نمایش بررسی اجمالی کیف پول</translation> </message> @@ -255,6 +279,18 @@ <translation>&تغییر گذرواژه...</translation> </message> <message> + <source>&Sending addresses...</source> + <translation>&در حال ارسال آدرس ها...</translation> + </message> + <message> + <source>&Receiving addresses...</source> + <translation>&در حال دریافت آدرس ها...</translation> + </message> + <message> + <source>Open &URI...</source> + <translation>باز کردن &آدرس</translation> + </message> + <message> <source>Importing blocks from disk...</source> <translation>دریافت بلوکها از دیسک...</translation> </message> @@ -303,6 +339,10 @@ <translation>&دریافت</translation> </message> <message> + <source>Show information about Bitcoin Core</source> + <translation>نمایش اطلاعات در مورد بیتکوین</translation> + </message> + <message> <source>&Show / Hide</source> <translation>&نمایش/ عدم نمایش</translation> </message> @@ -346,6 +386,14 @@ <source>&About Bitcoin Core</source> <translation>درباره هسته ی بیت کوین</translation> </message> + <message> + <source>Show the list of used sending addresses and labels</source> + <translation>نمایش لیست آدرس های ارسال و لیبل ها</translation> + </message> + <message> + <source>Show the list of used receiving addresses and labels</source> + <translation>نمایش لیست آدرس های دریافت و لیبل ها</translation> + </message> <message numerus="yes"> <source>%n active connection(s) to Bitcoin network</source> <translation><numerusform>%n ارتباط فعال با شبکهٔ بیتکوین</numerusform></translation> @@ -457,18 +505,42 @@ <translation>پول خورد:</translation> </message> <message> + <source>Tree mode</source> + <translation>مدل درختی</translation> + </message> + <message> + <source>List mode</source> + <translation>مدل لیست</translation> + </message> + <message> <source>Amount</source> <translation>مبلغ</translation> </message> <message> + <source>Received with label</source> + <translation>دریافت شده با برچسب</translation> + </message> + <message> + <source>Received with address</source> + <translation>دریافت شده با نشانی</translation> + </message> + <message> <source>Date</source> <translation>تاریخ</translation> </message> <message> + <source>Confirmations</source> + <translation>تاییدیه ها</translation> + </message> + <message> <source>Confirmed</source> <translation>تأیید شده</translation> </message> <message> + <source>Priority</source> + <translation>اولویت</translation> + </message> + <message> <source>Copy address</source> <translation>کپی نشانی</translation> </message> @@ -485,6 +557,46 @@ <translation>کپی شناسهٔ تراکنش</translation> </message> <message> + <source>highest</source> + <translation>بیشترین</translation> + </message> + <message> + <source>higher</source> + <translation>بیشتر</translation> + </message> + <message> + <source>high</source> + <translation>زیاد</translation> + </message> + <message> + <source>medium-high</source> + <translation>متوسط متمایل به زیاد</translation> + </message> + <message> + <source>medium</source> + <translation>متوسط</translation> + </message> + <message> + <source>low-medium</source> + <translation>متوسط متمایل به کم</translation> + </message> + <message> + <source>low</source> + <translation>کم</translation> + </message> + <message> + <source>lower</source> + <translation>کمتر</translation> + </message> + <message> + <source>lowest</source> + <translation>کمترین</translation> + </message> + <message> + <source>none</source> + <translation>هیچکدام</translation> + </message> + <message> <source>yes</source> <translation>بله</translation> </message> @@ -496,7 +608,11 @@ <source>(no label)</source> <translation>(بدون برچسب)</translation> </message> - </context> + <message> + <source>(change)</source> + <translation>(تغییر)</translation> + </message> +</context> <context> <name>EditAddressDialog</name> <message> @@ -578,6 +694,10 @@ <translation>نسخه</translation> </message> <message> + <source>About Bitcoin Core</source> + <translation>درباره هسته ی بیت کوین</translation> + </message> + <message> <source>Command-line options</source> <translation>گزینههای خطفرمان</translation> </message> @@ -597,6 +717,14 @@ <translation>خوشآمدید</translation> </message> <message> + <source>Welcome to Bitcoin Core.</source> + <translation>به هسته بیت کوین خوش آمدید.</translation> + </message> + <message> + <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source> + <translation>از آنجایی که این اولین اجرای برنامه است، شما میتوانید مسیر ذخیرهٔ دادهها را انتخاب کنید.</translation> + </message> + <message> <source>Use the default data directory</source> <translation>استفاده از مسیر پیشفرض</translation> </message> @@ -707,6 +835,10 @@ <translation>پیشفرض</translation> </message> <message> + <source>none</source> + <translation>هیچکدام</translation> + </message> + <message> <source>Confirm options reset</source> <translation>تأییدِ بازنشانی گزینهها</translation> </message> @@ -750,6 +882,10 @@ <translation>تراز استخراج شده از معدن که هنوز بالغ نشده است</translation> </message> <message> + <source>Balances</source> + <translation>تراز ها</translation> + </message> + <message> <source>Total:</source> <translation>جمع کل:</translation> </message> @@ -757,6 +893,14 @@ <source>Your current total balance</source> <translation>تراز کل فعلی شما</translation> </message> + <message> + <source>Spendable:</source> + <translation>:قابل خرج کردن</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>تراکنش های اخیر</translation> + </message> </context> <context> <name>PaymentServer</name> @@ -765,9 +909,25 @@ <translation>مدیریت URI</translation> </message> <message> + <source>Payment request rejected</source> + <translation>درخواست پرداخت رد شد.</translation> + </message> + <message> + <source>Payment request error</source> + <translation>خطای درخواست پرداخت</translation> + </message> + <message> <source>Cannot start bitcoin: click-to-pay handler</source> <translation>نمیتوان بیتکوین را اجرا کرد: کنترلکنندهٔ کلیک-و-پرداخت</translation> </message> + <message> + <source>Payment request expired.</source> + <translation>درخواست پرداخت منقضی شد.</translation> + </message> + <message> + <source>Invalid payment request.</source> + <translation>درخواست پرداخت نامعتبر</translation> + </message> </context> <context> <name>PeerTableModel</name> @@ -779,6 +939,10 @@ <translation>مبلغ</translation> </message> <message> + <source>None</source> + <translation>هیچکدام</translation> + </message> + <message> <source>N/A</source> <translation>ناموجود</translation> </message> @@ -837,6 +1001,22 @@ <translation>تعداد فعلی بلوکها</translation> </message> <message> + <source>Received</source> + <translation>دریافتی</translation> + </message> + <message> + <source>Sent</source> + <translation>ارسال شده</translation> + </message> + <message> + <source>Version</source> + <translation>نسخه</translation> + </message> + <message> + <source>Services</source> + <translation>سرویس ها</translation> + </message> + <message> <source>Last block time</source> <translation>زمان آخرین بلوک</translation> </message> @@ -865,6 +1045,10 @@ <translation>پاکسازی کنسول</translation> </message> <message> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>به کنسول RPC هسته بیت کوین خوش آمدید.</translation> + </message> + <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>دکمههای بالا و پایین برای پیمایش تاریخچه و <b>Ctrl-L</b> برای پاک کردن صفحه.</translation> </message> @@ -884,6 +1068,14 @@ <translation>&برچسب:</translation> </message> <message> + <source>Show</source> + <translation>نمایش</translation> + </message> + <message> + <source>Remove</source> + <translation>حذف کردن</translation> + </message> + <message> <source>Copy label</source> <translation>کپی برچسب</translation> </message> @@ -981,6 +1173,10 @@ <translation>پول خورد:</translation> </message> <message> + <source>fast</source> + <translation>سریع</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>ارسال به چند دریافتکنندهٔ بهطور همزمان</translation> </message> @@ -1029,9 +1225,17 @@ <translation>با احتساب هزینهٔ %1 برای هر تراکنش، مجموع میزان پرداختی از مبلغ تراز شما بیشتر میشود.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>درخواست پرداخت منقضی شد.</translation> + </message> + <message> <source>(no label)</source> <translation>(بدون برچسب)</translation> </message> + <message> + <source>Are you sure you want to send?</source> + <translation>آیا مطمئن هستید که می خواهید ارسال کنید؟</translation> + </message> </context> <context> <name>SendCoinsEntry</name> @@ -1052,6 +1256,18 @@ <translation>&برچسب:</translation> </message> <message> + <source>Choose previously used address</source> + <translation>انتخاب نشانی پیشتر استفاده شده</translation> + </message> + <message> + <source>This is a normal payment.</source> + <translation>این یک پرداخت عادی است</translation> + </message> + <message> + <source>The Bitcoin address to send the payment to</source> + <translation>نشانی بیتکوین برای ارسال پرداخت به آن</translation> + </message> + <message> <source>Alt+A</source> <translation>Alt+A</translation> </message> @@ -1064,6 +1280,10 @@ <translation>Alt+P</translation> </message> <message> + <source>Remove this entry</source> + <translation>حذف این مدخل</translation> + </message> + <message> <source>Message:</source> <translation>پیام:</translation> </message> @@ -1082,6 +1302,14 @@ <translation>ا&مضای پیام</translation> </message> <message> + <source>The Bitcoin address to sign the message with</source> + <translation>نشانی بیتکوین برای امضاء پیغام با آن</translation> + </message> + <message> + <source>Choose previously used address</source> + <translation>انتخاب نشانی پیشتر استفاده شده</translation> + </message> + <message> <source>Alt+A</source> <translation>Alt+A</translation> </message> @@ -1126,6 +1354,10 @@ <translation>&شناسایی پیام</translation> </message> <message> + <source>The Bitcoin address the message was signed with</source> + <translation>نشانی بیتکوین که پیغام با آن امضاء شده</translation> + </message> + <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> <translation>برای حصول اطمینان از اینکه پیام با نشانی بیتکوین مشخص شده امضا است یا خیر، پیام را شناسایی کنید</translation> </message> @@ -1197,13 +1429,21 @@ <translation> هسته Bitcoin </translation> </message> <message> + <source>The Bitcoin Core developers</source> + <translation>توسعهدهندگان هسته بیتکوین</translation> + </message> + <message> <source>[testnet]</source> <translation>آزمایش شبکه</translation> </message> </context> <context> <name>TrafficGraphWidget</name> - </context> + <message> + <source>KB/s</source> + <translation>کیلوبایت</translation> + </message> +</context> <context> <name>TransactionDesc</name> <message> @@ -1504,6 +1744,10 @@ <translation>استخراج انجام نشد</translation> </message> <message> + <source>Exporting Successful</source> + <translation>استخراج موفق</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>پروندهٔ نوع CSV جداشونده با کاما (*.csv)</translation> </message> @@ -1659,10 +1903,22 @@ <translation>خطا در بازگشایی پایگاه داده ی بلوک</translation> </message> <message> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation>خطا: یک خطای داخلی مهلک روی داد، debug.log را برای جزئیات ببینید</translation> + </message> + <message> + <source>Error: Disk space is low!</source> + <translation>خطا: فضای دیسک کم است!</translation> + </message> + <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>شنیدن هر گونه درگاه انجام پذیر نیست. ازlisten=0 برای اینکار استفاده کیند.</translation> </message> <message> + <source>Importing...</source> + <translation>در حال پیادهسازی...</translation> + </message> + <message> <source>Verifying blocks...</source> <translation>در حال بازبینی بلوک ها...</translation> </message> @@ -1671,6 +1927,10 @@ <translation>در حال بازبینی کیف پول...</translation> </message> <message> + <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>هشدار: تاریخ و ساعت کامپیوتر خود را بررسی کنید. اگر ساعت درست نباشد هسته بیتکوین به درستی کار نخواهد کرد.</translation> + </message> + <message> <source>Choose data directory on startup (default: 0)</source> <translation>انتخاب مسیر دادهها در ابتدای اجرای برنامه (پیشفرض: 0)</translation> </message> @@ -1699,6 +1959,10 @@ <translation>اجرای برنامه به صورت کوچکشده</translation> </message> <message> + <source>UI Options:</source> + <translation>گزینههای رابط کاربری:</translation> + </message> + <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>از UPnP برای شناسایی درگاه شنیداری استفاده کنید (پیش فرض:1 در زمان شنیدن)</translation> </message> diff --git a/src/qt/locale/bitcoin_fa_IR.ts b/src/qt/locale/bitcoin_fa_IR.ts index da95f10474..1174e24b46 100644 --- a/src/qt/locale/bitcoin_fa_IR.ts +++ b/src/qt/locale/bitcoin_fa_IR.ts @@ -1,4 +1,4 @@ -<TS language="fa_IR" version="2.1"> +<TS language="fa_IR" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -14,30 +14,78 @@ <translation>کپی کردن حساب انتخاب شده به حافظه سیستم - کلیپ بورد</translation> </message> <message> + <source>&Copy</source> + <translation>کپی</translation> + </message> + <message> + <source>C&lose</source> + <translation>بستن</translation> + </message> + <message> <source>&Copy Address</source> - <translation>و کپی آدرس</translation> + <translation>کپی آدرس</translation> + </message> + <message> + <source>Delete the currently selected address from the list</source> + <translation>حذف آدرس های انتخاب شده از لیست</translation> </message> <message> <source>Export the data in the current tab to a file</source> <translation>صدور داده نوار جاری به یک فایل</translation> </message> <message> + <source>&Export</source> + <translation>صدور</translation> + </message> + <message> <source>&Delete</source> - <translation>و حذف</translation> + <translation>حذف</translation> + </message> + <message> + <source>Choose the address to send coins to</source> + <translation>انتخاب آدرس جهت ارسال کوین ها به آن آدرس</translation> + </message> + <message> + <source>Choose the address to receive coins with</source> + <translation>انتخاب آدرس جهت دریافت کوین ها از آن آدرس</translation> + </message> + <message> + <source>C&hoose</source> + <translation>انتخاب</translation> + </message> + <message> + <source>Sending addresses</source> + <translation>ارسال آدرس ها</translation> + </message> + <message> + <source>Receiving addresses</source> + <translation>دریافت آدرس ها</translation> </message> <message> <source>Copy &Label</source> - <translation>کپی و برچسب</translation> + <translation>کپی برچسب</translation> </message> <message> <source>&Edit</source> - <translation>و ویرایش</translation> + <translation>ویرایش</translation> + </message> + <message> + <source>Export Address List</source> + <translation>صدور لیست آدرس</translation> </message> <message> <source>Comma separated file (*.csv)</source> - <translation>Comma separated file (*.csv) فایل جداگانه دستوری</translation> + <translation>فایل سی اس وی (*.csv)</translation> </message> - </context> + <message> + <source>Exporting Failed</source> + <translation>صدور با شکست مواجه شد</translation> + </message> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>خطایی به هنگام ذخیره لیست آدرس در %1 رخ داده است. لطفا دوباره تلاش کنید.</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -56,6 +104,10 @@ <context> <name>AskPassphraseDialog</name> <message> + <source>Passphrase Dialog</source> + <translation>دیالوگ رمزعبور</translation> + </message> + <message> <source>Enter passphrase</source> <translation>رمز/پَس فرِیز را وارد کنید</translation> </message> @@ -96,10 +148,18 @@ <translation>رمزگذاری wallet را تایید کنید</translation> </message> <message> + <source>Warning: The Caps Lock key is on!</source> + <translation>اخطار: کلید Caps Lock فعال است!</translation> + </message> + <message> <source>Wallet encrypted</source> <translation>تایید رمزگذاری</translation> </message> <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>رمز قدیمی و جدید کیف پول را وارد کنید.</translation> + </message> + <message> <source>Wallet encryption failed</source> <translation>رمزگذاری تایید نشد</translation> </message> @@ -123,7 +183,11 @@ <source>Wallet decryption failed</source> <translation>کشف رمز wallet انجام نشد</translation> </message> - </context> + <message> + <source>Wallet passphrase was successfully changed.</source> + <translation>رمز عبور کیف پول با موفقیت تغییر کرد.</translation> + </message> +</context> <context> <name>BitcoinGUI</name> <message> @@ -160,11 +224,11 @@ </message> <message> <source>About &Qt</source> - <translation>درباره و QT</translation> + <translation>درباره و Qt</translation> </message> <message> <source>Show information about Qt</source> - <translation>نمایش اطلاعات درباره QT</translation> + <translation>نمایش اطلاعات درباره Qt</translation> </message> <message> <source>&Options...</source> @@ -580,10 +644,26 @@ <source>Message:</source> <translation>پیام:</translation> </message> - </context> + <message> + <source>Pay To:</source> + <translation>پرداخت به:</translation> + </message> + <message> + <source>Memo:</source> + <translation>یادداشت:</translation> + </message> +</context> <context> <name>ShutdownWindow</name> - </context> + <message> + <source>Bitcoin Core is shutting down...</source> + <translation>هسته بیت کوین در حال خاموش شدن است...</translation> + </message> + <message> + <source>Do not shut down the computer until this window disappears.</source> + <translation>تا پیش از بسته شدن این پنجره کامپیوتر خود را خاموش نکنید.</translation> + </message> +</context> <context> <name>SignVerifyMessageDialog</name> <message> @@ -813,6 +893,14 @@ <translation>برچسب را ویرایش کنید</translation> </message> <message> + <source>Exporting Failed</source> + <translation>صدور با شکست مواجه شد</translation> + </message> + <message> + <source>Exporting Successful</source> + <translation>صدور با موفقیت انجام شد</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Comma separated file (*.csv) فایل جداگانه دستوری</translation> </message> @@ -865,6 +953,10 @@ <context> <name>WalletView</name> <message> + <source>&Export</source> + <translation>صدور</translation> + </message> + <message> <source>Export the data in the current tab to a file</source> <translation>صدور داده نوار جاری به یک فایل</translation> </message> @@ -905,10 +997,22 @@ <translation>از تستِ شبکه استفاده نمایید</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>مبلغ تراکنش کمتر از آن است که پس از کسر هزینه تراکنش قابل ارسال باشد</translation> + </message> + <message> + <source>RPC server options:</source> + <translation>گزینه های سرویس دهنده RPC:</translation> + </message> + <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>ارسال اطلاعات پیگیری/خطایابی به کنسول به جای ارسال به فایل debug.log</translation> </message> <message> + <source>Send transactions as zero-fee transactions if possible (default: %u)</source> + <translation>ارسال تراکنش ها به صورت بدون کارمزد در صورت امکان (پیش فرض: %u)</translation> + </message> + <message> <source>Username for JSON-RPC connections</source> <translation>شناسه کاربری برای ارتباطاتِ JSON-RPC</translation> </message> @@ -949,6 +1053,22 @@ <translation>خطا در هنگام لود شدن wallet.dat</translation> </message> <message> + <source>Set minimum block size in bytes (default: %u)</source> + <translation>تنظیم کمینه اندازه بلاک بر حسب بایت (پیش فرض: %u)</translation> + </message> + <message> + <source>Set the number of threads to service RPC calls (default: %d)</source> + <translation>تنظیم تعداد ریسمان ها برای سرویس دهی فراخوانی های RPC (پیش فرض: %d)</translation> + </message> + <message> + <source>Specify configuration file (default: %s)</source> + <translation>فایل تنظیمات را مشخص کنید (پیش فرض: %s)</translation> + </message> + <message> + <source>Specify pid file (default: %s)</source> + <translation>فایل pid را مشخص کنید (پیش فرض: %s)</translation> + </message> + <message> <source>Invalid amount for -paytxfee=<amount>: '%s'</source> <translation>میزان اشتباه است for -paytxfee=<amount>: '%s'</translation> </message> diff --git a/src/qt/locale/bitcoin_fi.ts b/src/qt/locale/bitcoin_fi.ts index db59ea1751..eb90aa4281 100644 --- a/src/qt/locale/bitcoin_fi.ts +++ b/src/qt/locale/bitcoin_fi.ts @@ -1,9 +1,9 @@ -<TS language="fi" version="2.1"> +<TS language="fi" version="2.0"> <context> <name>AddressBookPage</name> <message> <source>Right-click to edit address or label</source> - <translation>Klikkaa hiiren oikealla painikkeella muokataksesi osoitetta tai nimikettä</translation> + <translation>Valitse hiiren oikealla painikkeella muokataksesi osoitetta tai nimikettä</translation> </message> <message> <source>Create a new address</source> @@ -27,7 +27,7 @@ </message> <message> <source>&Copy Address</source> - <translation>&Kopioi Osoite</translation> + <translation>&Kopioi osoite</translation> </message> <message> <source>Delete the currently selected address from the list</source> @@ -168,6 +168,10 @@ <translation>Haluatko varmasti salata lompakkosi?</translation> </message> <message> + <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>Bitcoin Core sammuu nyt viimeistelläkseen kryptaamisen. Muista että lompakon kryptaaminen ei voi täysin suojata bitcoinejasi varkaudelta malwaren saastuttamalla tietokoneella.</translation> + </message> + <message> <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source> <translation>TÄRKEÄÄ: Kaikki vanhat lompakon varmuuskopiot pitäisi korvata uusilla suojatuilla varmuuskopioilla. Turvallisuussyistä edelliset varmuuskopiot muuttuvat turhiksi, kun aloitat suojatun lompakon käytön.</translation> </message> @@ -184,6 +188,10 @@ <translation>Anna salauslause lompakkoon. <br/>Ole hyvä ja käytä lausetta jossa on <b>kymmenen tai enemmän satunnaista merkkiä</b> tai <b>kahdeksan tai useampi sanaa</b>.</translation> </message> <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Syötä vanha ja uusi salasana lompakolle.</translation> + </message> + <message> <source>Wallet encryption failed</source> <translation>Lompakon salaus epäonnistui</translation> </message> @@ -256,7 +264,7 @@ </message> <message> <source>Show information about Qt</source> - <translation>Näytä tietoja QT:ta</translation> + <translation>Näytä tietoja Qt:ta</translation> </message> <message> <source>&Options...</source> @@ -391,6 +399,10 @@ <translation>&Tietoja Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Muokkaa kokoonpanoasetuksia Bitcoin Corelle</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Näytä lähettämiseen käytettyjen osoitteiden ja nimien lista</translation> </message> @@ -419,6 +431,10 @@ <translation>Lohkojen lähdettä ei saatavilla...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Prosessoitu %n lohko rahansiirtohistoriasta.</numerusform><numerusform>Prosessoitu %n lohkoa rahansiirtohistoriasta.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n tunti</numerusform><numerusform>%n tuntia</numerusform></translation> </message> @@ -471,6 +487,36 @@ <translation>Saavutetaan verkkoa...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Päivämäärä: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Määrä: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Tyyppi: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Nimike: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Osoite: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Lähetetyt rahansiirrot</translation> </message> @@ -669,6 +715,18 @@ <translation>ei mitään</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Tämä nimi muuttuu punaiseksi mikäli rahansiirron koko on suurempi kuin 1000 tavua.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Tämä nimi muuttuu punaiseksi mikäli prioriteetti on pienempi kuin "medium".</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Tämä nimike muuttuu punaiseksi mikäli mikä tahansa saaja vastaanottaa pienemmän määrän kuin %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Saattaa vaihdella +/- %1 satoshia per syöte.</translation> </message> @@ -943,6 +1001,14 @@ <translation>&Verkko</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Käynnistä Bitcoin Core automaattisesti järjestelmään kirjautumisen jälkeen.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Käynnistä Bitcoin Core järjestelmään kirjautuessa</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = auto, <0 = jätä näin monta ydintä vapaaksi)</translation> </message> @@ -1055,6 +1121,10 @@ <translation>Ohjelman uudelleenkäynnistys aktivoi muutokset.</translation> </message> <message> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Asiakasohjelma sammutetaan. Haluatko jatkaa?</translation> + </message> + <message> <source>This change would require a client restart.</source> <translation>Tämä muutos vaatii ohjelman uudelleenkäynnistyksen.</translation> </message> @@ -1185,14 +1255,30 @@ <translation>Maksupyynnön tiedoston käsittely</translation> </message> <message> + <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source> + <translation>Maksupyynnön tiedostoa ei voida lukea! Tämä voi aiheutua sopimattomasta maksupyyntötiedostosta.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Maksupyyntö on vanhentunut.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Varmistamattomia maksupyyntöjä kustomoituun maksupalveluun ei tueta.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Epäkelpo maksupyyntö.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Maksupalautus %1:sta</translation> </message> <message> + <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source> + <translation>Maksupyyntö %1 on liian suuri (%2 tavua, sallittu %3 tavua).</translation> + </message> + <message> <source>Payment request DoS protection</source> <translation>Maksupyynnön DoS-suojaus</translation> </message> @@ -1201,6 +1287,10 @@ <translation>Virhe kommunikoidessa %1n kanssa: %2</translation> </message> <message> + <source>Payment request cannot be parsed!</source> + <translation>Maksupyyntöä ei voida jäsentää!</translation> + </message> + <message> <source>Bad response from server %1</source> <translation>Huono vastaus palvelimelta %1</translation> </message> @@ -1220,6 +1310,10 @@ <translation>Käyttöliittymä</translation> </message> <message> + <source>Node/Service</source> + <translation>Noodi/Palvelu</translation> + </message> + <message> <source>Ping Time</source> <translation>Vasteaika</translation> </message> @@ -1409,6 +1503,10 @@ <translation>Vasteaika</translation> </message> <message> + <source>Time Offset</source> + <translation>Ajan poikkeama</translation> + </message> + <message> <source>Last block time</source> <translation>Viimeisimmän lohkon aika</translation> </message> @@ -1453,6 +1551,10 @@ <translation>Tyhjennä konsoli</translation> </message> <message> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Tervetuloa Bitcoin Coren RPC-konsoliin.</translation> + </message> + <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Ylös- ja alas-nuolet selaavat historiaa ja <b>Ctrl-L</b> tyhjentää ruudun.</translation> </message> @@ -1745,6 +1847,10 @@ <translation>per kilotavu</translation> </message> <message> + <source>Hide</source> + <translation>Piilota</translation> + </message> + <message> <source>total at least</source> <translation>yhteensä ainakin</translation> </message> @@ -1877,10 +1983,22 @@ <translation>Rahansiirto hylättiin! Tämä saattaa tapahtua jos lompakossa olevat kolikot on jo kulutettu, kuten jos käytät kopioita wallet.dat tiedostosta ja kolikot oli jos käytetty mutta ei merkattu täällä.</translation> </message> <message> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>Rahansiirtokulua %1 ja sitä suurempia määriä pidetään järjenvastaisen korkeana kuluna.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Maksupyyntö on vanhentunut.</translation> + </message> + <message> <source>Pay only the minimum fee of %1</source> <translation>Maksa vain vähimmäiskulu %1</translation> </message> <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Vastaanottajan osoite ei ole kelvollinen. Tarkistathan uudelleen.</translation> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Varoitus: Virheellinen Bitcoin osoite</translation> </message> @@ -1952,10 +2070,22 @@ <translation>Poista tämä alkio</translation> </message> <message> + <source>S&ubtract fee from amount</source> + <translation>V&ähennä maksukulu määrästä</translation> + </message> + <message> <source>Message:</source> <translation>Viesti:</translation> </message> <message> + <source>This is an unauthenticated payment request.</source> + <translation>Tämä on todentamaton maksupyyntö.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Tämä on todennettu maksupyyntö.</translation> + </message> + <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>Aseta nimi tälle osoitteelle lisätäksesi sen käytettyjen osoitteiden listalle.</translation> </message> @@ -2393,6 +2523,10 @@ <translation>Rahansiirron laatu.</translation> </message> <message> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <translation>Onko rahansiirrossa mukana ainoastaan katseltava osoite vai ei.</translation> + </message> + <message> <source>Amount removed from or added to balance.</source> <translation>Saldoon lisätty tai siitä vähennetty määrä.</translation> </message> @@ -2635,18 +2769,10 @@ <translation>Kytkeydy annettuun osoitteeseen ja pidä linja aina auki. Käytä [host]:portin merkintätapaa IPv6:lle.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Aloita regression testimoodi joka käyttää erikoisketjua jossa lohkoja voidaan ratkaista välittömästi.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Suorita käsky kun lompakossa rahansiirto muuttuu (%s cmd on vaihdettu TxID kanssa)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>Tässä moodissa -genproclimit ohjaa kuinka monta lohkoa luodaan välittömästi.</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation>Aseta script varmistuksen threadien lukumäärä (%u - %d, 0= auto, <0 = jätä näin monta ydintä vapaaksi, oletus: %d)</translation> </message> @@ -2735,6 +2861,10 @@ <translation>Virhe avattaessa lohkoindeksiä</translation> </message> <message> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation>Virhe: Sisäinen kriittinen virhe kohdattiin, katso debug.log:sta lisätietoja</translation> + </message> + <message> <source>Error: Disk space is low!</source> <translation>Varoitus: Levytila on vähissä!</translation> </message> @@ -2763,6 +2893,14 @@ <translation>Ei tarpeeksi tiedostomerkintöjä vapaana.</translation> </message> <message> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <translation>Yhdistä vain solmukohtiin <net>-verkossa (ipv4, ipv6 tai onion)</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>Karsittu tila ei ole yhteensopiva -txindex:n kanssa.</translation> + </message> + <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation>Aseta tietokannan välimuistin koko megatavuissa (%d - %d, oletus: %d</translation> </message> @@ -2775,10 +2913,6 @@ <translation>Aseta lompakkotiedosto (data-hakemiston sisällä)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Tämä on tarkoitettu regression testityökaluille ja ohjelman kehittämiseen.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Käytä UPnP:ta kuuntelevan portin kartoittamiseen (oletus: %u)</translation> </message> @@ -2799,6 +2933,10 @@ <translation>Lompakon valinnat:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Varoitus: Tämä versio on vanhentunut; päivittämistä vaaditaan!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Sinun tulee uudelleenrakentaa tietokanta käyttäen -reindex vaihtaen -txindex</translation> </message> @@ -2823,6 +2961,26 @@ <translation>Aseta kolikoiden luomiseen tarkoitettujen säikeiden lukumäärä (-1 = kaikki ytimet, oletus: %d)</translation> </message> <message> + <source>(default: %u)</source> + <translation>(oletus: %u)</translation> + </message> + <message> + <source>Accept public REST requests (default: %u)</source> + <translation>Hyväksy julkisia REST-pyyntöjä (oletus: %u)</translation> + </message> + <message> + <source>Activating best chain...</source> + <translation>Aktivoidaan parhainta ketjua...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>Lompakkoa ei voida ajaa karsitussa tilassa.</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>-whitebind -osoitetta '%s' ei voida jäsentää</translation> + </message> + <message> <source>Choose data directory on startup (default: 0)</source> <translation>Valitse data-hakemisto käynnistyksessä (oletus: 0)</translation> </message> @@ -2839,6 +2997,10 @@ <translation>Virhe ladattaessa wallet.dat-tiedostoa: Tarvitset uudemman version Bitcoinista</translation> </message> <message> + <source>Error reading from database, shutting down.</source> + <translation>Virheitä tietokantaa luettaessa, ohjelma pysäytetään.</translation> + </message> + <message> <source>Information</source> <translation>Tietoa</translation> </message> @@ -2863,12 +3025,12 @@ <translation>RPC-palvelimen valinnat:</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Satunnaisesti pudota 1 joka <n> verkkoviestistä</translation> + <source>RPC support for HTTP persistent connections (default: %d)</source> + <translation>RPC-tuki pysyville HTTP-yhteyksille (oletus: %d)</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Satunnaisesti sekoita 1 joka <n> verkkoviestistä</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Vastaanota ja näytä P2P-verkon hälytyksiä (oletus: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -2919,6 +3081,10 @@ <translation>Siirtosumma liian iso</translation> </message> <message> + <source>UI Options:</source> + <translation>Ulkoasun asetukset:</translation> + </message> + <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Käytä UPnP:tä kuunneltavan portin avaamiseen (vakioasetus: 1 kun kuuntelemassa)</translation> </message> @@ -2983,6 +3149,10 @@ <translation>Virhe ladattaessa wallet.dat-tiedostoa: Lompakko vioittunut</translation> </message> <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation>Käytä erillistä SOCKS5-proxyä tavoittaaksesi vertaisia Tor-piilopalveluiden kautta (oletus: %s)</translation> + </message> + <message> <source>(default: %s)</source> <translation>(oletus: %s)</translation> </message> @@ -2995,10 +3165,6 @@ <translation>Virhe ladattaessa wallet.dat-tiedostoa</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Pakota yhteensopivuustila (oletus: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Luo kolikoita (oletus: %u)</translation> </message> @@ -3015,6 +3181,14 @@ <translation>Virheellinen proxy-osoite '%s'</translation> </message> <message> + <source>Listen for connections on <port> (default: %u or testnet: %u)</source> + <translation>Kuuntele yhteyksiä portissa <port> (oletus: %u tai testnet: %u)</translation> + </message> + <message> + <source>Make the wallet broadcast transactions</source> + <translation>Aseta lompakko kuuluttamaan rahansiirtoja</translation> + </message> + <message> <source>Relay non-P2SH multisig (default: %u)</source> <translation>Välitä ei-P2SH-multisig (oletus: %u)</translation> </message> @@ -3047,6 +3221,10 @@ <translation>Määritä pid-tiedosto (oletus: %s)</translation> </message> <message> + <source>Spend unconfirmed change when sending transactions (default: %u)</source> + <translation>Käytä vahvistamattomia vaihtorahoja lähetettäessä rahansiirtoja (oletus: %u)</translation> + </message> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Tuntematon verkko -onlynet parametrina: '%s'</translation> </message> diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts index 67d920fd5e..fe140634e6 100644 --- a/src/qt/locale/bitcoin_fr.ts +++ b/src/qt/locale/bitcoin_fr.ts @@ -1,4 +1,4 @@ -<TS language="fr" version="2.1"> +<TS language="fr" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -2809,10 +2809,6 @@ <translation>Se lier à l'adresse donnée et toujours l'écouter. Utilisez la notation [host]:port pour l'IPv6</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)</source> - <translation>Limiter continuellement les transactions gratuites à <n>*1000 octets par minute (par défaut : %u)</translation> - </message> - <message> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <translation>Supprimer toutes les transactions du portefeuille et ne récupérer que ces parties de la chaîne de bloc avec -rescan au démarrage</translation> </message> @@ -2821,18 +2817,10 @@ <translation>Distribué sous la licence MIT d'utilisation d'un logiciel. Consultez le fichier joint COPYING ou <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Passer en mode de test de régression qui utilise une chaîne spéciale dans laquelle les blocs sont résolus instantanément.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Exécuter la commande lorsqu'une transaction de portefeuille change (%s dans la commande est remplacée par TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>Dans ce mode -genproclimit contrôle combien de blocs sont générés immédiatement.</translation> - </message> - <message> <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> <translation>Total maximal des frais à utiliser en une seule transaction de portefeuille. Le définir trop bas pourrait interrompre les grosses transactions (par défaut : %s)</translation> </message> @@ -2853,6 +2841,14 @@ <translation>Impossible de se lier à %s sur cet ordinateur. Bitcoin Core fonctionne probablement déjà.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>AVERTISSEMENT : un nombre anormalement élevé de blocs a été généré, %d blocs reçus durant les %d dernières heures (%d attendus)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>AVERTISSEMENT : vérifiez votre connexion réseau, %d blocs reçus durant les %d dernières heures (%d attendus)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Avertissement : -paytxfee est réglé sur un montant très élevé ! Il s'agit des frais de transaction que vous payerez si vous envoyez une transaction.</translation> </message> @@ -2989,10 +2985,6 @@ <translation>Spécifiez le fichier de portefeuille (dans le répertoire de données)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Ceci est à l'intention des outils de test de régression et du développement applicatif.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Utiliser l'UPnP pour mapper le port d'écoute (par défaut : %u)</translation> </message> @@ -3069,10 +3061,6 @@ <translation>Les frais (en BTC/Ko) inférieurs à ce seuil sont considérés comme étant nuls pour le relayage (par défaut : %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Les frais (en BTC/Ko) inférieurs à ce seuil sont considérés comme étant nuls pour la création de transactions (par défaut : %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Si paytxfee n'est pas défini, inclure suffisamment de frais afin que les transactions commencent la confirmation en moyenne avant n blocs (par défaut : %u)</translation> </message> @@ -3165,10 +3153,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Activation de la meilleure chaîne...</translation> </message> <message> - <source>Allow self signed root certificates (default: 0)</source> - <translation>Permettre les certificats racine autosignés (par défaut : 0)</translation> - </message> - <message> <source>Can't run with a wallet in prune mode.</source> <translation>L'exécution est impossible quand le portefeuille est en mode élagage.</translation> </message> @@ -3261,18 +3245,14 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Prise en charge de RPC pour les connexions persistantes HTTP (par défaut : %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Abandonner aléatoirement 1 message du réseau sur <n></translation> - </message> - <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Tester aléatoirement 1 message du réseau sur <n></translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>Reconstruire au démarrage l'index de la chaîne de blocs à partir des fichiers blk000??.dat actuels</translation> </message> <message> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Recevoir et afficher les alertes du réseau poste à poste (%u par défaut)</translation> + </message> + <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Envoyer les informations de débogage/trace à la console au lieu du fichier debug.log</translation> </message> @@ -3417,18 +3397,10 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>(1 = conserver les métadonnées de transmission, par ex. les informations du propriétaire du compte et de la demande de paiement, 2 = abandonner les métadonnées de transmission)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Purger l’activité de la base de données de la zone de mémoire vers le journal sur disque tous les <n> mégaoctets (par défaut : %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Degré de profondeur de la vérification des blocs -checkblocks (0-4, par défaut : %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Lors du minage, journaliser la priorité des transactions et les frais par ko (par défaut : %u) </translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Maintenir un index complet des transactions, utilisé par l'appel RPC getrawtransaction (obtenir la transaction brute) (par défaut : %u)</translation> </message> @@ -3457,18 +3429,10 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Toujours demander les adresses des pairs par recherche DNS (par défaut : %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Désactiver le mode sans échec, passer outre un événement sans échec réel (par défaut : %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Erreur lors du chargement de wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Forcer le mode sans échec (par défaut : %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Générer des pièces (défaut : %u)</translation> </message> @@ -3485,10 +3449,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Adresse -proxy invalide : « %s »</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Limiter la taille du cache des signatures à <n> entrées (par défaut : %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Écouter les connexions JSON-RPC sur <port> (par défaut : %u ou tesnet : %u)</translation> </message> @@ -3513,10 +3473,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Tampon maximal d'envoi par connexion », <n>*1000 octets (par défaut : %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>N'accepter qu'une chaîne de blocs correspondant aux points de vérification intégrés (par défaut : %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Ajouter l'horodatage au début de la sortie de débogage (par défaut : %u)</translation> </message> @@ -3529,10 +3485,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Relayer les multisignatures non-P2SH (par défaut : %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Exécuter une tâche pour purger le portefeuille périodiquement (par défaut : %u) </translation> - </message> - <message> <source>Set key pool size to <n> (default: %u)</source> <translation>Définir la taille de la réserve de clefs à <n> (par défaut : %u)</translation> </message> @@ -3541,10 +3493,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Définir la taille de bloc minimale en octets (par défaut : %u)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Définit le drapeau DB_PRIVATE dans l'environnement de la BD du portefeuille (par défaut : %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Spécifier le fichier de configuration (par défaut : %s)</translation> </message> @@ -3561,10 +3509,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Dépenser la monnaie non confirmée lors de l'envoi de transactions (par défaut : %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Cesser l'exécution après l'importation des blocs du disque (par défaut : %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Seuil de déconnexion des pairs présentant un mauvais comportement (par défaut : %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_fr_CA.ts b/src/qt/locale/bitcoin_fr_CA.ts index 186985d493..f4fe7d6597 100644 --- a/src/qt/locale/bitcoin_fr_CA.ts +++ b/src/qt/locale/bitcoin_fr_CA.ts @@ -1,4 +1,4 @@ -<TS language="fr_CA" version="2.1"> +<TS language="fr_CA" version="2.0"> <context> <name>AddressBookPage</name> <message> diff --git a/src/qt/locale/bitcoin_gl.ts b/src/qt/locale/bitcoin_gl.ts index 2473260c84..709b17e2f7 100644 --- a/src/qt/locale/bitcoin_gl.ts +++ b/src/qt/locale/bitcoin_gl.ts @@ -1,4 +1,4 @@ -<TS language="gl" version="2.1"> +<TS language="gl" version="2.0"> <context> <name>AddressBookPage</name> <message> diff --git a/src/qt/locale/bitcoin_gu_IN.ts b/src/qt/locale/bitcoin_gu_IN.ts index b7b091aa39..ef99b0dd39 100644 --- a/src/qt/locale/bitcoin_gu_IN.ts +++ b/src/qt/locale/bitcoin_gu_IN.ts @@ -1,4 +1,4 @@ -<TS language="gu_IN" version="2.1"> +<TS language="gu_IN" version="2.0"> <context> <name>AddressBookPage</name> </context> diff --git a/src/qt/locale/bitcoin_he.ts b/src/qt/locale/bitcoin_he.ts index 66dd05fca7..9c1863de8a 100644 --- a/src/qt/locale/bitcoin_he.ts +++ b/src/qt/locale/bitcoin_he.ts @@ -1,4 +1,4 @@ -<TS language="he" version="2.1"> +<TS language="he" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -2511,10 +2511,6 @@ <translation>מחיקת כל העברות הארנק ולשחזר רק את החלקים המסוימים בשרשרת המקטעים באמצעות -rescan עם ההפעלה</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>כניסה למצב בדיקת נסיגה, שמשתמש בשרשרת מיוחדת בה ניתן לפתור את המקטעים במהירות.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>ביצוע פקודה כאשר העברה בארנק משתנה (%s ב־cmd יוחלף ב־TxID)</translation> </message> @@ -2647,10 +2643,6 @@ <translation>ציון קובץ ארנק (בתוך תיקיית הנתונים)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>תכונה זו מיועדת לכלי בדיקות נסיגה ופיתוח יישומים.</translation> - </message> - <message> <source>Verifying blocks...</source> <translation>המקטעים מאומתים…</translation> </message> @@ -2679,10 +2671,6 @@ <translation>הרץ פקודה כאשר ההתראה הרלוונטית מתקבלת או כשאנחנו עדים לפיצול ארוך מאוד (%s בשורת הפקודה יוחלף ע"י ההודעה)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>העמלות (ב־BTC/ק״ב) הנמוכות מהסכום הזה נחשבות לעמלות אפס ליצירת העברה (בררת מחדל: %s)</translation> - </message> - <message> <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> <translation>אזהרה: נא לבדוק שהתאריך והשעה של המחשב שלך נכונים! אם השעון שלך שגוי ליבת ביטקוין לא תעבוד כראוי.</translation> </message> @@ -2759,10 +2747,6 @@ <translation>הגדרות שרת RPC</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>להשמיט אקראית אחת מתוך כל <n> הודעות רשת</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>שלח מידע דיבאג ועקבה לקונסולה במקום לקובץ debug.log</translation> </message> diff --git a/src/qt/locale/bitcoin_hi_IN.ts b/src/qt/locale/bitcoin_hi_IN.ts index 5fe8635dc0..01e074ffc6 100644 --- a/src/qt/locale/bitcoin_hi_IN.ts +++ b/src/qt/locale/bitcoin_hi_IN.ts @@ -1,4 +1,4 @@ -<TS language="hi_IN" version="2.1"> +<TS language="hi_IN" version="2.0"> <context> <name>AddressBookPage</name> <message> diff --git a/src/qt/locale/bitcoin_hr.ts b/src/qt/locale/bitcoin_hr.ts index 62bfe6a11f..74d380ec2b 100644 --- a/src/qt/locale/bitcoin_hr.ts +++ b/src/qt/locale/bitcoin_hr.ts @@ -1,7 +1,11 @@ -<TS language="hr" version="2.1"> +<TS language="hr" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>Desni klik za uređivanje adresa i oznaka</translation> + </message> + <message> <source>Create a new address</source> <translation>Dodajte novu adresu</translation> </message> @@ -23,7 +27,7 @@ </message> <message> <source>&Copy Address</source> - <translation>&Kopirati adresu</translation> + <translation>&Kopiraj adresu</translation> </message> <message> <source>Delete the currently selected address from the list</source> @@ -31,15 +35,15 @@ </message> <message> <source>Export the data in the current tab to a file</source> - <translation>Izvoz podataka iz trenutnog taba u datoteku</translation> + <translation>Izvoz podataka iz trenutnog lista u datoteku</translation> </message> <message> <source>&Export</source> - <translation>&Izvoz</translation> + <translation>&Izvozi</translation> </message> <message> <source>&Delete</source> - <translation>&Brisanje</translation> + <translation>Iz&briši</translation> </message> <message> <source>Choose the address to send coins to</source> @@ -63,19 +67,19 @@ </message> <message> <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> - <translation>Ovo su vaše Bitcoin adrese za slanje uplate. Uvijek provjerite iznos i adresu primatelja prije slanja novca.</translation> + <translation>Ovo su vaše Bitcoin adrese za slanje novca. Uvijek provjerite iznos i adresu primatelja prije slanja novca.</translation> </message> <message> <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> - <translation>Ovo su vaše Bitcoin adrese za primanje isplate. Preporučamo da koristite novu primateljsku adresu za svaku transakciju.</translation> + <translation>Ovo su vaše Bitcoin adrese za primanje novca. Preporučamo da koristite novu adresu za primanje za svaku transakciju.</translation> </message> <message> <source>Copy &Label</source> - <translation>Kopirati &oznaku</translation> + <translation>Kopiraj &oznaku</translation> </message> <message> <source>&Edit</source> - <translation>&Izmjeniti</translation> + <translation>&Uredi</translation> </message> <message> <source>Export Address List</source> @@ -157,7 +161,7 @@ </message> <message> <source>Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>!</source> - <translation>Upozorenje: Ako šifrirate vaš novčanik i izgubite lozinku, <b>IZGUBIT ĆETE SVE SVOJE BITCOINSE!</b></translation> + <translation>Upozorenje: Ako šifrirate vaš novčanik i izgubite lozinku, <b>IZGUBIT ĆETE SVE SVOJE BITCOINE!</b></translation> </message> <message> <source>Are you sure you wish to encrypt your wallet?</source> @@ -180,6 +184,10 @@ <translation>Unesite novu lozinku za novčanik. <br/>Molimo Vas da koristite zaporku od <b>deset ili više slučajnih znakova</b>, ili <b>osam ili više riječi.</b></translation> </message> <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Unesite staru i novu lozinku za novčanik.</translation> + </message> + <message> <source>Wallet encryption failed</source> <translation>Šifriranje novčanika nije uspjelo</translation> </message> @@ -256,7 +264,7 @@ </message> <message> <source>&Options...</source> - <translation>Pos&tavke</translation> + <translation>Pos&tavke...</translation> </message> <message> <source>&Encrypt Wallet...</source> @@ -264,19 +272,19 @@ </message> <message> <source>&Backup Wallet...</source> - <translation>Si&gurnosno kopiraj novčanik...</translation> + <translation>Spremi &kopiju novčanika...</translation> </message> <message> <source>&Change Passphrase...</source> - <translation>&Promjena lozinke...</translation> + <translation>Promjena &lozinke...</translation> </message> <message> <source>&Sending addresses...</source> - <translation>Adrese za s&lanje</translation> + <translation>Adrese za &slanje</translation> </message> <message> <source>&Receiving addresses...</source> - <translation>Adrese za p&rimanje</translation> + <translation>Adrese za &primanje</translation> </message> <message> <source>Open &URI...</source> @@ -308,11 +316,11 @@ </message> <message> <source>&Debug window</source> - <translation>&Ispravljanje programerskih pogrešaka</translation> + <translation>Konzola za dijagnostiku</translation> </message> <message> <source>Open debugging and diagnostic console</source> - <translation>Otvori konzolu za dijagnostiku i otklanjanje programskih pogrešaka.</translation> + <translation>Otvori konzolu za dijagnostiku</translation> </message> <message> <source>&Verify message...</source> @@ -332,11 +340,11 @@ </message> <message> <source>&Receive</source> - <translation>Pri&miti</translation> + <translation>Pri&mi</translation> </message> <message> <source>Show information about Bitcoin Core</source> - <translation>Prikaži informacije o Bitcoin Coreu</translation> + <translation>Prikaži informacije o programu Bitcoin Core</translation> </message> <message> <source>&Show / Hide</source> @@ -348,15 +356,15 @@ </message> <message> <source>Encrypt the private keys that belong to your wallet</source> - <translation>Šifriraj privatne ključeve koji pripadaju tvom novčaniku</translation> + <translation>Šifriranje privatnih ključeva koji u novčaniku</translation> </message> <message> <source>Sign messages with your Bitcoin addresses to prove you own them</source> - <translation>Potpiši poruke svojim Bitcoin adresama kako bi dokazao da si njihov vlasnik</translation> + <translation>Poruku potpišemo s bitcoin adresom, kako bi dokazali vlasništvo nad tom adresom</translation> </message> <message> <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source> - <translation>Provjerite porkue kako bi se uvjerili da su potpisane navedenim Bitcoin adresama</translation> + <translation>Provjeravanje poruke, kao dokaz, da je potpisana navedenom bitcoin adresom</translation> </message> <message> <source>&File</source> @@ -376,23 +384,75 @@ </message> <message> <source>Bitcoin Core</source> - <translation>Bitcoin Jezgra</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>Request payments (generates QR codes and bitcoin: URIs)</source> - <translation>Zatraži uplate (Stvara QR kodove i bitcoin: URIje)</translation> + <translation>Zatraži uplatu (stvara QR kod i bitcoin: URI adresu)</translation> </message> <message> <source>&About Bitcoin Core</source> - <translation>&O Bitcoin Jezgri</translation> + <translation>&O programu Bitcoin Core</translation> + </message> + <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Promijeni postavke programa</translation> </message> <message> <source>Show the list of used sending addresses and labels</source> - <translation>Prikaži popis korištenih adresa i oznaka za slanje isplate</translation> + <translation>Prikaži popis korištenih adresa i oznaka za slanje novca</translation> </message> <message> <source>Show the list of used receiving addresses and labels</source> - <translation>Prikaži popis korištenih adresa i oznaka za primanje isplate</translation> + <translation>Prikaži popis korištenih adresa i oznaka za primanje novca</translation> + </message> + <message> + <source>Open a bitcoin: URI or payment request</source> + <translation>Otvori bitcoin: URI adresu ili zahtjev za uplatu</translation> + </message> + <message> + <source>&Command-line options</source> + <translation>Opcije &naredbene linije</translation> + </message> + <message> + <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> + <translation>Ispis svih opcija naredbene linije programa sa kratkim opisom</translation> + </message> + <message numerus="yes"> + <source>%n active connection(s) to Bitcoin network</source> + <translation><numerusform>%n aktivna veza na Bitcoin mrežu</numerusform><numerusform>%n aktivnih veza na Bitcoin mrežu</numerusform><numerusform>%n aktivnih veza na Bitcoin mrežu</numerusform></translation> + </message> + <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Obrađen %n blok povijesti transakcije.</numerusform><numerusform>Obrađeno %n bloka povijesti transakcije.</numerusform><numerusform>Obrađeno %n blokova povijesti transakcije.</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n hour(s)</source> + <translation><numerusform>%n sat</numerusform><numerusform>%n sata</numerusform><numerusform>%n sati</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n day(s)</source> + <translation><numerusform>%n dan</numerusform><numerusform>%n dana</numerusform><numerusform>%n dana</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n week(s)</source> + <translation><numerusform>%n tjedan</numerusform><numerusform>%n tjedna</numerusform><numerusform>%n tjedana</numerusform></translation> + </message> + <message> + <source>%1 and %2</source> + <translation>%1 i %2</translation> + </message> + <message numerus="yes"> + <source>%n year(s)</source> + <translation><numerusform>%n godina</numerusform><numerusform>%n godine</numerusform><numerusform>%n godina</numerusform></translation> + </message> + <message> + <source>Last received block was generated %1 ago.</source> + <translation>Zadnji primljeni blok je bio ustvaren prije %1.</translation> + </message> + <message> + <source>Transactions after this will not yet be visible.</source> + <translation>Transakcije izvršene za tim blokom nisu još prikazane.</translation> </message> <message> <source>Error</source> @@ -415,6 +475,36 @@ <translation>Ažuriranje...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Datum: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Iznos: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Vrsta: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Oznaka: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Adresa: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Poslana transakcija</translation> </message> @@ -437,34 +527,146 @@ <context> <name>CoinControlDialog</name> <message> + <source>Coin Selection</source> + <translation>Izbor ulaza transakcije</translation> + </message> + <message> + <source>Quantity:</source> + <translation>Količina:</translation> + </message> + <message> + <source>Bytes:</source> + <translation>Bajtova:</translation> + </message> + <message> <source>Amount:</source> <translation>Iznos:</translation> </message> <message> + <source>Priority:</source> + <translation>Prioriteta:</translation> + </message> + <message> + <source>Fee:</source> + <translation>Naknada:</translation> + </message> + <message> + <source>Dust:</source> + <translation>Prah:</translation> + </message> + <message> + <source>Change:</source> + <translation>Vraćeno:</translation> + </message> + <message> + <source>(un)select all</source> + <translation>Izaberi sve/ništa</translation> + </message> + <message> <source>Amount</source> <translation>Iznos</translation> </message> <message> + <source>Received with label</source> + <translation>Primljeno pod oznakom</translation> + </message> + <message> + <source>Received with address</source> + <translation>Primljeno na adresu</translation> + </message> + <message> <source>Date</source> <translation>Datum</translation> </message> <message> + <source>Confirmations</source> + <translation>Broj potvrda</translation> + </message> + <message> <source>Confirmed</source> <translation>Potvrđeno</translation> </message> <message> + <source>Priority</source> + <translation>Prioriteta</translation> + </message> + <message> <source>Copy address</source> - <translation>Kopirati adresu</translation> + <translation>Kopiraj adresu</translation> </message> <message> <source>Copy label</source> - <translation>Kopirati oznaku</translation> + <translation>Kopiraj oznaku</translation> </message> <message> <source>Copy amount</source> <translation>Kopiraj iznos</translation> </message> <message> + <source>Copy transaction ID</source> + <translation>Kopiraj ID transakcije</translation> + </message> + <message> + <source>highest</source> + <translation>najviša</translation> + </message> + <message> + <source>higher</source> + <translation>viša</translation> + </message> + <message> + <source>high</source> + <translation>visoka</translation> + </message> + <message> + <source>medium-high</source> + <translation>srednje visoka</translation> + </message> + <message> + <source>medium</source> + <translation>srednja</translation> + </message> + <message> + <source>low-medium</source> + <translation>srednje niska</translation> + </message> + <message> + <source>low</source> + <translation>niska</translation> + </message> + <message> + <source>lower</source> + <translation>niža</translation> + </message> + <message> + <source>lowest</source> + <translation>najniža</translation> + </message> + <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Oznaka postane crvene boje ako je transakcija veća od 1000 bajtova.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Oznaka postane crvene boje ako je prioriteta transakcije niža od "srednja"</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Oznaka postane crvene boje ako je iznos manji od %1</translation> + </message> + <message> + <source>yes</source> + <translation>da</translation> + </message> + <message> + <source>no</source> + <translation>ne</translation> + </message> + <message> + <source>Transactions with higher priority are more likely to get included into a block.</source> + <translation>Transakcije više prioritete imaju veću vjerojatnost da budu prije dodane u novi blok.</translation> + </message> + <message> <source>(no label)</source> <translation>(bez oznake)</translation> </message> @@ -473,13 +675,21 @@ <name>EditAddressDialog</name> <message> <source>Edit Address</source> - <translation>Izmjeni adresu</translation> + <translation>Uredi adresu</translation> </message> <message> <source>&Label</source> <translation>&Oznaka</translation> </message> <message> + <source>The label associated with this address list entry</source> + <translation>Oznaka bitcoin adrese</translation> + </message> + <message> + <source>The address associated with this address list entry. This can only be modified for sending addresses.</source> + <translation>Bitcoin adresa. Izmjene adrese su moguće samo za adrese za slanje.</translation> + </message> + <message> <source>&Address</source> <translation>&Adresa</translation> </message> @@ -519,29 +729,49 @@ <context> <name>FreespaceChecker</name> <message> + <source>A new data directory will be created.</source> + <translation>Stvoren će biti novi direktorij za podatke.</translation> + </message> + <message> <source>name</source> <translation>ime</translation> </message> - </context> + <message> + <source>Cannot create data directory here.</source> + <translation>Nije moguće stvoriti direktorij za podatke na tom mjestu.</translation> + </message> +</context> <context> <name>HelpMessageDialog</name> <message> <source>Bitcoin Core</source> - <translation>Bitcoin Jezgra</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>version</source> <translation>verzija</translation> </message> <message> + <source>(%1-bit)</source> + <translation>(%1-bit)</translation> + </message> + <message> <source>About Bitcoin Core</source> - <translation>O Bitcoinovoj jezgri</translation> + <translation>O programu Bitcoin Core</translation> + </message> + <message> + <source>Command-line options</source> + <translation>Opcije programa u naredbenoj liniji</translation> </message> <message> <source>Usage:</source> <translation>Upotreba:</translation> </message> - </context> + <message> + <source>command-line options</source> + <translation>opcije programa u naredbenoj liniji</translation> + </message> +</context> <context> <name>Intro</name> <message> @@ -549,8 +779,12 @@ <translation>Dobrodošli</translation> </message> <message> + <source>Welcome to Bitcoin Core.</source> + <translation>Dobrodošli u programu Bitcoin Core.</translation> + </message> + <message> <source>Bitcoin Core</source> - <translation>Bitcoin Jezgra</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>Error</source> @@ -559,7 +793,27 @@ </context> <context> <name>OpenURIDialog</name> - </context> + <message> + <source>Open URI</source> + <translation>Otvori URI adresu</translation> + </message> + <message> + <source>Open payment request from URI or file</source> + <translation>Otvori zahtjev za plaćanje iz URI adrese ili datoteke</translation> + </message> + <message> + <source>URI:</source> + <translation>URI:</translation> + </message> + <message> + <source>Select payment request file</source> + <translation>Izaberi datoteku zahtjeva za plaćanje</translation> + </message> + <message> + <source>Select payment request file to open</source> + <translation>Izaberi datoteku zahtjeva za plaćanje</translation> + </message> +</context> <context> <name>OptionsDialog</name> <message> @@ -571,10 +825,58 @@ <translation>&Glavno</translation> </message> <message> + <source>Size of &database cache</source> + <translation>Veličina predmemorije baze podataka</translation> + </message> + <message> + <source>MB</source> + <translation>MB</translation> + </message> + <message> + <source>Number of script &verification threads</source> + <translation>Broj CPU niti za verifikaciju transakcija</translation> + </message> + <message> + <source>Allow incoming connections</source> + <translation>Dozvoli povezivanje izvana</translation> + </message> + <message> + <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> + <translation>IP adresa proxy servera (npr. IPv4: 127.0.0.1 / IPv6: ::1)</translation> + </message> + <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>Minimizirati aplikaciju umjesto zatvoriti, kada se zatvori prozor. Kada je ova opcija omogućena, aplikacija će biti zatvorena tek nakon odabira naredbe Izlaz u izborniku.</translation> + </message> + <message> + <source>Reset all client options to default.</source> + <translation>Nastavi sve postavke programa na početne vrijednosti.</translation> + </message> + <message> + <source>&Reset Options</source> + <translation>Po&nastavi postavke</translation> + </message> + <message> <source>&Network</source> <translation>&Mreža</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Program se automatski pokrene po prijavi u sustav.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Pokreni program kod prijave u sustav</translation> + </message> + <message> + <source>W&allet</source> + <translation>&Novčanik</translation> + </message> + <message> + <source>&Spend unconfirmed change</source> + <translation>&Trošenje nepotvrđenih vraćenih iznosa</translation> + </message> + <message> <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> <translation>Automatski otvori port Bitcoin klijenta na ruteru. To radi samo ako ruter podržava UPnP i ako je omogućen.</translation> </message> @@ -587,8 +889,12 @@ <translation>Proxy &IP:</translation> </message> <message> + <source>&Port:</source> + <translation>&Vrata:</translation> + </message> + <message> <source>Port of the proxy (e.g. 9050)</source> - <translation>Port od proxy-a (npr. 9050)</translation> + <translation>Proxy vrata (npr. 9050)</translation> </message> <message> <source>&Window</source> @@ -611,8 +917,12 @@ <translation>&Prikaz</translation> </message> <message> + <source>User Interface &language:</source> + <translation>Jezi&k sučelja:</translation> + </message> + <message> <source>&Unit to show amounts in:</source> - <translation>&Jedinica za prikazivanje iznosa:</translation> + <translation>&Jedinica za prikaz iznosa:</translation> </message> <message> <source>Choose the default subdivision unit to show in the interface and when sending coins.</source> @@ -674,6 +984,10 @@ <context> <name>QRImageWidget</name> <message> + <source>&Save Image...</source> + <translation>&Spremi sliku...</translation> + </message> + <message> <source>Save QR Code</source> <translation>Spremi QR kod</translation> </message> @@ -694,11 +1008,11 @@ </message> <message> <source>&Information</source> - <translation>&Informacija</translation> + <translation>&Informacije</translation> </message> <message> <source>Using OpenSSL version</source> - <translation>Koristim OpenSSL verziju</translation> + <translation>OpenSSL verzija u upotrebi</translation> </message> <message> <source>Network</source> @@ -710,7 +1024,7 @@ </message> <message> <source>Number of connections</source> - <translation>Broj konekcija</translation> + <translation>Broj veza</translation> </message> <message> <source>Block chain</source> @@ -721,6 +1035,34 @@ <translation>Trenutni broj blokova</translation> </message> <message> + <source>Received</source> + <translation>Primljeno</translation> + </message> + <message> + <source>Sent</source> + <translation>Poslano</translation> + </message> + <message> + <source>Direction</source> + <translation>Smjer</translation> + </message> + <message> + <source>Version</source> + <translation>Verzija</translation> + </message> + <message> + <source>Connection Time</source> + <translation>Trajanje veze</translation> + </message> + <message> + <source>Bytes Sent</source> + <translation>Bajtova poslano</translation> + </message> + <message> + <source>Bytes Received</source> + <translation>Bajtova primljeno</translation> + </message> + <message> <source>Last block time</source> <translation>Posljednje vrijeme bloka</translation> </message> @@ -733,6 +1075,10 @@ <translation>&Konzola</translation> </message> <message> + <source>&Network Traffic</source> + <translation>&Mrežni promet</translation> + </message> + <message> <source>Totals</source> <translation>Ukupno:</translation> </message> @@ -741,23 +1087,47 @@ <translation>Očisti konzolu</translation> </message> <message> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Dobrodošli u Bitcoin RPC konzolu.</translation> + </message> + <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> - <translation>Kako bi navigirali kroz povijest koristite strelice gore i dolje. <b>Ctrl-L</b> kako bi očistili ekran.</translation> + <translation>Koristite tipke gore i dolje za izbor već korištenih naredbi. <b>Ctrl-L</b> kako bi očistili ekran i povijest naredbi.</translation> + </message> + <message> + <source>Unknown</source> + <translation>Nepoznato</translation> </message> </context> <context> <name>ReceiveCoinsDialog</name> <message> + <source>&Amount:</source> + <translation>&Iznos:</translation> + </message> + <message> <source>&Label:</source> <translation>&Oznaka:</translation> </message> <message> + <source>&Message:</source> + <translation>&Poruka:</translation> + </message> + <message> + <source>Clear all fields of the form.</source> + <translation>Obriši sva polja</translation> + </message> + <message> + <source>&Request payment</source> + <translation>&Zatraži plaćanje</translation> + </message> + <message> <source>Show</source> <translation>Pokaži</translation> </message> <message> <source>Copy label</source> - <translation>Kopirati oznaku</translation> + <translation>Kopiraj oznaku</translation> </message> <message> <source>Copy amount</source> @@ -771,6 +1141,22 @@ <translation>QR kôd</translation> </message> <message> + <source>Copy &URI</source> + <translation>Kopiraj &URI</translation> + </message> + <message> + <source>Copy &Address</source> + <translation>Kopiraj &adresu</translation> + </message> + <message> + <source>&Save Image...</source> + <translation>&Spremi sliku...</translation> + </message> + <message> + <source>URI</source> + <translation>URI</translation> + </message> + <message> <source>Address</source> <translation>Adresa</translation> </message> @@ -788,9 +1174,13 @@ </message> <message> <source>Resulting URI too long, try to reduce the text for label / message.</source> - <translation>Rezultirajući URI je predug, probajte umanjiti tekst za naslov / poruku.</translation> + <translation>URI je predug, probajte skratiti tekst za naslov / poruku.</translation> </message> - </context> + <message> + <source>Error encoding URI into QR Code.</source> + <translation>Greška kod kodiranja URI adrese u QR kod.</translation> + </message> +</context> <context> <name>RecentRequestsTableModel</name> <message> @@ -813,7 +1203,15 @@ <source>(no label)</source> <translation>(bez oznake)</translation> </message> - </context> + <message> + <source>(no message)</source> + <translation>(bez poruke)</translation> + </message> + <message> + <source>(no amount)</source> + <translation>(bez iznosa)</translation> + </message> +</context> <context> <name>SendCoinsDialog</name> <message> @@ -821,18 +1219,46 @@ <translation>Slanje novca</translation> </message> <message> + <source>Quantity:</source> + <translation>Količina:</translation> + </message> + <message> + <source>Bytes:</source> + <translation>Bajtova:</translation> + </message> + <message> <source>Amount:</source> <translation>Iznos:</translation> </message> <message> + <source>Priority:</source> + <translation>Prioriteta:</translation> + </message> + <message> + <source>Fee:</source> + <translation>Naknada:</translation> + </message> + <message> + <source>Change:</source> + <translation>Vraćeno:</translation> + </message> + <message> <source>Send to multiple recipients at once</source> - <translation>Pošalji k nekoliko primatelja odjednom</translation> + <translation>Pošalji novce većem broju primatelja u jednoj transakciji</translation> </message> <message> <source>Add &Recipient</source> <translation>&Dodaj primatelja</translation> </message> <message> + <source>Clear all fields of the form.</source> + <translation>Obriši sva polja</translation> + </message> + <message> + <source>Dust:</source> + <translation>Prah:</translation> + </message> + <message> <source>Clear &All</source> <translation>Obriši &sve</translation> </message> @@ -866,11 +1292,11 @@ </message> <message> <source>The amount exceeds your balance.</source> - <translation>Iznos je veći od stanja računa.</translation> + <translation>Iznos je veći od raspoložljivog stanja novčanika.</translation> </message> <message> <source>The total exceeds your balance when the %1 transaction fee is included.</source> - <translation>Iznos je veći od stanja računa kad se doda naknada za transakcije od %1.</translation> + <translation>Iznos je veći od stanja novčanika kad se doda naknada za transakcije od %1.</translation> </message> <message> <source>(no label)</source> @@ -966,7 +1392,7 @@ <name>SplashScreen</name> <message> <source>Bitcoin Core</source> - <translation>Bitcoin Jezgra</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>[testnet]</source> @@ -1087,7 +1513,7 @@ </message> <message> <source>This pane shows a detailed description of the transaction</source> - <translation>Ova panela prikazuje detaljni opis transakcije</translation> + <translation>Ovaj prozor prikazuje detaljni opis transakcije</translation> </message> </context> <context> @@ -1110,7 +1536,7 @@ </message> <message> <source>This block was not received by any other nodes and will probably not be accepted!</source> - <translation>Generirano - Upozorenje: ovaj blok nije bio primljen od strane bilo kojeg drugog noda i vjerojatno neće biti prihvaćen!</translation> + <translation>Ovaj blok nije bio primljen od strane bilo kojeg drugog čvora i vjerojatno neće biti prihvaćen!</translation> </message> <message> <source>Generated but not accepted</source> @@ -1201,7 +1627,7 @@ </message> <message> <source>To yourself</source> - <translation>Tebi</translation> + <translation>Samom sebi</translation> </message> <message> <source>Mined</source> @@ -1221,19 +1647,23 @@ </message> <message> <source>Copy address</source> - <translation>Kopirati adresu</translation> + <translation>Kopiraj adresu</translation> </message> <message> <source>Copy label</source> - <translation>Kopirati oznaku</translation> + <translation>Kopiraj oznaku</translation> </message> <message> <source>Copy amount</source> <translation>Kopiraj iznos</translation> </message> <message> + <source>Copy transaction ID</source> + <translation>Kopiraj ID transakcije</translation> + </message> + <message> <source>Edit label</source> - <translation>Izmjeniti oznaku</translation> + <translation>Izmjeni oznaku</translation> </message> <message> <source>Show transaction details</source> @@ -1305,7 +1735,7 @@ </message> <message> <source>Backup Wallet</source> - <translation>Backup novčanika</translation> + <translation>Arhiviranje novčanika</translation> </message> <message> <source>Wallet Data (*.dat)</source> @@ -1313,7 +1743,7 @@ </message> <message> <source>Backup Failed</source> - <translation>Backup nije uspio</translation> + <translation>Arhiviranje nije uspjelo</translation> </message> </context> <context> @@ -1324,7 +1754,7 @@ </message> <message> <source>Specify data directory</source> - <translation>Odredi direktorij za datoteke</translation> + <translation>Odaberi direktorij za datoteke</translation> </message> <message> <source>Specify your own public address</source> @@ -1352,15 +1782,15 @@ </message> <message> <source>Connect only to the specified node(s)</source> - <translation>Poveži se samo sa određenim nodom</translation> + <translation>Poveži se samo sa određenim čvorom/čvorovima</translation> </message> <message> <source>Error: Disk space is low!</source> - <translation>Pogreška: Nema prostora na disku!</translation> + <translation>Pogreška: Nema dovoljno prostora na disku!</translation> </message> <message> <source>Imports blocks from external blk000??.dat file</source> - <translation>Importiraj blokove sa vanjskog blk000??.dat fajla</translation> + <translation>Uvozi blokove sa vanjske blk000??.dat datoteke</translation> </message> <message> <source>Information</source> @@ -1412,7 +1842,7 @@ </message> <message> <source>Allow DNS lookups for -addnode, -seednode and -connect</source> - <translation>Dozvoli DNS upite za dodavanje nodova i povezivanje</translation> + <translation>Dozvoli DNS upite za -addnode, -seednode i -connect</translation> </message> <message> <source>Loading addresses...</source> @@ -1420,11 +1850,11 @@ </message> <message> <source>Error loading wallet.dat: Wallet corrupted</source> - <translation>Greška kod učitavanja wallet.dat: Novčanik pokvaren</translation> + <translation>Greška kod učitavanja datoteke wallet.dat: Novčanik pokvaren</translation> </message> <message> <source>Error loading wallet.dat</source> - <translation>Greška kod učitavanja wallet.dat</translation> + <translation>Greška kod učitavanja datoteke wallet.dat</translation> </message> <message> <source>Invalid -proxy address: '%s'</source> @@ -1432,7 +1862,7 @@ </message> <message> <source>Invalid amount for -paytxfee=<amount>: '%s'</source> - <translation>Nevaljali iznos za opciju -paytxfee=<amount>: '%s'</translation> + <translation>Nevaljali iznos za opciju -paytxfee=<iznos>: '%s'</translation> </message> <message> <source>Insufficient funds</source> @@ -1444,7 +1874,7 @@ </message> <message> <source>Add a node to connect to and attempt to keep the connection open</source> - <translation>Unesite nod s kojim se želite spojiti and attempt to keep the connection open</translation> + <translation>Doda čvor s kojim se želite povezati i nastoji održati vezu otvorenu</translation> </message> <message> <source>Loading wallet...</source> @@ -1460,7 +1890,7 @@ </message> <message> <source>Rescanning...</source> - <translation>Rescaniranje</translation> + <translation>Ponovno pretraživanje...</translation> </message> <message> <source>Done loading</source> diff --git a/src/qt/locale/bitcoin_hu.ts b/src/qt/locale/bitcoin_hu.ts index c84d2c4e87..fd476611ee 100644 --- a/src/qt/locale/bitcoin_hu.ts +++ b/src/qt/locale/bitcoin_hu.ts @@ -1,4 +1,4 @@ -<TS language="hu" version="2.1"> +<TS language="hu" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -414,6 +414,10 @@ <source>No block source available...</source> <translation>Blokk forrása ismeretlen...</translation> </message> + <message numerus="yes"> + <source>%n hour(s)</source> + <translation><numerusform>%n óra</numerusform><numerusform>%n óra</numerusform></translation> + </message> <message> <source>%1 and %2</source> <translation>%1 és %2</translation> @@ -451,6 +455,18 @@ <translation>Frissítés...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Dátum: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Típus: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Tranzakció elküldve.</translation> </message> @@ -789,6 +805,10 @@ <translation>Üdvözlünk a Bitcoin Core-ban.</translation> </message> <message> + <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source> + <translation>A Bitcoin Core le fogja tölteni és tárolni fogja a Bitcoin blokklánc egy másolatát. Legalább %1GB adat lesz tárolva ebben a mappában, és ez folyamatosan nőni fog. A tárca szintén itt lesz tárolva.</translation> + </message> + <message> <source>Use the default data directory</source> <translation>Az alapértelmezett adat könyvtár használata</translation> </message> @@ -871,6 +891,14 @@ <translation>&Hálózat</translation> </message> <message> + <source>&Start Bitcoin Core on system login</source> + <translation>A Bitcoin elindítása bejelentkezéskor</translation> + </message> + <message> + <source>Expert</source> + <translation>szakértő</translation> + </message> + <message> <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> <translation>A Bitcoin-kliens portjának automatikus megnyitása a routeren. Ez csak akkor működik, ha a routered támogatja az UPnP-t és az engedélyezve is van rajta.</translation> </message> @@ -879,6 +907,10 @@ <translation>&UPnP port-feltérképezés</translation> </message> <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>Csatlakozás a Bitcoin hálózatához SOCKS5 proxyn keresztül</translation> + </message> + <message> <source>Proxy &IP:</source> <translation>Proxy &IP:</translation> </message> @@ -1016,6 +1048,10 @@ <context> <name>PeerTableModel</name> <message> + <source>User Agent</source> + <translation>User Agent</translation> + </message> + <message> <source>Ping Time</source> <translation>Ping idő</translation> </message> @@ -1137,10 +1173,30 @@ <translation>Verzió</translation> </message> <message> + <source>User Agent</source> + <translation>User Agent</translation> + </message> + <message> <source>Services</source> <translation>Szolgáltatások</translation> </message> <message> + <source>Last Send</source> + <translation>Legutóbbi küldés</translation> + </message> + <message> + <source>Last Receive</source> + <translation>Legutóbbi fogadás</translation> + </message> + <message> + <source>Bytes Sent</source> + <translation>Küldött bájtok</translation> + </message> + <message> + <source>Bytes Received</source> + <translation>Fogadott bájtok</translation> + </message> + <message> <source>Ping Time</source> <translation>Ping idő</translation> </message> @@ -1212,6 +1268,10 @@ <source>never</source> <translation>soha</translation> </message> + <message> + <source>Unknown</source> + <translation>Ismeretlen</translation> + </message> </context> <context> <name>ReceiveCoinsDialog</name> @@ -1220,6 +1280,10 @@ <translation>Címke:</translation> </message> <message> + <source>&Message:</source> + <translation>&Üzenet:</translation> + </message> + <message> <source>Clear</source> <translation>Törlés</translation> </message> @@ -1353,6 +1417,14 @@ <translation>Visszajáró:</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Tranzakciós díj</translation> + </message> + <message> + <source>Hide</source> + <translation>Elrejtés</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Küldés több címzettnek egyszerre</translation> </message> @@ -1750,6 +1822,10 @@ <translation>Címke</translation> </message> <message> + <source>Unconfirmed</source> + <translation>Megerősítetlen:</translation> + </message> + <message> <source>Received with</source> <translation>Erre a címre</translation> </message> @@ -1877,6 +1953,10 @@ <translation>Az exportálás sikertelen volt</translation> </message> <message> + <source>Exporting Successful</source> + <translation>Sikeres exportálás</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Vesszővel elválasztott fájl (*.csv)</translation> </message> @@ -2057,6 +2137,10 @@ <translation>Tárca ellenőrzése...</translation> </message> <message> + <source>Wallet options:</source> + <translation>Tárca beállítások:</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Az adatbázist újra kell építeni -reindex használatával (módosítás -tindex).</translation> </message> @@ -2065,6 +2149,14 @@ <translation>Adatkönyvtár kiválasztása induláskor (alapbeállítás: 0)</translation> </message> <message> + <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source> + <translation>Copyright (C) 2009-%i A Bitcoin Core Fejlesztői</translation> + </message> + <message> + <source>Error reading from database, shutting down.</source> + <translation>Hiba az adatbázis olvasásakor, leállítás</translation> + </message> + <message> <source>Information</source> <translation>Információ</translation> </message> diff --git a/src/qt/locale/bitcoin_id_ID.ts b/src/qt/locale/bitcoin_id_ID.ts index dec30dafb3..6855d11c80 100644 --- a/src/qt/locale/bitcoin_id_ID.ts +++ b/src/qt/locale/bitcoin_id_ID.ts @@ -1,4 +1,4 @@ -<TS language="id_ID" version="2.1"> +<TS language="id_ID" version="2.0"> <context> <name>AddressBookPage</name> <message> diff --git a/src/qt/locale/bitcoin_it.ts b/src/qt/locale/bitcoin_it.ts index c81f458e39..d3cc576979 100644 --- a/src/qt/locale/bitcoin_it.ts +++ b/src/qt/locale/bitcoin_it.ts @@ -1,4 +1,4 @@ -<TS language="it" version="2.1"> +<TS language="it" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -2806,10 +2806,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Associa all'indirizzo indicato e resta permanentemente in ascolto su di esso. Usa la notazione [host]:porta per l'IPv6</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)</source> - <translation>Limita la quantità di transazioni gratuite ad <n>*1000 byte al minuto (predefinito: %u)</translation> - </message> - <message> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <translation>Elimina tutte le transazioni dal portamonete e recupera solo quelle che fanno parte della blockchain attraverso il comando -rescan all'avvio.</translation> </message> @@ -2818,18 +2814,10 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Distribuito secondo la licenza software MIT, vedi il file COPYING incluso oppure <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Entra in modalità test di regressione. Questa utilizza una speciale catena in cui i blocchi possono essere risolti istantaneamente.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Esegue un comando quando lo stato di una transazione del portamonete cambia (%s in cmd è sostituito da TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>In questa modalità -genproclimit determina quanti blocchi saranno generati immediatamente.</translation> - </message> - <message> <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> <translation>Commissioni massime totali da includere in una singola transazione dal portamonete. Un'impostazione troppo bassa potrebbe provocare l'annullamento di transazioni di grosse dimensioni (predefinito: %s)</translation> </message> @@ -2850,6 +2838,14 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Impossibile associarsi a %s su questo computer. Probabilmente Bitcoin Core è già in esecuzione.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>ATTENZIONE, il numero di blocchi generati è insolitamente elevato: %d blocchi ricevuti nelle ultime %d ore (%d previsti)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>ATTENZIONE, si consiglia di verificare la connessione di rete: %d blocchi ricevuti nelle ultime %d ore (%d previsti)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Attenzione: -paytxfee è impostato su un valore molto elevato. Questa è la commissione che si paga quando si invia una transazione.</translation> </message> @@ -2986,10 +2982,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Specifica il file del portamonete (all'interno della cartella dati)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Questa impostazione è destinata all'uso con i test di regressione e per lo sviluppo di applicazioni.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Usa UPnP per mappare la porta di ascolto (predefinito: %u)</translation> </message> @@ -3062,10 +3054,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Le commissioni (in BTC/kB) inferiori a questo valore sono considerate pari a zero relativamente alla trasmissione (predefinito: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Le commissioni (in BTC/kB) inferiori a questo valore sono considerate pari a zero relativamente alla creazione della transazione (predefinito: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Nel caso in cui paytxfee non sia impostato, include una commissione tale da ottenere un avvio delle conferme entro una media di n blocchi (predefinito: %u)</translation> </message> @@ -3090,10 +3078,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Randomizza le credenziali per ogni connessione proxy. Permette la Tor stream isolation (predefinito: %u)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default: %u)</source> - <translation>Richiedi alta priorità per la trasmissione di transazioni a zero o basse commissioni (predefinito: %u)</translation> - </message> - <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Imposta la dimensione massima in byte delle transazioni ad alta-priorità/basse-commissioni (predefinito: %d)</translation> </message> @@ -3161,10 +3145,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Attivazione della blockchain migliore...</translation> </message> <message> - <source>Allow self signed root certificates (default: 0)</source> - <translation>Permette certificati radice auto-firmati (predefinito: 0)</translation> - </message> - <message> <source>Can't run with a wallet in prune mode.</source> <translation>Impossibile operare con un portamonete in modalità prune.</translation> </message> @@ -3257,12 +3237,12 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Supporto RPC per le connessioni HTTP persistenti (predefinito: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Scarta casualmente 1 ogni <n> messaggi di rete</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Ricostruzione dell'indice della block chain dai file blk000??.dat correnti all'avvio</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Altera casualmente 1 ogni <n> messaggi di rete</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Ricevi e visualizza gli alerts della rete P2P (default: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3409,18 +3389,10 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>(1 = mantiene metadati tx, ad es. proprietario account ed informazioni di richiesta di pagamento, 2 = scarta metadati tx)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Scarica l'attività del database dal pool in memoria al log su disco ogni <n> megabyte (predefinito: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Determina quanto sarà approfondita la verifica da parte di -checkblocks (0-4, predefinito: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Abilita il log della priorità di transazione e della commissione per kB quando si generano blocchi (predefinito: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Mantiene l'indice completo delle transazioni usato dalla chiamata rpc getrawtransaction (predefinito: %u)</translation> </message> @@ -3449,18 +3421,10 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Interroga sempre i DNS per ottenere gli indirizzi dei peer (predefinito: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Disabilita la modalità sicura ignorando gli eventi che porterebbero alla sua attivazione (predefinito: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Errore caricamento wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Forza modalità sicura (predefinito: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Genera bitcoin (predefinito: %u)</translation> </message> @@ -3477,10 +3441,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Indirizzo -proxy non valido: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Limita la dimensione della cache delle firme a <n> voci (predefinito: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Resta in attesa di connessioni JSON-RPC su <port> (predefinito: %u o testnet: %u)</translation> </message> @@ -3505,10 +3465,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Buffer di invio massimo per connessione, <n>*1000 byte (predefinito: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Accetta solo block chain corrispondenti ai checkpoint integrati nel codice (predefinito: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Antepone un timestamp all'output del debug (predefinito: %u)</translation> </message> @@ -3521,10 +3477,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Trasmette transazioni non-P2SH multisig (predefinito: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Mantieni in esecuzione un thread per scaricare periodicamente il portamonete (predefinito: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>File del certificato del server (predefinito: %s)</translation> </message> @@ -3545,10 +3497,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Imposta il numero di thread destinati a rispondere alle chiamate RPC (predefinito %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Imposta il flag DB_PRIVATE nell'ambiente di database del portamonete (predefinito: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Specifica il file di configurazione (predefinito: %s)</translation> </message> @@ -3565,10 +3513,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Abilita la spesa di resto non confermato quando si inviano transazioni (predefinito: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Interrompi l'esecuzione dopo aver importato i blocchi dal disco (predefinito: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Soglia di disconnessione per i peer che si comportano in maniera anomala (predefinito: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_ja.ts b/src/qt/locale/bitcoin_ja.ts index 376d36bed0..e2c22f7f6d 100644 --- a/src/qt/locale/bitcoin_ja.ts +++ b/src/qt/locale/bitcoin_ja.ts @@ -1,4 +1,4 @@ -<TS language="ja" version="2.1"> +<TS language="ja" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -2817,10 +2817,6 @@ <translation>指定のアドレスへバインドし、その上で常にリスンします。IPv6 は [ホスト名]:ポート番号 と表記します</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)</source> - <translation>継続的に無料トランザクションのレートを一分間に<n>*1000バイトに制限する (規定値: %u)</translation> - </message> - <message> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <translation>ウォレットの全トランザクションを削除し、これらを-rescanオプションを用いることで起動時にブロックチェインのデータのみからリカバリします。</translation> </message> @@ -2829,18 +2825,10 @@ <translation>MITソフトウェアライセンスのもとで配布されています。付属のCOPYINGファイルまたは<http://www.opensource.org/licenses/mit-license.php>を参照してください。</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>ブロックを瞬時に解決することができる特別なチェーンを使用して、リグレッションテストモードに入る。</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>ウォレットの取引を変更する際にコマンドを実行 (cmd の %s は TxID に置換される)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>このモードでは -genproclimit は何個のブロックをただちに生成するのか制御します。</translation> - </message> - <message> <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> <translation>ひとつのウォレットトランザクションで使用する合計手数料の最大値。低すぎる値を指定すると巨大なトランザクションの作成ができなくなります (規定値: %s)</translation> </message> @@ -2861,6 +2849,14 @@ <translation>このコンピュータの %s にバインドすることができません。おそらく Bitcoin Core は既に実行されています。</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>警告:異常に多くの数のブロックが生成されています。%d ブロックが最近 %d 時間以内に受け取られました。(期待値: %d)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>警告:ネットワーク接続を確認してください。%d ブロックが最近 %d 時間以内にに受け取られました。(期待値: %d)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>警告: -paytxfee が非常に高く設定されています! これは取引を送信する場合に支払う取引手数料です。</translation> </message> @@ -2998,10 +2994,6 @@ <translation>ウォレットのファイルを指定 (データ・ディレクトリの中に)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>これはリグレッションテストツールやアプリ開発のためのものです。</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>リッスンポートの割当に UPnP を使用 (初期値: %u)</translation> </message> @@ -3078,10 +3070,6 @@ <translation>中継の際、この値未満の手数料 (BTC/Kb単位) はゼロであるとみなす (デフォルト: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>トランザクション作成の際、この値未満の手数料 (BTC/Kb単位) はゼロであるとみなす (デフォルト: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>paytxfee が設定されていなかった場合、平均して n ブロック以内にトランザクションが検証され始めるのに十分な手数料を含める (初期値: %u)</translation> </message> @@ -3106,10 +3094,6 @@ <translation>認証情報をプロキシー接続ごとにランダム化する。これによりTorストリーム分離をすることができます (規定値: %u)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default: %u)</source> - <translation>無料や低い手数料のトランザクションのリレーに際し、高い優先度を要求する (規定値: %u)</translation> - </message> - <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>最優先/最低手数料の最大サイズをバイトで指定 (初期値: %d)</translation> </message> @@ -3178,10 +3162,6 @@ rpcpassword=%s <translation>最優良のチェインを有効化しています...</translation> </message> <message> - <source>Allow self signed root certificates (default: 0)</source> - <translation>自己署名ルート証明書を許可する (規定値: 0)</translation> - </message> - <message> <source>Can't run with a wallet in prune mode.</source> <translation>剪定モードではウォレット機能付きで起動できません。</translation> </message> @@ -3274,18 +3254,14 @@ rpcpassword=%s <translation>RPCにおけるHTTPの持続的接続のサポート (初期値: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation><n> 個のネットワークメッセージごとにひとつをランダムに捨てる</translation> - </message> - <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation><n>個のネットワークメッセージごとにひとつをランダムに改変する</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>起動時に現在の blk000??.dat ファイルからブロック チェーンのインデックスを再構築</translation> </message> <message> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>P2Pネットワークのアラートの受け取りと表示を行う (デフォルト: %u)</translation> + </message> + <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>トレース/デバッグ情報を debug.log ファイルの代わりにコンソールへ送る</translation> </message> @@ -3430,18 +3406,10 @@ rpcpassword=%s <translation>(1 = トランザクションのメタデータ、例えばアカウントの所有者や支払リクエストの内容を保持する, 2 = トランザクションのメタデータを破棄する)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation><n> メガバイトごとにメモリプールからデータベースのアクティビティをディスクログに書き出す (初期値: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>-checkblocks のブロックの検証レベル (0-4, 初期値: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>ブロックの採掘時にトランザクションの優先度と1kBあたりの手数料をログに残す (デフォルト: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>getrawtransaction rpc 呼び出し時に用いる、完全なトランザクションインデックスを保持する (初期値: %u)</translation> </message> @@ -3470,18 +3438,10 @@ rpcpassword=%s <translation>DNS ルックアップを通してピアアドレスを常に問い合わせる (初期値: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>セーフモードを無効化し、実際のセーフモードイベントも無効化する (初期値: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>wallet.dat 読み込みエラー</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>セーフモードを強制する (初期値: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>コインを生成 (初期値: %u)</translation> </message> @@ -3498,10 +3458,6 @@ rpcpassword=%s <translation>無効な -proxy アドレス: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>署名キャッシュのサイズを <n> エントリーに制限する (デフォルト: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation><port> で JSON-RPC 接続をリスン (初期値: %u、testnet は %u)</translation> </message> @@ -3526,10 +3482,6 @@ rpcpassword=%s <translation>接続毎の最大送信バッファ <n>*1000 バイト (初期値: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>内蔵のチェックポイントと一致するブロック チェーンのみを許可 (初期値: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>デバッグ出力にタイムスタンプを付ける (初期値: %u)</translation> </message> @@ -3542,10 +3494,6 @@ rpcpassword=%s <translation>P2SHでないマルチシグトランザクションをリレーする (初期値: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>ウォレットを定期的に書き出すためのスレッドを走らせる (初期値: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>サーバ証明書ファイル (初期値: %s)</translation> </message> @@ -3566,10 +3514,6 @@ rpcpassword=%s <translation>RPC サービスのスレッド数を設定 (初期値: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>ウォレットDB環境内にDB_PRIVATEフラグを設定する (デフォルト: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>設定ファイルの指定 (初期値: %s)</translation> </message> @@ -3586,10 +3530,6 @@ rpcpassword=%s <translation>トランザクション送信時に未検証のおつりを使用する (デフォルト: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>ディスクからブロックを読み込んだ後に終了する (デフォルト: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>不正なピアを切断するためのしきい値 (初期値: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_ka.ts b/src/qt/locale/bitcoin_ka.ts index b9e118a620..4c6ce13eff 100644 --- a/src/qt/locale/bitcoin_ka.ts +++ b/src/qt/locale/bitcoin_ka.ts @@ -1,4 +1,4 @@ -<TS language="ka" version="2.1"> +<TS language="ka" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -2215,10 +2215,6 @@ <translation>მოცემულ მისამართზე მიჯაჭვა მუდმივად მასზე მიყურადებით. გამოიყენეთ [host]:port ფორმა IPv6-სათვის</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>გადასვლა რეგრესული ტესტირების რეჟიმში, რომელიც იყენებს სპეციალურ ჯაჭვს ბლოკების დაუყოვნებლივი პოვნის შესაძლებლობით.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>კომანდის შესრულება საფულის ტრანსაქციის ცვლილებისას (%s კომანდაში ჩანაცვლდება TxID-ით)</translation> </message> @@ -2323,10 +2319,6 @@ <translation>მიუთითეთ საფულის ფაილი (კატალოგში)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>გამოიყენება რეგრესული ტესტირების ინსტრუმენტებისა და პროგრამების შემუშავებისას.</translation> - </message> - <message> <source>Verifying blocks...</source> <translation>ბლოკების ვერიფიკაცია...</translation> </message> diff --git a/src/qt/locale/bitcoin_kk_KZ.ts b/src/qt/locale/bitcoin_kk_KZ.ts index 4cc709fdb2..5ee9040633 100644 --- a/src/qt/locale/bitcoin_kk_KZ.ts +++ b/src/qt/locale/bitcoin_kk_KZ.ts @@ -1,4 +1,4 @@ -<TS language="kk_KZ" version="2.1"> +<TS language="kk_KZ" version="2.0"> <context> <name>AddressBookPage</name> <message> diff --git a/src/qt/locale/bitcoin_ko_KR.ts b/src/qt/locale/bitcoin_ko_KR.ts index 42eb9eedbb..5126e53f8e 100644 --- a/src/qt/locale/bitcoin_ko_KR.ts +++ b/src/qt/locale/bitcoin_ko_KR.ts @@ -1,7 +1,11 @@ -<TS language="ko_KR" version="2.1"> +<TS language="ko_KR" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>지갑 주소나 이름을 수정하려면 우클릭하세요.</translation> + </message> + <message> <source>Create a new address</source> <translation>새 주소 만들기</translation> </message> @@ -89,7 +93,11 @@ <source>Exporting Failed</source> <translation>내보내기 실패</translation> </message> - </context> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>%1으로 주소 리스트를 저장하는 동안 오류가 발생했습니다. 다시 시도해주세요.</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -477,6 +485,10 @@ <context> <name>CoinControlDialog</name> <message> + <source>Coin Selection</source> + <translation>코인 선택</translation> + </message> + <message> <source>Quantity:</source> <translation>수량:</translation> </message> @@ -895,6 +907,14 @@ <translation>사용중인 UPnP 포트 매핑(&U)</translation> </message> <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>SOCKS5 프록시를 통해 비트코인 네트워크 연결</translation> + </message> + <message> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation>SOCKS5 프록시를 거쳐 연결합니다 (기본값 프록시):</translation> + </message> + <message> <source>Proxy &IP:</source> <translation>프록시 IP(&I):</translation> </message> @@ -1091,6 +1111,10 @@ <translation>거래량</translation> </message> <message> + <source>Enter a Bitcoin address (e.g. %1)</source> + <translation>비트코인 주소를 입력하기 (예. %1)</translation> + </message> + <message> <source>N/A</source> <translation>없음</translation> </message> @@ -2403,10 +2427,6 @@ <translation>RPC 서버 설정</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>모든 네트워크 메시지 마다 무작위로 1이 떨어진다</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>추적오류 정보를 degug.log 자료로 보내는 대신 콘솔로 보내기</translation> </message> diff --git a/src/qt/locale/bitcoin_ky.ts b/src/qt/locale/bitcoin_ky.ts index 8edee19c70..442d7c5d52 100644 --- a/src/qt/locale/bitcoin_ky.ts +++ b/src/qt/locale/bitcoin_ky.ts @@ -1,4 +1,4 @@ -<TS language="ky" version="2.1"> +<TS language="ky" version="2.0"> <context> <name>AddressBookPage</name> <message> diff --git a/src/qt/locale/bitcoin_la.ts b/src/qt/locale/bitcoin_la.ts index 3e25cf95b6..b1a69c9a9e 100644 --- a/src/qt/locale/bitcoin_la.ts +++ b/src/qt/locale/bitcoin_la.ts @@ -1,4 +1,4 @@ -<TS language="la" version="2.1"> +<TS language="la" version="2.0"> <context> <name>AddressBookPage</name> <message> diff --git a/src/qt/locale/bitcoin_lt.ts b/src/qt/locale/bitcoin_lt.ts index 01fa94bab3..4e468911dc 100644 --- a/src/qt/locale/bitcoin_lt.ts +++ b/src/qt/locale/bitcoin_lt.ts @@ -1,7 +1,11 @@ -<TS language="lt" version="2.1"> +<TS language="lt" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>Spustelėkite dešinįjį klaviša norint keisti adresą arba etiketę</translation> + </message> + <message> <source>Create a new address</source> <translation>Sukurti naują adresą</translation> </message> @@ -26,6 +30,10 @@ <translation>&Kopijuoti adresą</translation> </message> <message> + <source>Delete the currently selected address from the list</source> + <translation>Ištrinti pasirinktą adresą iš sąrašo</translation> + </message> + <message> <source>&Export</source> <translation>&Eksportuoti</translation> </message> @@ -34,6 +42,10 @@ <translation>&Trinti</translation> </message> <message> + <source>Choose the address to send coins to</source> + <translation>Pasirinkite adresą kuriam siūsite monetas</translation> + </message> + <message> <source>C&hoose</source> <translation>P&asirinkti</translation> </message> @@ -247,6 +259,10 @@ <translation>&Gaunami adresai...</translation> </message> <message> + <source>Open &URI...</source> + <translation>Atidaryti &URI...</translation> + </message> + <message> <source>Bitcoin Core client</source> <translation>Bitcoin Core klientas</translation> </message> @@ -385,6 +401,10 @@ <context> <name>CoinControlDialog</name> <message> + <source>Coin Selection</source> + <translation>Monetų pasirinkimas</translation> + </message> + <message> <source>Quantity:</source> <translation>Kiekis:</translation> </message> @@ -715,6 +735,10 @@ <translation>niekas</translation> </message> <message> + <source>Confirm options reset</source> + <translation>Patvirtinti nustatymų atstatymą</translation> + </message> + <message> <source>The supplied proxy address is invalid.</source> <translation>Nurodytas tarpinio serverio adresas negalioja.</translation> </message> @@ -726,6 +750,14 @@ <translation>Forma</translation> </message> <message> + <source>Available:</source> + <translation>Galimi:</translation> + </message> + <message> + <source>Pending:</source> + <translation>Laukiantys:</translation> + </message> + <message> <source>Immature:</source> <translation>Nepribrendę:</translation> </message> @@ -745,6 +777,10 @@ <translation>URI apdorojimas</translation> </message> <message> + <source>Payment request rejected</source> + <translation>Mokėjimo siuntimas atmestas</translation> + </message> + <message> <source>Network request error</source> <translation>Tinklo užklausos klaida</translation> </message> @@ -821,6 +857,26 @@ <translation>Dabartinis blokų skaičius</translation> </message> <message> + <source>Received</source> + <translation>Gauta</translation> + </message> + <message> + <source>Direction</source> + <translation>Kryptis</translation> + </message> + <message> + <source>Version</source> + <translation>Versija</translation> + </message> + <message> + <source>Bytes Sent</source> + <translation>Nusiųsti baitai</translation> + </message> + <message> + <source>Bytes Received</source> + <translation>Gauti baitai</translation> + </message> + <message> <source>Last block time</source> <translation>Paskutinio bloko laikas</translation> </message> @@ -864,6 +920,10 @@ <source>%1 GB</source> <translation>%1 GB</translation> </message> + <message> + <source>never</source> + <translation>Niekada</translation> + </message> </context> <context> <name>ReceiveCoinsDialog</name> @@ -872,6 +932,10 @@ <translation>Ž&ymė:</translation> </message> <message> + <source>Clear</source> + <translation>Išvalyti</translation> + </message> + <message> <source>Copy label</source> <translation>Kopijuoti žymę</translation> </message> diff --git a/src/qt/locale/bitcoin_lv_LV.ts b/src/qt/locale/bitcoin_lv_LV.ts index 25f92b6642..23b846bd49 100644 --- a/src/qt/locale/bitcoin_lv_LV.ts +++ b/src/qt/locale/bitcoin_lv_LV.ts @@ -1,4 +1,4 @@ -<TS language="lv_LV" version="2.1"> +<TS language="lv_LV" version="2.0"> <context> <name>AddressBookPage</name> <message> diff --git a/src/qt/locale/bitcoin_mn.ts b/src/qt/locale/bitcoin_mn.ts index a1a07af8d5..73793482d6 100644 --- a/src/qt/locale/bitcoin_mn.ts +++ b/src/qt/locale/bitcoin_mn.ts @@ -1,4 +1,4 @@ -<TS language="mn" version="2.1"> +<TS language="mn" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -6,18 +6,66 @@ <translation>Шинэ хаяг нээх</translation> </message> <message> + <source>&New</source> + <translation>&Шинэ</translation> + </message> + <message> <source>Copy the currently selected address to the system clipboard</source> <translation>Одоогоор сонгогдсон байгаа хаягуудыг сануулах</translation> </message> <message> + <source>&Copy</source> + <translation>&Хуулах</translation> + </message> + <message> + <source>C&lose</source> + <translation>&Хаах</translation> + </message> + <message> <source>&Copy Address</source> <translation>Хаягийг &Хуулбарлах</translation> </message> <message> + <source>Delete the currently selected address from the list</source> + <translation>Одоо сонгогдсон байгаа хаягуудыг жагсаалтаас устгах</translation> + </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>Сонгогдсон таб дээрхи дата-г экспортлох</translation> + </message> + <message> + <source>&Export</source> + <translation>&Экспортдлох</translation> + </message> + <message> <source>&Delete</source> <translation>&Устгах</translation> </message> <message> + <source>Choose the address to send coins to</source> + <translation>Зооснуудыг илгээх хаягийг сонгоно уу</translation> + </message> + <message> + <source>Choose the address to receive coins with</source> + <translation>Зооснуудыг хүлээн авах хаягийг сонгоно уу</translation> + </message> + <message> + <source>Sending addresses</source> + <translation>Илгээх хаягууд</translation> + </message> + <message> + <source>Receiving addresses</source> + <translation>Хүлээн авах хаяг</translation> + </message> + <message> + <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> + <translation>Эдгээр Биткойн хаягууд нь илгээх хаягууд. Хүлээн авах хаяг болон тоо хэмжээг илгээхээсээ өмнө сайн нягталж үзэж байна уу</translation> + </message> + <message> + <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> + <translation>Эдгээр Биткойн хаягууд нь хүлээн авах хаягууд. Гүйлгээ болгонд шинээр хаяг үүсгэхийг бид санал болгож байна.</translation> + </message> + <message> <source>Copy &Label</source> <translation>&Шошгыг хуулбарлах</translation> </message> @@ -26,6 +74,10 @@ <translation>&Ѳѳрчлѳх</translation> </message> <message> + <source>Export Address List</source> + <translation>Экспорт хийх хаягуудын жагсаалт</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Таслалаар тусгаарлагдсан хүснэгтэн файл (.csv)</translation> </message> @@ -959,6 +1011,14 @@ </context> <context> <name>WalletView</name> + <message> + <source>&Export</source> + <translation>&Экспортдлох</translation> + </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>Сонгогдсон таб дээрхи дата-г экспортлох</translation> + </message> </context> <context> <name>bitcoin-core</name> diff --git a/src/qt/locale/bitcoin_ms_MY.ts b/src/qt/locale/bitcoin_ms_MY.ts index 999961beb8..5e10c80aff 100644 --- a/src/qt/locale/bitcoin_ms_MY.ts +++ b/src/qt/locale/bitcoin_ms_MY.ts @@ -1,4 +1,4 @@ -<TS language="ms_MY" version="2.1"> +<TS language="ms_MY" version="2.0"> <context> <name>AddressBookPage</name> <message> diff --git a/src/qt/locale/bitcoin_nb.ts b/src/qt/locale/bitcoin_nb.ts index 6e2b4e9fcc..385f038d46 100644 --- a/src/qt/locale/bitcoin_nb.ts +++ b/src/qt/locale/bitcoin_nb.ts @@ -1,4 +1,4 @@ -<TS language="nb" version="2.1"> +<TS language="nb" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -2817,10 +2817,6 @@ <translation>Bind til angitt adresse. Bruk [vertsmaskin]:port notasjon for IPv6</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)</source> - <translation>Ratebegrens gratistransaksjoner kontinuerlig til <n>*1000 bytes per minutt (standardverdi: %u)</translation> - </message> - <message> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <translation>Slett alle transaksjoner i lommeboken og gjenopprett kun de delene av blokkjeden gjennom -rescan ved oppstart</translation> </message> @@ -2829,18 +2825,10 @@ <translation>Distribuert under MIT programvarelisensen, se medfølgende fil COPYING eller <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Gå til modus for regresjonstesting, som bruker en spesiell blokkjede der blokker kan bli løst momentant.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Kjør kommando når en lommeboktransaksjon endres (%s i kommando er erstattet med TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>I denne modusen kontrollerer -genproclimit hvor mange blokker som genereres øyeblikkelig.</translation> - </message> - <message> <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> <translation>Maksimalt samlede gebyrer til å bruke i en enkelt lommeboktransaksjon; settes dette for lavt kan store transaksjoner kanskje avbrytes (standardverdi: %s)</translation> </message> @@ -2861,6 +2849,14 @@ <translation>Ute av stand til å binde til %s på denne datamaskinen. Bitcoin Core kjører sannsynligvis allerede.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>ADVARSEL: unormalt høyt antall blokker generert, %d blokker mottatt de siste %d timene (%d forventet)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>ADVARSEL: kontroller nettverkstilkoblingen, mottok %d blokker i de siste %d timene (%d forventet)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Advarsel: -paytxfee er satt veldig høyt! Dette er transaksjonsgebyret du betaler når du sender transaksjoner.</translation> </message> @@ -2997,10 +2993,6 @@ <translation>Angi lommebokfil (inne i datamappe)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Dette er tiltenkt verktøy for regresjonstesting og apputvikling.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Bruk UPnP for å sette opp lytteport (standardverdi: %u)</translation> </message> @@ -3077,10 +3069,6 @@ <translation>Gebyrer (i BTC/Kb) mindre enn dette anses som null gebyr for videresending (standardverdi: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Gebyrer (i BTC/Kb) mindre enn dette anses som null gebyr for laging av transaksjoner (standardverdi: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Hvis paytxfee ikke er angitt, inkluderer da nok i gebyr til at transaksjoner gjennomsnittligt bekreftes innen n blokker (standardverdi: %u)</translation> </message> @@ -3105,10 +3093,6 @@ <translation>Bruk tilfeldig identitet for hver proxytilkobling. Dette muliggjør TOR stream isolasjon (standardverdi: %u)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default: %u)</source> - <translation>Krev høy prioritet for videresending av gratistransaksjoner eller transaksjoner med lavt gebyr (standardverdi: %u)</translation> - </message> - <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Sett maksimum størrelse for transaksjoner med høy prioritet / lavt gebyr, i bytes (standardverdi: %d)</translation> </message> @@ -3177,10 +3161,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Aktiverer beste kjede...</translation> </message> <message> - <source>Allow self signed root certificates (default: 0)</source> - <translation>Tillat selvsignerte rotsertifikater (standardverdi: 0)</translation> - </message> - <message> <source>Can't run with a wallet in prune mode.</source> <translation>Kan ikke kjøre med en lommebok i beskjæringsmodus.</translation> </message> @@ -3273,18 +3253,14 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>RPC-støtte for persistente HTTP-forbindelser (standardverdi: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Slumpvis dropp 1 av hver <n> nettverksmeldinger</translation> - </message> - <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Slumpvis bland 1 av hver <n> nettverksmeldinger</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>Gjenopprett blokkjedeindeks fra gjeldende blk000??.dat filer ved oppstart</translation> </message> <message> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Motta og vis P2P nettverksvarsler (standardvalg: %u)</translation> + </message> + <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Send spor-/feilsøkingsinformasjon til konsollen istedenfor filen debug.log</translation> </message> @@ -3429,18 +3405,10 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(1 = behold metadata for transaksjon som f. eks. kontoeier og informasjon om betalingsanmodning, 2 = dropp metadata for transaksjon)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Overfør aktiviteten i databasen fra minnelageret til loggen på harddisken for hver <n> megabytes (standardverdi: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Hvor grundig blokkverifiseringen til -checkblocks er (0-4, standardverdi: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Logg transaksjonsprioritet og gebyr per kB under blokkutvinning (standardverdi: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Oppretthold en full transaksjonsindeks, brukt av getrawtransaction RPC-kall (standardverdi: %u)</translation> </message> @@ -3469,18 +3437,10 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Alltid søk etter nodeadresser via DNS-oppslag (standardverdi: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Slå av sikkerhetsmodus, overstyr en virkelig sikkerhetsmodushendelse (standardverdi: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Feil ved lasting av wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Tving sikkerhetsmodus (standardverdi: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Generer mynter (standardverdi: %u)</translation> </message> @@ -3497,10 +3457,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ugyldig -proxy adresse: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Begrens størrelsen på hurtigbufferen for signaturer til <n> oppføringer (standardverdi: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Lytt etter JSON-RPC tilkoblinger på <port> (standardverdi: %u eller testnett: %u)</translation> </message> @@ -3525,10 +3481,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Maks sendebuffer per forbindelse, <n>*1000 bytes (standardverdi: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Aksepter kun blokkjeden som stemmer med innebygde sjekkpunkter (standardvalg: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Sett inn tidsstempel i front av feilsøkingsdata (standardverdi: %u)</translation> </message> @@ -3541,10 +3493,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Videresend ikke-P2SH multisig (standardverdi: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Kjør en tråd som skriver lommeboken til disk periodisk (standardverdi: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Fil for tjenersertifikat (standardverdi: %s)</translation> </message> @@ -3565,10 +3513,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Sett antall tråder til betjening av RPC-kall (standardverdi: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Setter flagget DB_PRIVATE i miljøet til lommebokdatabasen (standardverdi: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Angi konfigurasjonsfil (standardverdi: %s)</translation> </message> @@ -3585,10 +3529,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Bruk ubekreftet veksel ved sending av transaksjoner (standardverdi: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Avslutt etter import av blokker fra disk (standardverdi: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Grenseverdi for å koble fra noder med dårlig oppførsel (standardverdi: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_nl.ts b/src/qt/locale/bitcoin_nl.ts index 385972845a..7999e263e4 100644 --- a/src/qt/locale/bitcoin_nl.ts +++ b/src/qt/locale/bitcoin_nl.ts @@ -1,4 +1,4 @@ -<TS language="nl" version="2.1"> +<TS language="nl" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -399,6 +399,10 @@ <translation>&Over Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Wijzig configuratieopties voor Bitcoin Core</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Toon de lijst met gebruikt verzend adressen en labels</translation> </message> @@ -973,6 +977,10 @@ <translation>IP-adres van de proxy (bijv. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>Minimaliseren in plaats van de applicatie af te sluiten wanneer het venster is afgesloten. Als deze optie is ingeschakeld, zal de toepassing pas worden afgesloten na het selecteren van Exit in het menu.</translation> + </message> + <message> <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> <translation>Stel hier de taal van de applicatie in. Deze instelling zal van kracht worden na het herstarten van de applicatie.</translation> </message> @@ -1259,10 +1267,18 @@ <translation>Betalingsverzoek-bestand kan niet gelezen of verwerkt worden! Dit kan veroorzaakt worden door een ongeldig betalingsverzoek-bestand.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Betalingsverzoek verlopen.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Niet-geverifieerde betalingsverzoeken naar aangepaste betaling scripts worden niet ondersteund.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Ongeldig betalingsverzoek.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Restitutie van %1</translation> </message> @@ -1423,6 +1439,10 @@ <translation>Huidig aantal blokken</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Open het Bitcoin Core debug logbestand van de huidige gegevens directory. Dit kan enkele seconden duren voor grote logbestanden.</translation> + </message> + <message> <source>Received</source> <translation>Ontvangen</translation> </message> @@ -1535,6 +1555,10 @@ <translation>Maak console leeg</translation> </message> <message> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Welkom op de Bitcoin Core RPC console.</translation> + </message> + <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Gebruik de pijltjestoetsen om door de geschiedenis te navigeren, en <b>Ctrl-L</b> om het scherm leeg te maken.</translation> </message> @@ -1831,6 +1855,10 @@ <translation>Als de aangepaste toeslag is ingesteld op 1000 satoshis en de transactie is maar 250 bytes, dan wordt bij "per kilobyte" 250 satoshis aan toeslag berekend, terwijl er bij "totaal tenminste" 1000 satoshis worden berekend. Voor transacties die groter zijn dan een kilobyte, wordt in beide gevallen per kilobyte de toeslag berekend.</translation> </message> <message> + <source>Hide</source> + <translation>Verbergen</translation> + </message> + <message> <source>total at least</source> <translation>totaal ten minste</translation> </message> @@ -1971,10 +1999,22 @@ <translation>De transactie was afgewezen. Dit kan gebeuren als u eerder uitgegeven munten opnieuw wilt versturen, zoals wanneer u een kopie van uw wallet.dat heeft gebruikt en in de kopie deze munten zijn gemarkeerd als uitgegeven, maar in de huidige nog niet.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Betalingsverzoek verlopen.</translation> + </message> + <message> <source>Pay only the minimum fee of %1</source> <translation>Betaal alleen de minimale transactiekosten van %1</translation> </message> <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Het adres van de ontvanger is niet geldig. Gelieve opnieuw te controleren..</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Dubbel adres gevonden: adressen mogen maar één keer worden gebruikt worden.</translation> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Waarschuwing: Ongeldig Bitcoin adres</translation> </message> @@ -2050,6 +2090,14 @@ <translation>Bericht:</translation> </message> <message> + <source>This is an unauthenticated payment request.</source> + <translation>Dit is een niet-geverifieerd betalingsverzoek.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Dit is een geverifieerd betalingsverzoek.</translation> + </message> + <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>Vul een label voor dit adres in om het aan de lijst met gebruikte adressen toe te voegen</translation> </message> @@ -2088,6 +2136,10 @@ <translation>O&nderteken Bericht</translation> </message> <message> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>U kunt berichten/overeenkomsten ondertekenen met uw adres om te bewijzen dat u Bitcoins kunt versturen. Wees voorzichtig met het ondertekenen van iets vaags of willekeurigs, omdat phishing-aanvallen u kunnen proberen te misleiden tot het ondertekenen van overeenkomsten om uw identiteit aan hen toe te vertrouwen. Onderteken alleen volledig gedetailleerde verklaringen voordat u akkoord gaat.</translation> + </message> + <message> <source>The Bitcoin address to sign the message with</source> <translation>Het Bitcoin adres om bericht mee te ondertekenen</translation> </message> @@ -2741,18 +2793,10 @@ <translation>Uitgegeven onder de MIT software licentie, zie het bijgevoegde bestand COPYING of <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Schakel regressietest-modus in, die een speciale blokketen gebruikt waarin blokken onmiddellijk opgelost kunnen worden.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Voer opdracht uit zodra een portemonneetransactie verandert (%s in cmd wordt vervangen door TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>In deze modus, -genproclimit controleert hoeveel blokken er onmiddellijk worden gegenereerd.</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation>Kies het aantal script verificatie processen (%u tot %d, 0 = auto, <0 = laat dit aantal kernen vrij, standaard: %d)</translation> </message> @@ -2765,6 +2809,10 @@ <translation>Niet in staat om %s te verbinden op deze computer. Bitcoin Core draait waarschijnlijk al.</translation> </message> <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>WAARSCHUWING: controleer uw netwerkverbinding, %d blokken ontvangen in de laatste %d uren (%d verwacht)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Waarschuwing: -paytxfee is zeer hoog ingesteld. Dit zijn de transactiekosten die u betaalt bij het versturen van een transactie.</translation> </message> @@ -2893,10 +2941,6 @@ <translation>Specificeer het portemonnee bestand (vanuit de gegevensmap)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Dit is bedoeld voor regressie test toepassingen en applicatie onwikkeling.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Gebruik UPnP om de luisterende poort te mappen (standaard: %u)</translation> </message> @@ -2917,6 +2961,10 @@ <translation>Portemonnee instellingen:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Waarschuwing: Deze versie is verouderd; upgraden verplicht!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Om -txindex te kunnen veranderen dient u de database opnieuw te bouwen met gebruik van -reindex.</translation> </message> @@ -2965,10 +3013,6 @@ <translation>Toeslagen (in BTC/Kb) kleiner dan dit worden beschouwd als geen vergoeding (voor doorgeven) (standaard: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Toeslagen (in BTC/Kb) kleiner dan dit worden beschouwd als geen vergoeding transactieaanmaak (standaard: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Als paytxfee niet is ingesteld, het pakket voldoende vergoeding zodat transacties beginnen bevestiging gemiddeld binnen in blokken (default: %u)</translation> </message> @@ -2994,10 +3038,37 @@ <translation>Stel het aantal threads in voor het genereren van coins indien ingesteld (-1 = alle kernen, standaard: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>Het transactiebedrag is te klein om te versturen nadat de vergoeding in mindering is gebracht</translation> + </message> + <message> <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source> <translation>Dit product bevat software dat ontwikkeld is door het OpenSSL Project voor gebruik in de OpenSSL Toolkit <https://www.openssl.org/> en cryptografische software geschreven door Eric Young en UPnP software geschreven door Thomas Bernard.</translation> </message> <message> + <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: +%s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +The username and password MUST NOT be the same. +If the file does not exist, create it with owner-readable-only file permissions. +It is also recommended to set alertnotify so you are notified of problems; +for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com +</source> + <translation>Om bitcoind of de -server optie naar bitcoin-gt te gebruiken, dient u een rpcwachtwoord in te stellen in het configuratiebestand: + %s +Wij raden u aan om het volgende wachtwoord willekeurig te gebruiken: +rpcuser=bitcoinrpc +rpcpassword=%s +(u hoeft dit wachtwoord niet te onthouden) +De gebruikersnaam en het wachtwoorden moeten NIET hetzelfde zijn. +Indien het bestand niet bestaat, maak het bestand aan met bestandsrechten: alleen lezen voor eigenaar. +Het is ook aan te raden om een alarmnotificatie in te stellen, zodat u op de hoogte bent van de problemen; +Voorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> + </message> + <message> <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> <translation>Let op: -maxtxfee is erg hoog ingesteld! Transactiekosten van dergelijke groottes kunnen in een enkele transactie worden betaald.</translation> </message> @@ -3010,10 +3081,18 @@ <translation>Goedgekeurde peers kunnen niet ge-DoS-banned worden en hun transacties worden altijd doorgestuurd, zelfs als ze reeds in de mempool aanwezig zijn, nuttig voor bijv. een gateway</translation> </message> <message> + <source>(default: %u)</source> + <translation>(standaard: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>Accepteer publieke REST-requests (standaard: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>Beste reeks activeren...</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Kan -whitebind adres niet herleiden: '%s'</translation> </message> @@ -3102,14 +3181,6 @@ <translation>RPC ondersteuning voor HTTP persisten verbindingen (default: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Laat willekeurig 1 elke <n> netwerkberichten vallen</translation> - </message> - <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Fuzz willekeurig 1 van elke <n> netwerkberichten</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Stuur trace/debug-info naar de console in plaats van het debug.log bestand</translation> </message> @@ -3146,6 +3217,10 @@ <translation>Geminimaliseerd starten</translation> </message> <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>Het transactiebedrag is te klein om de vergoeding te betalen</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Dit is experimentele software.</translation> </message> @@ -3166,6 +3241,10 @@ <translation>Transactie te groot</translation> </message> <message> + <source>UI Options:</source> + <translation>UI Opties:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Niet in staat om aan %s te binden op deze computer (bind gaf error %s)</translation> </message> @@ -3246,18 +3325,10 @@ <translation>(1 = behoudt tx meta data bijv. account eigenaar en betalingsverzoek informatie, 2. sla tx meta data niet op)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Leeg database-activiteit uit de geheugen pool naar schijf log elke <n> megabytes (standaard: %u) </translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Hoe grondig de blokverificatie van -checkblocks is (0-4, standaard: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Log transactieprioriteit en -kosten per kB bij het mijnen van blokken (standaard: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Onderhoud een volledige transactieindex, gebruikt door de getrawtransaction rpc call (standaard: %u)</translation> </message> @@ -3282,18 +3353,10 @@ <translation>Vind anderen door middel van een DNS-naslag (standaard: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Veilige modus uitschakelen, hef een echte veilige modus gebeurtenis uit (default: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Fout bij laden wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Forceer veilige modus (default: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Genereer munten (standaard: %u)</translation> </message> @@ -3310,10 +3373,6 @@ <translation>Ongeldig -proxy adres: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Limiteer grootte van de handtekening cache tot <n> entries (default: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Luister naar JSON-RPC-verbindingen op poort <port> (standaard: %u of testnet: %u)</translation> </message> @@ -3326,6 +3385,10 @@ <translation>Onderhoud maximaal <n> verbindingen naar peers (standaard: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Laat de portemonnee transacties uitsturen</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Maximum per-connectie ontvangstbuffer, <n>*1000 bytes (standaard: %u)</translation> </message> @@ -3334,10 +3397,6 @@ <translation>Maximum per-connectie zendbuffer, <n>*1000 bytes (standaard: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Accepteer alleen blokkenketen die overeenkomt met de ingebouwde checkpoints (standaard: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Prepend debug output met tijdstempel (standaard: %u)</translation> </message> @@ -3350,10 +3409,6 @@ <translation>Relay non-P2SH multisig (default: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Draai een proces om de wallet periodiek te flushen (default: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Certificaat-bestand voor server (standaard: %s)</translation> </message> @@ -3374,10 +3429,6 @@ <translation>Stel het aantal threads in om RPC-aanvragen mee te bedienen (standaard: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Plaatst de DB_PRIVATE vlag in de wallet db omgeving (default: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Specificeer configuratie bestand (standaard: %s)</translation> </message> @@ -3394,10 +3445,6 @@ <translation>Besteed onbevestigd wisselgeld bij het versturen van transacties (standaard: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Stop uitvoeren na het importeren van blokken van de schijf (standaard: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Drempel om verbinding te verbreken naar zich misdragende peers (standaard: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_pam.ts b/src/qt/locale/bitcoin_pam.ts index 54c30dfb6f..4939dff4b0 100644 --- a/src/qt/locale/bitcoin_pam.ts +++ b/src/qt/locale/bitcoin_pam.ts @@ -1,7 +1,11 @@ -<TS language="pam" version="2.1"> +<TS language="pam" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>I-right click ban alilan ing address o libel</translation> + </message> + <message> <source>Create a new address</source> <translation>Maglalang kang bayung address</translation> </message> diff --git a/src/qt/locale/bitcoin_pl.ts b/src/qt/locale/bitcoin_pl.ts index db49e20cf1..5bc7df0aca 100644 --- a/src/qt/locale/bitcoin_pl.ts +++ b/src/qt/locale/bitcoin_pl.ts @@ -1,4 +1,4 @@ -<TS language="pl" version="2.1"> +<TS language="pl" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -168,6 +168,10 @@ <translation>Jesteś pewien, że chcesz zaszyfrować swój portfel?</translation> </message> <message> + <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>Program Bitcoin Core zamknie się, aby dokończyć proces szyfrowania. Pamiętaj, że szyfrowanie portfela nie zabezpiecza w pełni Twoich bitcoinów przed kradzieżą przez wirusy lub trojany mogące zainfekować Twój komputer.</translation> + </message> + <message> <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source> <translation>WAŻNE: Wszystkie wykonane wcześniej kopie pliku portfela powinny być zamienione na nowe, szyfrowane pliki. Z powodów bezpieczeństwa, poprzednie kopie nieszyfrowanych plików portfela staną się bezużyteczne jak tylko zaczniesz korzystać z nowego, szyfrowanego portfela.</translation> </message> @@ -184,6 +188,10 @@ <translation>Wprowadź nowe hasło do portfela.<br/>Proszę używać hasła złożonego z <b>10 lub więcej losowych znaków</b> lub <b>ośmiu lub więcej słów.</b></translation> </message> <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Podaj stare i nowe hasło do portfela.</translation> + </message> + <message> <source>Wallet encryption failed</source> <translation>Szyfrowanie portfela nie powiodło się</translation> </message> @@ -391,6 +399,10 @@ <translation>&O Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Zmień opcje konfiguracji dla Bitcoin Core</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Pokaż listę adresów i etykiet użytych do wysyłania</translation> </message> @@ -410,14 +422,34 @@ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> <translation>Pokaż pomoc Rdzenia Bitcoin, aby zobaczyć listę wszystkich opcji linii poleceń</translation> </message> + <message numerus="yes"> + <source>%n active connection(s) to Bitcoin network</source> + <translation><numerusform>%n aktywnych połączeń do sieci Bitcoin</numerusform><numerusform>%n aktywnych połączeń do sieci Bitcoin</numerusform><numerusform>%n aktywnych połączeń do sieci Bitcoin</numerusform></translation> + </message> <message> <source>No block source available...</source> <translation>Brak dostępnych źródeł bloków...</translation> </message> + <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Przetworzono %n bloków historii transakcji.</numerusform><numerusform>Przetworzono %n bloków historii transakcji.</numerusform><numerusform>Przetworzono %n bloków historii transakcji.</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n hour(s)</source> + <translation><numerusform>%n godzin</numerusform><numerusform>%n godzin</numerusform><numerusform>%n godzin</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n week(s)</source> + <translation><numerusform>%n tygodni</numerusform><numerusform>%n tygodni</numerusform><numerusform>%n tygodni</numerusform></translation> + </message> <message> <source>%1 and %2</source> <translation>%1 i %2</translation> </message> + <message numerus="yes"> + <source>%n year(s)</source> + <translation><numerusform>%n lat</numerusform><numerusform>%n lat</numerusform><numerusform>%n lat</numerusform></translation> + </message> <message> <source>%1 behind</source> <translation>%1 wstecz</translation> @@ -451,6 +483,36 @@ <translation>Synchronizuję się...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Data: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Kwota: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Typ: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Etykieta: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Adres: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Transakcja wysłana</translation> </message> @@ -649,6 +711,18 @@ <translation>żaden</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Ta etykieta staje się czerwona, kiedy transakcja jest większa niż 1000 bajtów.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Ta etykieta jest czerwona, jeżeli priorytet jest mniejszy niż "średni"</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Etykieta staje się czerwona kiedy którykolwiek odbiorca otrzymuje kwotę mniejszą niż %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Waha się +/- %1 satoshi na wejście.</translation> </message> @@ -832,7 +906,15 @@ <source>Error</source> <translation>Błąd</translation> </message> - </context> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n GB dostępnego wolnego miejsca</numerusform><numerusform>%n GB dostępnego wolnego miejsca</numerusform><numerusform>%n GB dostępnego wolnego miejsca</numerusform></translation> + </message> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(z %n GB potrzebnych)</numerusform><numerusform>(z %n GB potrzebnych)</numerusform><numerusform>(z %n GB potrzebnych)</numerusform></translation> + </message> +</context> <context> <name>OpenURIDialog</name> <message> @@ -891,6 +973,22 @@ <translation>Adres IP serwera proxy (np. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>Minimalizuje zamiast zakończyć działanie programu przy zamykaniu okna. Kiedy ta opcja jest włączona, program zakończy działanie po wybieraniu Zamknij w menu.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>Można tu ustawić język interfejsu uzytkownika. Żeby ustawienie przyniosło skutek trzeba uruchomić ponownie Bitcoin.</translation> + </message> + <message> + <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> + <translation>Zewnętrzne URL podglądu transakcji (np. eksplorator bloków), które będą wyświetlały się w menu kontekstowym, w zakładce transakcji. %s będzie zamieniany w adresie na hash transakcji. Oddziel wiele adresów pionową kreską |.</translation> + </message> + <message> + <source>Third party transaction URLs</source> + <translation>Zewnętrzny URL podglądu transakcji</translation> + </message> + <message> <source>Active command-line options that override above options:</source> <translation>Aktywne opcje linii komend, które nadpisują powyższe opcje:</translation> </message> @@ -907,6 +1005,14 @@ <translation>&Sieć</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Automatycznie uruchamia Bitcoin po zalogowaniu do systemu.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>Uruchamiaj Bitcoin wraz z zalogowaniem do &systemu</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = automatycznie, <0 = zostaw tyle wolnych rdzeni)</translation> </message> @@ -923,6 +1029,10 @@ <translation>Włącz funk&cje kontoli monet</translation> </message> <message> + <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source> + <translation>Jeżeli wyłączysz możliwość wydania niezatwierdzonej wydanej reszty, reszta z transakcji nie będzie mogła zostać wykorzystana, dopóki ta transakcja nie będzie miała przynajmniej jednego potwierdzenia. To także ma wpływ na obliczanie Twojego salda.</translation> + </message> + <message> <source>&Spend unconfirmed change</source> <translation>Wydaj niepotwierdzoną re&sztę</translation> </message> @@ -1015,6 +1125,10 @@ <translation>Wymagany restart programu, aby uaktywnić zmiany.</translation> </message> <message> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Program zostanie wyłączony. Czy chcesz kontynuować?</translation> + </message> + <message> <source>This change would require a client restart.</source> <translation>Ta zmiana może wymagać ponownego uruchomienia klienta.</translation> </message> @@ -1137,14 +1251,50 @@ <translation>URL pobrania żądania zapłaty jest nieprawidłowe: %1</translation> </message> <message> + <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source> + <translation>URI nie może zostać przetworzony! Może to być spowodowane nieprawidłowym adresem Bitcoin lub uszkodzonymi parametrami URI.</translation> + </message> + <message> + <source>Payment request file handling</source> + <translation>Przechwytywanie plików żądania płatności</translation> + </message> + <message> + <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source> + <translation>Plików żądania płatności nie może zostać odczytany. Mogło to być spowodowane nieprawidłowym plikiem żądania płatności.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Żądanie płatności upłynęło.</translation> + </message> + <message> + <source>Unverified payment requests to custom payment scripts are unsupported.</source> + <translation>Niezweryfikowane żądania płatności do własnych skryptów płatności są niewspierane.</translation> + </message> + <message> + <source>Invalid payment request.</source> + <translation>Nieprawidłowe żądanie płatności</translation> + </message> + <message> <source>Refund from %1</source> <translation>Zwrot z %1</translation> </message> <message> + <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source> + <translation>Żądanie płatności %1 jest zbyt duże (%2 bajtów, dozwolone %3 bajtów).</translation> + </message> + <message> + <source>Payment request DoS protection</source> + <translation>Zabezpieczenie żądania płatności przed atakiem DoS</translation> + </message> + <message> <source>Error communicating with %1: %2</source> <translation>Błąd komunikacji z %1 : %2</translation> </message> <message> + <source>Payment request cannot be parsed!</source> + <translation>Żądanie płatności nie może zostać przetworzone.</translation> + </message> + <message> <source>Bad response from server %1</source> <translation>Błędna odpowiedź z serwera %1</translation> </message> @@ -1160,6 +1310,14 @@ <context> <name>PeerTableModel</name> <message> + <source>User Agent</source> + <translation>Aplikacja kliencka</translation> + </message> + <message> + <source>Node/Service</source> + <translation>Węzeł/Usługi</translation> + </message> + <message> <source>Ping Time</source> <translation>Czas odpowiedzi</translation> </message> @@ -1281,6 +1439,10 @@ <translation>Aktualna liczba bloków</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Otwórz plik logowania debugowania Bitcoin Core z obecnego katalogu z danymi. Może to potrwać kilka sekund przy większych plikach.</translation> + </message> + <message> <source>Received</source> <translation>Otrzymane</translation> </message> @@ -1289,6 +1451,10 @@ <translation>Wysłane</translation> </message> <message> + <source>&Peers</source> + <translation>&Węzły</translation> + </message> + <message> <source>Select a peer to view detailed information.</source> <translation>Wybierz węzeł żeby zobaczyć szczegóły.</translation> </message> @@ -1301,6 +1467,10 @@ <translation>Wersja</translation> </message> <message> + <source>User Agent</source> + <translation>Aplikacja kliencka</translation> + </message> + <message> <source>Services</source> <translation>Usługi</translation> </message> @@ -1309,10 +1479,26 @@ <translation>Początkowa wysokość</translation> </message> <message> + <source>Sync Height</source> + <translation>Zsynchronizowana wysokość</translation> + </message> + <message> + <source>Ban Score</source> + <translation>Punkty karne</translation> + </message> + <message> <source>Connection Time</source> <translation>Czas połączenia</translation> </message> <message> + <source>Last Send</source> + <translation>Ostatnio wysłano</translation> + </message> + <message> + <source>Last Receive</source> + <translation>Ostatnio odebrano</translation> + </message> + <message> <source>Bytes Sent</source> <translation>Bajtów wysłano</translation> </message> @@ -1325,6 +1511,10 @@ <translation>Czas odpowiedzi</translation> </message> <message> + <source>Time Offset</source> + <translation>Przesunięcie czasu</translation> + </message> + <message> <source>Last block time</source> <translation>Czas ostatniego bloku</translation> </message> @@ -1369,6 +1559,10 @@ <translation>Wyczyść konsolę</translation> </message> <message> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Witaj w konsoli Bitcoin Core RPC.</translation> + </message> + <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Użyj strzałek do przewijania historii i <b>Ctrl-L</b> aby wyczyścić ekran</translation> </message> @@ -1436,6 +1630,10 @@ <translation>Użyj jednego z poprzednio użytych adresów odbiorczych. Podczas ponownego używania adresów występują problemy z bezpieczeństwem i prywatnością. Nie korzystaj z tej opcji, chyba że odtwarzasz żądanie płatności wykonane już wcześniej.</translation> </message> <message> + <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source> + <translation>Opcjonalna wiadomość do dołączenia do żądania płatności, która będzie wyświetlana, gdy żądanie zostanie otwarte. Uwaga: wiadomość ta nie zostanie wysłana wraz z płatnością w sieci Bitcoin.</translation> + </message> + <message> <source>An optional label to associate with the new receiving address.</source> <translation>Opcjonalna etykieta do skojarzenia z nowym adresem odbiorczym.</translation> </message> @@ -1653,6 +1851,22 @@ <translation>za kilobajt</translation> </message> <message> + <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> + <translation>Jeżeli własna opłata zostanie ustawiona na 1000 satoshi, a transakcja będzie miała tylko 250 bajtów, to "za kilobajt" płaci tylko 250 satoshi, podczas gdy, "razem przynajmniej" płaci 1000 satoshi. Przy transakcjach większych niż kilobajt, w obu przypadkach płaci za każdy kilobajt.</translation> + </message> + <message> + <source>Hide</source> + <translation>Ukryj</translation> + </message> + <message> + <source>total at least</source> + <translation>razem przynajmniej</translation> + </message> + <message> + <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source> + <translation>Zapłacenie tylko minimalnej opłaty jest nadal wystarczające, dopóki jest mniejszy wolumen transakcji niż miejsca w blokach. Należy jednak mieć świadomość, że może skończyć się to niezatwierdzeniem nigdy transakcji, gdy jest większe zapotrzebowanie na transakcje bitcoina niż sieć może przetworzyć.</translation> + </message> + <message> <source>(read the tooltip)</source> <translation>(przeczytaj podpowiedź)</translation> </message> @@ -1661,6 +1875,10 @@ <translation>Zalecane:</translation> </message> <message> + <source>Custom:</source> + <translation>Własna:</translation> + </message> + <message> <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source> <translation>(Sprytne opłaty nie są jeszcze zainicjowane. Trwa to zwykle kilka bloków...)</translation> </message> @@ -1781,10 +1999,30 @@ <translation>Transakcja została odrzucona! Może się to zdarzyć jeśli część monet z portfela została już wydana używając kopii pliku wallet.dat i nie zostało to tutaj uwzględnione.</translation> </message> <message> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>Opłata wyższa niż %1 jest uważana za szalenie wysoką.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Żądanie płatności upłynęło.</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Przybliżony czas zatwierdzenia: %n bloków.</numerusform><numerusform>Przybliżony czas zatwierdzenia: %n bloków.</numerusform><numerusform>Przybliżony czas zatwierdzenia: %n bloków.</numerusform></translation> + </message> + <message> <source>Pay only the minimum fee of %1</source> <translation>Płac tylko minimalna opłatę %1</translation> </message> <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Adres odbiorcy jest nieprawidłowy, proszę sprawić ponownie.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Znaleziono powtórzony adres, można wysłać tylko raz na każdy adres podczas jednej operacji wysyłania.</translation> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Ostrzeżenie: nieprawidłowy adres Bitcoin</translation> </message> @@ -1836,6 +2074,10 @@ <translation>To jest standardowa płatność</translation> </message> <message> + <source>The Bitcoin address to send the payment to</source> + <translation>Adres Bitcoin gdzie wysłać płatność</translation> + </message> + <message> <source>Alt+A</source> <translation>Alt+A</translation> </message> @@ -1852,14 +2094,34 @@ <translation>Usuń ten wpis</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>Opłata zostanie odjęta od kwoty wysyłane.Odbiorca otrzyma mniej niż bitcoins wpisz w polu kwoty. Jeśli wybrano kilku odbiorców, opłata jest podzielona równo.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>Odejmij od wysokości opłaty</translation> + </message> + <message> <source>Message:</source> <translation>Wiadomość:</translation> </message> <message> + <source>This is an unauthenticated payment request.</source> + <translation>To żądanie zapłaty nie zostało zweryfikowane.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>To żądanie zapłaty jest zweryfikowane.</translation> + </message> + <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>Wprowadź etykietę dla tego adresu by dodać go do listy użytych adresów</translation> </message> <message> + <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source> + <translation>Wiadomość, która została dołączona do URI bitcoin:, która będzie przechowywana wraz z transakcją w celach informacyjnych. Uwaga: Ta wiadomość nie będzie rozsyłana w sieci Bitcoin.</translation> + </message> + <message> <source>Pay To:</source> <translation>Wpłać do:</translation> </message> @@ -1890,6 +2152,14 @@ <translation>Podpi&sz Wiadomość</translation> </message> <message> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>Możesz podpisywać wiadomości swoimi adresami aby udowodnić, że jesteś ich właścicielem. Uważaj, aby nie podpisywać niczego co wzbudza Twoje podejrzenia, ponieważ ktoś może stosować phishing próbując nakłonić Cię do ich podpisania. Akceptuj i podpisuj tylko w pełni zrozumiałe komunikaty i wiadomości.</translation> + </message> + <message> + <source>The Bitcoin address to sign the message with</source> + <translation>Adres Bitcoin, za pomocą którego podpisać wiadomość</translation> + </message> + <message> <source>Choose previously used address</source> <translation>Wybierz wcześniej użyty adres</translation> </message> @@ -1938,6 +2208,10 @@ <translation>&Zweryfikuj wiadomość</translation> </message> <message> + <source>The Bitcoin address the message was signed with</source> + <translation>Adres Bitcoin, którym została podpisana wiadomość</translation> + </message> + <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> <translation>Zweryfikuj wiadomość, aby upewnić się, że została podpisana odpowiednim adresem Bitcoin.</translation> </message> @@ -2050,6 +2324,10 @@ <source>Status</source> <translation>Status</translation> </message> + <message numerus="yes"> + <source>, broadcast through %n node(s)</source> + <translation><numerusform>, przekazywany przez %n węzłów</numerusform><numerusform>, przekazywany przez %n węzłów</numerusform><numerusform>, przekazywany przez %n węzłów</numerusform></translation> + </message> <message> <source>Date</source> <translation>Data</translation> @@ -2075,6 +2353,10 @@ <translation>własny adres</translation> </message> <message> + <source>watch-only</source> + <translation>tylko-obserwowany</translation> + </message> + <message> <source>label</source> <translation>etykieta</translation> </message> @@ -2082,6 +2364,10 @@ <source>Credit</source> <translation>Przypisy</translation> </message> + <message numerus="yes"> + <source>matures in %n more block(s)</source> + <translation><numerusform>potwierdzona przy %n blokach więcej</numerusform><numerusform>potwierdzona przy %n blokach więcej</numerusform><numerusform>potwierdzona przy %n blokach więcej</numerusform></translation> + </message> <message> <source>not accepted</source> <translation>niezaakceptowane</translation> @@ -2091,6 +2377,14 @@ <translation>Debet</translation> </message> <message> + <source>Total debit</source> + <translation>Razem wychodzących</translation> + </message> + <message> + <source>Total credit</source> + <translation>Razem przychodzących</translation> + </message> + <message> <source>Transaction fee</source> <translation>Opłata transakcyjna</translation> </message> @@ -2146,6 +2440,10 @@ <source>, has not been successfully broadcast yet</source> <translation>, nie został jeszcze pomyślnie rozesłany</translation> </message> + <message numerus="yes"> + <source>Open for %n more block(s)</source> + <translation><numerusform>Otwórz dla %n następnych bloków</numerusform><numerusform>Otwórz dla %n następnych bloków</numerusform><numerusform>Otwórz dla %n następnych bloków</numerusform></translation> + </message> <message> <source>unknown</source> <translation>nieznany</translation> @@ -2176,6 +2474,10 @@ <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Niedojrzała (%1 potwierdzeń, będzie dostępna po %2)</translation> </message> + <message numerus="yes"> + <source>Open for %n more block(s)</source> + <translation><numerusform>Otwórz dla %n następnych bloków</numerusform><numerusform>Otwórz dla %n następnych bloków</numerusform><numerusform>Otwórz dla %n następnych bloków</numerusform></translation> + </message> <message> <source>Open until %1</source> <translation>Otwórz do %1</translation> @@ -2233,6 +2535,10 @@ <translation>Wydobyto</translation> </message> <message> + <source>watch-only</source> + <translation>tylko-obserwowany</translation> + </message> + <message> <source>(n/a)</source> <translation>(brak)</translation> </message> @@ -2249,6 +2555,14 @@ <translation>Rodzaj transakcji.</translation> </message> <message> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <translation>Czy adres tylko-obserwowany jest lub nie użyty w tej transakcji.</translation> + </message> + <message> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Zdefiniowana przez użytkownika intencja/cel transakcji.</translation> + </message> + <message> <source>Amount removed from or added to balance.</source> <translation>Kwota usunięta z lub dodana do konta.</translation> </message> @@ -2340,6 +2654,10 @@ <translation>Eksport historii transakcji</translation> </message> <message> + <source>Watch-only</source> + <translation>Tylko obserwowany</translation> + </message> + <message> <source>Exporting Failed</source> <translation>Błąd przy próbie eksportu</translation> </message> @@ -2487,6 +2805,14 @@ <translation>Skojarz z podanym adresem i nasłuchuj na nim. Użyj formatu [host]:port dla IPv6</translation> </message> <message> + <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> + <translation>Usuwa wszystkie transakcje w portfelu i tylko odtwarza te części z łańcucha bloków poprzez -rescan przy starcie</translation> + </message> + <message> + <source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> + <translation>Rozprowadzane na licencji MIT, zobacz dołączony plik COPYING lub <http://www.opensource.org/licenses/mit-license.php>.</translation> + </message> + <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Wykonaj polecenie, kiedy transakcja portfela ulegnie zmianie (%s w poleceniu zostanie zastąpione przez TxID)</translation> </message> @@ -2523,6 +2849,10 @@ <translation>Ostrzeżenie: Odtworzono dane z uszkodzonego pliku wallet.dat! Oryginalny wallet.dat został zapisany jako wallet.{timestamp}.bak w %s; jeśli twoje saldo lub transakcje są niepoprawne powinieneś odtworzyć kopię zapasową.</translation> </message> <message> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>Dodawaj do białej listy węzły łączące się z podanej maski sieciowej lub adresu IP. Może być określona kilka razy.</translation> + </message> + <message> <source>(default: 1)</source> <translation>(domyślnie: 1)</translation> </message> @@ -2591,6 +2921,10 @@ <translation>Próba nasłuchiwania na jakimkolwiek porcie nie powiodła się. Użyj -listen=0 jeśli tego chcesz.</translation> </message> <message> + <source>If <category> is not supplied, output all debugging information.</source> + <translation>Jeżeli <category> nie zostanie określona, wyświetl wszystkie informacje debugowania.</translation> + </message> + <message> <source>Importing...</source> <translation>Importowanie…</translation> </message> @@ -2611,6 +2945,10 @@ <translation>Łącz z węzłami tylko w sieci <net> (ipv4, piv6 lub onion)</translation> </message> <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>Tryb ograniczony jest niekompatybilny z -txindex.</translation> + </message> + <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation>Ustaw wielkość pamięci podręcznej w megabajtach (%d do %d, domyślnie: %d)</translation> </message> @@ -2623,10 +2961,6 @@ <translation>Określ plik portfela (w obrębie folderu danych)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Jest to przeznaczone dla narzędzi testowania regresji i rozwoju aplikacji.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Użyj UPnP do przekazania portu nasłuchu (domyślnie : %u)</translation> </message> @@ -2647,6 +2981,10 @@ <translation>Opcje portfela:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Uwaga: Ta wersja jest przestarzała, wymagana jest aktualizacja!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Musisz przebudować bazę używając parametru -reindex aby zmienić -txindex</translation> </message> @@ -2663,10 +3001,22 @@ <translation>Napotkano błąd podczas ustawiania adres RPC %s port %u dla nasłuchiwania: %s</translation> </message> <message> + <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> + <translation>Podepnij się do podanego adresu i dodawaj do białej listy węzły łączące się z nim. Użyj notacji [host]:port dla IPv6</translation> + </message> + <message> + <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source> + <translation>Powiąż się z podanym adresem, aby nasłuchiwać połączenia JSON-RPC. Użyj notacji [host]:port dla IPv6. Ta opcja może być określona kilka razy (domyślnie: powiąż ze wszystkimi interfejsami)</translation> + </message> + <message> <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> <translation>Nie można uzyskać blokady na katalogu z danymi %s. Rdzeń Bitcoin najprawdopodobniej jest już uruchomiony.</translation> </message> <message> + <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> + <translation>Twórz nowe pliki z domyślnymi dla systemu uprawnieniami, zamiast umask 077 (skuteczne tylko przy wyłączonej funkcjonalności portfela)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Błąd: Nasłuchiwanie połączeń przychodzących nie powiodło się (nasłuch zwrócił błąd %s)</translation> </message> @@ -2679,6 +3029,18 @@ <translation>Uruchom polecenie przy otrzymaniu odpowiedniego powiadomienia lub gdy zobaczymy naprawdę długie rozgałęzienie (%s w poleceniu jest podstawiane za komunikat)</translation> </message> <message> + <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> + <translation>Opłaty (w BTC/Kb) mniejsze niż ta będą traktowane jako bez opłaty przy propagowaniu (domyślnie: %s)</translation> + </message> + <message> + <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> + <translation>Jeżeli nie ustawiono paytxfee, dołącz wystarczająca opłatę, aby transakcja mogła zostać zatwierdzona w ciągu średniej ilości n bloków (domyślnie: %u)</translation> + </message> + <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source> + <translation>Niewłaściwa ilość dla -maxtxfee=<ilość>: '%s' (musi wynosić przynajmniej minimalną wielkość %s aby zapobiec utknięciu transakcji)</translation> + </message> + <message> <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> <translation>Maksymalny rozmiar danych w transakcji przekazującej dane które przekazujemy i wydobywamy (domyślnie: %u)</translation> </message> @@ -2695,14 +3057,70 @@ <translation>Ustaw liczbę wątków dla generowania monet (-1 = wszystkie rdzenie, domyślnie: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>Zbyt niska kwota transakcji do wysłania po odjęciu opłaty</translation> + </message> + <message> <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source> <translation>Program ten zawiera oprogramowanie stworzone przez OpenSSL Project do użycia w OpensSSL Toolkit <https://www.openssl.org/>, oprogramowanie kryptograficzne napisane przez Eric Young oraz oprogramowanie UPnP napisane przez Thomas Bernard.</translation> </message> <message> + <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: +%s +It is recommended you use the following random password: +rpcuser=bitcoinrpc +rpcpassword=%s +(you do not need to remember this password) +The username and password MUST NOT be the same. +If the file does not exist, create it with owner-readable-only file permissions. +It is also recommended to set alertnotify so you are notified of problems; +for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com +</source> + <translation>Aby korzystać z bitcoind, lub opcji -server w bitcoin-qt, musisz ustawić opcję rpcpassword w pliku konfiguracyjnym: +%s +Zalecane jest użycie poniższego losowego hasła: +rpcuser=bitcoinrpc +rpcpassword=%s +(nie musisz pamiętać tego hasła) +Nazwa użytkownika i hasło NIE MOGĄ być takie same. +Jeżeli ten plik nie istnieje, utwórz go z uprawnieniami tylko-do-odczytu przez właściciela. +Zalecane jest także ustawienie opcji alertnotify, dzięki której będziesz powiadamiany o problemach; +na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com +</translation> + </message> + <message> <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> <translation>Ostrzeżenie: -matxfee jest ustawione bardzo wysokie! Tak wysokie opłaty mogą być zapłacone w jednej transakcji.</translation> </message> <message> + <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>Ostrzeżenie: Proszę sprawdzić czy data i czas na Twoim komputerze są poprawne! Jeżeli ustawienia zegara będą złe, Bitcoin Core nie będzie działał prawidłowo.</translation> + </message> + <message> + <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source> + <translation>Węzły z białej listy nie mogą zostać zbanowane za ataki DoS, a ich transakcje będą zawsze przekazywane, nawet jeżeli będą znajdywać się już w pamięci, przydatne np. dla bramek płatniczych</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(domyślnie: %u)</translation> + </message> + <message> + <source>Accept public REST requests (default: %u)</source> + <translation>Akceptuj publiczne żądania REST (domyślnie: %u)</translation> + </message> + <message> + <source>Activating best chain...</source> + <translation>Aktywuje najlepszy łańcuch</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>Nie można uruchomić z portfela w trybie ograniczonym.</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Nie można rozwiązać adresu -whitebind: '%s'</translation> + </message> + <message> <source>Choose data directory on startup (default: 0)</source> <translation>Wybierz folder danych przy starcie (domyślnie: 0)</translation> </message> @@ -2715,6 +3133,10 @@ <translation>Copyright (C) 2009-%i The Bitcoin Core Developers</translation> </message> <message> + <source>Could not parse -rpcbind value %s as network address</source> + <translation>Nie można przetworzyć wartości -rpcbind %s jako adresu sieciowego</translation> + </message> + <message> <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> <translation>Błąd ładowania wallet.dat: Portfel wymaga nowszej wersji Bitcoin Core</translation> </message> @@ -2755,6 +3177,14 @@ <translation>Nieprawidłowa kwota dla -paytxfee=<amount>: '%s' (musi być co najmniej %s)</translation> </message> <message> + <source>Invalid netmask specified in -whitelist: '%s'</source> + <translation>Nieprawidłowa maska sieci określona w -whitelist: '%s'</translation> + </message> + <message> + <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> + <translation>Przechowuj w pamięci maksymalnie <n> transakcji nie możliwych do połączenia (domyślnie: %u)</translation> + </message> + <message> <source>Node relay options:</source> <translation>Opcje przekaźnikowe węzła:</translation> </message> @@ -2767,12 +3197,16 @@ <translation>Opcje serwera RPC:</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Losowo ignoruje 1 z każdych <n> wiadomości sieciowych.</translation> + <source>RPC support for HTTP persistent connections (default: %d)</source> + <translation>Wsparcie RPC dla ciągłych połączeń HTTP (domyślnie: %d)</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Losowo miesza 1 z wszystkich <n> wiadomości sieciowych.</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Odbuduj indeks łańcucha bloków z obecnych plików blk000??.dat podczas ponownego uruchomienia</translation> + </message> + <message> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Odbieranie i wyświetlanie alertów sieci P2P (domyślnie: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -2811,6 +3245,10 @@ <translation>Uruchom zminimalizowany</translation> </message> <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>Zbyt niska kwota transakcji by zapłacić opłatę</translation> + </message> + <message> <source>This is experimental software.</source> <translation>To oprogramowanie eksperymentalne.</translation> </message> @@ -2831,6 +3269,10 @@ <translation>Transakcja zbyt duża</translation> </message> <message> + <source>UI Options:</source> + <translation>Opcje UI</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Nie można przywiązać do %s na tym komputerze (bind zwrócił błąd %s)</translation> </message> @@ -2915,10 +3357,6 @@ <translation>Jak dokładna jest weryfikacja bloków przy -checkblocks (0-4, domyślnie: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Loguj priorytety transakcji i opłaty na kB podczas kopania bloków (domyślnie: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Utrzymuj pełny indeks transakcji, używany przy wywołaniu RPC getrawtransaction (domyślnie: %u)</translation> </message> @@ -2927,16 +3365,28 @@ <translation>Czas w sekundach, przez jaki nietrzymające się zasad węzły nie będą mogły ponownie się podłączyć (domyślnie: %u)</translation> </message> <message> + <source>Output debugging information (default: %u, supplying <category> is optional)</source> + <translation>Wypuść informacje debugowania (domyślnie: %u, podanie <category> jest opcjonalne)</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation>Użyj oddzielnego prozy SOCKS5 aby osiągnąć węzły w ukrytych usługach Tor (domyślnie: %s)</translation> + </message> + <message> <source>(default: %s)</source> <translation>(domyślnie: %s)</translation> </message> <message> - <source>Error loading wallet.dat</source> - <translation>Błąd ładowania wallet.dat</translation> + <source>Acceptable ciphers (default: %s)</source> + <translation>Akceptowane szyfry (domyślne: %s)</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Wymuś tryb bezpieczny (domyślnie: %u)</translation> + <source>Always query for peer addresses via DNS lookup (default: %u)</source> + <translation>Zawsze wypytuj o adresy węzłów poprzez podejrzenie DNS (domyślnie: %u)</translation> + </message> + <message> + <source>Error loading wallet.dat</source> + <translation>Błąd ładowania wallet.dat</translation> </message> <message> <source>Generate coins (default: %u)</source> @@ -2955,10 +3405,6 @@ <translation>Nieprawidłowy adres -proxy: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Ogranicz rozmiar pamięci podręcznej sygnatur do <n> wpisów (domyślnie: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Nasłuchuj połączeń JSON-RPC na <port> (domyślnie: %u lub testnet: %u)</translation> </message> @@ -2971,6 +3417,10 @@ <translation>Utrzymuj maksymalnie <n> połączeń z węzłami (domyślnie: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Spraw by portfel dokonał transmisji transakcji</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Maksymalny bufor odbioru na połączenie, <n>*1000 bajtów (domyślnie: %u)</translation> </message> @@ -2979,10 +3429,6 @@ <translation>Maksymalny bufor wysyłania na połączenie, <n>*1000 bajtów (domyślnie: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Akceptuj tylko łańcuch bloków zgodny z wbudowanymi punktami kontrolnymi (domyślnie: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Dołączaj znacznik czasu do logowania (domyślnie: %u)</translation> </message> @@ -2995,10 +3441,6 @@ <translation>Przekazuj transakcje multisig inne niż P2SH (domyślnie: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Uruchom wątek do okresowego zapisywania portfela (domyślnie: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Plik certyfikatu serwera (domyślnie: %s)</translation> </message> @@ -3019,10 +3461,6 @@ <translation>Ustaw liczbę wątków do obsługi RPC (domyślnie: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Ustaw flagę DB_PRIVATE w środowisku wallet db (domyślnie: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Wskaż plik konfiguracyjny (domyślnie: %s)</translation> </message> @@ -3039,10 +3477,6 @@ <translation>Wydawaj niepotwierdzoną resztę podczas wysyłania transakcji (domyślnie: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Zatrzymaj po zaimportowaniu bloków z dysku (domyślnie: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Próg, po którym nastąpi rozłączenie węzłów nietrzymających się zasad (domyślnie: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts index 42a781de99..cd2a5a6323 100644 --- a/src/qt/locale/bitcoin_pt_BR.ts +++ b/src/qt/locale/bitcoin_pt_BR.ts @@ -1,4 +1,4 @@ -<TS language="pt_BR" version="2.1"> +<TS language="pt_BR" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -67,7 +67,7 @@ </message> <message> <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> - <translation>Estes são os seus endereços Bitcoin para receber pagamentos. Você pode querer enviar um endereço diferente para cada remetente, para acompanhar quem está pagando.</translation> + <translation>Esses são seus endereços Bitcoin para enviar pagamentos. Certifique-se sempre da quantia e do destinatário antes de enviar moedas.</translation> </message> <message> <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> @@ -276,7 +276,7 @@ </message> <message> <source>&Backup Wallet...</source> - <translation>&Backup Carteira...</translation> + <translation>&Backup da carteira...</translation> </message> <message> <source>&Change Passphrase...</source> @@ -288,7 +288,7 @@ </message> <message> <source>&Receiving addresses...</source> - <translation>Endereços de &Recebimento...</translation> + <translation>Endereços de &recebimento...</translation> </message> <message> <source>Open &URI...</source> @@ -1831,6 +1831,10 @@ <translation>Escolher</translation> </message> <message> + <source>collapse fee-settings</source> + <translation>colapso Taxa de definições</translation> + </message> + <message> <source>per kilobyte</source> <translation>por kilobyte</translation> </message> @@ -2078,6 +2082,10 @@ <translation>Remover esta entrada</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>A taxa será deduzida da quantia sendo enviada. O beneficiario receberá menos bitcoins do que você colocou no campo de quantidade. Se varios beneficiarios estão selecionados, a taxa é dividida igualmente.</translation> + </message> + <message> <source>S&ubtract fee from amount</source> <translation>&Retirar taxa da quantia</translation> </message> @@ -2086,6 +2094,14 @@ <translation>Mensagem:</translation> </message> <message> + <source>This is an unauthenticated payment request.</source> + <translation>Esta é uma cobrança não autenticada.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Esta é uma cobrança autenticada.</translation> + </message> + <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>Digite um rótulo para este endereço para adicioná-lo no catálogo</translation> </message> @@ -2110,7 +2126,7 @@ </message> <message> <source>Do not shut down the computer until this window disappears.</source> - <translation>Não desligue o computador até esta janela desapareça.</translation> + <translation>Não desligue o computador até que esta janela desapareça.</translation> </message> </context> <context> @@ -2523,6 +2539,10 @@ <translation>Tipo de transação.</translation> </message> <message> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <translation>Mostrar ou não endereços Bitcoin na lista de transações.</translation> + </message> + <message> <source>Amount removed from or added to balance.</source> <translation>Quantidade debitada ou creditada ao saldo.</translation> </message> @@ -2734,7 +2754,7 @@ </message> <message> <source>Specify data directory</source> - <translation>Especificar diretório de dados</translation> + <translation>Especificar o diretório de dados</translation> </message> <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> @@ -2773,16 +2793,12 @@ <translation>Distribuido sob a licença MIT software license. Veja os termos em <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Entra no modo de teste de regressão, que usa uma cadeia especial onde os blocos podem ser resolvidos instantaneamente.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> - <translation>Executar comando quando uma transação da carteira mudar (%s no comando será substituído por TxID)</translation> + <translation>Executa um comando quando uma transação da carteira mudar (%s no comando será substituído por TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>Neste modo -genproclimit controla quantos blocos são gerados imediatamente.</translation> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>Reduz o armazenamento requerido prunando (apagando) blocos antigos. Este modo desativa o suporte a carteira e é incompatível com -txindex. Aviso: Reverter essa opção requer re-baixar o blockchain inteiro. (padrão: 0 = disativado, >%u = Tamanho em mega para os arquivos de bloco)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2817,6 +2833,10 @@ <translation>Atenção: wallet.dat corrompido, dados recuperados! Arquivo wallet.dat original salvo como wallet.{timestamp}.bak em %s; se seu saldo ou transações estiverem incorretos, você deve restaurar o backup.</translation> </message> <message> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>Lista Branca pares de ligação da máscara de rede dado ou o endereço IP . Pode ser especificado várias vezes.</translation> + </message> + <message> <source>(default: 1)</source> <translation>(padrão: 1)</translation> </message> @@ -2834,7 +2854,7 @@ </message> <message> <source>Connect only to the specified node(s)</source> - <translation>Conectar apenas a nó(s) específico(s)</translation> + <translation>Conectar apenas a cliente(s) específico(s)</translation> </message> <message> <source>Connection options:</source> @@ -2909,6 +2929,14 @@ <translation>Somente conectar a clientes na rede <net> (ipv4, ipv6 ou onion)</translation> </message> <message> + <source>Prune cannot be configured with a negative value.</source> + <translation>O modo Prune não pode ser configurado com um valor negativo.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>O modo Prune é incompatível com -txindex.</translation> + </message> + <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation>Define o tamanho do cache do banco de dados em megabytes (%d para %d, padrão: %d)</translation> </message> @@ -2921,10 +2949,6 @@ <translation>Especifique o arquivo da carteira (dentro do diretório de dados)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Isso é usado para testes de regressão e ferramentas de desenvolvimento.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Use UPnP para mapear a porta de entrada (padrão: %u)</translation> </message> @@ -2965,24 +2989,32 @@ <translation>Um erro ocorreu enquanto configurando o endereço RPC %s porta %u para escuta: %s</translation> </message> <message> + <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> + <translation>Vincular ao endereço fornecido e sempre escutar nele. Use a notação [host]:port para IPv6</translation> + </message> + <message> <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> <translation>Não foi possível obter acesso exclusivo ao diretório de dados %s. Provavelmente Bitcoin já está sendo executado.</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Descobrir o próprio IP (padrão: 1 enquanto aguardando conexões e sem -externalip ou -proxy)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Erro: Aceitar conexões de entrada falhou (retornou erro %s)</translation> </message> <message> <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source> - <translation>Executa o comando quando um alerta relevante é recebido ou vemos uma longa segregação (%s em cmd é substituído pela mensagem)</translation> + <translation>Executa um comando quando um alerta relevante é recebido ou vemos uma longa segregação (%s em cmd é substituído pela mensagem)</translation> </message> <message> <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> <translation>Taxas (em BTC/Kb) menores do que este valor são consideradas inexistentes para divulgação (padrão: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Taxas (em BTC/Kb) menores do que este valor são consideradas inexistentes para a criação da transação (padrão: %s)</translation> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>Prunagem configurada abaixo do mínimo de %d MB. Use um número maior.</translation> </message> <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> @@ -3013,10 +3045,18 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br </translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>Você precisa reconstruir o banco de dados usando -reindex para sair do modo prune. Isso irá rebaixar todo o blockchain.</translation> + </message> + <message> <source>(default: %u)</source> <translation>(padrão: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>Ativando a melhor sequência...</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Impossível resolver endereço -whitebind: '%s'</translation> </message> @@ -3081,6 +3121,10 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>Necessário informar uma porta com -whitebind: '%s'</translation> </message> <message> + <source>Node relay options:</source> + <translation>Opções de relé nó :</translation> + </message> + <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>Opções RPC SSL: (veja o Bitcoin Wiki para instruções de configuração SSL)</translation> </message> @@ -3089,14 +3133,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>Opções do servidor RPC:</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Aleatoriamente descarta 1 em cada <n> mensagens da rede</translation> - </message> - <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Aleatoriamente embaralha 1 em cada <n> mensagens da rede</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Mandar informação de trace/debug para o console em vez de para o arquivo debug.log</translation> </message> @@ -3194,7 +3230,7 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br </message> <message> <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source> - <translation>Executar comando quando o melhor bloco mudar (%s no comando será substituído pelo hash do bloco)</translation> + <translation>Executa um comando quando o melhor bloco mudar (%s no comando será substituído pelo hash do bloco)</translation> </message> <message> <source>Upgrade wallet to latest format</source> @@ -3210,7 +3246,7 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br </message> <message> <source>This help message</source> - <translation>Esta mensagem de ajuda</translation> + <translation>Exibe esta mensagem de ajuda</translation> </message> <message> <source>Allow DNS lookups for -addnode, -seednode and -connect</source> @@ -3229,18 +3265,22 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>(padrão: %s)</translation> </message> <message> - <source>Error loading wallet.dat</source> - <translation>Erro ao carregar wallet.dat</translation> + <source>Acceptable ciphers (default: %s)</source> + <translation>Cífras aceitas (padrão: %s)</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Forçar modo seguro (default: %u)</translation> + <source>Error loading wallet.dat</source> + <translation>Erro ao carregar wallet.dat</translation> </message> <message> <source>Generate coins (default: %u)</source> <translation>Gerar moedas (padrão: %u)</translation> </message> <message> + <source>How many blocks to check at startup (default: %u, 0 = all)</source> + <translation>Quantos blocos devem ser checados ao iniciar (padrão: %u, 0 = todos)</translation> + </message> + <message> <source>Include IP addresses in debug output (default: %u)</source> <translation>Incluir endereço IP na saída de depuração (padrão: %u)</translation> </message> @@ -3249,14 +3289,18 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>Endereço -proxy inválido: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Tamanho limite do cache de assinaturas de <n> entradas (padrão: %u)</translation> - </message> - <message> <source>Listen for connections on <port> (default: %u or testnet: %u)</source> <translation>Aguardar por conexões na porta <port> (padrão: %u ou testnet: %u)</translation> </message> <message> + <source>Prepend debug output with timestamp (default: %u)</source> + <translation>Adiciona timestamp como prefixo no debug (default: %u)</translation> + </message> + <message> + <source>Relay non-P2SH multisig (default: %u)</source> + <translation>Retransmitir P2SH não multisig (default: %u)</translation> + </message> + <message> <source>Server certificate file (default: %s)</source> <translation>Arquivo de certificado do servidor (padrão: %s)</translation> </message> @@ -3265,6 +3309,18 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>Chave privada do servidor (padrão: %s)</translation> </message> <message> + <source>Set minimum block size in bytes (default: %u)</source> + <translation>Definir tamanho mínimo do bloco, em bytes (padrão: %u)</translation> + </message> + <message> + <source>Specify configuration file (default: %s)</source> + <translation>Especificar arquivo de configuração (padrão: %s)</translation> + </message> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Especificar tempo para desistência de conexões, em mili segundos (mínimo: 1, padrão: %d)</translation> + </message> + <message> <source>Specify pid file (default: %s)</source> <translation>Especificar aqrquivo pid (default: %s)</translation> </message> @@ -3294,7 +3350,7 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br </message> <message> <source>Add a node to connect to and attempt to keep the connection open</source> - <translation>Adicionar um nó com o qual se conectar e tentar manter a conexão ativa</translation> + <translation>Adicionar um cliente para se conectar e tentar manter a conexão ativa</translation> </message> <message> <source>Loading wallet...</source> diff --git a/src/qt/locale/bitcoin_pt_PT.ts b/src/qt/locale/bitcoin_pt_PT.ts index 5012ff8d83..7ac0a4fa5c 100644 --- a/src/qt/locale/bitcoin_pt_PT.ts +++ b/src/qt/locale/bitcoin_pt_PT.ts @@ -1,4 +1,4 @@ -<TS language="pt_PT" version="2.1"> +<TS language="pt_PT" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -168,6 +168,10 @@ <translation>Tem a certeza que deseja encriptar a carteira?</translation> </message> <message> + <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>O cliente Bitcoin Core irá agora ser fechado para terminar o processo de encriptação. Recorde que a encriptação da sua carteira não protegerá totalmente os seus bitcoins de serem roubados por programas maliciosos que infectem o seu computador.</translation> + </message> + <message> <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source> <translation>IMPORTANTE: Qualquer cópia de segurança da carteira anterior deverá ser substituída com o novo ficheiro de carteira, agora encriptado. Por razões de segurança, cópias de segurança não encriptadas tornar-se-ão inúteis assim que começar a usar a nova carteira encriptada.</translation> </message> @@ -184,6 +188,10 @@ <translation>Escreva a nova frase de seguraça da sua carteira. <br/> Por favor, use uma frase de <b>10 ou mais caracteres aleatórios,</b> ou <b>oito ou mais palavras</b>.</translation> </message> <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Escreva a antiga frase de segurança da carteira, seguida da nova.</translation> + </message> + <message> <source>Wallet encryption failed</source> <translation>A encriptação da carteira falhou</translation> </message> @@ -391,6 +399,10 @@ <translation>&Sobre o Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Modificar opções de configuração de Bitcoin Core</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Mostrar a lista de rótulos e endereços de envio usados</translation> </message> @@ -419,6 +431,10 @@ <translation>Nenhuma fonte de blocos disponível...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Processado %n bloco do histórico de transações.</numerusform><numerusform>Processados %n blocos do histórico de transações.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n hora</numerusform><numerusform>%n horas</numerusform></translation> </message> @@ -471,6 +487,36 @@ <translation>Recuperando o atraso...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Data: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Quantia: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Tipo: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Rótulo: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Endereço: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Transação enviada</translation> </message> @@ -669,6 +715,18 @@ <translation>nenhum</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Este rótulo fica vermelho se o tamanho da transacção exceder os 1000 bytes.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Esta legenda fica vermelha se a prioridade for menor que "média".</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Este rótulo fica vermelho se algum recipiente receber uma quantia menor que %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Pode variar +/- %1 satoshi(s) por entrada</translation> </message> @@ -919,6 +977,14 @@ <translation>Endereço IP do proxy (p.ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>Minimize ao invés de sair da aplicação quando a janela é fechada. Com esta opção selecionada, a aplicação apenas será encerrada quando escolher Sair da aplicação no menú.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>A linguagem da interface do utilizador pode ser definida aqui. Esta definição entrará em efeito após reiniciar o Bitcoin Core.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>URLs de outrem (ex. um explorador de blocos) que aparece no separador de transações como itens do menu de contexto. %s do URL é substituído por hash de transação. Vários URLs são separados por barra vertical |.</translation> @@ -944,6 +1010,14 @@ <translation>&Rede</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Começar o Bitcoin Core automaticamente ao iniciar sessão no sistema.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Começar o Bitcoin Core ao iniciar o sistema</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = auto, <0 = Deixar essa quantidade de núcleos livre)</translation> </message> @@ -1056,6 +1130,10 @@ <translation>É necessário reiniciar o cliente para ativar as alterações.</translation> </message> <message> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>O cliente será desligado. Deseja continuar?</translation> + </message> + <message> <source>This change would require a client restart.</source> <translation>Esta alteração requer um reinício do cliente.</translation> </message> @@ -1190,10 +1268,18 @@ <translation>O ficheiro de pedido de pagamento não pôde ser lido! Isto pode ter sido causado por um ficheiro de pedido de pagamento inválido.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Pedido de pagamento expirou.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Pedidos de pagamento não-verificados para scripts de pagamento personalizados não são suportados.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Pedido de pagamento inválido.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Reembolsar de %1</translation> </message> @@ -1233,6 +1319,10 @@ <translation>Agente Usuário</translation> </message> <message> + <source>Node/Service</source> + <translation>Nó/Serviço</translation> + </message> + <message> <source>Ping Time</source> <translation>Tempo de Latência</translation> </message> @@ -1466,6 +1556,10 @@ <translation>Limpar consola</translation> </message> <message> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Bem-vindo à consola RPC do Bitcoin Core.</translation> + </message> + <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Use as setas para cima e para baixo para navegar no histórico e <b>Ctrl-L</b> para limpar o ecrã.</translation> </message> @@ -1762,6 +1856,10 @@ <translation>Se a taxa fixa for 1000 satoshis e a transação for somente 250 bytes, pagará somente 250 satoshis "por kilobyte" em custos se trasacionar "pelo menos" 1000 satoshis. Transações superiores a um kilobyte são cobradas por kilobyte.</translation> </message> <message> + <source>Hide</source> + <translation>Esconder</translation> + </message> + <message> <source>total at least</source> <translation>total minimo</translation> </message> @@ -1902,6 +2000,10 @@ <translation>A transação foi rejeitada! Isto poderá acontecer se algumas das moedas na sua carteira já tiverem sido gastas, se por exemplo tiver usado uma cópia do ficheiro wallet.dat e as moedas tiverem sido gastas na cópia mas não tiverem sido marcadas como gastas aqui.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Pedido de pagamento expirou.</translation> + </message> + <message> <source>Pay only the minimum fee of %1</source> <translation>Pagar somente a taxa minima de %1</translation> </message> @@ -2672,18 +2774,10 @@ <translation>Distribuido através da licença de software MIT, verifique o ficheiro anexado COPYING ou <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Entre no modo de teste de regressão, que usa uma cadeia especial cujos blocos podem ser resolvidos instantaneamente.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Executar comando quando uma das transações na carteira mudar (no comando, %s é substituído pelo ID da Transação)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>O modo -genproclimit controla quantos blocos são generados imediatamente.</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation>Defina o número de processos de verificação (%u até %d, 0 = automático, <0 = ldisponibiliza esse número de núcleos livres, por defeito: %d)</translation> </message> @@ -2824,10 +2918,6 @@ <translation>Especifique ficheiro de carteira (dentro da pasta de dados)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Isto têm como fim a realização de testes de regressão para pools e desenvolvimento de aplicações.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Use UPnP para mapear a porto de escuta (default: %u)</translation> </message> @@ -2848,6 +2938,10 @@ <translation>Opções da carteira:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Aviso: Esta versão está desatualizada; atualização necessária!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>É necessário reconstruir as bases de dados usando -reindex para mudar o -txindex</translation> </message> @@ -2880,10 +2974,26 @@ <translation>Definir tamanho máximo de transações com alta-prioridade/baixa-taxa em bytes (por defeito: %d)</translation> </message> <message> + <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>Atenção: Por favor verifique que a data e hora do seu computador estão correctas! Se o seu relógio não estiver certo o Bitcoin Core não irá funcionar correctamente.</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(por defeito: %u)</translation> + </message> + <message> <source>Choose data directory on startup (default: 0)</source> <translation>Escolha a pasta de dados ao iniciar (por defeito: 0)</translation> </message> <message> + <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source> + <translation>Copyright (C) 2009-%i Os Programadores do Bitcoin Core</translation> + </message> + <message> + <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> + <translation>Erro ao carregar wallet.dat: A Carteira requer uma versão mais recente do Bitcoin Core</translation> + </message> + <message> <source>Information</source> <translation>Informação</translation> </message> @@ -2944,6 +3054,10 @@ <translation>Nome de utilizador para ligações JSON-RPC</translation> </message> <message> + <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source> + <translation>A Carteira precisou de ser reescrita: reinicie o Bitcoin Core para completar o processo</translation> + </message> + <message> <source>Warning</source> <translation>Aviso</translation> </message> @@ -3000,6 +3114,58 @@ <translation>Endereço -proxy inválido: '%s'</translation> </message> <message> + <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> + <translation>Escutar por ligações JSON-RPC na porta <port> (por defeito: %u ou rede de testes: %u)</translation> + </message> + <message> + <source>Listen for connections on <port> (default: %u or testnet: %u)</source> + <translation>Escute ligações na porta <port> (por defeito: %u ou testnet: %u)</translation> + </message> + <message> + <source>Maintain at most <n> connections to peers (default: %u)</source> + <translation>Manter no máximo <n> ligações a outros nós da rede (por defeito: %u)</translation> + </message> + <message> + <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> + <translation>Maximo armazenamento intermédio de recepção por ligação, <n>*1000 bytes (por defeito: %u)</translation> + </message> + <message> + <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source> + <translation>Maximo armazenamento intermédio de envio por ligação, <n>*1000 bytes (por defeito: %u)</translation> + </message> + <message> + <source>Prepend debug output with timestamp (default: %u)</source> + <translation>Adicionar data e hora à informação de depuração (por defeito: %u)</translation> + </message> + <message> + <source>Server certificate file (default: %s)</source> + <translation>Ficheiro de certificado do servidor (por defeito: %s)</translation> + </message> + <message> + <source>Server private key (default: %s)</source> + <translation>Chave privada do servidor (por defeito: %s)</translation> + </message> + <message> + <source>Set key pool size to <n> (default: %u)</source> + <translation>Definir o tamanho da memória de chaves para <n> (por defeito: %u)</translation> + </message> + <message> + <source>Set minimum block size in bytes (default: %u)</source> + <translation>Definir tamanho minímo de um bloco em bytes (por defeito: %u)</translation> + </message> + <message> + <source>Set the number of threads to service RPC calls (default: %d)</source> + <translation>Defina o número de processos para servir as chamadas RPC (por defeito: %d)</translation> + </message> + <message> + <source>Specify configuration file (default: %s)</source> + <translation>Especificar ficheiro de configuração (por defeito: %s)</translation> + </message> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Especificar tempo de espera da ligação em milissegundos (mínimo 1, por defeito: %d)</translation> + </message> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Rede desconhecida especificada em -onlynet: '%s'</translation> </message> diff --git a/src/qt/locale/bitcoin_ro_RO.ts b/src/qt/locale/bitcoin_ro_RO.ts index 11a29e86c9..be24668536 100644 --- a/src/qt/locale/bitcoin_ro_RO.ts +++ b/src/qt/locale/bitcoin_ro_RO.ts @@ -1,4 +1,4 @@ -<TS language="ro_RO" version="2.1"> +<TS language="ro_RO" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -2713,18 +2713,10 @@ <translation>Distribuit sub licenţa de programe MIT/X11, vezi fişierul însoţitor COPYING sau <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Iniţiază modul de test regresie, care foloseşte un lanţ special în care blocurile pot fi rezolvate instantaneu.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Execută comanda cînd o tranzacţie a portofelului se schimbă (%s în cmd este înlocuit de TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>În acest mod -genproclimit controlează cîte blocuri sînt generate imediat.</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation>Setează numărul de thread-uri de verificare a script-urilor (%u la %d, 0 = auto, <0 = lasă atîtea nuclee libere, implicit: %d)</translation> </message> @@ -2857,10 +2849,6 @@ <translation>Specifică fişierul portofel (în dosarul de date)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Este folosită pentru programe de testare a regresiei în algoritmi şi dezvoltare de alte aplicaţii.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Foloseşte mapare UPnP pentru asculatere port (implicit: %u)</translation> </message> @@ -2985,14 +2973,6 @@ <translation>RPC suportă pentru HTTP conexiuni persistente (implicit: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Aleator sccapă 1 din fiecare <n> mesaje ale reţelei</translation> - </message> - <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Aleator aproximează 1 din fiecare <n> mesaje ale reţelei</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Trimite informaţiile trace/debug la consolă în locul fişierului debug.log</translation> </message> @@ -3125,10 +3105,6 @@ <translation>Eroare la încărcarea wallet.dat: Portofel corupt</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Goleşte baza de date a activităţii din memoria pool în jurnal pe disc la fiecare <n> megaocteţi (implicit: %u)</translation> - </message> - <message> <source>Output debugging information (default: %u, supplying <category> is optional)</source> <translation>Produce toate informaţiile de depanare (implicit: %u <category> furnizată este opţională)</translation> </message> @@ -3145,10 +3121,6 @@ <translation>Eroare la încărcarea wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Forţează mod sigur (implicit: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Generează monede (implicit: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index c208b3e25e..004208d345 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -1,4 +1,4 @@ -<TS language="ru" version="2.1"> +<TS language="ru" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -164,6 +164,10 @@ <translation>Вы уверены, что хотите зашифровать ваш бумажник?</translation> </message> <message> + <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>Сейчас программа закроется для завершения процесса шифрования. Помните, что шифрование вашего бумажника не может полностью защитить ваши биткоины от кражи с помощью инфицирования вашего компьютера вредоносным ПО.</translation> + </message> + <message> <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source> <translation>ВАЖНО: все предыдущие резервные копии вашего бумажника должны быть заменены новым зашифрованным файлом. В целях безопасности предыдущие резервные копии незашифрованного бумажника станут бесполезны, как только вы начнёте использовать новый зашифрованный бумажник.</translation> </message> @@ -180,6 +184,10 @@ <translation>Введите новый пароль бумажника.<br/>Используйте пароль, состоящий из <b>десяти или более случайных символов</b>, или <b>восьми или более слов</b>.</translation> </message> <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Введите старый и новый пароль для кошелька.</translation> + </message> + <message> <source>Wallet encryption failed</source> <translation>Не удалось зашифровать бумажник</translation> </message> @@ -387,6 +395,10 @@ <translation>&О Bitcoin Core</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Изменить опции конфигурации Bitcoin Core</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Показать список использованных адресов и меток отправки</translation> </message> @@ -410,6 +422,10 @@ <source>No block source available...</source> <translation>Источник блоков недоступен...</translation> </message> + <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Обработан %n блок истории транзакций.</numerusform><numerusform>Обработано %n блока истории транзакций.</numerusform><numerusform>Обработано %n блоков истории транзакций.</numerusform><numerusform>Обработано %n блоков истории транзакций.</numerusform></translation> + </message> <message> <source>%1 and %2</source> <translation>%1 и %2</translation> @@ -447,6 +463,36 @@ <translation>Синхронизируется...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Дата: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Количество: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Тип: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Метка: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Адрес: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Исходящая транзакция</translation> </message> @@ -645,6 +691,18 @@ <translation>ничего</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Эта метка становится красной, если размер транзакции будет больше, чем 1000 байт.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Эта метка становится красной, если приоритет меньше, чем "среднее".</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Эта метка становится красной, если любой из получателей принимает количество меньше, чем %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Может отличаться на +/- %1 сатоши на вход.</translation> </message> @@ -887,6 +945,14 @@ <translation>IP-адрес прокси (например IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>Сворачивать вместо закрытия. Если данная опция будет выбрана — приложение закроется только после выбора соответствующего пункта в меню.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>Здесь можно выбрать язык интерфейса. Настройки вступят в силу после перезапуска Bitcoin Core.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>Сторонние URL (например, block explorer), которые отображаются на вкладке транзакций как пункты контекстного меню. %s в URL заменяется хэшем транзакции. URL отделяются друг от друга вертикальной чертой |.</translation> </message> @@ -911,6 +977,14 @@ <translation>&Сеть</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Автоматически запускать Bitcoin Core после входа в систему</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Запускать Bitcoin Core при входе в систему</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = автоматически, <0 = оставить столько незагруженных ядер)</translation> </message> @@ -1023,6 +1097,10 @@ <translation>Для применения изменений требуется перезапуск клиента.</translation> </message> <message> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Клиент будет выключен. Желаете продолжить?</translation> + </message> + <message> <source>This change would require a client restart.</source> <translation>Это изменение потребует перезапуска клиента.</translation> </message> @@ -1157,10 +1235,18 @@ <translation>Файл запроса платежа не может быть прочитан! Обычно это происходит из-за неверного файла запроса платежа.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Запрос платежа просрочен.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Непроверенные запросы платежей с нестандартными платёжными сценариями не поддерживаются.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Неверный запрос платежа.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Возврат от %1</translation> </message> @@ -1200,6 +1286,10 @@ <translation>Юзер-агент</translation> </message> <message> + <source>Node/Service</source> + <translation>Узел/сервис</translation> + </message> + <message> <source>Ping Time</source> <translation>Время задержки</translation> </message> @@ -1321,6 +1411,10 @@ <translation>Текущее число блоков</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Открыть отладочный лог-файл Bitcoin Core из текущего каталога данных. Это может занять несколько секунд для больших лог-файлов.</translation> + </message> + <message> <source>Received</source> <translation>Получено</translation> </message> @@ -1389,6 +1483,10 @@ <translation>Время задержки</translation> </message> <message> + <source>Time Offset</source> + <translation>Смещение времени</translation> + </message> + <message> <source>Last block time</source> <translation>Время последнего блока</translation> </message> @@ -1433,6 +1531,10 @@ <translation>Очистить консоль</translation> </message> <message> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Добро пожаловать в RPC-консоль Bitcoin Core.</translation> + </message> + <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Используйте стрелки вверх и вниз для просмотра истории и <b>Ctrl-L</b> для очистки экрана.</translation> </message> @@ -1729,6 +1831,10 @@ <translation>Если комиссия установлена в 1000 сатоши, а транзакция составляет лишь 250 байт, тогда комиссия "на килобайт" составит 250 сатоши, а "всего как минимум" — 1000 сатоши. Для транзакций крупнее килобайта в обоих случаях будет использоваться платёж "на килобайт".</translation> </message> <message> + <source>Hide</source> + <translation>Скрыть</translation> + </message> + <message> <source>total at least</source> <translation>Итого как минимум</translation> </message> @@ -1873,6 +1979,18 @@ <translation>Комиссия больше, чем %1, считается невероятно большой.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Запрос платежа просрочен.</translation> + </message> + <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Адрес получателя неверный. Пожалуйста, перепроверьте.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Обнаружен дублирующийся адрес: используйте каждый адрес только один раз.</translation> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Внимание: неверный адрес Bitcoin</translation> </message> @@ -1944,10 +2062,26 @@ <translation>Удалить эту запись</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>С отправляемой суммы будет удержана комиссия. Получателю придёт меньше биткоинов, чем вы вводите в поле количества. Если выбрано несколько получателей, комиссия распределяется поровну.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>Вычесть комиссию из суммы</translation> + </message> + <message> <source>Message:</source> <translation>Сообщение:</translation> </message> <message> + <source>This is an unauthenticated payment request.</source> + <translation>Это неавторизованный запрос платежа.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Это авторизованный запрос платежа.</translation> + </message> + <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>Введите метку для этого адреса, чтобы добавить его в список использованных</translation> </message> @@ -1986,6 +2120,10 @@ <translation>&Подписать сообщение</translation> </message> <message> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>Вы можете подписывать сообщения/соглашения своими адресами, чтобы доказать свою возможность получать биткоины на них. Будьте осторожны, не подписывайте что-то неопределённое или случайное, так как фишинговые атаки могут обманным путём заставить вас подписать нежелательные сообщения. Подписывайте только те сообщения, с которыми вы согласны вплоть до мелочей.</translation> + </message> + <message> <source>The Bitcoin address to sign the message with</source> <translation>Адрес Bitcoin, которым подписать сообщение</translation> </message> @@ -2038,6 +2176,10 @@ <translation>&Проверить сообщение</translation> </message> <message> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Введите ниже адрес получателя, сообщение (убедитесь, что переводы строк, пробелы, табы и т.п. в точности скопированы) и подпись, чтобы проверить сообщение. Убедитесь, что не скопировали лишнего в подпись, по сравнению с самим подписываемым сообщением, чтобы не стать жертвой атаки "man-in-the-middle". Заметьте, что эта операция удостоверяет лишь авторство подписавшего, но не может удостоверить отправителя транзакции.</translation> + </message> + <message> <source>The Bitcoin address the message was signed with</source> <translation>Адрес Bitcoin, которым было подписано сообщение</translation> </message> @@ -2369,6 +2511,10 @@ <translation>Использовался ли в транзакции адрес для наблюдения.</translation> </message> <message> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Определяемое пользователем намерение/цель транзакции.</translation> + </message> + <message> <source>Amount removed from or added to balance.</source> <translation>Сумма, добавленная, или снятая с баланса.</translation> </message> @@ -2619,16 +2765,16 @@ <translation>Распространяется под лицензией MIT, см. приложенный файл COPYING или <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Войти в режим тестирования на регрессии, в котором используется специальная цепь, где блоки находятся мгновенно.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Выполнить команду, когда меняется транзакция в бумажнике (%s в команде заменяется на TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>В этом режиме -genproclimit определяет, сколько блоков генерируется немедленно.</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Максимальная сумма комиссий для одной транзакции в бумажнике; слишком низкое значение может вызвать прерывание больших транзакций (по умолчанию: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>Уменьшить размер хранилища за счёт удаления (обрезания) старых блоков. Этот режим отключает поддержку бумажника и несовместим с -txindex. Внимание: переключение этой опции обратно потребует полной загрузки цепи блоков. (по умолчанию: 0 = отключить удаление блоков, >%u = целевой размер в Мб для файлов блоков)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2643,6 +2789,14 @@ <translation>Не удалось забиндиться на %s на этом компьютере. Возможно, Bitcoin Core уже запущен.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>ВНИМАНИЕ: сгенерировано ненормально большое число блоков, %d блоков получено за последние %d часов (ожидалось %d)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>ВНИМАНИЕ: проверьте сетевое подключение, получено %d блоков за последние %d часов (ожидалось %d)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Внимание: установлено очень большое значение -paytxfee. Это комиссия, которую вы заплатите при проведении транзакции.</translation> </message> @@ -2759,6 +2913,14 @@ <translation>Соединяться только по сети <net> (ipv4, ipv6 или onion)</translation> </message> <message> + <source>Prune cannot be configured with a negative value.</source> + <translation>Удаление блоков не может использовать отрицательное значение.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>Режим удаления блоков несовместим с -txindex.</translation> + </message> + <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation>Установить размер кэша БД в мегабайтах(от %d до %d, по умолчанию: %d)</translation> </message> @@ -2771,10 +2933,6 @@ <translation>Укажите файл бумажника (внутри каталога данных)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Это рассчитано на инструменты регрессионного тестирования и разработку приложений.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Использовать UPnP для проброса порта (по умолчанию: %u)</translation> </message> @@ -2795,6 +2953,10 @@ <translation>Настройки бумажника:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Внимание: эта версия устарела; требуется обновление!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Вам необходимо пересобрать базы данных с помощью -reindex, чтобы изменить -txindex</translation> </message> @@ -2827,6 +2989,10 @@ <translation>Создавать новые файлы с системными правами по умолчанию вместо umask 077 (эффективно только при отключенном бумажнике)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Обнаруживать собственный IP адрес (по умолчанию: 1 при прослушивании и без -externalip или -proxy)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Ошибка: не удалось начать прослушивание входящих подключений (прослушивание вернуло ошибку %s)</translation> </message> @@ -2843,10 +3009,6 @@ <translation>Комиссии (в BTC/Кб) меньшие этого значения считаются нулевыми для трансляции (по умолчанию: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Комиссии (в BTC/Кб) меньшие этого значения считаются нулевыми для создания транзакции (по умолчанию: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Если paytxfee не задан, включить достаточную комиссию для подтверждения транзакции в среднем за n блоков (по умолчанию: %u)</translation> </message> @@ -2859,10 +3021,18 @@ <translation>Наибольший размер данных в носителе данных транзакций, которые мы передаем и генерируем (по умолчанию: %u)</translation> </message> <message> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>Удаление блоков выставлено ниже, чем минимум в %d Мб. Пожалуйста, используйте большее значение.</translation> + </message> + <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Запрашивать адреса участников с помощью DNS, если адресов мало (по умолчанию: 1, если не указан -connect)</translation> </message> <message> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Использовать случайные учётные данные для каждого прокси-подключения. Эта функция позволяет изолировать потоки Tor (по умолчанию: %u)</translation> + </message> + <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Задать максимальный размер высокоприоритетных/низкокомиссионных транзакций в байтах (по умолчанию: %d)</translation> </message> @@ -2871,6 +3041,10 @@ <translation>Задать число потоков генерации монет, если она включена (-1 = все ядра процессора, по умолчанию: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>Сумма транзакции за вычетом комиссии слишком мала</translation> + </message> + <message> <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source> <translation>Этот продукт включает ПО, разработанное OpenSSL Project для использования в OpenSSL Toolkit <https://www.openssl.org/> и криптографическое ПО, написанное Eric Young и ПО для работы с UPnP, написанное Thomas Bernard.</translation> </message> @@ -2911,10 +3085,26 @@ rpcpassword=%s <translation>Участники из белого списка не могуть быть забанены за DoS, и их транзакции всегда транслируются, даже если они уже содержатся в памяти. Полезно, например, для шлюза.</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>Вам необходимо пересобрать базу данных с помощью -reindex, чтобы вернуться к полному режиму. Это приведёт к перезагрузке всей цепи блоков</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(по умолчанию: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>Принимать публичные REST-запросы (по умолчанию: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>Активируется лучшая цепь...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>Нельзя работать с бумажником в режиме с удалением блоков.</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Не удаётся разрешить адрес в параметре -whitebind: '%s'</translation> </message> @@ -3003,12 +3193,12 @@ rpcpassword=%s <translation>Поддержка RPC постоянных HTTP подключений (по умолчанию: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Случайно отбрасывать 1 из каждых <n> сетевых сообщений</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Перестроить при запуске индекс цепи блоков из текущих файлов blk000??.dat</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Случайно разбрасывать 1 из каждых <n> сетевых сообщений</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Получать и отображать P2P сетевые тревоги (по умолчанию: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3047,6 +3237,10 @@ rpcpassword=%s <translation>Запускать свёрнутым</translation> </message> <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>Сумма транзакции слишком мала для уплаты комиссии</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Это экспериментальное ПО.</translation> </message> @@ -3067,6 +3261,10 @@ rpcpassword=%s <translation>Транзакция слишком большая</translation> </message> <message> + <source>UI Options:</source> + <translation>Настройки интерфейса:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Невозможно привязаться к %s на этом компьютере (bind вернул ошибку %s)</translation> </message> @@ -3147,18 +3345,10 @@ rpcpassword=%s <translation>(1 = сохранять метаданные транзакции: например, владельца аккаунта и информацию запроса платежа; 2 = отбросить метаданные)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Сбрасывать активность базы данных из памяти на диск каждые <n> мегабайт (по умолчанию: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Насколько тщательна проверка контрольных блоков -checkblocks (0-4, по умолчанию: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Записывать в лог приоритет транзакции и комиссию на килобайт во время добычи блоков (по умолчанию: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Держать полный индекс транзакций, используемый RPC-запросом getrawtransaction (по умолчанию: %u)</translation> </message> @@ -3187,18 +3377,10 @@ rpcpassword=%s <translation>Всегда запрашивать адреса участников с помощью DNS (по умолчанию: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Отключить безопасный режим, перекрыть реальное событие безопасного режима (по умолчанию: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Ошибка при загрузке wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Принудительный безопасный режим (по умолчанию: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Включить добычу монет (по умолчанию: %u)</translation> </message> @@ -3215,10 +3397,6 @@ rpcpassword=%s <translation>Неверный адрес -proxy: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Ограничить размер кэша подписей <n> записями (по умолчанию: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Прослушивать подключения JSON-RPC на <порту> (по умолчанию: %u или %u в тестовой сети)</translation> </message> @@ -3231,6 +3409,10 @@ rpcpassword=%s <translation>Поддерживать не более <n> подключений к узлам (по умолчанию: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Рассылать транзакции из бумажника</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Максимальный размер буфера приёма на соединение, <n>*1000 байт (по умолчанию: %u)</translation> </message> @@ -3239,10 +3421,6 @@ rpcpassword=%s <translation>Максимальный размер буфера отправки на соединение, <n>*1000 байт (по умолчанию: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Принимать цепь блоков, лишь если она соответствует встроенным контрольным точкам (по умолчанию: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Дописывать отметки времени к отладочному выводу (по умолчанию: %u)</translation> </message> @@ -3255,10 +3433,6 @@ rpcpassword=%s <translation>Транслировать не-P2SH мультиподпись (по умолчанию: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Запустить поток для периодического сохранения бумажника (по умолчанию: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Файл сертификата сервера (по умолчанию: %s)</translation> </message> @@ -3275,10 +3449,6 @@ rpcpassword=%s <translation>Задать число потоков выполнения запросов RPC (по умолчанию: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Установить флаг DB_PRIVATE в окружении базы данных бумажника (по умолчанию: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Указать конфигурационный файл (по умолчанию: %s)</translation> </message> @@ -3295,10 +3465,6 @@ rpcpassword=%s <translation>Тратить неподтвержденную сдачу при отправке транзакций (по умолчанию: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Остановиться после импорта блоков с диска (по умолчанию: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Порог для отключения неправильно ведущих себя узлов (по умолчанию: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_sah.ts b/src/qt/locale/bitcoin_sah.ts index 6cc17f480a..9ca08ee7da 100644 --- a/src/qt/locale/bitcoin_sah.ts +++ b/src/qt/locale/bitcoin_sah.ts @@ -1,4 +1,4 @@ -<TS language="sah" version="2.1"> +<TS language="sah" version="2.0"> <context> <name>AddressBookPage</name> </context> diff --git a/src/qt/locale/bitcoin_sk.ts b/src/qt/locale/bitcoin_sk.ts index 8e7d38be00..48d5a09142 100644 --- a/src/qt/locale/bitcoin_sk.ts +++ b/src/qt/locale/bitcoin_sk.ts @@ -1,4 +1,4 @@ -<TS language="sk" version="2.1"> +<TS language="sk" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -168,6 +168,10 @@ <translation>Ste si istí, že si želáte zašifrovať peňaženku?</translation> </message> <message> + <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>Jadro Bitcoin sa teraz ukončí pre dokončenie procesu šifrovania. Pamätaj, že šifrovanie peňaženky Ťa nemôže úplne ochrániť pred krádežou bitcoinov pomocou škodlivého software.</translation> + </message> + <message> <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source> <translation>DÔLEŽITÉ: Všetky doterajšie záložné kópie peňaženky ktoré ste zhotovili by mali byť nahradené novým zašifrovaným súborom s peňaženkou. Z bezpečnostných dôvodov sa predchádzajúce kópie nezašifrovanej peňaženky stanú neužitočné keď začnete používať novú zašifrovanú peňaženku.</translation> </message> @@ -184,6 +188,10 @@ <translation>Zadajte nové heslo k peňaženke.<br/>Prosím použite heslo s dĺžkou aspoň <b>10 alebo viac náhodných znakov</b>, alebo <b>8 alebo viac slov</b>.</translation> </message> <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Zadajte staré a nové heslo k peňaženke.</translation> + </message> + <message> <source>Wallet encryption failed</source> <translation>Šifrovanie peňaženky zlyhalo</translation> </message> @@ -268,7 +276,7 @@ </message> <message> <source>&Backup Wallet...</source> - <translation>&Backup peňaženku...</translation> + <translation>&Zálohovať peňaženku...</translation> </message> <message> <source>&Change Passphrase...</source> @@ -320,7 +328,7 @@ </message> <message> <source>&Verify message...</source> - <translation>Overiť správu</translation> + <translation>O&veriť správu...</translation> </message> <message> <source>Bitcoin</source> @@ -384,13 +392,17 @@ </message> <message> <source>Request payments (generates QR codes and bitcoin: URIs)</source> - <translation>Vyžiadať platbu (vygeneruje QR kód a bitcoin: URI)</translation> + <translation>Vyžiadať platby (vygeneruje QR kódy a bitcoin: URI)</translation> </message> <message> <source>&About Bitcoin Core</source> <translation>O jadre Bitcoin</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Upraviť možnosti nastavenia pre Jadro Bitcoin</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>Zobraziť zoznam použitých adries odosielateľa a ich popisy</translation> </message> @@ -410,14 +422,38 @@ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> <translation>Zobraziť pomocnú správu od Bitcoin Jadra pre získanie zoznamu dostupných možností príkazového riadku</translation> </message> + <message numerus="yes"> + <source>%n active connection(s) to Bitcoin network</source> + <translation><numerusform>%n aktívne pripojenie do siete Bitcoin</numerusform><numerusform>%n aktívne pripojenia do siete Bitcoin</numerusform><numerusform>%n aktívnych pripojení do siete Bitcoin</numerusform></translation> + </message> <message> <source>No block source available...</source> <translation>Nedostupný zdroj blokov...</translation> </message> + <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Spracovaných %n blok transakčnej histórie.</numerusform><numerusform>Spracovaných %n bloky transakčnej histórie.</numerusform><numerusform>Spracovaných %n blokov transakčnej histórie.</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n hour(s)</source> + <translation><numerusform>%n hodina</numerusform><numerusform>%n hodiny</numerusform><numerusform>%n hodín</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n day(s)</source> + <translation><numerusform>%n deň</numerusform><numerusform>%n dni</numerusform><numerusform>%n dní</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n week(s)</source> + <translation><numerusform>%n týždeň</numerusform><numerusform>%n týždne</numerusform><numerusform>%n týždňov</numerusform></translation> + </message> <message> <source>%1 and %2</source> <translation> %1 a %2</translation> </message> + <message numerus="yes"> + <source>%n year(s)</source> + <translation><numerusform>%n rok</numerusform><numerusform>%n roky</numerusform><numerusform>%n rokov</numerusform></translation> + </message> <message> <source>%1 behind</source> <translation>%1 pozadu</translation> @@ -451,12 +487,42 @@ <translation>Sťahujem...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Dátum: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Suma: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Typ: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Popis: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Adresa: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Odoslané transakcie</translation> </message> <message> <source>Incoming transaction</source> - <translation>Prijaté transakcie</translation> + <translation>Prijatá transakcia</translation> </message> <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> @@ -649,6 +715,18 @@ <translation>žiadne</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Tento popis sčervenie ak veľkosť transakcie presiahne 1000 bajtov.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Tento popis sčervenie ak je priorita nižšia ako "stredná".</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Tento popis sčervenie ak ktorýkoľvek príjemca dostane sumu menšiu ako %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Môže sa líšiť o +/- %1 satoshi pre každý vstup</translation> </message> @@ -825,10 +903,22 @@ <translation>Jadro Bitcoin</translation> </message> <message> + <source>Error: Specified data directory "%1" cannot be created.</source> + <translation>Chyba: Zadaný priečinok pre dáta "%1" nemôže byť vytvorený.</translation> + </message> + <message> <source>Error</source> <translation>Chyba</translation> </message> - </context> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n GB voľného miesta</numerusform><numerusform>%n GB voľného miesta</numerusform><numerusform>%n GB voľného miesta</numerusform></translation> + </message> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(z %n GB potrebného)</numerusform><numerusform>(z %n GB potrebných)</numerusform><numerusform>(z %n GB potrebných)</numerusform></translation> + </message> +</context> <context> <name>OpenURIDialog</name> <message> @@ -887,6 +977,14 @@ <translation>IP adresy proxy (napr. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>Minimalizovať namiesto ukončenia aplikácie keď sa okno zavrie. Keď je zvolená táto možnosť, aplikácia sa zavrie len po zvolení Ukončiť v menu.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>Tu sa dá nastaviť jazyk užívateľského rozhrania. Toto nastavenie bude účinné po reštartovaní Jadra Bitcoin.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>URL tretích strán (napr. prehliadač blockchain) ktoré sa zobrazujú v záložke transakcií ako položky kontextového menu. %s v URL je nahradené hash-om transakcie. Viaceré URL sú oddelené zvislou čiarou |.</translation> </message> @@ -896,7 +994,7 @@ </message> <message> <source>Active command-line options that override above options:</source> - <translation>Aktévne možnosti príkazového riadku ktoré prepíšu možnosti vyššie:</translation> + <translation>Aktívne možnosti príkazového riadku ktoré prepíšu možnosti vyššie:</translation> </message> <message> <source>Reset all client options to default.</source> @@ -911,6 +1009,14 @@ <translation>Sieť</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Automaticky spustiť Jadro Bitcoin po prihlásení do systému</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Spustiť Bitcoin pri spustení systému správy okien</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = auto, <0 = nechať toľko jadier voľných)</translation> </message> @@ -1023,6 +1129,10 @@ <translation>Reštart klienta potrebný pre aktivovanie zmien.</translation> </message> <message> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Klient bude vypnutý, chcete pokračovať?</translation> + </message> + <message> <source>This change would require a client restart.</source> <translation>Táto zmena by vyžadovala reštart klienta.</translation> </message> @@ -1042,6 +1152,10 @@ <translation>Zobrazené informácie môžu byť neaktuálne. Vaša peňaženka sa automaticky synchronizuje so sieťou Bitcoin po nadviazaní spojenia, ale tento proces ešte nie je ukončený.</translation> </message> <message> + <source>Watch-only:</source> + <translation>Iba sledované:</translation> + </message> + <message> <source>Available:</source> <translation>Disponibilné:</translation> </message> @@ -1078,10 +1192,30 @@ <translation>Váš súčasný celkový zostatok</translation> </message> <message> + <source>Your current balance in watch-only addresses</source> + <translation>Váš celkový zostatok pre adresy ktoré sa iba sledujú</translation> + </message> + <message> + <source>Spendable:</source> + <translation>Použiteľné:</translation> + </message> + <message> <source>Recent transactions</source> <translation>Nedávne transakcie</translation> </message> - </context> + <message> + <source>Unconfirmed transactions to watch-only addresses</source> + <translation>Nepotvrdené transakcie pre adresy ktoré sa iba sledujú</translation> + </message> + <message> + <source>Mined balance in watch-only addresses that has not yet matured</source> + <translation>Vyťažená suma pre adresy ktoré sa iba sledujú ale ešte nie je dozretá</translation> + </message> + <message> + <source>Current total balance in watch-only addresses</source> + <translation>Aktuálny celkový zostatok pre adries ktoré sa iba sledujú</translation> + </message> +</context> <context> <name>PaymentServer</name> <message> @@ -1093,6 +1227,18 @@ <translation>Neplatná adresa platby %1</translation> </message> <message> + <source>Payment request rejected</source> + <translation>Požiadavka na platbu zamietnutá</translation> + </message> + <message> + <source>Payment request network doesn't match client network.</source> + <translation>Sieť požiadavky na platbu nie je zhodná so sieťou klienta.</translation> + </message> + <message> + <source>Payment request is not initialized.</source> + <translation>Požiadavka na platbu nie je inicializovaná</translation> + </message> + <message> <source>Requested payment amount of %1 is too small (considered dust).</source> <translation>Požadovaná platba sumy %1 je príliš malá (považovaná za prach).</translation> </message> @@ -1109,22 +1255,50 @@ <translation>URL pre stiahnutie výzvy na zaplatenie je neplatné: %1</translation> </message> <message> + <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source> + <translation>URI sa nedá analyzovať! To môže byť spôsobené neplatnou Bitcoin adresou alebo zle upravenými vlastnosťami URI.</translation> + </message> + <message> <source>Payment request file handling</source> <translation>Obsluha súboru s požiadavkou na platbu</translation> </message> <message> + <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source> + <translation>Súbor s výzvou na zaplatenie sa nedá čítať alebo spracovať! To môže byť spôsobené aj neplatným súborom s výzvou.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Vypršala platnosť požiadavky na platbu.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Program nepodporuje neoverené platobné výzvy na vlastná skripty.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Chybná požiadavka na platbu.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Vrátenie z %1</translation> </message> <message> + <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source> + <translation>Požiadavka na platbu %1 je príliš veľká (%2 bajtov, povolené je %3 bajtov).</translation> + </message> + <message> + <source>Payment request DoS protection</source> + <translation>Ochrana pred zahltením požiadavkami na platbu</translation> + </message> + <message> <source>Error communicating with %1: %2</source> <translation>Chyba komunikácie s %1: %2 </translation> </message> <message> + <source>Payment request cannot be parsed!</source> + <translation>Požiadavka na platbu nemôže byť analyzovaná!</translation> + </message> + <message> <source>Bad response from server %1</source> <translation>Zlá odpoveď zo servera %1</translation> </message> @@ -1144,6 +1318,10 @@ <translation>Aplikácia</translation> </message> <message> + <source>Node/Service</source> + <translation>Uzol/Služba</translation> + </message> + <message> <source>Ping Time</source> <translation>Čas odozvy</translation> </message> @@ -1159,6 +1337,10 @@ <translation>Zadajte bitcoin adresu (napr. %1)</translation> </message> <message> + <source>%1 d</source> + <translation>%1 d</translation> + </message> + <message> <source>%1 h</source> <translation>%1 h</translation> </message> @@ -1167,6 +1349,14 @@ <translation>%1 m</translation> </message> <message> + <source>%1 s</source> + <translation>%1 s</translation> + </message> + <message> + <source>None</source> + <translation>Žiadne</translation> + </message> + <message> <source>N/A</source> <translation>nie je k dispozícii</translation> </message> @@ -1253,6 +1443,10 @@ <translation>Aktuálny počet blokov</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Otvoriť Bitcoin log súbor pre ladenie z aktuálneho dátového adresára. Toto môže trvať niekoľko sekúnd pre veľké súbory.</translation> + </message> + <message> <source>Received</source> <translation>Prijaté</translation> </message> @@ -1261,6 +1455,10 @@ <translation>Odoslané</translation> </message> <message> + <source>&Peers</source> + <translation>&Partneri</translation> + </message> + <message> <source>Select a peer to view detailed information.</source> <translation>Vyberte počítač pre zobrazenie podrobností.</translation> </message> @@ -1285,10 +1483,26 @@ <translation>Počiatočná výška</translation> </message> <message> + <source>Sync Height</source> + <translation>Synchronizovaná výška</translation> + </message> + <message> + <source>Ban Score</source> + <translation>Skóre zákazu</translation> + </message> + <message> <source>Connection Time</source> <translation>Dĺžka spojenia</translation> </message> <message> + <source>Last Send</source> + <translation>Posledné odoslanie</translation> + </message> + <message> + <source>Last Receive</source> + <translation>Posledné prijatie</translation> + </message> + <message> <source>Bytes Sent</source> <translation>Odoslaných bajtov</translation> </message> @@ -1301,6 +1515,10 @@ <translation>Čas odozvy</translation> </message> <message> + <source>Time Offset</source> + <translation>Časový posun</translation> + </message> + <message> <source>Last block time</source> <translation>Čas posledného bloku</translation> </message> @@ -1345,6 +1563,10 @@ <translation>Vymazať konzolu</translation> </message> <message> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Vitajte v RPC konzole pre Jadro Bitcoin.</translation> + </message> + <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Použi šípky hore a dolu pre navigáciu históriou a <b>Ctrl-L</b> pre vyčistenie obrazovky.</translation> </message> @@ -1369,6 +1591,14 @@ <translation>%1 GB</translation> </message> <message> + <source>via %1</source> + <translation>cez %1</translation> + </message> + <message> + <source>never</source> + <translation>nikdy</translation> + </message> + <message> <source>Inbound</source> <translation>Prichádzajúce</translation> </message> @@ -1377,6 +1607,10 @@ <translation>Odchádzajúce</translation> </message> <message> + <source>Unknown</source> + <translation>neznámy</translation> + </message> + <message> <source>Fetching...</source> <translation>Získava sa...</translation> </message> @@ -1613,6 +1847,10 @@ <translation>Poplatok za transakciu:</translation> </message> <message> + <source>Choose...</source> + <translation>Zvoliť...</translation> + </message> + <message> <source>collapse fee-settings</source> <translation>zbaliť nastavenia poplatkov</translation> </message> @@ -1625,6 +1863,10 @@ <translation>Ak je poplatok nastavený na 1000 satoshi a transakcia je veľká len 250 bajtov, potom "za kilobajt" zaplatí poplatok 250 satoshi, ale "spolu aspoň" zaplatí 1000 satoshi. Pre transakcie väčšie ako kilobajt platia oba spôsoby za každý kilobajt.</translation> </message> <message> + <source>Hide</source> + <translation>Skryť</translation> + </message> + <message> <source>total at least</source> <translation>spolu aspoň</translation> </message> @@ -1686,7 +1928,7 @@ </message> <message> <source>Clear &All</source> - <translation>Zmazať &všetko</translation> + <translation>&Zmazať všetko</translation> </message> <message> <source>Balance:</source> @@ -1765,10 +2007,26 @@ <translation>Transakcia bola zamietnutá! Toto sa môže stať ak niektoré coins vo vašej peňaženke už boli minuté, ako keď použijete kópiu wallet.dat a coins boli minuté z kópie ale neoznačené ako minuté tu.</translation> </message> <message> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>Poplatok vyšší ako %1 je považovaný za šialene vysoký.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Vypršala platnosť požiadavky na platbu.</translation> + </message> + <message> <source>Pay only the minimum fee of %1</source> <translation>Zaplatiť minimálny poplatok %1</translation> </message> <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Adresa príjemcu je neplatná. Prosím, overte ju.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Našla sa duplicitná adresa: každú adresu je možné použiť len raz.</translation> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Varovanie: Nesprávna Bitcoin adresa</translation> </message> @@ -1820,6 +2078,10 @@ <translation>Toto je normálna platba.</translation> </message> <message> + <source>The Bitcoin address to send the payment to</source> + <translation>Zvoľte adresu kam poslať platbu</translation> + </message> + <message> <source>Alt+A</source> <translation>Alt+A</translation> </message> @@ -1836,10 +2098,22 @@ <translation>Odstrániť túto položku</translation> </message> <message> + <source>S&ubtract fee from amount</source> + <translation>Odpočítať poplatok od s&umy</translation> + </message> + <message> <source>Message:</source> <translation>Správa:</translation> </message> <message> + <source>This is an unauthenticated payment request.</source> + <translation>Toto je neoverená výzva k platbe.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Toto je overená výzva k platbe.</translation> + </message> + <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>Vložte popis pre túto adresu aby sa uložila do zoznamu použitých adries</translation> </message> @@ -1919,11 +2193,15 @@ </message> <message> <source>Clear &All</source> - <translation>Zmazať &všetko</translation> + <translation>&Zmazať všetko</translation> </message> <message> <source>&Verify Message</source> - <translation>Overiť správu...</translation> + <translation>O&veriť správu...</translation> + </message> + <message> + <source>The Bitcoin address the message was signed with</source> + <translation>Adresa Bitcoin, ktorou bola podpísaná správa</translation> </message> <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> @@ -1931,7 +2209,7 @@ </message> <message> <source>Verify &Message</source> - <translation>Overiť správu</translation> + <translation>&Overiť správu</translation> </message> <message> <source>Reset all verify message fields</source> @@ -2038,6 +2316,10 @@ <source>Status</source> <translation>Stav</translation> </message> + <message numerus="yes"> + <source>, broadcast through %n node(s)</source> + <translation><numerusform>, vysielať cez %n uzol</numerusform><numerusform>, vysielať cez %n uzle</numerusform><numerusform>, vysielať cez %n uzolov</numerusform></translation> + </message> <message> <source>Date</source> <translation>Dátum</translation> @@ -2063,6 +2345,10 @@ <translation>vlastná adresa</translation> </message> <message> + <source>watch-only</source> + <translation>Iba sledovanie</translation> + </message> + <message> <source>label</source> <translation>popis</translation> </message> @@ -2079,6 +2365,14 @@ <translation>Debet</translation> </message> <message> + <source>Total debit</source> + <translation>Debit spolu</translation> + </message> + <message> + <source>Total credit</source> + <translation>Kredit spolu</translation> + </message> + <message> <source>Transaction fee</source> <translation>Transakčný poplatok</translation> </message> @@ -2104,7 +2398,7 @@ </message> <message> <source>Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source> - <translation>Vytvorené coins musia dospieť %1 blokov kým môžu byť minuté. Keď vytvoríte tento blok, bude rozoslaný do siete aby bol akceptovaný do reťaze blokov. Ak sa nedostane reťaze, jeho stav sa zmení na "zamietnutý" a nebude sa dať minúť. Toto sa môže občas stať ak iná nóda vytvorí blok približne v tom istom čase.</translation> + <translation>Vygenerované mince musia dospieť %1 blokov kým môžu byť minuté. Keď vytvoríte tento blok, bude rozoslaný do siete aby bol akceptovaný do reťaze blokov. Ak sa nedostane do reťazca, jeho stav sa zmení na "zamietnutý" a nebude sa dať minúť. Toto sa môže občas stať ak iný uzol vytvorí blok približne v rovnakom čase.</translation> </message> <message> <source>Debug information</source> @@ -2134,6 +2428,10 @@ <source>, has not been successfully broadcast yet</source> <translation>, ešte nebola úspešne odoslaná</translation> </message> + <message numerus="yes"> + <source>Open for %n more block(s)</source> + <translation><numerusform>Otvorené pre %n ďalší blok</numerusform><numerusform>Otvorené pre %n ďalšie bloky</numerusform><numerusform>Otvorené pre %n ďalších blokov</numerusform></translation> + </message> <message> <source>unknown</source> <translation>neznámy</translation> @@ -2164,6 +2462,10 @@ <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Nezrelé (%1 potvrdení, bude k dispozícii po %2)</translation> </message> + <message numerus="yes"> + <source>Open for %n more block(s)</source> + <translation><numerusform>Otvorené pre %n ďalší blok</numerusform><numerusform>Otvorené pre %n ďalšie bloky</numerusform><numerusform>Otvorené pre %n ďalších blokov</numerusform></translation> + </message> <message> <source>Open until %1</source> <translation>Otvorené do %1</translation> @@ -2178,7 +2480,7 @@ </message> <message> <source>Generated but not accepted</source> - <translation>Vypočítané ale neakceptované</translation> + <translation>Vygenerované ale neakceptované</translation> </message> <message> <source>Offline</source> @@ -2218,7 +2520,11 @@ </message> <message> <source>Mined</source> - <translation>Vyfárané</translation> + <translation>Vyťažené</translation> + </message> + <message> + <source>watch-only</source> + <translation>Iba sledovanie</translation> </message> <message> <source>(n/a)</source> @@ -2237,6 +2543,10 @@ <translation>Typ transakcie.</translation> </message> <message> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <translation>Či sú ale nie sú, adresy iba na sledovanie zahrnuté v tejto transakcii.</translation> + </message> + <message> <source>Amount removed from or added to balance.</source> <translation>Suma pridaná alebo odobraná k zostatku.</translation> </message> @@ -2285,7 +2595,7 @@ </message> <message> <source>Mined</source> - <translation>Vyfárané</translation> + <translation>Vyťažené</translation> </message> <message> <source>Other</source> @@ -2328,6 +2638,10 @@ <translation>Exportovať históriu transakcií</translation> </message> <message> + <source>Watch-only</source> + <translation>Iba sledovanie</translation> + </message> + <message> <source>Exporting Failed</source> <translation>Export zlyhal</translation> </message> @@ -2382,7 +2696,11 @@ </context> <context> <name>UnitDisplayStatusBarControl</name> - </context> + <message> + <source>Unit to show amounts in. Click to select another unit.</source> + <translation>Jednotka pre zobrazovanie súm. Kliknite pre zvolenie inej jednotky.</translation> + </message> +</context> <context> <name>WalletFrame</name> <message> @@ -2471,16 +2789,16 @@ <translation>Spojiť s danou adresou a vždy na nej počúvať. Použite zápis [host]:port pre IPv6</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Vojsť do režimu regresného testovania, ktorý používa špeciálnu reťaz v ktorej môžu byť bloky v okamihu vyriešené.</translation> + <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> + <translation>Vymazať všetky transakcie z peňaženky a pri spustení znova získať z reťazca blokov iba tie získané pomocou -rescan</translation> </message> <message> - <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> - <translation>Vykonaj príkaz keď sa zmení transakcia peňaženky (%s v príkaze je nahradená TxID)</translation> + <source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> + <translation>Distribuované pod softvérovou licenciou MIT, viď sprievodný súbor COPYING alebo <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>V tomto režime -getproclimit kontroluje koľko blokov sa vytvorí okamžite.</translation> + <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> + <translation>Vykonaj príkaz keď sa zmení transakcia peňaženky (%s v príkaze je nahradená TxID)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2517,6 +2835,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Varovanie: wallet.dat je poškodený, údaje úspešne získané! Pôvodný wallet.dat uložený ako wallet.{timestamp}.bak v %s; ak váš zostatok alebo transakcie niesu správne, mali by ste súbor obnoviť zo zálohy.</translation> </message> <message> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>Uzle na zoznam povolených, ktoré sa pripájajú z danej netmask alebo IP adresy. Môže byť zadané viac krát.</translation> + </message> + <message> <source>(default: 1)</source> <translation>(predvolené: 1)</translation> </message> @@ -2573,6 +2895,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Chyba otvárania databázy blokov</translation> </message> <message> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation>Chyba: Nastala fatálna interná chyba. Pre podrobnosti pozrite debug.log</translation> + </message> + <message> <source>Error: Disk space is low!</source> <translation>Chyba: Málo miesta na disku!</translation> </message> @@ -2601,6 +2927,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Nedostatok kľúčových slov súboru.</translation> </message> <message> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <translation>Pripojiť iba k uzlom v sieti <net> (ipv4, ipv6, alebo onion)</translation> + </message> + <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation>Nastaviť veľkosť pomocnej pamäti databázy v megabajtoch (%d do %d, prednastavené: %d)</translation> </message> @@ -2613,8 +2943,8 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Označ súbor peňaženky (v priečinku s dátami)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Toto je mienené nástrojom pre regresné testovania a vývoj programu.</translation> + <source>Use UPnP to map the listening port (default: %u)</source> + <translation>Použiť UPnP pre mapovanie počúvajúceho portu (predvolené: %u)</translation> </message> <message> <source>Verifying blocks...</source> @@ -2641,14 +2971,38 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Importuje bloky z externého súboru blk000??.dat</translation> </message> <message> + <source>Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source> + <translation>Povoliť JSON-RPC pripojenia zo zadaného zdroja. Pre <ip> sú platné jednoduché IP (napr. 1.2.3.4), sieť/netmask (napr. 1.2.3.4/255.255.255.0) alebo sieť/CIDR (napr. 1.2.3.4/24). Táto možnosť môže byť zadaná niekoľko krát</translation> + </message> + <message> + <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> + <translation>Pri nastavovaní RPC adresy %s na porte %u pre počúvanie došlo k chybe: %s</translation> + </message> + <message> + <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> + <translation>Spojiť s danou adresou a povolenými partnerskými zariadeniami ktoré sa tam pripájajú. Použite zápis [host]:port pre IPv6</translation> + </message> + <message> + <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source> + <translation>Spojiť s danou adresou pre počúvanie JSON-RPC spojení. Použite zápis [host]:port pre IPv6. Táto možnosť môže byt zadaná niekoľko krát (predvolené: spojiť so všetkými rozhraniami)</translation> + </message> + <message> <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> <translation>Neviem uzamknúť data adresár %s. Jadro Bitcoin je pravdepodobne už spustené.</translation> </message> <message> + <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> + <translation>Vytvoriť nové súbory z predvolenými systémovými právami, namiesto umask 077 (funguje iba z vypnutou funkcionalitou peňaženky)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Chyba: Počúvanie prichádzajúcich spojení zlyhalo (vrátená chyba je %s)</translation> </message> <message> + <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> + <translation>Chyba: Nájdený nepodporovaný argument -socks. Nastavenie SOCKS verzie nie je už možné, podporované sú už iba proxy SOCKS5.</translation> + </message> + <message> <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source> <translation>Vykonať príkaz po prijatí patričného varovania alebo uvidíme veľmi dlhé rozdvojenie siete (%s v cmd je nahradené správou)</translation> </message> @@ -2657,14 +3011,54 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Poplatky (v BTC/Kb) nižšie ako toľkoto sa považujú za nulové pri postupovaní transakcií (predvolené: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Poplatky (v BTC/Kb) nižšie ako toľkoto sa považujú za nulové pri vytváraní transakcií (predvolené: %s)</translation> + <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> + <translation>Ak nie je nastavené paytxfee, pridať dostatočný poplatok aby sa transakcia začala potvrdzovať priemerne v rámci bloku (predvolené: %u)</translation> + </message> + <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source> + <translation>Neplatná suma pre -maxtxfee=<amount>: '%s' (aby sa transakcia nezasekla, minimálny prenosový poplatok musí byť aspoň %s)</translation> + </message> + <message> + <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> + <translation>Maximálna veľkosť dát v transakciách nosných dát, ktoré prenášame a ťažíme (predvolené: %u)</translation> + </message> + <message> + <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> + <translation>Dotaz na partnerské adresy pomocou vyhľadávania DNS v prípade nedostatku adries (predvolené: 1, pokiaľ -connect)</translation> </message> <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Nastaviť najväčšiu veľkosť vysoká-dôležitosť/nízke-poplatky transakcií v bajtoch (prednastavené: %d)</translation> </message> <message> + <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source> + <translation>Nastaviť počet vlákien pre generáciu mincí (-1 = všetky jadrá, predvolené: %d)</translation> + </message> + <message> + <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source> + <translation>Tento produkt obsahuje softvér vyvinutý projektom OpenSSL pre použitie sady nástrojov OpenSSL <https://www.openssl.org/> a kryptografického softvéru napísaného Eric Young a UPnP softvér napísaný Thomas Bernard.</translation> + </message> + <message> + <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> + <translation>Upozornenie: -maxtxfee je nastavené príliš vysoko! Takto vysoké poplatky by mali byť zaplatené za jednu transakciu.</translation> + </message> + <message> + <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source> + <translation>Uzle na zoznam povolených nemôžu byť DoS zakázané a ich transakcie vždy postúpené ďalej, aj v prípade, ak sú už pamäťovej fronte. Užitočné napr. pre brány</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(predvolené: %u)</translation> + </message> + <message> + <source>Accept public REST requests (default: %u)</source> + <translation>Akceptovať verejné REST žiadosti (predvolené: %u)</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Nedá sa vyriešiť -whitebind adresa: '%s'</translation> + </message> + <message> <source>Choose data directory on startup (default: 0)</source> <translation>Zvoľte dátový priečinok pri štarte (prednastavené: 0)</translation> </message> @@ -2673,10 +3067,26 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Pripojiť cez proxy server SOCKS5</translation> </message> <message> + <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source> + <translation>Autorské práva (C) 2009-%i Vývojári jadra Bitcoin</translation> + </message> + <message> + <source>Could not parse -rpcbind value %s as network address</source> + <translation>Nedá sa analyzovať -rpcbind hodnota %s ako sieťová adresa</translation> + </message> + <message> <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> <translation>Chyba pri čítaní wallet.dat: Peňaženka vyžaduje vyššiu verziu Jadra Bitcoin</translation> </message> <message> + <source>Error reading from database, shutting down.</source> + <translation>Chyba pri načítaní z databázy, ukončuje sa.</translation> + </message> + <message> + <source>Error: Unsupported argument -tor found, use -onion.</source> + <translation>Chyba: nájdený nepodporovaný argument -tor, použite -onion.</translation> + </message> + <message> <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> <translation>Poplatok (v BTC/kB), ktorý sa pridá k transakciám, ktoré odosielate (predvolený: %s)</translation> </message> @@ -2685,6 +3095,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Informácia</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Neplatná suma pre -maxtxfee=<amount>: '%s'</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>Neplatná suma pre -minrelaytxfee=<amount>: '%s'</translation> </message> @@ -2693,6 +3107,26 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Neplatná suma pre -mintxfee=<amount>: '%s'</translation> </message> <message> + <source>Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)</source> + <translation>Neplatná suma pre -paytxfee=<amount>: '%s' (musí byť aspoň %s)</translation> + </message> + <message> + <source>Invalid netmask specified in -whitelist: '%s'</source> + <translation>Nadaná neplatná netmask vo -whitelist: '%s'</translation> + </message> + <message> + <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> + <translation>V pamäti udržiavať najviac <n> nepotvrdených transakcií (predvolené: %u)</translation> + </message> + <message> + <source>Need to specify a port with -whitebind: '%s'</source> + <translation>Je potrebné zadať port s -whitebind: '%s'</translation> + </message> + <message> + <source>Node relay options:</source> + <translation>Prenosové možnosti uzla:</translation> + </message> + <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>Možnosti RPC SSL: (Pozri v Bitcoin Wiki pokyny pre SSL nastavenie)</translation> </message> @@ -2701,12 +3135,12 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Možnosti servra RPC:</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Náhodne zahadzuj 1 z každých <n> sieťových správ</translation> + <source>RPC support for HTTP persistent connections (default: %d)</source> + <translation>Podpora RPC pre trvalé HTTP spojenia (predvolené: %d)</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Náhodne premiešaj 1 z každých <n> sieťových správ</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Obdržať a zobraziť sieťové P2P varovania (predvolené: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -2765,6 +3199,14 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Transakcia príliš veľká</translation> </message> <message> + <source>UI Options:</source> + <translation>Možnosti používateľského rozhrania:</translation> + </message> + <message> + <source>Unable to bind to %s on this computer (bind returned error %s)</source> + <translation>Na tomto počítači sa nedá vytvoriť väzba %s (vytvorenie väzby vrátilo chybu %s)</translation> + </message> + <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Skúsiť použiť UPnP pre mapovanie počúvajúceho portu (default: 1 when listening)</translation> </message> @@ -2777,6 +3219,14 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Upozornenie</translation> </message> <message> + <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> + <translation>Upozornenie: Nepodporovaný argument -benchmark bol ignorovaný, použite -debug=bench.</translation> + </message> + <message> + <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>Upozornenie: Nepodporovaný argument -debugnet bol ignorovaný, použite -debug=net.</translation> + </message> + <message> <source>Zapping all transactions from wallet...</source> <translation>Zmazať všetky transakcie z peňaženky...</translation> </message> @@ -2825,26 +3275,130 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Chyba načítania wallet.dat: Peňaženka je poškodená</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Zaznamenať prioritu transakcie a poplatok za kB pri ťažení blokov (predvolené: %u)</translation> + <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source> + <translation>(1 = zachovať metaúdaje tx napr. vlastníka účtu a informácie o platobných príkazoch, 2 = zahodiť metaúdaje tx)</translation> + </message> + <message> + <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> + <translation>Ako dôkladné je -checkblocks overenie blokov (0-4, predvolené: %u)</translation> + </message> + <message> + <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> + <translation>Udržiavať kompletný transakčný index, využíva getrawtransaction rpc volanie (predvolené: %u)</translation> + </message> + <message> + <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source> + <translation>Počet sekúnd, počas ktorých nepripájať zle správajúce sa uzle (predvolené: %u)</translation> + </message> + <message> + <source>Output debugging information (default: %u, supplying <category> is optional)</source> + <translation>Výstupné ladiace informácie (predvolené: %u, dodanie <category> je voliteľné)</translation> </message> <message> <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> <translation>Použiť samostatný SOCKS5 proxy server na dosiahnutie počítačov cez skryté služby Tor (predvolené: %s)</translation> </message> <message> + <source>(default: %s)</source> + <translation>(predvolené: %s)</translation> + </message> + <message> + <source>Acceptable ciphers (default: %s)</source> + <translation>Prijateľné šifry (predvolené: %s)</translation> + </message> + <message> + <source>Always query for peer addresses via DNS lookup (default: %u)</source> + <translation>Vždy sa dotazovať adresy partnerských uzlov cez vyhľadávanie DNS (predvolené: %u)</translation> + </message> + <message> <source>Error loading wallet.dat</source> <translation>Chyba načítania wallet.dat</translation> </message> <message> + <source>How many blocks to check at startup (default: %u, 0 = all)</source> + <translation>Koľko blokov overiť pri spustení (predvolené: %u, 0 = všetky)</translation> + </message> + <message> + <source>Include IP addresses in debug output (default: %u)</source> + <translation>Zahrnúť IP adresy v ladiacom výstupe (predvolené: %u)</translation> + </message> + <message> <source>Invalid -proxy address: '%s'</source> <translation>Neplatná adresa proxy: '%s'</translation> </message> <message> + <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> + <translation>Počúvať JSON-RPC pripojenia na <port> (predvolené: %u alebo testovacia sieť: %u)</translation> + </message> + <message> + <source>Listen for connections on <port> (default: %u or testnet: %u)</source> + <translation>Počúvať pripojenia na <port> (predvolené: %u alebo testovacia sieť: %u)</translation> + </message> + <message> <source>Maintain at most <n> connections to peers (default: %u)</source> <translation>Udržiavať najviac <n> spojení s inými počítačmi (predvolené: %u)</translation> </message> <message> + <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> + <translation>Maximálna prijímajúca medzipamäť pre pripojenie, <n>*1000 bajtov (predvolené: %u)</translation> + </message> + <message> + <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source> + <translation>Maximálna odosielajúca medzipamäť pre pripojenie, <n>*1000 bajtov (predvolené: %u)</translation> + </message> + <message> + <source>Prepend debug output with timestamp (default: %u)</source> + <translation>Na začiatok pripojiť časovú známku k ladiacemu výstupu (predvolené: %u)</translation> + </message> + <message> + <source>Relay and mine data carrier transactions (default: %u)</source> + <translation>Prenášať a ťažiť transakcie nosných dát (predvolené: %u)</translation> + </message> + <message> + <source>Relay non-P2SH multisig (default: %u)</source> + <translation>Prenášať non-P2SH multi-podpis (predvolené: %u)</translation> + </message> + <message> + <source>Server certificate file (default: %s)</source> + <translation>Certifikačný súbor servera (predvolené: %s)</translation> + </message> + <message> + <source>Server private key (default: %s)</source> + <translation>Privátny kľúč servera (predvolené: %s)</translation> + </message> + <message> + <source>Set key pool size to <n> (default: %u)</source> + <translation>Nastaviť veľkosť kľúča fronty na <n> (predvolené: %u)</translation> + </message> + <message> + <source>Set minimum block size in bytes (default: %u)</source> + <translation>Nastaviť minimálnu veľkosť bloku v bajtoch (predvolené: %u)</translation> + </message> + <message> + <source>Set the number of threads to service RPC calls (default: %d)</source> + <translation>Nastaviť počet vlákien na obsluhu RPC volaní (predvolené: %d)</translation> + </message> + <message> + <source>Specify configuration file (default: %s)</source> + <translation>Zadať konfiguračný súbor (predvolené: %s)</translation> + </message> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Zadajte časový limit pripojenia v milisekundách (minimum: 1, predvolené: %d)</translation> + </message> + <message> + <source>Specify pid file (default: %s)</source> + <translation>Zadať pid súbor (predvolené: %s)</translation> + </message> + <message> + <source>Spend unconfirmed change when sending transactions (default: %u)</source> + <translation>Minúť nepotvrdené zmenu pri posielaní transakcií (predvolené: %u)</translation> + </message> + <message> + <source>Threshold for disconnecting misbehaving peers (default: %u)</source> + <translation>Hranica pre odpájanie zle sa správajúcim partnerským uzlom (predvolené: %u)</translation> + </message> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Neznáma sieť upresnená v -onlynet: '%s'</translation> </message> diff --git a/src/qt/locale/bitcoin_sl_SI.ts b/src/qt/locale/bitcoin_sl_SI.ts index abbdba3760..39dcb6e997 100644 --- a/src/qt/locale/bitcoin_sl_SI.ts +++ b/src/qt/locale/bitcoin_sl_SI.ts @@ -1,7 +1,11 @@ -<TS language="sl_SI" version="2.1"> +<TS language="sl_SI" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>Desni klik za urejanje naslovov ali oznak</translation> + </message> + <message> <source>Create a new address</source> <translation>Ustvari nov naslov</translation> </message> @@ -19,7 +23,7 @@ </message> <message> <source>C&lose</source> - <translation>&Zapri (close)</translation> + <translation>&Zapri</translation> </message> <message> <source>&Copy Address</source> @@ -31,7 +35,7 @@ </message> <message> <source>Export the data in the current tab to a file</source> - <translation>Izvozi podatke v trenutni zavih v datoteko</translation> + <translation>Izvozi podatke v trenutnem zavihku v datoteko</translation> </message> <message> <source>&Export</source> @@ -39,15 +43,15 @@ </message> <message> <source>&Delete</source> - <translation>&Zbriši</translation> + <translation>I&zbriši</translation> </message> <message> <source>Choose the address to send coins to</source> - <translation>Izberi naslov prejemnika kovancev</translation> + <translation>Izbira naslova, na katerega pošiljate plačilo</translation> </message> <message> <source>Choose the address to receive coins with</source> - <translation>Izberi naslov pošiljatelja kovancev</translation> + <translation>Izbira naslova za prejem plačila</translation> </message> <message> <source>C&hoose</source> @@ -55,19 +59,19 @@ </message> <message> <source>Sending addresses</source> - <translation>Naslovi za pošiljanje</translation> + <translation>Imenik naslovov za pošiljanje</translation> </message> <message> <source>Receiving addresses</source> - <translation>Naslovi za prejemanje</translation> + <translation>Imenik naslovov za prejemanje</translation> </message> <message> <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> - <translation>To so tvoji Bitcoin naslovi za pošiljanje plačil. Vedno preveri znesek in prejemnikov naslov pred pošiljanjem kovancev.</translation> + <translation>To je vaš imenik shranjenih naslovov Bitcoin, na katere lahko pošiljate plačila. Pred vsakim odlivom vedno preverite, če sta znesek in prejemnikov naslov pravilna.</translation> </message> <message> <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> - <translation>To so tvoji Bitcoin naslovi za prejemanje plačil. Priporočljivo je uporabljati nov prejemni naslov za vsako izmed transakcij.</translation> + <translation>To je imenik vaših ustvarjenih naslovov Bitcoin, na katere lahko prejemate plačila. Priporočljivo je, da za vsak nov priliv ustvarite nov prejemni naslov.</translation> </message> <message> <source>Copy &Label</source> @@ -87,9 +91,13 @@ </message> <message> <source>Exporting Failed</source> - <translation>Neuspešen izvoz</translation> + <translation>Seznama naslovov ni bilo mogoče izvoziti.</translation> </message> - </context> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>Napaka pri shranjevanju seznama naslovov v datoteko %1. Prosimo, poskusite znova.</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -102,14 +110,14 @@ </message> <message> <source>(no label)</source> - <translation>(ni oznake)</translation> + <translation>(brez oznake)</translation> </message> </context> <context> <name>AskPassphraseDialog</name> <message> <source>Passphrase Dialog</source> - <translation>Poziv gesla</translation> + <translation>Vnos gesla</translation> </message> <message> <source>Enter passphrase</source> @@ -149,49 +157,69 @@ </message> <message> <source>Confirm wallet encryption</source> - <translation>Potrdi šifriranje denarnice</translation> + <translation>Potrditev šifriranja denarnice</translation> </message> <message> <source>Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>!</source> - <translation>Opozorilo: V primeru izgube gesla kriptirane denarnice, boš <b>IZGUBIL VSE SVOJE BITCOINE</b>!</translation> + <translation>Opozorilo: V primeru izgube gesla šifrirane denarnice, boste <b>IZGUBILI VSE BITCOINE V DENARNICI</b>!</translation> </message> <message> <source>Are you sure you wish to encrypt your wallet?</source> <translation>Ali ste prepričani, da želite šifrirati vašo denarnico?</translation> </message> <message> + <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>Program se bo zaprl, da dokonča proces šifriranja. Zapomnite si, da šifriranje ne more popolnoma zaščititi vaše denarnice pred krajami in zlonamernimi programi, ki bi lahko bili nameščeni na vašem računalniku.</translation> + </message> + <message> + <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source> + <translation>POMEMBNO: Vse starejše obstoječe varnostne kopije denarnice je potrebno zamenjati s to novo, šifrirano varnostno kopijo. Iz varnostnih razlogov bodo stare varnostne kopije postale neuporabne takoj, ko začnete uporabljati novo, šifrirano denarnico.</translation> + </message> + <message> <source>Warning: The Caps Lock key is on!</source> - <translation>Opozorilo: imate prižgan Cap Lock</translation> + <translation>Opozorilo: imate vklopljene velike črke (Caps Lock)</translation> </message> <message> <source>Wallet encrypted</source> - <translation>Denarnica šifrirana</translation> + <translation>Denarnica je šifrirana</translation> + </message> + <message> + <source>Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>.</source> + <translation>Vnesite novo geslo. Prosimo, da uporabite geslo sestavljeno iz <b>deset ali več</b> naključnih znakov, ali <b>osem ali več</b> besed.</translation> + </message> + <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Vnesite staro in novo geslo denarnice.</translation> </message> <message> <source>Wallet encryption failed</source> - <translation>Šifriranje denarnice spodletelo</translation> + <translation>Denarnice ni bilo mogoče šifrirati.</translation> </message> <message> <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source> - <translation>Šifriranje denarnice spodletelo zaradi notranje napake. Vaša denarnica ni šifrirana.</translation> + <translation>Prišlo je do napake. Denarnice ni bilo mogoče šifrirati.</translation> </message> <message> <source>The supplied passphrases do not match.</source> - <translation>Vnešeno geslo se ne ujema</translation> + <translation>Vnešeni gesli se ne ujemata</translation> </message> <message> <source>Wallet unlock failed</source> - <translation>Odklep denarnice spodletel</translation> + <translation>Denarnice ni bilo mogoče odkleniti.</translation> </message> <message> <source>The passphrase entered for the wallet decryption was incorrect.</source> - <translation>Geslo za dešifriranje denarnice, ki ste ga vnesli, ni pravilno.</translation> + <translation>Vnesli ste napačno geslo za dešifriranje denarnice.</translation> </message> <message> <source>Wallet decryption failed</source> - <translation>Dešifriranje denarnice spodletelo</translation> + <translation>Denarnice ni bilo mogoče dešifrirati.</translation> </message> - </context> + <message> + <source>Wallet passphrase was successfully changed.</source> + <translation>Geslo za dostop do denarnice je bilo uspešno zamenjano.</translation> + </message> +</context> <context> <name>BitcoinGUI</name> <message> @@ -200,11 +228,11 @@ </message> <message> <source>Synchronizing with network...</source> - <translation>Sinhroniziranje z omrežjem ...</translation> + <translation>Dohitevam omrežje ...</translation> </message> <message> <source>&Overview</source> - <translation>&Pregled</translation> + <translation>Pre&gled</translation> </message> <message> <source>Node</source> @@ -212,7 +240,7 @@ </message> <message> <source>Show general overview of wallet</source> - <translation>Pokaži splošen pregled denarnice</translation> + <translation>Oglejte si splošne informacije o vaši denarnici</translation> </message> <message> <source>&Transactions</source> @@ -220,7 +248,7 @@ </message> <message> <source>Browse transaction history</source> - <translation>Brskaj po zgodovini transakcij</translation> + <translation>Brskajte po zgodovini transakcij</translation> </message> <message> <source>E&xit</source> @@ -228,7 +256,7 @@ </message> <message> <source>Quit application</source> - <translation>Izhod iz aplikacije</translation> + <translation>Ustavite program</translation> </message> <message> <source>About &Qt</source> @@ -236,7 +264,7 @@ </message> <message> <source>Show information about Qt</source> - <translation>Prikaži informacije o Qt</translation> + <translation>Oglejte si informacije o Qt</translation> </message> <message> <source>&Options...</source> @@ -248,7 +276,7 @@ </message> <message> <source>&Backup Wallet...</source> - <translation>&Napravi varnostno kopijo denarnice ...</translation> + <translation>Shrani &varnostno kopijo denarnice ...</translation> </message> <message> <source>&Change Passphrase...</source> @@ -256,15 +284,15 @@ </message> <message> <source>&Sending addresses...</source> - <translation>&Pošiljanje naslovov...</translation> + <translation>Naslovi za po&šiljanje ...</translation> </message> <message> <source>&Receiving addresses...</source> - <translation>&Prejemanje naslovov...</translation> + <translation>Naslovi za &prejemanje...</translation> </message> <message> <source>Open &URI...</source> - <translation>Odpri &URI...</translation> + <translation>Odpri &URI ...</translation> </message> <message> <source>Bitcoin Core client</source> @@ -272,23 +300,23 @@ </message> <message> <source>Importing blocks from disk...</source> - <translation>Uvažam bloke z diska...</translation> + <translation>Uvažam bloke z diska ...</translation> </message> <message> <source>Reindexing blocks on disk...</source> - <translation>Poustvarjam kazalo blokov na disku...</translation> + <translation>Poustvarjam kazalo blokov na disku ...</translation> </message> <message> <source>Send coins to a Bitcoin address</source> - <translation>Pošlji kovance na Bitcoin naslov</translation> + <translation>Izvedite plačilo na naslov Bitcoin</translation> </message> <message> <source>Backup wallet to another location</source> - <translation>Napravi varnostno kopijo denarnice na drugo lokacijo</translation> + <translation>Shranite varnostno kopijo svoje denarnice na drugo lokacijo</translation> </message> <message> <source>Change the passphrase used for wallet encryption</source> - <translation>Spremeni šifrirno geslo denarnice</translation> + <translation>Spremenite geslo za šifriranje denarnice</translation> </message> <message> <source>&Debug window</source> @@ -296,7 +324,11 @@ </message> <message> <source>Open debugging and diagnostic console</source> - <translation>Odpri razhroščevalno in diagnostično konzolo</translation> + <translation>Odprite razhroščevalno in diagnostično konzolo</translation> + </message> + <message> + <source>&Verify message...</source> + <translation>&Preveri sporočilo ...</translation> </message> <message> <source>Bitcoin</source> @@ -312,11 +344,11 @@ </message> <message> <source>&Receive</source> - <translation>&Sprejmi</translation> + <translation>P&rejmi</translation> </message> <message> <source>Show information about Bitcoin Core</source> - <translation>Pokaži informacije o Bitcoin Core</translation> + <translation>Oglejte si informacije o programu</translation> </message> <message> <source>&Show / Hide</source> @@ -328,11 +360,15 @@ </message> <message> <source>Encrypt the private keys that belong to your wallet</source> - <translation>Šifiraj zasebne ključe v moji denarnici</translation> + <translation>Šifrirajte zasebne ključe, ki se nahajajo v denarnici</translation> </message> <message> <source>Sign messages with your Bitcoin addresses to prove you own them</source> - <translation>Za dokaz, da ste lastniki sporočil, se podpišite z Bitcoin naslovom</translation> + <translation>Podpišite poljubno sporočilo z enim svojih naslovov Bitcoin, da prejemniku sporočila dokažete, da je ta naslov v vaši lasti.</translation> + </message> + <message> + <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source> + <translation>Preverite, če je bilo prejeto sporočilo podpisano z določenim naslovom Bitcoin</translation> </message> <message> <source>&File</source> @@ -352,35 +388,83 @@ </message> <message> <source>Bitcoin Core</source> - <translation>Jedro Bitcoina</translation> + <translation>Bitcoin Core</translation> + </message> + <message> + <source>Request payments (generates QR codes and bitcoin: URIs)</source> + <translation>Zahtevajte plačilo (ustvarite zahtevek s kodo QR in URI tipa bitcoin:)</translation> </message> <message> <source>&About Bitcoin Core</source> - <translation>&O jedru Bitcoina</translation> + <translation>&O programu</translation> + </message> + <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Spremenite programske nastavitve</translation> </message> <message> <source>Show the list of used sending addresses and labels</source> - <translation>Prikaži seznam uporabljenih naslovov za pošiljanje in oznak</translation> + <translation>Preglejte in uredite seznam naslovov, na katere ste kdaj poslali plačila</translation> </message> <message> <source>Show the list of used receiving addresses and labels</source> - <translation>Prikaži seznam uporabljenih sprejemnih naslovov in oznak</translation> + <translation>Preglejte in uredite seznam naslovov, na katere ste kdaj prejeli plačila</translation> </message> <message> <source>Open a bitcoin: URI or payment request</source> - <translation>Odpri Bitcoin: URI ali zahteva o plačilu</translation> + <translation>Izvedite plačilo iz zahtevka v datoteki ali iz URI tipa bitcoin:</translation> + </message> + <message> + <source>&Command-line options</source> + <translation>Opcije &ukazne vrstice</translation> + </message> + <message> + <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> + <translation>Oglejte si seznam in kratek opis vseh opcij pri zagonu programa iz ukazne vrstice</translation> + </message> + <message numerus="yes"> + <source>%n active connection(s) to Bitcoin network</source> + <translation><numerusform>%n aktivna povezava v bitcoin omrežje</numerusform><numerusform>%n aktivni povezavi v bitcoin omrežje</numerusform><numerusform>%n aktivne povezave v bitcoin omrežje</numerusform><numerusform>%n aktivnih povezav v bitcoin omrežje</numerusform></translation> + </message> + <message> + <source>No block source available...</source> + <translation>Ni virov za prenos blokov ...</translation> + </message> + <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>%n obdelan blok zgodovine transakcij.</numerusform><numerusform>%n obdelana bloka zgodovine transakcij.</numerusform><numerusform>%n obdelani bloki zgodovine transakcij.</numerusform><numerusform>%n obdelanih blokov zgodovine transakcij.</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n hour(s)</source> + <translation><numerusform>%n ura</numerusform><numerusform>%n uri</numerusform><numerusform>%n ure</numerusform><numerusform>%n ur</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n day(s)</source> + <translation><numerusform>%n dan</numerusform><numerusform>%n dneva</numerusform><numerusform>%n dni</numerusform><numerusform>%n dni</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n week(s)</source> + <translation><numerusform>%n teden</numerusform><numerusform>%n tedna</numerusform><numerusform>%n tedne</numerusform><numerusform>%n tednov</numerusform></translation> </message> <message> <source>%1 and %2</source> <translation>%1 in %2</translation> </message> + <message numerus="yes"> + <source>%n year(s)</source> + <translation><numerusform>%n leto</numerusform><numerusform>%n leti</numerusform><numerusform>%n leta</numerusform><numerusform>%n let</numerusform></translation> + </message> <message> <source>%1 behind</source> - <translation>%1 odzadaj</translation> + <translation>imam še %1 zaostanka</translation> + </message> + <message> + <source>Last received block was generated %1 ago.</source> + <translation>Zadnji prejeti blok je bil ustvarjen %1 nazaj.</translation> </message> <message> <source>Transactions after this will not yet be visible.</source> - <translation>Transkacija za tem ne bo bila še na voljo.</translation> + <translation>Novejše transakcije še ne bodo vidne.</translation> </message> <message> <source>Error</source> @@ -400,7 +484,37 @@ </message> <message> <source>Catching up...</source> - <translation>Pridobivanje ...</translation> + <translation>Dohitevam omrežje ...</translation> + </message> + <message> + <source>Date: %1 +</source> + <translation>Datum: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Znesek: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Vrsta: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Oznaka: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Naslov: %1 +</translation> </message> <message> <source>Sent transaction</source> @@ -423,18 +537,22 @@ <name>ClientModel</name> <message> <source>Network Alert</source> - <translation>Omrežno Opozorilo</translation> + <translation>Omrežno opozorilo</translation> </message> </context> <context> <name>CoinControlDialog</name> <message> + <source>Coin Selection</source> + <translation>Izbira vhodnih kovancev</translation> + </message> + <message> <source>Quantity:</source> - <translation>Količina:</translation> + <translation>Št.vhodov:</translation> </message> <message> <source>Bytes:</source> - <translation>Biti:</translation> + <translation>Št.bajtov:</translation> </message> <message> <source>Amount:</source> @@ -442,7 +560,7 @@ </message> <message> <source>Priority:</source> - <translation>Prednostno mesto:</translation> + <translation>Prioriteta:</translation> </message> <message> <source>Fee:</source> @@ -453,16 +571,20 @@ <translation>Prah:</translation> </message> <message> + <source>After Fee:</source> + <translation>Po proviziji:</translation> + </message> + <message> <source>Change:</source> - <translation>Sprememba:</translation> + <translation>Vračilo:</translation> </message> <message> <source>(un)select all</source> - <translation>(ne)izberi vse</translation> + <translation>izberi vse/nič</translation> </message> <message> <source>Tree mode</source> - <translation>Drevo</translation> + <translation>Drevesni prikaz</translation> </message> <message> <source>List mode</source> @@ -470,7 +592,15 @@ </message> <message> <source>Amount</source> - <translation>Količina</translation> + <translation>Znesek</translation> + </message> + <message> + <source>Received with label</source> + <translation>Oznaka priliva</translation> + </message> + <message> + <source>Received with address</source> + <translation>Naslov priliva</translation> </message> <message> <source>Date</source> @@ -478,7 +608,7 @@ </message> <message> <source>Confirmations</source> - <translation>Potrdila</translation> + <translation>Potrditve</translation> </message> <message> <source>Confirmed</source> @@ -486,7 +616,7 @@ </message> <message> <source>Priority</source> - <translation>Prednostno mesto</translation> + <translation>Prioriteta</translation> </message> <message> <source>Copy address</source> @@ -498,7 +628,7 @@ </message> <message> <source>Copy amount</source> - <translation>Kopiraj količino</translation> + <translation>Kopiraj znesek</translation> </message> <message> <source>Copy transaction ID</source> @@ -514,19 +644,23 @@ </message> <message> <source>Copy quantity</source> - <translation>Kopiraj količino</translation> + <translation>Kopiraj število vhodov</translation> </message> <message> <source>Copy fee</source> - <translation>Kopiraj provizijo</translation> + <translation>Kopiraj znesek provizije</translation> + </message> + <message> + <source>Copy after fee</source> + <translation>Kopiraj končni znesek</translation> </message> <message> <source>Copy bytes</source> - <translation>Kopiraj bite</translation> + <translation>Kopiraj število bajtov</translation> </message> <message> <source>Copy priority</source> - <translation>Kopiraj prednostno mesto</translation> + <translation>Kopiraj prioriteto</translation> </message> <message> <source>Copy dust</source> @@ -534,7 +668,7 @@ </message> <message> <source>Copy change</source> - <translation>Kopiraj drobiž</translation> + <translation>Kopiraj znesek vračila</translation> </message> <message> <source>highest</source> @@ -554,7 +688,7 @@ </message> <message> <source>medium</source> - <translation>srednje</translation> + <translation>srednja</translation> </message> <message> <source>low-medium</source> @@ -578,11 +712,23 @@ </message> <message> <source>none</source> - <translation>Nič</translation> + <translation>nič</translation> + </message> + <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Oznaka postane rdeča, če je transakcije večja od 1000 bajtov.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Oznaka postane rdeča, če je prioriteta transakcije manjša kot "srednja".</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Oznaka postane rdeča, če je znesek manjši od %1.</translation> </message> <message> <source>Can vary +/- %1 satoshi(s) per input.</source> - <translation>Se lahko razlikuje +/- %1 satošijev na vnos.</translation> + <translation>Lahko variira +/- %1 satoshijev na vhod.</translation> </message> <message> <source>yes</source> @@ -593,8 +739,12 @@ <translation>ne</translation> </message> <message> + <source>This means a fee of at least %1 per kB is required.</source> + <translation>To pomeni, da je zahtevana provizija v višini vsaj %1 na KiB.</translation> + </message> + <message> <source>Can vary +/- 1 byte per input.</source> - <translation>Se lahko razlikuje +/- 1 byte na vnos.</translation> + <translation>Lahko variira +/-1 bajt na vhod.</translation> </message> <message> <source>Transactions with higher priority are more likely to get included into a block.</source> @@ -602,15 +752,15 @@ </message> <message> <source>(no label)</source> - <translation>(ni oznake)</translation> + <translation>(brez oznake)</translation> </message> <message> <source>change from %1 (%2)</source> - <translation>drobiž od %1 (%2)</translation> + <translation>vračilo od %1 (%2)</translation> </message> <message> <source>(change)</source> - <translation>(drobiž)</translation> + <translation>(vračilo)</translation> </message> </context> <context> @@ -625,11 +775,11 @@ </message> <message> <source>The label associated with this address list entry</source> - <translation>Oznaka je povezana s tem vnosom seznama naslovov</translation> + <translation>Oznaka, pod katero je spodnji naslov naveden v vašem imeniku naslovov.</translation> </message> <message> <source>The address associated with this address list entry. This can only be modified for sending addresses.</source> - <translation>Naslov povezan s tem vnosom seznama naslovov. Sprememba je mogoča le za naslove namenjene pošiljanju.</translation> + <translation>Naslov tega vnosa v imeniku. Spremeniti ga je mogoče le pri vnosih iz imenika naslovov za pošiljanje.</translation> </message> <message> <source>&Address</source> @@ -652,23 +802,27 @@ <translation>Uredi naslov za odlive</translation> </message> <message> + <source>The entered address "%1" is already in the address book.</source> + <translation>Vnešeni naslov %1 je že v imeniku.</translation> + </message> + <message> <source>The entered address "%1" is not a valid Bitcoin address.</source> - <translation>Vnešeni naslov "%1" ni veljaven Bitcoin naslov.</translation> + <translation>Vnešeni naslov %1 ni veljaven naslov Bitcoin.</translation> </message> <message> <source>Could not unlock wallet.</source> - <translation>Ni bilo moč odkleniti denarnice.</translation> + <translation>Denarnice ni bilo mogoče odkleniti.</translation> </message> <message> <source>New key generation failed.</source> - <translation>Generiranje novega ključa je spodletelo.</translation> + <translation>Novega ključa ni bilo mogoče ustvariti.</translation> </message> </context> <context> <name>FreespaceChecker</name> <message> <source>A new data directory will be created.</source> - <translation>Ustvarjena bo nova mapa za shranjevanje podatkov.</translation> + <translation>Ustvarjena bo nova podatkovna mapa.</translation> </message> <message> <source>name</source> @@ -676,7 +830,7 @@ </message> <message> <source>Directory already exists. Add %1 if you intend to create a new directory here.</source> - <translation>Mapa že obstaja. Dodaj %1, če tu želiš ustvariti novo mapo.</translation> + <translation>Mapa že obstaja. Dodajte %1, če tu želite ustvariti novo mapo.</translation> </message> <message> <source>Path already exists, and is not a directory.</source> @@ -684,14 +838,14 @@ </message> <message> <source>Cannot create data directory here.</source> - <translation>Na tem mestu ne moreš ustvariti nove mape.</translation> + <translation>Na tem mestu ni mogoče ustvariti nove mape.</translation> </message> </context> <context> <name>HelpMessageDialog</name> <message> <source>Bitcoin Core</source> - <translation>Jedro Bitcoina</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>version</source> @@ -703,7 +857,7 @@ </message> <message> <source>About Bitcoin Core</source> - <translation>O jedru Bitcoina</translation> + <translation>O programu Bitcoin Core</translation> </message> <message> <source>Command-line options</source> @@ -726,36 +880,40 @@ </message> <message> <source>Welcome to Bitcoin Core.</source> - <translation>Dobrodošli v jedru Bitcoina</translation> + <translation>Dobrodošli v programu Bitcoin Core.</translation> </message> <message> <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source> - <translation>Program poganjaš prvič. Izberi kje bo Bitcoin Core shranjeval svoje podatke.</translation> + <translation>To je prvi zagon programa, zato lahko izberete mapo, v katero bo program shranjeval podatke.</translation> </message> <message> <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source> - <translation>Bitcoin Core bo prenesel in shranil kopijo Bitcoin verige blokov. V izbrano mapo bo shranjenih vsaj %1 GB podatkov, ta količina pa bo sčasoma še naraščala. Denarnica bo prav tako shranjena v to mapo.</translation> + <translation>Program bo prenesel in shranil kopijo verige blokov. V izbrani podatkovni mapi bo shranjenih vsaj %1 GiB podatkov, ta količina pa bo sčasoma še naraščala. V tej mapi bo shranjena tudi denarnica.</translation> </message> <message> <source>Use the default data directory</source> - <translation>Uporabi privzeto mapo za shranjevanje podatkov.</translation> + <translation>Uporabi privzeto podatkovno mapo</translation> </message> <message> <source>Use a custom data directory:</source> - <translation>Uporabi to mapo za shranjevanje podatkov:</translation> + <translation>Uporabi to podatkovno mapo:</translation> </message> <message> <source>Bitcoin Core</source> - <translation>Jedro Bitcoina</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>Error: Specified data directory "%1" cannot be created.</source> - <translation>Napaka: Ne morem ustvariti mape "%1".</translation> + <translation>Napaka: Ni mogoče ustvariti mape "%1".</translation> </message> <message> <source>Error</source> <translation>Napaka</translation> </message> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n GiB prostega prostora na voljo</numerusform><numerusform>%n GiB prostega prostora na voljo</numerusform><numerusform>%n GiB prostega prostora na voljo</numerusform><numerusform>%n GiB prostega prostora na voljo</numerusform></translation> + </message> </context> <context> <name>OpenURIDialog</name> @@ -765,7 +923,7 @@ </message> <message> <source>Open payment request from URI or file</source> - <translation>Odpri zahtevo o plačilo od ORI ali datoteke</translation> + <translation>Vnesite zahtevek za plačilo iz URI ali pa ga naložite iz datoteke</translation> </message> <message> <source>URI:</source> @@ -773,11 +931,11 @@ </message> <message> <source>Select payment request file</source> - <translation>Izberi datoteko plačilnega zahtevka</translation> + <translation>Izbiranje datoteke z zahtevkom za plačilo</translation> </message> <message> <source>Select payment request file to open</source> - <translation>Izberi datoteko plačilnega zahtevka</translation> + <translation>Izberite datoteko, ki vsebuje zahtevek za plačilo</translation> </message> </context> <context> @@ -792,55 +950,111 @@ </message> <message> <source>Size of &database cache</source> - <translation>Velikost lokalne zbirke &podatkovne baze</translation> + <translation>Velikost &predpomnilnika podatkovne baze</translation> </message> <message> <source>MB</source> - <translation>megabite</translation> + <translation>MiB</translation> + </message> + <message> + <source>Number of script &verification threads</source> + <translation>Število programskih &niti za preverjanje</translation> </message> <message> <source>Accept connections from outside</source> - <translation>Sprejmi povezave od zunaj</translation> + <translation>Sprejemaj zunanje povezave</translation> </message> <message> <source>Allow incoming connections</source> - <translation>Dovoli prihajajoče povezave</translation> + <translation>Dovoli dohodne povezave</translation> </message> <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> - <translation>IP naslov proxy strežnika (npr. IPv4: 127.0.0.1 ali IPv6: ::1)</translation> + <translation>Naslov IP posredniškega strežnika (npr. IPv4: 127.0.0.1 ali IPv6: ::1)</translation> + </message> + <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>Ko zaprete glavno okno programa, bo program tekel še naprej, okno pa bo zgolj minimirano. Program v tem primeru ustavite tako, da v meniju izberete ukaz Izhod.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>Nastavitev jezika uporabniškega vmesnika programa. Nova nastavitev jezika bo uporabljena šele, ko boste znova zagnali program.</translation> + </message> + <message> + <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> + <translation>Naslovi URL tretjih oseb (npr. raziskovalec blokov), ki bodo navedeni v kontekstnem meniju seznama transakcij. Niz %s iz naslova URL je nadomeščen s hash vrednostjo transakcije. Več zaporednih naslovov URL je med seboj ločenih z znakom |.</translation> + </message> + <message> + <source>Third party transaction URLs</source> + <translation>Zunanje povezave za transakcije</translation> + </message> + <message> + <source>Active command-line options that override above options:</source> + <translation>Aktivne opcije iz ukazne vrstice, ki preglasijo zgornje opcije:</translation> + </message> + <message> + <source>Reset all client options to default.</source> + <translation>Ponastavi vse nastavitve programa na privzete vrednosti.</translation> </message> <message> <source>&Reset Options</source> - <translation>&Opcije resetiranja</translation> + <translation>&Ponastavi nastavitve</translation> </message> <message> <source>&Network</source> <translation>&Omrežje</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Ob uporabnikovi prijavi v sistem se bo program samodejno zagnal</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Zaženi program ob prijavi v sistem</translation> + </message> + <message> + <source>(0 = auto, <0 = leave that many cores free)</source> + <translation>(0 = samodejno, <0 = toliko procesorskih jeder naj ostane prostih)</translation> + </message> + <message> <source>W&allet</source> <translation>&Denarnica</translation> </message> <message> <source>Expert</source> - <translation>Poznavalec</translation> + <translation>Napredne možnosti</translation> </message> <message> <source>Enable coin &control features</source> - <translation>Omogoči Coin & Control funkcijo</translation> + <translation>Omogoči upravljanje s kovanci</translation> + </message> + <message> + <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source> + <translation>Če onemogočite trošenje drobiža iz še nepotrjenih transakcij, potem vrnjenega drobiža ne morete uporabiti, dokler plačilo ni vsaj enkrat potrjeno. Ta opcija vpliva tudi na izračun stanja sredstev.</translation> + </message> + <message> + <source>&Spend unconfirmed change</source> + <translation>Omogoči &trošenje drobiža iz še nepotrjenih plačil</translation> </message> <message> <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> - <translation>Avtomatično odpri vrata Bitcoin odjemalca na usmerjevalniku. To deluje samo, če vaš usmerjevalnik podpira UPnP in je omogočen.</translation> + <translation>Program samodejno odpre ustrezna vrata na usmerjevalniku. To deluje samo, če vaš usmerjevalnik podpira in ima omogočen UPnP.</translation> </message> <message> <source>Map port using &UPnP</source> - <translation>Naslavljanje vrat z uporabo &UPnP</translation> + <translation>Preslikaj vrata z uporabo &UPnP</translation> + </message> + <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>Poveži se v omrežje Bitcoin preko posredniškega strežnika SOCKS5.</translation> + </message> + <message> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation>&Poveži se preko posredniškega strežnika SOCKS5 (privzeti strežnik):</translation> </message> <message> <source>Proxy &IP:</source> - <translation>IP posredniškega strežnika:</translation> + <translation>Naslov &IP posredniškega strežnika:</translation> </message> <message> <source>&Port:</source> @@ -848,15 +1062,15 @@ </message> <message> <source>Port of the proxy (e.g. 9050)</source> - <translation>Vrata strežnika (npr.: 9050)</translation> + <translation>Vrata posredniškega strežnika (npr. 9050)</translation> </message> <message> <source>&Window</source> - <translation>&Okno</translation> + <translation>O&kno</translation> </message> <message> <source>Show only a tray icon after minimizing the window.</source> - <translation>Prikaži samo pomanjšano ikono programa po pomanjšitvi okna.</translation> + <translation>Po minimiranju okna samo prikaži ikono programa v pladnju.</translation> </message> <message> <source>&Minimize to the tray instead of the taskbar</source> @@ -864,7 +1078,7 @@ </message> <message> <source>M&inimize on close</source> - <translation>&Minimiziraj na ukaz zapri</translation> + <translation>Ob zapiranju okno zgolj m&inimiraj</translation> </message> <message> <source>&Display</source> @@ -872,11 +1086,19 @@ </message> <message> <source>User Interface &language:</source> - <translation>Vmesnik uporabnika &jezik:</translation> + <translation>&Jezik uporabniškega vmesnika:</translation> </message> <message> <source>&Unit to show amounts in:</source> - <translation>&</translation> + <translation>&Enota za prikaz zneskov:</translation> + </message> + <message> + <source>Choose the default subdivision unit to show in the interface and when sending coins.</source> + <translation>Izberite privzeto mersko enoto za prikaz v uporabniškem vmesniku in pri pošiljanju kovancev.</translation> + </message> + <message> + <source>Whether to show coin control features or not.</source> + <translation>Omogoči dodatno možnost podrobnega nadzora nad posameznimi kovanci v transakcijah.</translation> </message> <message> <source>&OK</source> @@ -884,7 +1106,7 @@ </message> <message> <source>&Cancel</source> - <translation>&Prekini</translation> + <translation>&Prekliči</translation> </message> <message> <source>default</source> @@ -892,9 +1114,29 @@ </message> <message> <source>none</source> - <translation>Nič</translation> + <translation>nič</translation> </message> - </context> + <message> + <source>Confirm options reset</source> + <translation>Potrditev ponastavitve</translation> + </message> + <message> + <source>Client restart required to activate changes.</source> + <translation>Za uveljavitev sprememb je potreben ponoven zagon programa.</translation> + </message> + <message> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Program bo zaustavljen. Želite nadaljevati z izhodom?</translation> + </message> + <message> + <source>This change would require a client restart.</source> + <translation>Ta sprememba zahteva ponoven zagon programa.</translation> + </message> + <message> + <source>The supplied proxy address is invalid.</source> + <translation>Vnešeni naslov posredniškega strežnika ni veljaven.</translation> + </message> +</context> <context> <name>OverviewPage</name> <message> @@ -903,23 +1145,39 @@ </message> <message> <source>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</source> - <translation>Prikazanim podatkom je lahko potekel rok. Vaša denarnica bo po vzpostavitvi povezave samodejno sinhronizirana z Bitcoin omrežjem, ampak ta proces še ni bil zaključen.</translation> + <translation>Prikazani podatki so morda zastareli. Program ob vzpostavitvi povezave samodejno sinhronizira denarnico z omrežjem Bitcoin, a trenutno ta proces še ni zaključen.</translation> </message> <message> <source>Watch-only:</source> - <translation>Samo gledanje</translation> + <translation>Opazovano:</translation> </message> <message> <source>Available:</source> - <translation>Razpoložljivost:</translation> + <translation>Na voljo:</translation> </message> <message> <source>Your current spendable balance</source> - <translation>Vaše trenutno razpoložljivo stanje</translation> + <translation>Skupni znesek vaših sredstev, s katerimi lahko prosto razpolagate</translation> + </message> + <message> + <source>Pending:</source> + <translation>Nepotrjeno:</translation> </message> <message> <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source> - <translation>Skupno število potrjenih transakcij, ki sicer niso bile prištete k razpoložljivem stanju</translation> + <translation>Skupni znesek sredstev s katerimi še ne razpolagate prosto, ker so del še nepotrjenih transakcij.</translation> + </message> + <message> + <source>Immature:</source> + <translation>Nedozorelo:</translation> + </message> + <message> + <source>Mined balance that has not yet matured</source> + <translation>Nedozorel narudarjeni znesek</translation> + </message> + <message> + <source>Balances</source> + <translation>Stanje sredstev</translation> </message> <message> <source>Total:</source> @@ -927,9 +1185,33 @@ </message> <message> <source>Your current total balance</source> - <translation>Vaše trenutno skupno stanje</translation> + <translation>Trenutna vsota vseh vaših sredstev</translation> </message> - </context> + <message> + <source>Your current balance in watch-only addresses</source> + <translation>Trenutno stanje vaših sredstev na opazovanih naslovih</translation> + </message> + <message> + <source>Spendable:</source> + <translation>Na voljo:</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>Nedavne transakcije</translation> + </message> + <message> + <source>Unconfirmed transactions to watch-only addresses</source> + <translation>Nepotrjene transakcije na opazovanih naslovih</translation> + </message> + <message> + <source>Mined balance in watch-only addresses that has not yet matured</source> + <translation>Nedozoreli narudarjeni znesek na opazovanih naslovih</translation> + </message> + <message> + <source>Current total balance in watch-only addresses</source> + <translation>Trenutno skupno stanje sredstev na opazovanih naslovih</translation> + </message> +</context> <context> <name>PaymentServer</name> <message> @@ -941,16 +1223,80 @@ <translation>Neveljaven naslov plačila %1</translation> </message> <message> + <source>Payment request rejected</source> + <translation>Zahtevek za plačilo je bil zavrnjen.</translation> + </message> + <message> + <source>Payment request network doesn't match client network.</source> + <translation>Zahtevek za plačilo in vaš odjemalec se nahajata na dveh različnih omrežjih.</translation> + </message> + <message> + <source>Payment request is not initialized.</source> + <translation>Zahtevek za plačilo ni inicializiran.</translation> + </message> + <message> + <source>Requested payment amount of %1 is too small (considered dust).</source> + <translation>Znesek %1 v zahtevku za plačilo je prenizek (smatran za prah.)</translation> + </message> + <message> <source>Payment request error</source> - <translation>Napaka pri zahtevi plačila</translation> + <translation>Napaka pri zahtevku za plačilo</translation> + </message> + <message> + <source>Cannot start bitcoin: click-to-pay handler</source> + <translation>Ni mogoče zagnati rokovalca plačilnih povezav tipa bitcoin:.</translation> + </message> + <message> + <source>Payment request fetch URL is invalid: %1</source> + <translation>Naslov URL za pridobitev zahtevka za plačilo ni veljaven: %1</translation> + </message> + <message> + <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source> + <translation>URI je neprepoznaven! Možno je, da je naslov Bitcoin neveljaven, ali da so parametri v URI napačno oblikovani.</translation> + </message> + <message> + <source>Payment request file handling</source> + <translation>Rokovanje z datoteko z zahtevkom za plačilo</translation> + </message> + <message> + <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source> + <translation>Datoteke z zahtevkom za plačilo ni mogoče prebrati! Možno je, da datoteka ni veljavna.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Zahtevek za plačilo je potekel.</translation> + </message> + <message> + <source>Unverified payment requests to custom payment scripts are unsupported.</source> + <translation>Nepreverjeni zahtevki za plačilo, namenjeni plačilni skripti po meri, niso podprti.</translation> + </message> + <message> + <source>Invalid payment request.</source> + <translation>Neveljaven zahtevek za plačilo.</translation> + </message> + <message> + <source>Refund from %1</source> + <translation>Povračilo od %1</translation> + </message> + <message> + <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source> + <translation>Zahtevek za plačilo %1 je prevelik (%2 bajtov, dovoljenih je %3 bajtov.)</translation> + </message> + <message> + <source>Payment request DoS protection</source> + <translation>Zaščita pred napadom denial-of-service zahtevka za plačilo</translation> </message> <message> <source>Error communicating with %1: %2</source> <translation>Napaka pri povezavi z %1: %2</translation> </message> <message> + <source>Payment request cannot be parsed!</source> + <translation>Zahtevek za plačilo je neprepoznaven!</translation> + </message> + <message> <source>Bad response from server %1</source> - <translation>Slab odziv strežnika %1</translation> + <translation>Napačen odziv strežnika %1</translation> </message> <message> <source>Payment acknowledged</source> @@ -964,6 +1310,14 @@ <context> <name>PeerTableModel</name> <message> + <source>User Agent</source> + <translation>Ime agenta</translation> + </message> + <message> + <source>Node/Service</source> + <translation>Vozlišče/Storitev</translation> + </message> + <message> <source>Ping Time</source> <translation>Odzivni čas</translation> </message> @@ -972,26 +1326,46 @@ <name>QObject</name> <message> <source>Amount</source> - <translation>Količina</translation> + <translation>Znesek</translation> + </message> + <message> + <source>Enter a Bitcoin address (e.g. %1)</source> + <translation>Vnesite naslov Bitcoin (npr. %1):</translation> + </message> + <message> + <source>%1 d</source> + <translation>%1 d</translation> </message> <message> <source>%1 h</source> - <translation>%1 ur</translation> + <translation>%1 h</translation> </message> <message> <source>%1 m</source> - <translation>%1 minut</translation> + <translation>%1 m</translation> + </message> + <message> + <source>%1 s</source> + <translation>%1 s</translation> + </message> + <message> + <source>None</source> + <translation>Nič</translation> </message> <message> <source>N/A</source> <translation>Neznano</translation> </message> - </context> + <message> + <source>%1 ms</source> + <translation>%1 ms</translation> + </message> +</context> <context> <name>QRImageWidget</name> <message> <source>&Save Image...</source> - <translation>&Shrani sliko..</translation> + <translation>&Shrani sliko ...</translation> </message> <message> <source>&Copy Image</source> @@ -999,7 +1373,7 @@ </message> <message> <source>Save QR Code</source> - <translation>Shrani QR kodo</translation> + <translation>Shrani kodo QR</translation> </message> <message> <source>PNG Image (*.png)</source> @@ -1025,6 +1399,14 @@ <translation>&Informacije</translation> </message> <message> + <source>Debug window</source> + <translation>Razhroščevalno okno</translation> + </message> + <message> + <source>General</source> + <translation>Splošno</translation> + </message> + <message> <source>Using OpenSSL version</source> <translation>OpenSSL različica v rabi</translation> </message> @@ -1041,6 +1423,10 @@ <translation>Omrežje</translation> </message> <message> + <source>Name</source> + <translation>Ime</translation> + </message> + <message> <source>Number of connections</source> <translation>Število povezav</translation> </message> @@ -1053,26 +1439,82 @@ <translation>Trenutno število blokov</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Odpre razhroščevalni dnevnik debug.log, ki se nahaja v trenutni podatkovni mapi. Če je datoteka velika, lahko postopek traja nekaj sekund.</translation> + </message> + <message> <source>Received</source> <translation>Prejeto</translation> </message> <message> <source>Sent</source> - <translation>Poslano</translation> + <translation>Oddano</translation> + </message> + <message> + <source>&Peers</source> + <translation>&Soležniki</translation> + </message> + <message> + <source>Select a peer to view detailed information.</source> + <translation>Izberite soležnika, o katerem si želite ogledati podrobnejše informacije.</translation> + </message> + <message> + <source>Direction</source> + <translation>Smer povezave</translation> </message> <message> <source>Version</source> <translation>Različica</translation> </message> <message> + <source>User Agent</source> + <translation>Ime agenta</translation> + </message> + <message> <source>Services</source> <translation>Storitve</translation> </message> <message> + <source>Starting Height</source> + <translation>Začetna višina</translation> + </message> + <message> + <source>Sync Height</source> + <translation>Trenutna višina</translation> + </message> + <message> + <source>Ban Score</source> + <translation>Kazenske točke</translation> + </message> + <message> + <source>Connection Time</source> + <translation>Trajanje povezave</translation> + </message> + <message> + <source>Last Send</source> + <translation>Nazadje oddano</translation> + </message> + <message> + <source>Last Receive</source> + <translation>Nazadnje prejeto</translation> + </message> + <message> + <source>Bytes Sent</source> + <translation>Oddanih bajtov</translation> + </message> + <message> + <source>Bytes Received</source> + <translation>Prejetih bajtov</translation> + </message> + <message> <source>Ping Time</source> <translation>Odzivni čas</translation> </message> <message> + <source>Time Offset</source> + <translation>Časovni odklon</translation> + </message> + <message> <source>Last block time</source> <translation>Čas zadnjega bloka</translation> </message> @@ -1090,11 +1532,19 @@ </message> <message> <source>&Clear</source> - <translation>&Pošisti</translation> + <translation>&Počisti</translation> </message> <message> <source>Totals</source> - <translation>Vsote</translation> + <translation>Promet</translation> + </message> + <message> + <source>In:</source> + <translation>Dohodnih:</translation> + </message> + <message> + <source>Out:</source> + <translation>Odhodnih:</translation> </message> <message> <source>Build date</source> @@ -1102,54 +1552,70 @@ </message> <message> <source>Debug log file</source> - <translation>Razhroščevalna dnevniška datoteka</translation> + <translation>Razhroščevalni dnevnik</translation> </message> <message> <source>Clear console</source> <translation>Počisti konzolo</translation> </message> <message> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Dobrodošli v konzoli RPC programa Bitcoin Core.</translation> + </message> + <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> - <translation>Uporabi puščice za gor in dol za navigacijo po zgodovini in <b>Ctrl-L</b> za izbris izpisa na ekranu.</translation> + <translation>Uporabite tipki gor in dol za navigacijo po zgodovini ukazov. Uporabite <b>Ctrl-L</b> za izbris zaslona in zgodovine ukazov.</translation> </message> <message> <source>Type <b>help</b> for an overview of available commands.</source> - <translation>Vtipkaj <b>pomoč</b> za vpogled v razpožljive ukaze.</translation> + <translation>Vtipkajte <b>help</b> za pregled razpoložljivih ukazov.</translation> </message> <message> <source>%1 B</source> - <translation>%1 bitov</translation> + <translation>%1 B</translation> </message> <message> <source>%1 KB</source> - <translation>%1 kilobitov</translation> + <translation>%1 KiB</translation> </message> <message> <source>%1 MB</source> - <translation>%1 megabitov</translation> + <translation>%1 MiB</translation> </message> <message> <source>%1 GB</source> - <translation>%1 gigabitov</translation> + <translation>%1 GiB</translation> + </message> + <message> + <source>via %1</source> + <translation>preko %1</translation> </message> <message> <source>never</source> <translation>nikoli</translation> </message> <message> + <source>Inbound</source> + <translation>Dohodna</translation> + </message> + <message> + <source>Outbound</source> + <translation>Odhodna</translation> + </message> + <message> <source>Unknown</source> <translation>Neznano</translation> </message> <message> <source>Fetching...</source> - <translation>Pridobivam...</translation> + <translation>Pridobivam ...</translation> </message> </context> <context> <name>ReceiveCoinsDialog</name> <message> <source>&Amount:</source> - <translation>&Količina:</translation> + <translation>&Znesek:</translation> </message> <message> <source>&Label:</source> @@ -1160,18 +1626,50 @@ <translation>&Sporočilo:</translation> </message> <message> + <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source> + <translation>Ponovno uporabite enega od že uporabljenih naslovov za prejemanje. Večkratna uporaba istih naslovov za prejemanje negativno vpliva na varnost in zasebnost. To opcijo uporabite samo v primeru, da poustvarjate obstoječ zahtevek za plačilo.</translation> + </message> + <message> + <source>R&euse an existing receiving address (not recommended)</source> + <translation>P&onovno uporabite obstoječ naslov za prejemanje. (Ni priporočeno.)</translation> + </message> + <message> + <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source> + <translation>Neobvezno sporočilo kot priponka zahtevku za plačilo, ki bo prikazano, ko bo zahtevek odprt. Opomba: Opravljeno plačilo.prek omrežja Bitcoin tega sporočila ne bo vsebovalo.</translation> + </message> + <message> <source>An optional label to associate with the new receiving address.</source> - <translation>Pomožna oznaka je povezana z novim sprejemnim naslovom.</translation> + <translation>Oznaka novega sprejemnega naslova.</translation> + </message> + <message> + <source>Use this form to request payments. All fields are <b>optional</b>.</source> + <translation>S tem obrazcem ustvarite nov zahtevek za plačilo. Vsa polja so <b>neobvezna</b>.</translation> + </message> + <message> + <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source> + <translation>Zahtevani znesek. Če ne zahtevate določenega zneska, pustite prazno ali nastavite vrednost na 0.</translation> + </message> + <message> + <source>Clear all fields of the form.</source> + <translation>Počisti vsa polja.</translation> </message> <message> <source>Clear</source> <translation>Počisti</translation> </message> <message> + <source>Requested payments history</source> + <translation>Zgodovina zahtevkov za plačilo</translation> + </message> + <message> <source>&Request payment</source> <translation>&Zahtevaj plačilo</translation> </message> <message> + <source>Show the selected request (does the same as double clicking an entry)</source> + <translation>Prikaz izbranega zahtevka. (Isto funkcijo opravi dvojni klik na zapis.)</translation> + </message> + <message> <source>Show</source> <translation>Pokaži</translation> </message> @@ -1193,7 +1691,7 @@ </message> <message> <source>Copy amount</source> - <translation>Kopiraj količino</translation> + <translation>Kopiraj znesek</translation> </message> </context> <context> @@ -1204,19 +1702,23 @@ </message> <message> <source>Copy &URI</source> - <translation>Kopraj &URl</translation> + <translation>Kopiraj &URl</translation> </message> <message> <source>Copy &Address</source> - <translation>Kopiraj &Naslov</translation> + <translation>Kopiraj &naslov</translation> </message> <message> <source>&Save Image...</source> - <translation>&Shrani sliko..</translation> + <translation>&Shrani sliko ...</translation> + </message> + <message> + <source>Request payment to %1</source> + <translation>Zahtevek za plačilo z oznako: %1</translation> </message> <message> <source>Payment information</source> - <translation>Informacija o plačilu</translation> + <translation>Informacije o plačilu</translation> </message> <message> <source>URI</source> @@ -1228,7 +1730,7 @@ </message> <message> <source>Amount</source> - <translation>Količina</translation> + <translation>Znesek</translation> </message> <message> <source>Label</source> @@ -1240,11 +1742,11 @@ </message> <message> <source>Resulting URI too long, try to reduce the text for label / message.</source> - <translation>URI predolg, skušajte zmanjšati besedilo oznake/sporočila.</translation> + <translation>Nastali URI je predolg. Skušajte skrajšati besedilo v oznaki/sporočilu.</translation> </message> <message> <source>Error encoding URI into QR Code.</source> - <translation>Napaka pri kodiranju URIja v QR kodo.</translation> + <translation>Napaka pri pretvorbi URI v kodo QR.</translation> </message> </context> <context> @@ -1263,34 +1765,38 @@ </message> <message> <source>Amount</source> - <translation>Količina</translation> + <translation>Znesek</translation> </message> <message> <source>(no label)</source> - <translation>(ni oznake)</translation> + <translation>(brez oznake)</translation> </message> <message> <source>(no message)</source> - <translation>(ni sporočila)</translation> + <translation>(brez sporočila)</translation> </message> <message> <source>(no amount)</source> - <translation>(brez količine)</translation> + <translation>(brez zneska)</translation> </message> </context> <context> <name>SendCoinsDialog</name> <message> <source>Send Coins</source> - <translation>Pošlji kovance</translation> + <translation>Pošlji</translation> + </message> + <message> + <source>Coin Control Features</source> + <translation>Upravljanje s kovanci</translation> </message> <message> <source>Inputs...</source> - <translation>Vnosi...</translation> + <translation>Vhodi ...</translation> </message> <message> <source>automatically selected</source> - <translation>samodejno izbran</translation> + <translation>samodejno izbrani</translation> </message> <message> <source>Insufficient funds!</source> @@ -1298,11 +1804,11 @@ </message> <message> <source>Quantity:</source> - <translation>Količina:</translation> + <translation>Št.vhodov:</translation> </message> <message> <source>Bytes:</source> - <translation>Biti:</translation> + <translation>Št.bajtov:</translation> </message> <message> <source>Amount:</source> @@ -1310,15 +1816,95 @@ </message> <message> <source>Priority:</source> - <translation>Prednostno mesto:</translation> + <translation>Prioriteta:</translation> </message> <message> <source>Fee:</source> <translation>Provizija:</translation> </message> <message> + <source>After Fee:</source> + <translation>Po proviziji:</translation> + </message> + <message> <source>Change:</source> - <translation>Sprememba:</translation> + <translation>Vračilo:</translation> + </message> + <message> + <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source> + <translation>Če to vključite, nato pa vnesete neveljaven naslov, ali pa pustite polje prazno, bo vrnjen drobiž poslan na novo ustvarjen naslov.</translation> + </message> + <message> + <source>Custom change address</source> + <translation>Naslov za vračilo drobiža po meri</translation> + </message> + <message> + <source>Transaction Fee:</source> + <translation>Provizija:</translation> + </message> + <message> + <source>Choose...</source> + <translation>Izberi ...</translation> + </message> + <message> + <source>collapse fee-settings</source> + <translation>Skrije nastavitve provizije</translation> + </message> + <message> + <source>per kilobyte</source> + <translation>na KiB</translation> + </message> + <message> + <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> + <translation>Če je nastavitev zneska provizije po meri enaka 1000 satoshijev, transakcija pa je velika samo 250 bajtov, je obračunani znesek provizije pri nastavitvi "za KiB" samo 250 satoshijev, medtem ko je pri nastavitvi "skupno vsaj" ta znesek 1000 satoshijev. Za transakcije, večje od 1 KiB, se končni znesek pri obeh nastavitvah obračuna na KiB.</translation> + </message> + <message> + <source>Hide</source> + <translation>Skrij</translation> + </message> + <message> + <source>total at least</source> + <translation>skupno vsaj</translation> + </message> + <message> + <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source> + <translation>Dokler bo v blokih še dovolj prostora za vse nastajajoče transakcije, zadostuje, če plačate samo minimalno provizijo. Ko pa se bo količina vseh transakcij povečala do meja zmogljivosti omrežja, se lahko zgodi, da vaša transakcija brez večje provizije nikoli ne bo potrjena.</translation> + </message> + <message> + <source>(read the tooltip)</source> + <translation>(oglejte si namig)</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Priporočena:</translation> + </message> + <message> + <source>Custom:</source> + <translation>Po meri:</translation> + </message> + <message> + <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source> + <translation>(Samodejni obračun provizije še ni pripravljen. Po navadi izračun traja nekaj blokov ...)</translation> + </message> + <message> + <source>Confirmation time:</source> + <translation>Čas do potrditve:</translation> + </message> + <message> + <source>normal</source> + <translation>navadno</translation> + </message> + <message> + <source>fast</source> + <translation>hitro</translation> + </message> + <message> + <source>Send as zero-fee transaction if possible</source> + <translation>Pošlji brez provizije, če je mogoče</translation> + </message> + <message> + <source>(confirmation may take longer)</source> + <translation>(čas do potrditve je lahko daljši)</translation> </message> <message> <source>Send to multiple recipients at once</source> @@ -1329,6 +1915,10 @@ <translation>Dodaj &prejemnika</translation> </message> <message> + <source>Clear all fields of the form.</source> + <translation>Počisti vsa polja.</translation> + </message> + <message> <source>Dust:</source> <translation>Prah:</translation> </message> @@ -1338,43 +1928,55 @@ </message> <message> <source>Balance:</source> - <translation>Dobroimetje:</translation> + <translation>Stanje:</translation> </message> <message> <source>Confirm the send action</source> - <translation>Potrdi odlivno dejanje</translation> + <translation>Potrdi pošiljanje</translation> </message> <message> <source>S&end</source> - <translation>P&ošlji</translation> + <translation>&Pošlji</translation> </message> <message> <source>Confirm send coins</source> - <translation>Potrdi odliv kovancev </translation> + <translation>Potrdi pošiljanje</translation> + </message> + <message> + <source>%1 to %2</source> + <translation>%1 na %2</translation> </message> <message> <source>Copy quantity</source> - <translation>Kopiraj količino</translation> + <translation>Kopiraj število vhodov</translation> </message> <message> <source>Copy amount</source> - <translation>Kopiraj količino</translation> + <translation>Kopiraj znesek</translation> </message> <message> <source>Copy fee</source> <translation>Kopiraj provizijo</translation> </message> <message> + <source>Copy after fee</source> + <translation>Kopiraj Po proviziji</translation> + </message> + <message> <source>Copy bytes</source> - <translation>Kopiraj bite</translation> + <translation>Kopiraj bajte</translation> </message> <message> <source>Copy priority</source> - <translation>Kopiraj prednostno mesto</translation> + <translation>Kopiraj prioriteto</translation> </message> <message> <source>Copy change</source> - <translation>Kopiraj drobiž</translation> + <translation>Kopiraj vračilo</translation> + </message> + <message> + <source>Total Amount %1 (= %2)</source> + <translation>Skupni znesek %1 (= %2)</translation> </message> <message> <source>or</source> @@ -1382,19 +1984,59 @@ </message> <message> <source>The amount to pay must be larger than 0.</source> - <translation>Količina za plačilo mora biti večja od 0.</translation> + <translation>Znesek za plačilo mora biti večji od 0.</translation> </message> <message> <source>The amount exceeds your balance.</source> - <translation>Količina presega vaše dobroimetje</translation> + <translation>Znesek je večji od stanja sredstev, s katerimi razpolagate.</translation> + </message> + <message> + <source>The total exceeds your balance when the %1 transaction fee is included.</source> + <translation>Celotni znesek z vključeno provizijo %1 je večji od stanja sredstev, s katerimi razpolagate.</translation> + </message> + <message> + <source>Transaction creation failed!</source> + <translation>Transakcije ni bilo mogoče ustvariti!</translation> + </message> + <message> + <source>The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source> + <translation>Transakcija je bila zavrnjena! To se lahko zgodi, če so bili kateri od kovancev iz denarnice že porabljeni, kot v primeru, da ste kje uporabili kopijo datoteke wallet.dat in kovance tam že porabili, lokalno pa ti še niso bili označeni kot porabljeni.</translation> + </message> + <message> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>Provizija, višja od %1, velja za nesmiselno visoko.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Zahtevek za plačilo je potekel.</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Predviden začetek potrditev po %n najdenem bloku.</numerusform><numerusform>Predviden začetek potrditev po %n najdenih blokih.</numerusform><numerusform>Predviden začetek potrditev po %n najdenih blokih.</numerusform><numerusform>Predviden začetek potrditev po %n najdenih blokih.</numerusform></translation> + </message> + <message> + <source>Pay only the minimum fee of %1</source> + <translation>Plačilo samo minimalne provizije v znesku %1</translation> + </message> + <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Naslov prejemnika je neveljaven. Prosimo, preverite.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Naslov je že bil uporabljen. Vsak naslov naj bi se uporabil samo enkrat.</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> - <translation>Opozorilo: Neveljaven Bitcoin naslov</translation> + <translation>Opozorilo: Neveljaven bitcoin naslov</translation> </message> <message> <source>(no label)</source> - <translation>(ni oznake)</translation> + <translation>(brez oznake)</translation> + </message> + <message> + <source>Warning: Unknown change address</source> + <translation>Opozorilo: Neznan naslov za vračilo drobiža</translation> </message> <message> <source>Copy dust</source> @@ -1402,7 +2044,7 @@ </message> <message> <source>Are you sure you want to send?</source> - <translation>Ali ste prepričani, da želite poslati?</translation> + <translation>Ali ste prepričani, da želite izvesti plačilo?</translation> </message> <message> <source>added as transaction fee</source> @@ -1413,7 +2055,7 @@ <name>SendCoinsEntry</name> <message> <source>A&mount:</source> - <translation>K&oličina:</translation> + <translation>&Znesek:</translation> </message> <message> <source>Pay &To:</source> @@ -1421,7 +2063,7 @@ </message> <message> <source>Enter a label for this address to add it to your address book</source> - <translation>Vnesite oznako za ta naslov, ki bo shranjena v imenik</translation> + <translation>Vnesite oznako, pod katero bo zgornji naslov shranjen v imenik</translation> </message> <message> <source>&Label:</source> @@ -1429,7 +2071,15 @@ </message> <message> <source>Choose previously used address</source> - <translation>Izberi zadnje uporabljen naslov</translation> + <translation>Izberite enega od že uporabljenih naslovov</translation> + </message> + <message> + <source>This is a normal payment.</source> + <translation>Plačilo je navadne vrste.</translation> + </message> + <message> + <source>The Bitcoin address to send the payment to</source> + <translation>Naslov Bitcoin, na katerega bo plačilo poslano</translation> </message> <message> <source>Alt+A</source> @@ -1437,41 +2087,85 @@ </message> <message> <source>Paste address from clipboard</source> - <translation>Prilepi naslov iz odložišča</translation> + <translation>Prilepite naslov iz odložišča</translation> </message> <message> <source>Alt+P</source> <translation>Alt+P</translation> </message> <message> + <source>Remove this entry</source> + <translation>Izpraznite vsebino polja</translation> + </message> + <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>Znesek plačila bo zmanjšan za znesek provizije. Prejemnik bo prejel manjše število kovancev, kot je bil vnešeni znesek. Če je prejemnikov več, bo provizija med njih enakomerno porazdeljena.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>O&dštej provizijo od zneska</translation> + </message> + <message> <source>Message:</source> <translation>Sporočilo:</translation> </message> <message> + <source>This is an unauthenticated payment request.</source> + <translation>Zahtevek za plačilo je neoverjen.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Zahtevek za plačilo je overjen.</translation> + </message> + <message> <source>Enter a label for this address to add it to the list of used addresses</source> - <translation>Vnesite oznako za ta naslov, ki bo shranjena v seznam uporabljenih naslovov</translation> + <translation>Če vnesete oznako za zgornji naslov, se bo skupaj z naslovom shranila v imenk že uporabljenih naslovov</translation> </message> - </context> + <message> + <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source> + <translation>Sporočilo, ki ste ga pripeli na URI tipa bitcoin:. Shranjeno bo skupaj s podatki o transakciji. Opomba: Sporočilo ne bo poslano preko omrežja Bitcoin.</translation> + </message> + <message> + <source>Pay To:</source> + <translation>Prejemnik:</translation> + </message> + <message> + <source>Memo:</source> + <translation>Opomba:</translation> + </message> +</context> <context> <name>ShutdownWindow</name> <message> + <source>Bitcoin Core is shutting down...</source> + <translation>Program se ustavlja ...</translation> + </message> + <message> <source>Do not shut down the computer until this window disappears.</source> - <translation>Ne zaustavite računalnika dokler to okno ne izgine.</translation> + <translation>Dokler to okno ne izgine, ne zaustavljajte računalnika.</translation> </message> </context> <context> <name>SignVerifyMessageDialog</name> <message> <source>Signatures - Sign / Verify a Message</source> - <translation>Podpisi - Podpiši/preveri sporočilo</translation> + <translation>Podpiši / preveri sporočilo</translation> </message> <message> <source>&Sign Message</source> <translation>&Podpiši sporočilo</translation> </message> <message> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>S svojimi naslovi lahko podpisujete sporočila ali pogodbe in s tem dokazujete, da na teh naslovih lahko prejemate kovance. Bodite previdni in ne podpisujte ničesar nejasnega ali naključnega, ker vas zlikovci preko ribarjenja (phishing) lahko prelisičijo, da na njih prepišete svojo identiteto. Podpisujte samo podrobno opisane izjave, s katerimi se strinjate.</translation> + </message> + <message> + <source>The Bitcoin address to sign the message with</source> + <translation>Naslov Bitcoin, s katerim podpisujete sporočilo</translation> + </message> + <message> <source>Choose previously used address</source> - <translation>Izberi zadnje uporabljen naslov</translation> + <translation>Izberite enega od že uporabljenih naslovov</translation> </message> <message> <source>Alt+A</source> @@ -1479,21 +2173,37 @@ </message> <message> <source>Paste address from clipboard</source> - <translation>Prilepi naslov iz odložišča</translation> + <translation>Prilepite naslov iz odložišča</translation> </message> <message> <source>Alt+P</source> <translation>Alt+P</translation> </message> <message> + <source>Enter the message you want to sign here</source> + <translation>Vnesite sporočilo, ki ga želite podpisati</translation> + </message> + <message> <source>Signature</source> <translation>Podpis</translation> </message> <message> + <source>Copy the current signature to the system clipboard</source> + <translation>Kopiranje trenutnega podpisa na sistemsko odložišče.</translation> + </message> + <message> + <source>Sign the message to prove you own this Bitcoin address</source> + <translation>Podpišite sporočilo, da dokažete lastništvo nad zgornjim naslovom.</translation> + </message> + <message> <source>Sign &Message</source> <translation>Podpiši &sporočilo</translation> </message> <message> + <source>Reset all sign message fields</source> + <translation>Počisti vsa polja za vnos v oknu za podpisovanje</translation> + </message> + <message> <source>Clear &All</source> <translation>Počisti &vse </translation> </message> @@ -1502,12 +2212,28 @@ <translation>&Preveri sporočilo</translation> </message> <message> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Da preverite verodostojnost sporočila, spodaj vnesite: prejemnikov naslov, prejeto sporočilo (pazljivo skopirajte vse prelome vrstic, presledke, tabulatorje ipd.,) in prejeti podpis. Da se izognete napadom tipa man-in-the-middle, vedite, da iz veljavnega podpisa ne sledi nič drugega, kot tisto, kar je navedeno v sporočilu. Podpis samo potrjuje dejstvo, da ima podpisnik v lasti prejemni naslov, ne more pa dokazati vira nobene transakcije!</translation> + </message> + <message> + <source>The Bitcoin address the message was signed with</source> + <translation>Naslov Bitcoin, s katerim je bilo sporočilo podpisano</translation> + </message> + <message> + <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> + <translation>Preverite, ali je bilo sporočilo v resnici podpisano z navedenim naslovom Bitcoin.</translation> + </message> + <message> <source>Verify &Message</source> - <translation>Preveri &Sporočilo</translation> + <translation>Preveri &sporočilo</translation> + </message> + <message> + <source>Reset all verify message fields</source> + <translation>Počisti vsa polja za vnos v oknu za preverjanje</translation> </message> <message> <source>Click "Sign Message" to generate signature</source> - <translation>Kliknite "Podpiši sporočilo" za ustvaritev podpisa</translation> + <translation>Kliknite "Podpiši sporočilo" da ustvarite podpis</translation> </message> <message> <source>The entered address is invalid.</source> @@ -1515,46 +2241,58 @@ </message> <message> <source>Please check the address and try again.</source> - <translation>Prosimo preverite naslov in poizkusite znova.</translation> + <translation>Prosimo preverite naslov in poskusite znova.</translation> + </message> + <message> + <source>The entered address does not refer to a key.</source> + <translation>Vnešeni naslov se ne nanaša na noben ključ.</translation> </message> <message> <source>Wallet unlock was cancelled.</source> - <translation>Odklepanje denarnice je bilo prekinjeno.</translation> + <translation>Odklepanje denarnice je bilo preklicano.</translation> </message> <message> <source>Private key for the entered address is not available.</source> - <translation>Zasebni ključ vnešenega naslov ni na voljo.</translation> + <translation>Zasebni ključ vnešenega naslova ni na voljo.</translation> </message> <message> <source>Message signing failed.</source> - <translation>Podpisovanje sporočila spodletelo.</translation> + <translation>Podpisa ni bilo mogoče ustvariti.</translation> </message> <message> <source>Message signed.</source> - <translation>Sporočilo podpisano.</translation> + <translation>Podpis je bil ustvarjen.</translation> </message> <message> <source>The signature could not be decoded.</source> - <translation>Ni bilo mogoče dešifrirati podpisa.</translation> + <translation>Podpisa ni bilo mogoče razbrati.</translation> </message> <message> <source>Please check the signature and try again.</source> - <translation>Prosimo preverite podpis in poizkusite znova.</translation> + <translation>Prosimo preverite podpis in poskusite znova.</translation> + </message> + <message> + <source>The signature did not match the message digest.</source> + <translation>Podpis se ne ujema z rezultatom funkcije preverjanja.</translation> </message> <message> <source>Message verification failed.</source> - <translation>Pregledovanje sporočila spodletelo.</translation> + <translation>Podpis ni veljaven za to sporočilo.</translation> </message> <message> <source>Message verified.</source> - <translation>Sporočilo pregledano.</translation> + <translation>Podpis sporočila je veljaven.</translation> </message> </context> <context> <name>SplashScreen</name> <message> <source>Bitcoin Core</source> - <translation>Jedro Bitcoina</translation> + <translation>Bitcoin Core</translation> + </message> + <message> + <source>The Bitcoin Core developers</source> + <translation>Bitcoin Core razvijalci</translation> </message> <message> <source>[testnet]</source> @@ -1563,12 +2301,24 @@ </context> <context> <name>TrafficGraphWidget</name> - </context> + <message> + <source>KB/s</source> + <translation>KiB/s</translation> + </message> +</context> <context> <name>TransactionDesc</name> <message> <source>Open until %1</source> - <translation>Odpri enoto %1</translation> + <translation>Odprto do %1</translation> + </message> + <message> + <source>conflicted</source> + <translation>v konfliktu</translation> + </message> + <message> + <source>%1/offline</source> + <translation>%1/brez povezave</translation> </message> <message> <source>%1/unconfirmed</source> @@ -1580,7 +2330,11 @@ </message> <message> <source>Status</source> - <translation>Stanje</translation> + <translation>Status</translation> + </message> + <message numerus="yes"> + <source>, broadcast through %n node(s)</source> + <translation><numerusform>, posredovano %n vozlišču</numerusform><numerusform>, posredovano %n vozliščema</numerusform><numerusform>, posredovano %n vozliščem</numerusform><numerusform>, posredovano %n vozliščem</numerusform></translation> </message> <message> <source>Date</source> @@ -1607,16 +2361,36 @@ <translation>lasten naslov</translation> </message> <message> + <source>watch-only</source> + <translation>opazovano</translation> + </message> + <message> <source>label</source> <translation>oznaka</translation> </message> <message> + <source>Credit</source> + <translation>V dobro</translation> + </message> + <message numerus="yes"> + <source>matures in %n more block(s)</source> + <translation><numerusform>dozori po %n najdenem bloku</numerusform><numerusform>dozori po %n najdenih blokih</numerusform><numerusform>dozori po %n najdenih blokih</numerusform><numerusform>dozori po %n najdenih blokih</numerusform></translation> + </message> + <message> <source>not accepted</source> <translation>ni bilo sprejeto</translation> </message> <message> <source>Debit</source> - <translation>Dolg</translation> + <translation>Debit</translation> + </message> + <message> + <source>Total debit</source> + <translation>Skupaj v breme</translation> + </message> + <message> + <source>Total credit</source> + <translation>Skupaj v dobro</translation> </message> <message> <source>Transaction fee</source> @@ -1624,7 +2398,7 @@ </message> <message> <source>Net amount</source> - <translation>Neto količina</translation> + <translation>Neto znesek</translation> </message> <message> <source>Message</source> @@ -1643,8 +2417,12 @@ <translation>Trgovec</translation> </message> <message> + <source>Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source> + <translation>Ustvarjeni kovanci morajo zoreti %1 blokov, preden jih lahko porabite. Ko ste ta blok zgenerirali, je bil posredovan v omrežje, da bo dodan v verigo. Če se bloku ni uspelo uvrstiti v verigo, se bo njegovo stanje spremenilo v "ni bilo sprejeto" in kovancev ne bo mogoče porabiti. To se včasih zgodi, če kak drug rudar v roku nekaj sekund hkrati z vami odkrije drug blok.</translation> + </message> + <message> <source>Debug information</source> - <translation>Razhroščevalna informacija</translation> + <translation>Razhroščevalne informacije</translation> </message> <message> <source>Transaction</source> @@ -1652,11 +2430,11 @@ </message> <message> <source>Inputs</source> - <translation>Vnosi</translation> + <translation>Vhodi</translation> </message> <message> <source>Amount</source> - <translation>Količina</translation> + <translation>Znesek</translation> </message> <message> <source>true</source> @@ -1670,6 +2448,10 @@ <source>, has not been successfully broadcast yet</source> <translation>, še ni bila uspešno raznešena</translation> </message> + <message numerus="yes"> + <source>Open for %n more block(s)</source> + <translation><numerusform>Odprto še %n blok</numerusform><numerusform>Odprto še %n bloka</numerusform><numerusform>Odprto še %n bloke</numerusform><numerusform>Odprto še %n blokov</numerusform></translation> + </message> <message> <source>unknown</source> <translation>neznano</translation> @@ -1683,7 +2465,7 @@ </message> <message> <source>This pane shows a detailed description of the transaction</source> - <translation>To podokno prikazuje podroben opis transakcije</translation> + <translation>V tem podoknu so prikazane podrobnosti o transakciji</translation> </message> </context> <context> @@ -1697,8 +2479,16 @@ <translation>Vrsta</translation> </message> <message> + <source>Immature (%1 confirmations, will be available after %2)</source> + <translation>Nedozorelo (št. potrditev: %1, na voljo šele po: %2)</translation> + </message> + <message numerus="yes"> + <source>Open for %n more block(s)</source> + <translation><numerusform>Odprto še %n blok</numerusform><numerusform>Odprto še %n bloka</numerusform><numerusform>Odprto še %n bloke</numerusform><numerusform>Odprto še %n blokov</numerusform></translation> + </message> + <message> <source>Open until %1</source> - <translation>Odpri enoto %1</translation> + <translation>Odprto do %1</translation> </message> <message> <source>Confirmed (%1 confirmations)</source> @@ -1713,6 +2503,10 @@ <translation>Generirano, toda ne sprejeto</translation> </message> <message> + <source>Offline</source> + <translation>Brez povezave</translation> + </message> + <message> <source>Label</source> <translation>Oznaka</translation> </message> @@ -1721,24 +2515,36 @@ <translation>Nepotrjeno</translation> </message> <message> + <source>Confirming (%1 of %2 recommended confirmations)</source> + <translation>V potrjevanju (št. potrditev: %1 od priporočenih %2)</translation> + </message> + <message> + <source>Conflicted</source> + <translation>V konfliktu</translation> + </message> + <message> <source>Received with</source> - <translation>Prejeto z</translation> + <translation>Prejemek</translation> </message> <message> <source>Received from</source> - <translation>Prejeto od</translation> + <translation>Prejemek</translation> </message> <message> <source>Sent to</source> - <translation>Poslano</translation> + <translation>Izdatek</translation> </message> <message> <source>Payment to yourself</source> - <translation>Izplačilo sebi</translation> + <translation>Nakazilo sebi</translation> </message> <message> <source>Mined</source> - <translation>Minirano</translation> + <translation>Narudarjeno</translation> + </message> + <message> + <source>watch-only</source> + <translation>opazovano</translation> </message> <message> <source>(n/a)</source> @@ -1757,8 +2563,16 @@ <translation>Vrsta transakcije.</translation> </message> <message> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <translation>Ali je v transakciji udeležen kateri od opazovanih naslovov.</translation> + </message> + <message> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Uporabniško določen namen transakcije.</translation> + </message> + <message> <source>Amount removed from or added to balance.</source> - <translation>Količina odlita ali prilita dobroimetju.</translation> + <translation>Znesek spremembe stanja sredstev.</translation> </message> </context> <context> @@ -1793,19 +2607,19 @@ </message> <message> <source>Received with</source> - <translation>Prejeto z</translation> + <translation>Prejemek</translation> </message> <message> <source>Sent to</source> - <translation>Poslano</translation> + <translation>Izdatek</translation> </message> <message> <source>To yourself</source> - <translation>Samemu sebi</translation> + <translation>Nakazilo sebi</translation> </message> <message> <source>Mined</source> - <translation>Minirano</translation> + <translation>Narudarjeno</translation> </message> <message> <source>Other</source> @@ -1813,11 +2627,11 @@ </message> <message> <source>Enter address or label to search</source> - <translation>Vnesite naslov ali oznako za iskanje</translation> + <translation>Iščite po naslovu ali oznaki</translation> </message> <message> <source>Min amount</source> - <translation>Minimalna količina</translation> + <translation>Minimalni znesek</translation> </message> <message> <source>Copy address</source> @@ -1829,7 +2643,7 @@ </message> <message> <source>Copy amount</source> - <translation>Kopiraj količino</translation> + <translation>Kopiraj znesek</translation> </message> <message> <source>Copy transaction ID</source> @@ -1844,8 +2658,20 @@ <translation>Prikaži podrobnosti transakcije</translation> </message> <message> + <source>Export Transaction History</source> + <translation>Izvoz zgodovine transakcij</translation> + </message> + <message> + <source>Watch-only</source> + <translation>Opazovano</translation> + </message> + <message> <source>Exporting Failed</source> - <translation>Neuspešen izvoz</translation> + <translation>Seznama transakcij ni bilo mogoče izvoziti.</translation> + </message> + <message> + <source>There was an error trying to save the transaction history to %1.</source> + <translation>Prišlo je do napake med shranjevanjem zgodovine transakcij v datoteko %1.</translation> </message> <message> <source>Exporting Successful</source> @@ -1853,7 +2679,7 @@ </message> <message> <source>The transaction history was successfully saved to %1.</source> - <translation>Zgodovina poteklih transakcij je bila uspešno shranjena na %1.</translation> + <translation>Zgodovina poteklih transakcij je bila uspešno shranjena v datoteko %1.</translation> </message> <message> <source>Comma separated file (*.csv)</source> @@ -1894,15 +2720,23 @@ </context> <context> <name>UnitDisplayStatusBarControl</name> - </context> + <message> + <source>Unit to show amounts in. Click to select another unit.</source> + <translation>Merska enota za prikaz zneskov. Kliknite za izbiro druge enote.</translation> + </message> +</context> <context> <name>WalletFrame</name> - </context> + <message> + <source>No wallet has been loaded.</source> + <translation>Denarnica ni bila naložena.</translation> + </message> +</context> <context> <name>WalletModel</name> <message> <source>Send Coins</source> - <translation>Pošlji kovance</translation> + <translation>Pošlji</translation> </message> </context> <context> @@ -1913,11 +2747,11 @@ </message> <message> <source>Export the data in the current tab to a file</source> - <translation>Izvozi podatke v trenutni zavih v datoteko</translation> + <translation>Izvozi podatke iz trenutnega zavihka v datoteko</translation> </message> <message> <source>Backup Wallet</source> - <translation>Napravi varnostno kopijo denarnice</translation> + <translation>Izdelava varnostne kopije denarnice</translation> </message> <message> <source>Wallet Data (*.dat)</source> @@ -1925,19 +2759,19 @@ </message> <message> <source>Backup Failed</source> - <translation>Varnostna kopijo neuspešna</translation> + <translation>Varnostne kopije ni bilo mogoče izdelati.</translation> </message> <message> <source>There was an error trying to save the wallet data to %1.</source> - <translation>Prišlo je do napake pri shranjevanju podatkov denarnice na %1.</translation> + <translation>Prišlo je do napake pri shranjevanju podatkov denarnice v datoteko %1.</translation> </message> <message> <source>The wallet data was successfully saved to %1.</source> - <translation>Podatki denarnice so bili uspešno shranjena na %1.</translation> + <translation>Podatki iz denarnice so bili uspešno shranjeni v datoteko %1.</translation> </message> <message> <source>Backup Successful</source> - <translation>Varnostna kopija uspešna</translation> + <translation>Varnostna kopija je bila uspešno izdelana</translation> </message> </context> <context> @@ -1948,11 +2782,11 @@ </message> <message> <source>Specify data directory</source> - <translation>Določi podatkovni imenik</translation> + <translation>Izberite podatkovno mapo</translation> </message> <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> - <translation>Povežite se z vozliščem za pridobitev naslovov uporabnikov in nato prekinite povezavo.</translation> + <translation>Povežite se z vozliščem za pridobitev naslovov soležnikov in nato prekinite povezavo.</translation> </message> <message> <source>Specify your own public address</source> @@ -1960,7 +2794,7 @@ </message> <message> <source>Accept command line and JSON-RPC commands</source> - <translation>Sprejmi ukaze iz ukazne vrstice in JSON-RPC</translation> + <translation>Sprejemaj ukaze iz ukazne vrstice in preko JSON-RPC</translation> </message> <message> <source>Run in the background as a daemon and accept commands</source> @@ -1971,16 +2805,72 @@ <translation>Uporabi testno omrežje</translation> </message> <message> + <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> + <translation>Sprejemaj zunanje povezave (privzeto: 1, razen če ste vklopili opciji -proxy ali -connect)</translation> + </message> + <message> + <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> + <translation>Veži dani naslov in tam vedno poslušaj. Za naslove protokola IPv6 uporabite zapis [gostitelj]:vrata.</translation> + </message> + <message> + <source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> + <translation>Distribuirano v okviru programske licence MIT. Podrobnosti so navedene v priloženi datoteki COPYING ali na naslovu <http://www.opensource.org/licenses/mit-license.php>.</translation> + </message> + <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Izvedi ukaz, ko bo transakcija denarnice se spremenila (V cmd je bil TxID zamenjan za %s)</translation> </message> <message> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Največji še veljavni skupni znesek provizij pri transakcijah z uporabo ene denarnice. Prenizka nastavitev lahko povzroči izločitev večjih transakcij (privzeto %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>Omogoči obrezovanje (brisanje) starejših blokov in s tem prihrani pri prostoru za shranjevanje. Ta način delovanja onemogoči uporabo denarnice in ni združljivo z opcijo -txindex. Opozorilo: Če kasneje to opcijo povrnete na privzeto vrednost, boste morali ponovno prenesti celotno verigo. (privzeto: 0 = onemogoči obrezovanje, >%u = ciljna velikost datotek blokov v MiB)</translation> + </message> + <message> + <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> + <translation>Nastavi število niti za preverjanje skript (%u do %d, 0 = samodejno, <0 toliko procesorskih jeder naj ostane prostih, privzeto: %d)</translation> + </message> + <message> <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source> - <translation>To je pred izdana poizkusna verzija - uporaba na lastno odgovornost - ne uporabljajte je za rudarstvo ali trgovske aplikacije</translation> + <translation>To je preizkusna različica še neizdanega programa. Uporabljate jo na lastno odgovornost. Programa ne uporabljajte je za rudarjenje ali trgovske aplikacije.</translation> + </message> + <message> + <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source> + <translation>Na tem računalniku ni bilo mogoče vezati naslova %s. Odjemalec Bitcoin Core je verjetno že zagnan.</translation> + </message> + <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>OPOZORILO: Generirano je bilo nenavadno veliko število blokov. Št. prejetih blokov: %d v št. ur: %d (pričakovanih je %d blokov)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>OPOZORILO: Preverite vašo omrežno povezavo. Št. prejetih blokov: %d v št. ur: %d (pričakovanih je %d blokov)</translation> + </message> + <message> + <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> + <translation>Opozorilo: Vrednost opcije -paytxfee je zelo visoka. To je provizija, ki jo boste plačali, če izvedete plačilo.</translation> + </message> + <message> + <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> + <translation>Opozorilo: Trenutno na omrežju ni videti konsenza! Videti je, kot da bi imeli nekateri rudarji težave.</translation> + </message> + <message> + <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source> + <translation>Opozorilo: Trenutno se s soležniki ne strinjam v popolnosti! Mogoče bi morali vi ali drugi udeleženci posodobiti odjemalce.</translation> </message> <message> <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source> - <translation>Opozorilo: napaka pri branju wallet.dat! Vsi ključi so bili pravilno prebrani, podatki o transakciji ali imenik vnešenih naslovov so morda izgubljeni ali nepravilni.</translation> + <translation>Opozorilo: napaka pri branju datoteke wallet.dat! Vsi ključi so bili pravilno prebrani, podatki o transakciji ali imenik vnešenih naslovov so morda izgubljeni ali nepravilni.</translation> + </message> + <message> + <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source> + <translation>Opozorilo: Datoteka wallet.dat je bila okvarjena, podatki pa so bili kljub temu rešeni! Originalna datoteka je bila shranjena kot wallet.{čas.oznaka}.bak v mapo %s. Če sta skupno stanje ali seznam transakcij napačna, morate datoteko restavrirati iz varnostne kopije.</translation> + </message> + <message> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>Sprejemaj povezave samo od soležnikov, ki so na naslovih, ki ustrezajo navedeni omrežni maski ali naslovu. Opcijo lahko navedete večkrat.</translation> </message> <message> <source>(default: 1)</source> @@ -1991,92 +2881,328 @@ <translation><category> je lahko:</translation> </message> <message> + <source>Attempt to recover private keys from a corrupt wallet.dat</source> + <translation>Skušaj obnoviti zasebne ključe iz okvarjene datoteke wallet.dat</translation> + </message> + <message> <source>Block creation options:</source> <translation>Možnosti ustvarjanja blokov:</translation> </message> <message> + <source>Connect only to the specified node(s)</source> + <translation>Poveži se samo z (enim ali več) navedenimi vozlišči</translation> + </message> + <message> + <source>Connection options:</source> + <translation>Izbire povezave:</translation> + </message> + <message> + <source>Corrupted block database detected</source> + <translation>Podatkovna baza blokov je okvarjena</translation> + </message> + <message> + <source>Debugging/Testing options:</source> + <translation>Možnosti razhroščevanja in testiranja:</translation> + </message> + <message> + <source>Do not load the wallet and disable wallet RPC calls</source> + <translation>Ne naloži denarnice in onemogoči s tem povezane klice RPC</translation> + </message> + <message> + <source>Do you want to rebuild the block database now?</source> + <translation>Želite zdaj obnoviti podatkovno bazo blokov?</translation> + </message> + <message> + <source>Error initializing block database</source> + <translation>Napaka pri inicializaciji podatkovne baze blokov</translation> + </message> + <message> + <source>Error initializing wallet database environment %s!</source> + <translation>Napaka pri inicializaciji okolja podatkovne baze denarnice %s!</translation> + </message> + <message> + <source>Error loading block database</source> + <translation>Napaka pri nalaganju podatkovne baze blokov</translation> + </message> + <message> + <source>Error opening block database</source> + <translation>Napaka pri odpiranju podatkovne baze blokov</translation> + </message> + <message> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation>Napaka: Med izvajanjem je prišlo do nepopravljive napake. Podrobnosti so v datoteki debug.log</translation> + </message> + <message> <source>Error: Disk space is low!</source> <translation>Opozorilo: Premalo prostora na disku!</translation> </message> <message> + <source>Failed to listen on any port. Use -listen=0 if you want this.</source> + <translation>Ni mogoče poslušati na nobenih vratih. Če to zares želite, uporabite opcijo -listen=0.</translation> + </message> + <message> + <source>If <category> is not supplied, output all debugging information.</source> + <translation>Če element <category> ni naveden, izpisuje vse informacije za razhroščevanje.</translation> + </message> + <message> <source>Importing...</source> - <translation>Uvažam...</translation> + <translation>Uvažam ...</translation> + </message> + <message> + <source>Incorrect or no genesis block found. Wrong datadir for network?</source> + <translation>Izvornega bloka ni mogoče najti ali pa je neveljaven. Preverite, če ste izbrali pravo podatkovno mapo za izbrano omrežje.</translation> + </message> + <message> + <source>Invalid -onion address: '%s'</source> + <translation>Neveljaven naslov tipa -onion: '%s'</translation> + </message> + <message> + <source>Not enough file descriptors available.</source> + <translation>Na voljo ni dovolj deskriptorjev datotek.</translation> + </message> + <message> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <translation>Povezuj se samo z vozlišči na omrežju tipa <net> (IPv4, IPv6 ali onion)</translation> + </message> + <message> + <source>Prune cannot be configured with a negative value.</source> + <translation>Negativne vrednosti parametra funkcije obrezovanja niso sprejemljive.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>Funkcija obrezovanja ni združljiva z opcijo -txindex.</translation> + </message> + <message> + <source>Set database cache size in megabytes (%d to %d, default: %d)</source> + <translation>Nastavitev velikosti predpomnilnik podatkovne baze v MiB (%d do %d, privzeto: %d)</translation> + </message> + <message> + <source>Set maximum block size in bytes (default: %d)</source> + <translation>Nastavitev maksimalne velikosti bloka v bajtih (privzeto: %d)</translation> + </message> + <message> + <source>Specify wallet file (within data directory)</source> + <translation>Ime datoteke z denarnico (znotraj podatkovne mape)</translation> + </message> + <message> + <source>Use UPnP to map the listening port (default: %u)</source> + <translation>Uporabi protokol UPnP za preslikavo vrat za poslušanje (privzeto: %u)</translation> + </message> + <message> + <source>Verifying blocks...</source> + <translation>Preverjam celovitost blokov ...</translation> + </message> + <message> + <source>Verifying wallet...</source> + <translation>Preverjam celovitost denarnice ...</translation> + </message> + <message> + <source>Wallet %s resides outside data directory %s</source> + <translation>Datoteka %s z denarnico se nahaja izven podatkovne mape %s</translation> + </message> + <message> + <source>Wallet options:</source> + <translation>Izbire denarnice:</translation> + </message> + <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Opozorilo: Različica vašega odjemalca je zastarela. Potrebna je nadgradnja!</translation> + </message> + <message> + <source>You need to rebuild the database using -reindex to change -txindex</source> + <translation>Ob spremembi vrednosti opcije -txindex boste morali obnoviti bazo podatkov z uporabo opcije -reindex</translation> + </message> + <message> + <source>Imports blocks from external blk000??.dat file</source> + <translation>Uvozi bloke iz zunanje datoteke blk000??.dat</translation> + </message> + <message> + <source>Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source> + <translation>Iz navedenega vira dovoli povezave na JSON-RPC. Veljavne oblike vrednosti parametra <ip> so: edinstven naslov IP (npr.: 1.2.3.4), kombinacija omrežje/netmask (npr.: 1.2.3.4/255.255.255.0), ali pa kombinacija omrežje/CIDR (1.2.3.4/24). To opcijo lahko navedete večkrat.</translation> + </message> + <message> + <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> + <translation>Prišlo je do napake med zagonom poslušalca RPC na naslovu %s in vratih %u: %s</translation> + </message> + <message> + <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> + <translation>Veži dani naslov in sprejemaj povezave samo od navedenih soležnikov. Za naslove protokola IPv6 uporabite zapis [gostitelj]:vrata.</translation> + </message> + <message> + <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source> + <translation>Veži dani naslov in sprejemaj povezave na JSON-RPC. Za naslove protokola IPv6 uporabite zapis [gostitelj]:vrata. To opcijo lahko navedete večkrat. (privzeto: veži vse omrežne vmesnike)</translation> + </message> + <message> + <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> + <translation>Ne morem zakleniti podatkovne mape %s. Bitcoin Core je verjetno že zagnan.</translation> + </message> + <message> + <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> + <translation>Ustvarjaj nove datoteke s privzetimi sistemskimi dovoljenji, namesto z umask 077. (To pride v poštev samo, kadar imate izklopljeno funkcijo denarnice.)</translation> + </message> + <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Odkrij svoj naslov IP (privzeto: 1, če poslušate in sta opciji -externalip in -proxy neaktivni)</translation> + </message> + <message> + <source>Error: Listening for incoming connections failed (listen returned error %s)</source> + <translation>Napaka: Ni mogoče sprejemati dohodnih povezav (vrnjena napaka: %s)</translation> + </message> + <message> + <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> + <translation>Napaka: Navedli ste nepodprto vrednost opcije -socks. Različice protokola SOCKS ni več mogoče navesti, podprti so samo posredniški strežniki tipa SOCKS5.</translation> + </message> + <message> + <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source> + <translation>Ko bo prejeto ustrezno opozorilo, ali ko bo opažena zelo dolga razvejitev, izvedi navedeni ukazni niz. (Niz %s bo nadomeščen z vsebino sporočila.)</translation> + </message> + <message> + <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> + <translation>Provizije (v BTC/KiB), ki so manjše od te vrednosti, se pri posredovanju smatrajo za nične (privzeto: %s)</translation> + </message> + <message> + <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> + <translation>Če opcija -paytxfee ni nastavljena, nastavi znesek provizije tako visoko, da bodo transakcije potrjene v povprečno n blokih. (privzeto: %u)</translation> + </message> + <message> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Na vsak posredniški strežnik se prijavi z drugimi naključnimi podatki. Tako je omogočena osamitev tokov v omrežju Tor (privzeto: %u)</translation> + </message> + <message> + <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>Opozorilo: Preverite, če sta datum in ura na vašem računalniku točna! Bitcoin Core ne bo dobro deloval, če je nastavljeni čas nepravilen.</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(privzeto: %u)</translation> + </message> + <message> + <source>Activating best chain...</source> + <translation>Preklapljam na najboljšo verigo ...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>Če je omogočena funkcija obrezovanja, ni mogoče uporabljati denarnice.</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Naslova %s, podanega pri opciji -whitebind ni mogoče razrešiti.</translation> </message> <message> <source>Choose data directory on startup (default: 0)</source> - <translation>Ob zagonu izberi mapo za shranjevanje podatkov (privzeto: 0)</translation> + <translation>Ob zagonu pozovi uporabnika, naj izbere podatkovno mapo (privzeto: 0)</translation> + </message> + <message> + <source>Connect through SOCKS5 proxy</source> + <translation>Poveži se preko posredniškega strežnika SOCKS5</translation> + </message> + <message> + <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source> + <translation>Copyright (C) 2009-%i The Bitcoin Core Developers</translation> + </message> + <message> + <source>Could not parse -rpcbind value %s as network address</source> + <translation>Vrednost %s opcije -rpcbind ni prepoznaven omrežni naslov</translation> </message> <message> <source>Information</source> <translation>Informacije</translation> </message> <message> + <source>Need to specify a port with -whitebind: '%s'</source> + <translation>Pri opciji -whitebind morate navesti vrata: %s</translation> + </message> + <message> <source>Send trace/debug info to console instead of debug.log file</source> - <translation>Pošlji sledilne/razhroščevalne informacije v konzolo namesto jih shraniti v debug.log datoteko</translation> + <translation>Pošilja sledilne/razhroščevalne informacije na konzolo namesto v datoteko debug.log</translation> </message> <message> <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Nastavi korenske SSL certifikate za plačilni zahtevek (privzeto: -system-)</translation> + <translation>Nastavi korenske certifikate SSL za preverjanje zahtevkov za plačilo (privzeto: -system-)</translation> </message> <message> <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Nastavi jezik, npr. "sl_SI" (privzeto: jezikovna oznaka sistema)</translation> + <translation>Nastavi jezik, npr. "sl_SI" (privzeto: jezik sistema)</translation> </message> <message> <source>Show splash screen on startup (default: 1)</source> <translation>Ob zagonu prikaži uvodni zaslon (privzeto: 1)</translation> </message> <message> + <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> + <translation>Ob zagonu skrajšaj datoteko debug.log (privzeto: 1, če ni vklopljena opcija -debug)</translation> + </message> + <message> <source>Signing transaction failed</source> - <translation>Podpisovanje transakcije spodletelo</translation> + <translation>Transakcije ni bilo mogoče podpisati.</translation> </message> <message> <source>Start minimized</source> - <translation>Zaženi pomanjšano</translation> + <translation>Zaženi v minimiranem oknu</translation> + </message> + <message> + <source>This is experimental software.</source> + <translation>Program je eksperimentalne narave.</translation> </message> <message> <source>Transaction amount too small</source> - <translation>Količina transakcije je pramajhna</translation> + <translation>Znesek je pramajhen</translation> </message> <message> <source>Transaction amounts must be positive</source> - <translation>Količina transkacije mora biti pozitivna</translation> + <translation>Znesek mora biti pozitiven</translation> </message> <message> <source>Transaction too large</source> <translation>Transkacija je prevelika</translation> </message> <message> + <source>UI Options:</source> + <translation>Možnosti uporabniškega vmesnika:</translation> + </message> + <message> + <source>Unable to bind to %s on this computer (bind returned error %s)</source> + <translation>Na tem računalniku ni bilo mogoče vezati naslova %s (vrnjena napaka: %s)</translation> + </message> + <message> <source>Username for JSON-RPC connections</source> - <translation>Uporabniško ime za JSON-RPC povezave</translation> + <translation>Uporabniško ime za povezave na JSON-RPC</translation> </message> <message> <source>Warning</source> <translation>Opozorilo</translation> </message> <message> + <source>Zapping all transactions from wallet...</source> + <translation>Brišem vse transakcije iz denarnice ...</translation> + </message> + <message> + <source>on startup</source> + <translation>ob zagonu</translation> + </message> + <message> <source>wallet.dat corrupt, salvage failed</source> - <translation>wallet.dat poškodovana, neuspešna obnova</translation> + <translation>Datoteka wallet.dat je poškodovana in je ni bilo mogoče obnoviti.</translation> </message> <message> <source>Password for JSON-RPC connections</source> - <translation>Geslo za JSON-RPC povezave</translation> + <translation>Geslo za povezave na JSON-RPC</translation> </message> <message> <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source> - <translation>Izvedi ukaz, ko je najboljši blok spremenjen (%s je v cmd zamenjan za iskalnik blokov)</translation> + <translation>Izvedi ukaz, ko je najden najboljši blok (niz %s v ukazu bo zamenjan s hash vrednostjo bloka)</translation> </message> <message> <source>Upgrade wallet to latest format</source> - <translation>Posodobi denarnico v najnovejši zapis</translation> + <translation>Nadgradi denarnico na najnovejšo različico</translation> </message> <message> <source>Rescan the block chain for missing wallet transactions</source> - <translation>Ponovno preglej verigo blokov za manjkajoče transakcije denarnice</translation> + <translation>S ponovnim pregledom verige blokov poišči manjkajoče transakcije iz denarnice</translation> </message> <message> <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Uporabi OpenSSL (https) za JSON-RPC povezave</translation> + <translation>Uporabi OpenSSL (https) za povezave na JSON-RPC</translation> </message> <message> <source>This help message</source> @@ -2084,23 +3210,59 @@ </message> <message> <source>Allow DNS lookups for -addnode, -seednode and -connect</source> - <translation>Omogoči DNS poizvedbe za -addnode, -seednode in -connect.</translation> + <translation>Omogoči poizvedbe DNS za opcije -addnode, -seednode in -connect.</translation> </message> <message> <source>Loading addresses...</source> - <translation>Nalaganje naslovov ...</translation> + <translation>Nalagam naslove ...</translation> </message> <message> <source>Error loading wallet.dat: Wallet corrupted</source> <translation>Napaka pri nalaganju wallet.dat: denarnica pokvarjena</translation> </message> <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation>Za dostop do soležnikov preko skritih storitev Tor uporabi drug posredniški strežnik SOCKS5 (privzeto: %s)</translation> + </message> + <message> + <source>(default: %s)</source> + <translation>(privzeto: %s)</translation> + </message> + <message> + <source>Acceptable ciphers (default: %s)</source> + <translation>Sprejemljivi tipi šifriranja (privzeto: %s)</translation> + </message> + <message> <source>Error loading wallet.dat</source> <translation>Napaka pri nalaganju wallet.dat</translation> </message> <message> <source>Invalid -proxy address: '%s'</source> - <translation>Neveljaven -proxy naslov: '%s'</translation> + <translation>Neveljaven naslov -proxy: '%s'</translation> + </message> + <message> + <source>Relay non-P2SH multisig (default: %u)</source> + <translation>Posreduj transakcije tipa multisig, ki niso hkrati tipa P2SH. (privzeto: %u)</translation> + </message> + <message> + <source>Specify configuration file (default: %s)</source> + <translation>Za shranjevanje konfiguracije uporabi navedeno datoteko. (privzeto: %s)</translation> + </message> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Vzpostavljanje nove povezave poteče po navedenem št. pretečenih milisekund. (najmanj: 1, privzeto: %d)</translation> + </message> + <message> + <source>Specify pid file (default: %s)</source> + <translation>Za shranjevanje PID uporabi navedeno datoteko. (privzeto: %s)</translation> + </message> + <message> + <source>Spend unconfirmed change when sending transactions (default: %u)</source> + <translation>Pri odlivnih transakcijah omogoči trošenje drobiža iz še nepotrjenih plačil (privzeto: %u)</translation> + </message> + <message> + <source>Threshold for disconnecting misbehaving peers (default: %u)</source> + <translation>Prekini povezavo s soležnikom, ko št. njegovih kazenskih točk preseže navedeni prag. (privzeto: %u)</translation> </message> <message> <source>Unknown network specified in -onlynet: '%s'</source> @@ -2108,11 +3270,11 @@ </message> <message> <source>Cannot resolve -bind address: '%s'</source> - <translation>Nemogoče rešiti -bind naslova: '%s'</translation> + <translation>Naslova %s, podanega pri opciji -bind ni mogoče razrešiti.</translation> </message> <message> <source>Cannot resolve -externalip address: '%s'</source> - <translation>Nemogoče rešiti -externalip naslova: '%s'</translation> + <translation>Naslova "%s", podanega pri opciji -externalip ni mogoče razrešiti.</translation> </message> <message> <source>Invalid amount for -paytxfee=<amount>: '%s'</source> @@ -2124,15 +3286,15 @@ </message> <message> <source>Loading block index...</source> - <translation>Nalaganje indeksa blokov ...</translation> + <translation>Nalagam kazalo blokov ...</translation> </message> <message> <source>Add a node to connect to and attempt to keep the connection open</source> - <translation>Dodaj vozlišče za povezavo nanj in skušaj le to obdržati odprto</translation> + <translation>Dodaj povezavo na vozlišče in jo skušaj držati odprto</translation> </message> <message> <source>Loading wallet...</source> - <translation>Nalaganje denarnice ...</translation> + <translation>Nalagam denarnico ...</translation> </message> <message> <source>Cannot downgrade wallet</source> @@ -2144,7 +3306,7 @@ </message> <message> <source>Rescanning...</source> - <translation>Ponovno pregledovanje ...</translation> + <translation>Ponovno pregledujem verigo ...</translation> </message> <message> <source>Done loading</source> diff --git a/src/qt/locale/bitcoin_sq.ts b/src/qt/locale/bitcoin_sq.ts index 2e345e85cb..6ed9856889 100644 --- a/src/qt/locale/bitcoin_sq.ts +++ b/src/qt/locale/bitcoin_sq.ts @@ -1,4 +1,4 @@ -<TS language="sq" version="2.1"> +<TS language="sq" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -46,14 +46,38 @@ <translation>Duke marr adresen</translation> </message> <message> + <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> + <translation>Këto janë Bitcoin adresat e juaja për të dërguar pagesa. Gjithmon kontrolloni shumën dhe adresën pranuese para se të dërgoni monedha.</translation> + </message> + <message> + <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> + <translation>Këto janë Bitcoin adresat e juaja për të pranuar pagesa. Rekomandohet që gjithmon të përdorni një adresë të re për çdo transaksion.</translation> + </message> + <message> + <source>Copy &Label</source> + <translation>Kopjo &Etiketë</translation> + </message> + <message> <source>&Edit</source> <translation>&Ndrysho</translation> </message> <message> + <source>Export Address List</source> + <translation>Eksporto listën e adresave</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Skedar i ndarë me pikëpresje(*.csv)</translation> </message> - </context> + <message> + <source>Exporting Failed</source> + <translation>Eksportimi dështoj</translation> + </message> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>Gabim gjatë ruajtjes së listës së adresave në %1. Ju lutem provoni prapë.</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -688,6 +712,10 @@ <translation>Kopjo adresën</translation> </message> <message> + <source>Exporting Failed</source> + <translation>Eksportimi dështoj</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Skedar i ndarë me pikëpresje(*.csv)</translation> </message> diff --git a/src/qt/locale/bitcoin_sr.ts b/src/qt/locale/bitcoin_sr.ts index 83e6e2f29e..ddaab9ab2b 100644 --- a/src/qt/locale/bitcoin_sr.ts +++ b/src/qt/locale/bitcoin_sr.ts @@ -1,4 +1,4 @@ -<TS language="sr" version="2.1"> +<TS language="sr" version="2.0"> <context> <name>AddressBookPage</name> <message> diff --git a/src/qt/locale/bitcoin_sv.ts b/src/qt/locale/bitcoin_sv.ts index 289074f134..0139154019 100644 --- a/src/qt/locale/bitcoin_sv.ts +++ b/src/qt/locale/bitcoin_sv.ts @@ -1,4 +1,4 @@ -<TS language="sv" version="2.1"> +<TS language="sv" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -67,11 +67,11 @@ </message> <message> <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> - <translation>Detta är dina Bitcoin adresser för att skicka betalningar. Kolla alltid summan och den mottagande adressen innan du skickar Bitcoins.</translation> + <translation>Detta är dina Bitcoin-adresser för att skicka betalningar. Kolla alltid summan och den mottagande adressen innan du skickar Bitcoins.</translation> </message> <message> <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> - <translation>Detta är dina Bitcoin adresser för att ta emot betalningar. Det rekommenderas att använda en ny mottagningsadress för varje transaktion.</translation> + <translation>Detta är dina Bitcoin-adresser för att ta emot betalningar. Det rekommenderas att använda en ny mottagningsadress för varje transaktion.</translation> </message> <message> <source>Copy &Label</source> @@ -111,14 +111,14 @@ Var vänlig och försök igen.</translation> </message> <message> <source>(no label)</source> - <translation>(Ingen etikett)</translation> + <translation>(ingen etikett)</translation> </message> </context> <context> <name>AskPassphraseDialog</name> <message> <source>Passphrase Dialog</source> - <translation>Lösenords Dialog</translation> + <translation>Lösenordsdialog</translation> </message> <message> <source>Enter passphrase</source> @@ -281,7 +281,7 @@ Var vänlig och försök igen.</translation> </message> <message> <source>&Change Passphrase...</source> - <translation>&Byt Lösenord...</translation> + <translation>&Byt lösenord...</translation> </message> <message> <source>&Sending addresses...</source> @@ -297,7 +297,7 @@ Var vänlig och försök igen.</translation> </message> <message> <source>Bitcoin Core client</source> - <translation>Bitcoin Core klient</translation> + <translation>Bitcoin Core-klient</translation> </message> <message> <source>Importing blocks from disk...</source> @@ -321,7 +321,7 @@ Var vänlig och försök igen.</translation> </message> <message> <source>&Debug window</source> - <translation>&Debug fönster</translation> + <translation>&Debug-fönster</translation> </message> <message> <source>Open debugging and diagnostic console</source> @@ -385,11 +385,11 @@ Var vänlig och försök igen.</translation> </message> <message> <source>Tabs toolbar</source> - <translation>Verktygsfält för Tabbar</translation> + <translation>Verktygsfält för tabbar</translation> </message> <message> <source>Bitcoin Core</source> - <translation>Bitcoin Kärna</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>Request payments (generates QR codes and bitcoin: URIs)</source> @@ -421,7 +421,7 @@ Var vänlig och försök igen.</translation> </message> <message> <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> - <translation>Visa Bitcoin Core hjälpmeddelande för att få en lista med möjliga Bitcoin kommandoradsalternativ.</translation> + <translation>Visa Bitcoin Cores hjälpmeddelande för att få en lista med möjliga Bitcoin-kommandoradsalternativ.</translation> </message> <message numerus="yes"> <source>%n active connection(s) to Bitcoin network</source> @@ -461,7 +461,7 @@ Var vänlig och försök igen.</translation> </message> <message> <source>Last received block was generated %1 ago.</source> - <translation>Senast mottagna block genererades %1 sen.</translation> + <translation>Senast mottagna block genererades för %1 sen.</translation> </message> <message> <source>Transactions after this will not yet be visible.</source> @@ -553,7 +553,7 @@ Var vänlig och försök igen.</translation> </message> <message> <source>Bytes:</source> - <translation>Antal Byte:</translation> + <translation>Antal byte:</translation> </message> <message> <source>Amount:</source> @@ -581,15 +581,15 @@ Var vänlig och försök igen.</translation> </message> <message> <source>(un)select all</source> - <translation>(av)välj allt</translation> + <translation>(av)markera allt</translation> </message> <message> <source>Tree mode</source> - <translation>Trädmetod</translation> + <translation>Trädvy</translation> </message> <message> <source>List mode</source> - <translation>Listmetod</translation> + <translation>Listvy</translation> </message> <message> <source>Amount</source> @@ -609,7 +609,7 @@ Var vänlig och försök igen.</translation> </message> <message> <source>Confirmations</source> - <translation>Konfirmationer</translation> + <translation>Bekräftelser</translation> </message> <message> <source>Confirmed</source> @@ -764,7 +764,7 @@ Var vänlig och försök igen.</translation> <name>EditAddressDialog</name> <message> <source>Edit Address</source> - <translation>Redigera Adress</translation> + <translation>Redigera adress</translation> </message> <message> <source>&Label</source> @@ -842,7 +842,7 @@ Var vänlig och försök igen.</translation> <name>HelpMessageDialog</name> <message> <source>Bitcoin Core</source> - <translation>Bitcoin Kärna</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>version</source> @@ -881,11 +881,11 @@ Var vänlig och försök igen.</translation> </message> <message> <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source> - <translation>Eftersom detta är första gången programmet startas får du välja var Bitcoin Core skall lagra sitt data.</translation> + <translation>Eftersom detta är första gången programmet startas får du välja var Bitcoin Core skall lagra sina data.</translation> </message> <message> <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source> - <translation>Bitcoin Core kommer att ladda ner och spara en kopia av Bitcoin blockkedjan. Åtminstone %1GB av data kommer att sparas i denna katalog, och den kommer att växa över tiden. Plånboken kommer också att sparas i denna katalog.</translation> + <translation>Bitcoin Core kommer att ladda ner och spara en kopia av Bitcoin-blockkedjan. Åtminstone %1GB av data kommer att sparas i denna katalog, och den kommer att växa över tiden. Plånboken kommer också att sparas i denna katalog.</translation> </message> <message> <source>Use the default data directory</source> @@ -897,7 +897,7 @@ Var vänlig och försök igen.</translation> </message> <message> <source>Bitcoin Core</source> - <translation>Bitcoin Kärna</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>Error: Specified data directory "%1" cannot be created.</source> @@ -959,7 +959,7 @@ Var vänlig och försök igen.</translation> </message> <message> <source>Number of script &verification threads</source> - <translation>Antalet skript & verifikationstrådar</translation> + <translation>Antalet skript&verifikationstrådar</translation> </message> <message> <source>Accept connections from outside</source> @@ -983,7 +983,7 @@ Var vänlig och försök igen.</translation> </message> <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> - <translation>Tredjeparts URL:er (t.ex. en block utforskare) som finns i transaktionstabben som ett menyval i sammanhanget. %s i URL:en ersätts med tansaktionshashen. Flera URL:er är separerade med vertikala streck |.</translation> + <translation>Tredjeparts URL:er (t.ex. en blockutforskare) som finns i transaktionstabben som ett menyval i sammanhanget. %s i URL:en ersätts med tansaktionshashen. Flera URL:er är separerade med vertikala streck |.</translation> </message> <message> <source>Third party transaction URLs</source> @@ -991,15 +991,15 @@ Var vänlig och försök igen.</translation> </message> <message> <source>Active command-line options that override above options:</source> - <translation>Aktiva kommandoradsalternativ som överrider alternativen ovan:</translation> + <translation>Aktiva kommandoradsalternativ som ersätter alternativen ovan:</translation> </message> <message> <source>Reset all client options to default.</source> - <translation>Återställ alla klient inställningar till förvalen.</translation> + <translation>Återställ alla klientinställningar till förvalen.</translation> </message> <message> <source>&Reset Options</source> - <translation>&Återställ Alternativ</translation> + <translation>&Återställ alternativ</translation> </message> <message> <source>&Network</source> @@ -1027,15 +1027,15 @@ Var vänlig och försök igen.</translation> </message> <message> <source>Enable coin &control features</source> - <translation>Aktivera mynt och kontrollfunktioner</translation> + <translation>Aktivera mynt&kontrollfunktioner</translation> </message> <message> <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source> - <translation>Om du avaktiverar betalning med okonfirmerade växel, kan inte växeln från en transaktion användas förrän den transaktionen har minst en konfirmation.</translation> + <translation>Om du avaktiverar betalning med obekräftad växel, kan inte växeln från en transaktion användas förrän den transaktionen har minst en bekräftelse.</translation> </message> <message> <source>&Spend unconfirmed change</source> - <translation>&Spendera okonfirmerad växel</translation> + <translation>&Spendera obekräftad växel</translation> </message> <message> <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> @@ -1095,7 +1095,7 @@ Var vänlig och försök igen.</translation> </message> <message> <source>Choose the default subdivision unit to show in the interface and when sending coins.</source> - <translation>Välj en måttenhet att visa när du skickar mynt.</translation> + <translation>Välj en måttenhet att visa i gränssnittet och när du skickar mynt.</translation> </message> <message> <source>Whether to show coin control features or not.</source> @@ -1135,7 +1135,7 @@ Var vänlig och försök igen.</translation> </message> <message> <source>The supplied proxy address is invalid.</source> - <translation>Den medföljande proxy adressen är ogiltig.</translation> + <translation>Den angivna proxy-adressen är ogiltig.</translation> </message> </context> <context> @@ -2806,10 +2806,6 @@ Var vänlig och försök igen.</translation> <translation>Bind till given adress och lyssna alltid på den. Använd [värd]:port notation för IPv6</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)</source> - <translation>Hastighetsbegränsa avgiftsfria transaktionerna till <n>*1000 bytes per minut (förvalt: %u)</translation> - </message> - <message> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <translation>Ta bort alla plånbokstransaktioner och återskapa bara dom som är en del av blockkedjan genom att ange -rescan vid uppstart</translation> </message> @@ -2818,18 +2814,10 @@ Var vänlig och försök igen.</translation> <translation>Distribuerad under MIT mjukvarulicens, se den bifogade filen COPYING eller <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Ange regressiontestläge, som använder en speciell kedja i vilka block kan lösas omedelbart.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Exekvera kommando när en plånbokstransaktion ändras (%s i cmd är ersatt av TxID)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>I denna mode kontrollerar -genproclimit hur många block som genereras på en gång.</translation> - </message> - <message> <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> <translation>Maximal total avgift att använda i en plånbokstransaktion. Sätts denna för lågt kommer stora transaktioner att avbrytas (förvalt: %s)</translation> </message> @@ -2850,6 +2838,14 @@ Var vänlig och försök igen.</translation> <translation>Det går inte att binda till %s på den här datorn. Bitcoin Core är förmodligen redan igång.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>Varning: Onormalt antal block block genererade. %d block mottagna senaste %d timmarna (%d förväntade)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>Varning: Kontrollera din närverksanslutning. %d block mottagna senaste %d timmarna, (%d förväntade)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Varning: -paytxfee är satt väldigt hög! Detta är avgiften du kommer betala för varje transaktion.</translation> </message> @@ -2986,10 +2982,6 @@ Var vänlig och försök igen.</translation> <translation>Ange plånboksfil (inom datakatalogen)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Detta är avsett för regressionstestningsverktyg och applikationsutveckling.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Använd UPnP för att mappa den lyssnande porten (förvalt: %u)</translation> </message> @@ -3066,10 +3058,6 @@ Var vänlig och försök igen.</translation> <translation>Avgifter (i BTC/Kb) mindre än detta betraktas som nollavgift för vidarebefodran (förvalt: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Avgifter (i BTC/Kb) mindre än detta betraktas som nollavgift för transaktionsskapande (förvalt: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Om paytxfee inte är satt, inkludera tillräcklig avgift så att transaktionen börjar att konfirmeras inom n blocks (förvalt: %u)</translation> </message> @@ -3094,10 +3082,6 @@ Var vänlig och försök igen.</translation> <translation>Slumpa autentiseringen för varje proxyanslutning. Detta möjliggör Tor ström-isolering (förvalt: %u)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default: %u)</source> - <translation>Begär hög prioritet för att vidarebefodra lågavgiftstransaktioner (förvalt: %u)</translation> - </message> - <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Sätt den maximala storleken av hög-prioriterade/låg-avgifts transaktioner i byte (förvalt: %d)</translation> </message> @@ -3162,10 +3146,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Aktiverar bästa kedjan...</translation> </message> <message> - <source>Allow self signed root certificates (default: 0)</source> - <translation>Tillåt självsignerade root-certifikat (förvalt: 0)</translation> - </message> - <message> <source>Can't run with a wallet in prune mode.</source> <translation>Kan inte köra med en plånbok i beskärningsläge.</translation> </message> @@ -3258,18 +3238,14 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>RPC support för HTTP permanent anslutning (förvalt: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Slumpmässigt tappa 1 av varje <n> nåtverksmeddelande</translation> - </message> - <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Slupmässigt brus 1 gång varje <n> nätverksmeddelande</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>Återskapa blockkedjans index från nuvarande blk000??.dat filer under uppstarten</translation> </message> <message> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Mottag och visa P2P nätverksvarningar (förvalt: %u)</translation> + </message> + <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Skicka trace-/debuginformation till terminalen istället för till debug.log</translation> </message> @@ -3414,18 +3390,10 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(1 = spara tx metadata t.ex. kontoägare och betalningsbegäransinformation, 2 = släng tx metadata)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Töm databasens minnespool till disk varje <n> megabytes (förvalt: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Hur grundlig blockverifikationen vid -checkblocks är (0-4, förvalt: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Logga transaktionsprioritet och avgift per kB vid blockbrytning (förvalt: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Upprätthåll ett fullständigt transaktionsindex, som används av getrawtransaction rpc-anrop (förval: %u)</translation> </message> @@ -3454,18 +3422,10 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Sök alltid efter klientadresser med DNS sökningen (förvalt: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Avaktivera säkert läge. Åsidosätt en riktigt säkert läge händelse (förvalt: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Fel vid inläsning av plånboksfilen wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Tvångskör i säkert läge (förvalt: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Generera mynt (förvalt: %u)</translation> </message> @@ -3482,10 +3442,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ogiltig -proxy adress: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Begränsa signaturcachestorleken till <n> poster (förvalt: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Lyssna på JSON-RPC-anslutningar på <port> (förval: %u eller testnet: %u)</translation> </message> @@ -3510,10 +3466,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Maximal sändningsbuffert per anslutning, <n>*1000 byte (förvalt: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Acceptera bara blockkedjans matchande inbyggda kontrollpunkter (förvalt: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Skriv ut tidsstämpel i avlusningsinformationen (förvalt: %u)</translation> </message> @@ -3526,10 +3478,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Reläa icke P2SH multisig (förvalt: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Kör en tråd för att tömma plånboken periodiskt (förvalt: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Serverns certifikatfil (förvalt: %s)</translation> </message> @@ -3550,10 +3498,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ange antalet trådar för att hantera RPC anrop (förvalt: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Sätt DB_PRIVATE flaggan i plånbokens databasmiljö (förvalt: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Ange konfigurationsfil (förvalt: %s)</translation> </message> @@ -3570,10 +3514,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Spendera okonfirmerad växel när transaktioner sänds (förvalt: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Sluta köra efter importen av block från disk är klar (förvalt: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Tröskelvärde för att koppla ifrån klienter som missköter sig (förvalt: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_th_TH.ts b/src/qt/locale/bitcoin_th_TH.ts index 7b5d1ae01c..0980502968 100644 --- a/src/qt/locale/bitcoin_th_TH.ts +++ b/src/qt/locale/bitcoin_th_TH.ts @@ -1,4 +1,4 @@ -<TS language="th_TH" version="2.1"> +<TS language="th_TH" version="2.0"> <context> <name>AddressBookPage</name> <message> diff --git a/src/qt/locale/bitcoin_tr.ts b/src/qt/locale/bitcoin_tr.ts index bf6f3f2791..dcc82e644d 100644 --- a/src/qt/locale/bitcoin_tr.ts +++ b/src/qt/locale/bitcoin_tr.ts @@ -1,9 +1,9 @@ -<TS language="tr" version="2.1"> +<TS language="tr" version="2.0"> <context> <name>AddressBookPage</name> <message> <source>Right-click to edit address or label</source> - <translation>Adresi ya da etiketi düzenlemek için sağ düğme ile tıklayınız.</translation> + <translation>Adres veya etiketi düzenlemek için sağ tıklayınız.</translation> </message> <message> <source>Create a new address</source> @@ -15,7 +15,7 @@ </message> <message> <source>Copy the currently selected address to the system clipboard</source> - <translation>Şu anda seçili olan adresi sistem panosuna kopyala</translation> + <translation>Seçili adresi panoya kopyala</translation> </message> <message> <source>&Copy</source> @@ -35,7 +35,7 @@ </message> <message> <source>Export the data in the current tab to a file</source> - <translation>Güncel sekmedeki verileri bir dosyaya aktar</translation> + <translation>Açık olan sekmedeki verileri bir dosyaya aktar</translation> </message> <message> <source>&Export</source> @@ -67,11 +67,11 @@ </message> <message> <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> - <translation>Bunlar ödeme yapmak için kullanacağınız Bitcoin adreslerinizdir. Bitcoin yollamadan önce meblağı ve alıcı adresini daima kontrol ediniz.</translation> + <translation>Bunlar ödemeleri göndermek için kullanacağınız Bitcoin adreslerinizdir. Bitcoin yollamadan önce miktarı ve alıcının alım adresini daima kontrol ediniz.</translation> </message> <message> <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> - <translation>Bunlar ödeme almak için kullanacağınız Bitcoin adreslerinizdir. Her muamele için yeni bir alım adresi kullanmanız tavsiye edilir.</translation> + <translation>Bunlar ödemeleri almak için kullanacağınız Bitcoin adreslerinizdir. Her işlem için yeni bir alım adresi kullanmanız tavsiye edilir.</translation> </message> <message> <source>Copy &Label</source> @@ -110,7 +110,7 @@ </message> <message> <source>(no label)</source> - <translation>(boş etiket)</translation> + <translation>(etiket yok)</translation> </message> </context> <context> @@ -145,11 +145,11 @@ </message> <message> <source>This operation needs your wallet passphrase to decrypt the wallet.</source> - <translation>Bu işlem, cüzdan şifresini açmak için cüzdan parolasını gerektirir.</translation> + <translation>Bu işlem cüzdanın şifrelemesini açmak için cüzdan parolasını gerektirir.</translation> </message> <message> <source>Decrypt wallet</source> - <translation>Cüzdan şifresini aç</translation> + <translation>Cüzdanın şifrelemesini aç</translation> </message> <message> <source>Change passphrase</source> @@ -157,7 +157,7 @@ </message> <message> <source>Confirm wallet encryption</source> - <translation>Cüzdan şifrelenmesini teyit eder</translation> + <translation>Cüzdanın şifrelemesini teyit eder</translation> </message> <message> <source>Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>!</source> @@ -1323,7 +1323,7 @@ </message> <message> <source>Ping Time</source> - <translation>Ping Zamanı</translation> + <translation>Ping Süresi</translation> </message> </context> <context> @@ -1492,7 +1492,7 @@ </message> <message> <source>Connection Time</source> - <translation>Bağlantı Zamanı</translation> + <translation>Bağlantı Süresi</translation> </message> <message> <source>Last Send</source> @@ -1512,7 +1512,7 @@ </message> <message> <source>Ping Time</source> - <translation>Ping Zamanı</translation> + <translation>Ping Süresi</translation> </message> <message> <source>Time Offset</source> @@ -2813,10 +2813,6 @@ <translation>Belirtilen adrese bağlan ve daima ondan dinle. IPv6 için [makine]:port yazımını kullanınız</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)</source> - <translation>Devamlı olarak ücretsiz muameleleri dakikada <n>*1000 bayt olarak sınırla (varsayılan: %u)</translation> - </message> - <message> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <translation>Tüm cüzdan muamelelerini sil ve başlangıçta -rescan ile sadece blok zincirinin parçası olanları geri getir</translation> </message> @@ -2825,18 +2821,10 @@ <translation>MIT yazılım lisansı kapsamında yayınlanmıştır, ekteki COPYING dosyasına ya da <http://www.opensource.org/licenses/mit-license.php> adresine bakınız.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Blokların anında çözülebileceği özel bir zincir kullanan regresyon deneme kipine gir.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Bir cüzdan muamelesi değiştiğinde komutu çalıştır (komuttaki %s muamele kimliği ile değiştirilecektir)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>Bu kipte -genproclimit kaç sayıda bloğun anında oluşturulduğunu kontrol eder.</translation> - </message> - <message> <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> <translation>Tek cüzdan muamelesinde kullanılacak azami toplam ücret; bunu çok düşük olarak ayarlamak büyük muameleleri iptal edebilir (varsayılan: %s)</translation> </message> @@ -2857,6 +2845,14 @@ <translation>Bu bilgisayarda %s unsuruna bağlanılamadı. Bitcoin Çekirdeği muhtemelen hâlihazırda çalışmaktadır.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>İKAZ: anormal yüksek sayıda blok oluşturulmuştur, %d blok son %d saat içinde alınmıştır (%d bekleniyordu)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>İKAZ: ağ bağlantınızı kontrol ediniz, %d blok son %d saat içinde alınmıştır (%d bekleniyordu)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Uyarı: -paytxfee çok yüksek bir değere ayarlanmış! Bu, muamele gönderirseniz ödeyeceğiniz muamele ücretidir.</translation> </message> @@ -2993,10 +2989,6 @@ <translation>Cüzdan dosyası belirtiniz (veri klasörünün içinde)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Bu, regresyon deneme araçları ve uygulama geliştirmesi için tasarlanmıştır. </translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Dinleme portunu haritalamak için UPnP kullan (varsayılan: %u)</translation> </message> @@ -3073,10 +3065,6 @@ <translation>Kb başına BTC olarak bundan düşük ücretler aktarım için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Kb başına BTC olarak bundan düşük ücretler muamele oluşturulması için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Eğer paytxfee ayarlanmadıysa kafi derecede ücret ekleyin ki muameleler teyite vasati n blok içinde başlasın (varsayılan: %u)</translation> </message> @@ -3101,10 +3089,6 @@ <translation>Her vekil bağlantısı için kimlik verilerini rastgele yap. Bu, Tor akış izolasyonunu etkinleştirir (varsayılan: %u)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default: %u)</source> - <translation>Ücretsiz ya da düşük ücretli muamelelerin geçişi için yüksek öncelik iste (varsayılan: %u)</translation> - </message> - <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Yüksek öncelikli/düşük ücretli muamelelerin azami boyutunu bayt olarak ayarla (varsayılan: %d)</translation> </message> @@ -3173,10 +3157,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>En iyi zincir etkinleştiriliyor...</translation> </message> <message> - <source>Allow self signed root certificates (default: 0)</source> - <translation>Kendinden imzalı kök sertifikalara müsaade et (varsayılan: 0)</translation> - </message> - <message> <source>Can't run with a wallet in prune mode.</source> <translation>Prune kipindeki bir cüzdan ile çalışamaz.</translation> </message> @@ -3269,18 +3249,14 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Kalıcı HTTP bağlantıları için RPC desteği (varsayılan: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Her <n> şebeke mesajından rastgele 1 mesajı görmezden gel</translation> - </message> - <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Her <n> şebeke mesajından rastgele birini bulanıklaştır</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>Başlangıçta blok zinciri indeksini güncel blk000??.dat dosyalarından tekrar inşa et</translation> </message> <message> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>P2P ağından gelen önemli uyarıları alın ve gösterin (önseçili değer: %u)</translation> + </message> + <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Trace/hata ayıklama verilerini debug.log dosyası yerine konsola gönder</translation> </message> @@ -3425,18 +3401,10 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(1 = tx meta verilerini tut mesela hesap sahibi ve ödeme talebi bilgileri, 2 = tx meta verilerini at)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Veritabanı etkinliğini bellekten disk kütüğüne her <n> megabaytta aktar (varsayılan: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>-checkblocks'un blok kontrolünün ne kadar kapsamlı olacağı (0 ilâ 4, varsayılan: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Blok oluşturulduğunda muamele önceliğini ve kB başı ücreti kütüğe al (varsayılan: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Muamelelerin tamamının indeksini tut, getrawtransaction rpc çağrısı tarafından kullanılır (varsayılan: %u)</translation> </message> @@ -3465,18 +3433,10 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Eş adresleri sorgulaması için daima DNS aramasını kullan (varsayılan: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Güvenli kipi devre dışı bırak, gerçek bir güvenli olayı geçersiz kıl (varsayılan: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>wallet.dat dosyasının yüklenmesinde hata oluştu</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Güvenli kipi zorla (varsayılan: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Bitcoin oluştur (varsayılan: %u)</translation> </message> @@ -3493,10 +3453,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Geçersiz -proxy adresi: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>İmza arabelleğinin boyutunu <n> unsurla sınırla (varsayılan: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>JSON-RPC bağlantılarını <port> üzerinde dinle (varsayılan: %u veya tesnet: %u)</translation> </message> @@ -3521,10 +3477,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Her bağlantı için azami yollama tamponu, <n>*1000 bayt (varsayılan: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Sadece yerleşik kontrol noktalarıyla eşleşen blok zincirini kabul et (varsayılan: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Hata ayıklama verilerinin önüne zaman damgası ekle (varsayılan: %u)</translation> </message> @@ -3537,10 +3489,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>P2SH olmayan çoklu imzaları aktar (varsayılan: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Periyodik olarak cüdanı diske yazdırmak için bir iş parçacığı çalıştır (varsayılan: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Sunucu sertifika dosyası (varsayılan: %s)</translation> </message> @@ -3561,10 +3509,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Hizmet RCP aramaları iş parçacığı sayısını belirle (varsayılan: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Cüzdan veritabanı ortamında DB_PRIVATE bayrağını koyar (varsayılan: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Yapılandırma dosyası belirtiniz (varsayılan: %s)</translation> </message> @@ -3581,10 +3525,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Gönderme muamelelerinde teyit edilmemiş para üstünü harca (varsayılan: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Diskten blokları içeri aktardıktan sonra çalışmayı durdur (varsayılan: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Aksaklık gösteren eşlerle bağlantıyı kesme sınırı (varsayılan: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_uk.ts b/src/qt/locale/bitcoin_uk.ts index 92e0cc75c4..21ab4ac191 100644 --- a/src/qt/locale/bitcoin_uk.ts +++ b/src/qt/locale/bitcoin_uk.ts @@ -1,9 +1,9 @@ -<TS language="uk" version="2.1"> +<TS language="uk" version="2.0"> <context> <name>AddressBookPage</name> <message> <source>Right-click to edit address or label</source> - <translation>Клік правою кнопкою для редагування адреси або мітки</translation> + <translation>Клікніть правою кнопкою для редагування адреси або мітки</translation> </message> <message> <source>Create a new address</source> @@ -71,7 +71,7 @@ </message> <message> <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> - <translation>Це ваша нова Bitcoin адреса для отримування платежів. Рекомендовано використовувати нову адресу для кожної транзакції.</translation> + <translation>Це ваша нова Bitcoin адреса для отримання платежів. Рекомендовано використовувати нову адресу для кожної транзакції.</translation> </message> <message> <source>Copy &Label</source> @@ -168,8 +168,12 @@ <translation>Ви дійсно хочете зашифрувати свій гаманець?</translation> </message> <message> + <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>Клієнт «Bitcoin Core» буде закрито для завершення процесу шифрування. Пам'ятайте, що шифрування гаманця не зможе повністю захистити ваші біткоїни від крадіжки якщо ваш комп'ютер буде інфіковано шкідливими програмами.</translation> + </message> + <message> <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source> - <translation>ВАЖЛИВО: Всі попередні резервні копії, які ви зробили з вашого файлу гаманця повинні бути замінені новоствореним, зашифрованим файлом гаманця. З міркувань безпеки, попередні резервні копії незашифрованого файла гаманця стануть марними одразу ж, як тільки ви почнете використовувати новий, зашифрований гаманець.</translation> + <translation>ВАЖЛИВО: Всі попередні резервні копії, які ви зробили з вашого файлу гаманця повинні бути замінені новоствореним, зашифрованим файлом гаманця. З міркувань безпеки, попередні резервні копії незашифрованого файла гаманця стануть непридатними одразу ж, як тільки ви почнете використовувати новий, зашифрований гаманець.</translation> </message> <message> <source>Warning: The Caps Lock key is on!</source> @@ -181,7 +185,11 @@ </message> <message> <source>Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>.</source> - <translation>Введіть нову кодову фразу для гаманця.<br/>Будь ласка, використовуйте кодові фрази що містять <b> як мінімум десять випадкових символів </b> або <b> як мінімум вісім слів </b>.</translation> + <translation>Введіть нову кодову фразу для гаманця.<br/>Будь ласка, використовуйте кодові фрази що містять <b> щонайменше десять випадкових символів </b> або <b> щонайменше вісім слів </b>.</translation> + </message> + <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Введіть старий пароль та новий пароль до гаманця.</translation> </message> <message> <source>Wallet encryption failed</source> @@ -232,11 +240,11 @@ </message> <message> <source>Show general overview of wallet</source> - <translation>Показати загальний огляд гаманця</translation> + <translation>Показати стан гаманця</translation> </message> <message> <source>&Transactions</source> - <translation>Транзакції</translation> + <translation>&Транзакції</translation> </message> <message> <source>Browse transaction history</source> @@ -312,7 +320,7 @@ </message> <message> <source>&Debug window</source> - <translation>Вікно зневадження</translation> + <translation>В&ікно зневадження</translation> </message> <message> <source>Open debugging and diagnostic console</source> @@ -344,7 +352,7 @@ </message> <message> <source>&Show / Hide</source> - <translation>Показати / Приховати</translation> + <translation>Показа&ти / Приховати</translation> </message> <message> <source>Show or hide the main Window</source> @@ -352,7 +360,7 @@ </message> <message> <source>Encrypt the private keys that belong to your wallet</source> - <translation>Шифрування закритих ключів, які належать вашому гаманці</translation> + <translation>Зашифрувати закриті ключі, що знаходяться у вашому гаманці</translation> </message> <message> <source>Sign messages with your Bitcoin addresses to prove you own them</source> @@ -388,7 +396,11 @@ </message> <message> <source>&About Bitcoin Core</source> - <translation>&Про Bitcoin Core</translation> + <translation>П&ро Bitcoin Core</translation> + </message> + <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Редагувати параметри Bitcoin Core</translation> </message> <message> <source>Show the list of used sending addresses and labels</source> @@ -404,7 +416,7 @@ </message> <message> <source>&Command-line options</source> - <translation>Параметри командного рядка</translation> + <translation>П&араметри командного рядка</translation> </message> <message> <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> @@ -412,13 +424,17 @@ </message> <message numerus="yes"> <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>%n активне з'єднання з мережею</numerusform><numerusform>%n активні з'єднання з мережею</numerusform><numerusform>%n активних з'єднань з мережею Bitcoin</numerusform></translation> + <translation><numerusform>%n активне з'єднання з мережею Bitcoin</numerusform><numerusform>%n активні з'єднання з мережею Bitcoin</numerusform><numerusform>%n активних з'єднань з мережею Bitcoin</numerusform></translation> </message> <message> <source>No block source available...</source> <translation>Недоступно жодного джерела блоків...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Оброблено %n блок історії транзакцій.</numerusform><numerusform>Оброблено %n блоки історії транзакцій.</numerusform><numerusform>Оброблено %n блоків історії транзакцій.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n година</numerusform><numerusform>%n години</numerusform><numerusform>%n годин</numerusform></translation> </message> @@ -471,6 +487,36 @@ <translation>Синхронізується...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Дата: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Кількість: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Тип: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Мітка: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Адреса: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Надіслані транзакції</translation> </message> @@ -510,7 +556,7 @@ </message> <message> <source>Amount:</source> - <translation>Кількість:</translation> + <translation>Сума:</translation> </message> <message> <source>Priority:</source> @@ -582,11 +628,11 @@ </message> <message> <source>Copy amount</source> - <translation>Копіювати кількість</translation> + <translation>Скопіювати суму</translation> </message> <message> <source>Copy transaction ID</source> - <translation>Копіювати ID транзакції </translation> + <translation>Скопіювати ID транзакції </translation> </message> <message> <source>Lock unspent</source> @@ -598,31 +644,31 @@ </message> <message> <source>Copy quantity</source> - <translation>Копіювати кількість</translation> + <translation>Скопіювати кількість</translation> </message> <message> <source>Copy fee</source> - <translation>Копіювати комісію</translation> + <translation>Скопіювати комісію</translation> </message> <message> <source>Copy after fee</source> - <translation>Копіювати після комісії</translation> + <translation>Скопіювати після комісії</translation> </message> <message> <source>Copy bytes</source> - <translation>Копіювати байти</translation> + <translation>Скопіювати байти</translation> </message> <message> <source>Copy priority</source> - <translation>Копіювати пріорітет</translation> + <translation>Скопіювати пріорітет</translation> </message> <message> <source>Copy dust</source> - <translation>Копіювати пил</translation> + <translation>Скопіювати пил</translation> </message> <message> <source>Copy change</source> - <translation>Копіювати решту</translation> + <translation>Скопіювати решту</translation> </message> <message> <source>highest</source> @@ -669,6 +715,18 @@ <translation>відсутній</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Ця позначка стане червоною, якщо розмір транзакції перевищить 1000 байтів.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Ця позначка стане червоною, якщо пріоритет транзакції менше, ніж «середній».</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Ця позначка стане червоною, якщо будь-який отримувач отримає суму, меншу за %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Може відрізнятися на +/- %1 сатоші за вхід</translation> </message> @@ -764,7 +822,7 @@ <name>FreespaceChecker</name> <message> <source>A new data directory will be created.</source> - <translation>Буде створена новий каталог даних.</translation> + <translation>Буде створено новий каталог даних.</translation> </message> <message> <source>name</source> @@ -904,7 +962,7 @@ </message> <message> <source>Number of script &verification threads</source> - <translation>Кількість потоків сценарію перевірки</translation> + <translation>Кількість потоків &сценарію перевірки</translation> </message> <message> <source>Accept connections from outside</source> @@ -919,6 +977,14 @@ <translation>IP-адреса проксі-сервера (наприклад IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>Згортати замість закриття. Якщо ця опція включена, програма закриється лише після вибору відповідного пункту в меню.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>Встановлює мову інтерфейсу. Зміни набудуть чинності після перезапуску Bitcoin Core.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>Сторонні URL (наприклад, block explorer), що з'являться на вкладці транзакцій у вигляді пункту контекстного меню. %s в URL буде замінено на хеш транзакції. Для відокремлення URLів використовуйте вертикальну риску |.</translation> </message> @@ -936,13 +1002,21 @@ </message> <message> <source>&Reset Options</source> - <translation>Скинути параметри</translation> + <translation>С&кинути параметри</translation> </message> <message> <source>&Network</source> <translation>&Мережа</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Автоматично запускати Bitcoin Core при вході до системи.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Запускати Bitcoin Core при вході до системи</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 = автоматично, <0 = вказує кількість вільних ядер)</translation> </message> @@ -1055,6 +1129,10 @@ <translation>Для застосування змін необхідно перезапустити клієнта.</translation> </message> <message> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Клієнт буде вимкнено. Продовжити?</translation> + </message> + <message> <source>This change would require a client restart.</source> <translation>Ця зміна вступить в силу після перезапуску клієнта</translation> </message> @@ -1189,14 +1267,26 @@ <translation>Неможливо прочитати файл запиту платежу! Ймовірно, файл пошкоджено.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Запит платежу прострочено.</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>Неперевірені запити платежів з власними платіжними сценаріями не підтримуються.</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>Помилка в запиті платежу.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Відшкодування з %1</translation> </message> <message> + <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source> + <translation>Запит платежу %1 занадто великий (%2 байт, дозволено %3 байт).</translation> + </message> + <message> <source>Payment request DoS protection</source> <translation>Оплата потребує захисту DoS</translation> </message> @@ -1228,6 +1318,10 @@ <translation>Клієнт користувача</translation> </message> <message> + <source>Node/Service</source> + <translation>Вузол/Сервіс</translation> + </message> + <message> <source>Ping Time</source> <translation>Затримка</translation> </message> @@ -1349,6 +1443,10 @@ <translation>Поточне число блоків</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Відкрити файл журналу налагодження Bitcoin Core з поточного каталогу даних. Це може зайняти кілька секунд для великих файлів журналів.</translation> + </message> + <message> <source>Received</source> <translation>Отримано</translation> </message> @@ -1417,16 +1515,20 @@ <translation>Затримка</translation> </message> <message> + <source>Time Offset</source> + <translation>Різниця часу</translation> + </message> + <message> <source>Last block time</source> <translation>Час останнього блоку</translation> </message> <message> <source>&Open</source> - <translation>Відкрити</translation> + <translation>&Відкрити</translation> </message> <message> <source>&Console</source> - <translation>Консоль</translation> + <translation>&Консоль</translation> </message> <message> <source>&Network Traffic</source> @@ -1461,6 +1563,10 @@ <translation>Очистити консоль</translation> </message> <message> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Вітаємо у RPC-консолі Bitcoin Core.</translation> + </message> + <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Використовуйте стрілки вгору вниз для навігації по історії, і <b>Ctrl-L</b> для очищення екрана.</translation> </message> @@ -1600,11 +1706,11 @@ </message> <message> <source>Copy &URI</source> - <translation>Скопіювати URI</translation> + <translation>&Скопіювати URI</translation> </message> <message> <source>Copy &Address</source> - <translation>Скопіювати адресу</translation> + <translation>Скопіювати &адресу</translation> </message> <message> <source>&Save Image...</source> @@ -1754,7 +1860,11 @@ </message> <message> <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> - <translation>Якщо оплата користувача встановлюється в 1000 Satoshi і розмір передачі всього 250 байт, то "за кілобайт" платить тільки 250 Satoshi, в той час як "всього щонайменше" платить 1000 satoshis. Для передач більших, ніж кілобайт обоє платять за кілобайт.</translation> + <translation>Якщо комісія встановлюється в 1000 сатоші і розмір транзакції лише 250 байтів, то опція "за кілобайт" встановлює комісію в 250 сатоші, в той час, як "всього щонайменше" - в 1000 сатоші. Для транзакцій більших за кілобайт в обох випадках буде знято комісію за кілобайт.</translation> + </message> + <message> + <source>Hide</source> + <translation>Приховати</translation> </message> <message> <source>total at least</source> @@ -1762,7 +1872,7 @@ </message> <message> <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source> - <translation>Оплата тільки мінімальних зборів є прийнятною до тих пір, як обсяг транзакцій там є меншим аніж простору в блоках. Але майте на увазі, що це може анулювати транзакцію, якщо попит на Bitcoin транзакції стане значно більшим, ніж мережа зможе обробити.</translation> + <translation>Оплата тільки мінімальної комісії є прийнятною, допоки обсяг транзакцій є меншим простору в блоках. Але майте на увазі, що це може анулювати транзакцію, якщо попит на Bitcoin транзакції стане більшим, ніж мережа зможе обробити.</translation> </message> <message> <source>(read the tooltip)</source> @@ -1778,7 +1888,7 @@ </message> <message> <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source> - <translation>(Розумна оплата ще не ініціалізована. Це звичайно займає кілька блоків...)</translation> + <translation>(Розумну оплату ще не ініціалізовано. Це, зазвичай, триває кілька блоків...)</translation> </message> <message> <source>Confirmation time:</source> @@ -1846,7 +1956,7 @@ </message> <message> <source>Copy amount</source> - <translation>Копіювати кількість</translation> + <translation>Копіювати суму</translation> </message> <message> <source>Copy fee</source> @@ -1901,8 +2011,24 @@ <translation>Плата вища, ніж %1 вважається шалено високою.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Запит платежу прострочено.</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Перше підтвердження очікується протягом %n блоку.</numerusform><numerusform>Перше підтвердження очікується протягом %n блоків.</numerusform><numerusform>Перше підтвердження очікується протягом %n блоків.</numerusform></translation> + </message> + <message> <source>Pay only the minimum fee of %1</source> - <translation>Платити тільки мінімальний збір у розмірі %1</translation> + <translation>Платити тільки мінімальну комісію у розмірі %1</translation> + </message> + <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>Адреса отримувача неправильна. Будь ласка, перевірте її.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Знайдено адресу, що дублюється: кожна адреса має бути вказана не більше одного разу.</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> @@ -1976,10 +2102,26 @@ <translation>Видалити цей запис</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>Комісію буде знято зі вказаної суми. До отримувача надійде менше біткоінів, ніж було вказано в полі кількості. Якщо ж отримувачів декілька - комісію буде розподілено між ними.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>В&ідняти комісію від суми</translation> + </message> + <message> <source>Message:</source> <translation>Повідомлення:</translation> </message> <message> + <source>This is an unauthenticated payment request.</source> + <translation>Цей запит платежу не є автентифікованим.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>Цей запит платежу є автентифікованим.</translation> + </message> + <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>Введіть мітку для цієї адреси для додавання її в список використаних адрес</translation> </message> @@ -2018,6 +2160,10 @@ <translation>&Підписати повідомлення</translation> </message> <message> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>Ви можете підписувати повідомлення/угоди своїми адресами, щоб довести можливість отримання біткоінів, що будуть надіслані на них. Остерігайтеся підписувати будь-що нечітке чи неочікуване, так як за допомогою фішинг-атаки вас можуть спробувати ввести в оману для отримання вашого підпису під чужими словами. Підписуйте лише чіткі твердження, з якими ви повністю згодні.</translation> + </message> + <message> <source>The Bitcoin address to sign the message with</source> <translation>Адреса Bitcoin для підпису цього повідомлення</translation> </message> @@ -2067,7 +2213,11 @@ </message> <message> <source>&Verify Message</source> - <translation>Перевірити повідомлення</translation> + <translation>П&еревірити повідомлення</translation> + </message> + <message> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Введіть нижче адресу отримувача, повідомлення (впевніться, що ви точно скопіювали символи завершення рядка, табуляцію, пробіли тощо) та підпис для перевірки повідомлення. Впевніться, що в підпис не було додано зайвих символів: це допоможе уникнути атак типу «людина посередині». Зауважте, що це лише засвідчує можливість отримання транзакцій підписувачем, але не в стані підтвердити джерело жодної транзакції!</translation> </message> <message> <source>The Bitcoin address the message was signed with</source> @@ -2079,7 +2229,7 @@ </message> <message> <source>Verify &Message</source> - <translation>Перевірити повідомлення</translation> + <translation>Пере&вірити повідомлення</translation> </message> <message> <source>Reset all verify message fields</source> @@ -2284,7 +2434,7 @@ </message> <message> <source>Inputs</source> - <translation>витрати</translation> + <translation>Входи</translation> </message> <message> <source>Amount</source> @@ -2421,6 +2571,10 @@ <translation>Показує, чи було залучено адресу для спостереження в цій транзакції.</translation> </message> <message> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Призначення транзакції (визначається користувачем).</translation> + </message> + <message> <source>Amount removed from or added to balance.</source> <translation>Сума, додана чи знята з балансу.</translation> </message> @@ -2493,11 +2647,11 @@ </message> <message> <source>Copy amount</source> - <translation>Копіювати кількість</translation> + <translation>Скопіювати суму</translation> </message> <message> <source>Copy transaction ID</source> - <translation>Копіювати ID транзакції </translation> + <translation>Скопіювати ID транзакції </translation> </message> <message> <source>Edit label</source> @@ -2671,16 +2825,16 @@ <translation>Поширюється за ліцензією MIT, додаткова інформація міститься у файлі COPYING та за адресою <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>Ввійти в режим регресивного тестування, що використовує спеціальний ланцюг з миттєвим знаходженням блоків.</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>Виконати команду, коли транзакція гаманця зміниться (замість %s в команді буде підставлено ідентифікатор транзакції)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>В цьому режимі -genproclimit встановлює кількість блоків, що можуть бути згенеровані негайно.</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Максимальна загальна комісія за одну транзакцію; занадто низьке значення може скасувати відправку великих транзакцій (типово: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>Зменшити вимоги до наявного простору на носії даних за допомогою скорочення ланцюжка (видалення старих блоків). Цей режим вимикає підтримку гаманця та є несумісним з параметром -txindex. Увага: при поверненні до типового значення видалені частини ланцюжка буде повторно завантажено. (типово: 0 = вимкнути скорочення ланцюжка, >%u = очікуваний розмір файлів блоків в МіБ)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2695,6 +2849,14 @@ <translation>Неможливо прив'язатися до %s на цьому комп'ютері. Можливо, Bitcoin Core вже запущено.</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>УВАГА: аномально висока кількість згенерованих блоків, %d блок(ів) було отримано за останні %d годин(и) (має бути %d)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>УВАГА: перевірте ваше мережеве з'єднання, %d блок(ів) було отримано за останні %d годин(и) (має бути %d)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>Увага: встановлено занадто велику комісію (-paytxfee). Комісія зніматиметься кожен раз коли ви проводитимете транзакції.</translation> </message> @@ -2736,7 +2898,7 @@ </message> <message> <source>Connect only to the specified node(s)</source> - <translation>Підключитись лише до вказаного вузла</translation> + <translation>Підключитись лише до вказаного вузла/вузлів</translation> </message> <message> <source>Connection options:</source> @@ -2808,7 +2970,15 @@ </message> <message> <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> - <translation>Підключити тільки до вузлів в мережі <net> (ipv4, ipv6 або onion)</translation> + <translation>Підключатися тільки до вузлів в мережі <net> (ipv4, ipv6 або onion)</translation> + </message> + <message> + <source>Prune cannot be configured with a negative value.</source> + <translation>Розмір скороченого ланцюжка блоків не може бути від'ємним. </translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>Використання скороченого ланцюжка блоків несумісне з параметром -txindex.</translation> </message> <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> @@ -2823,10 +2993,6 @@ <translation>Вкажіть файл гаманця (в межах каталогу даних)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>Це призначено для інструментів регресивного тестування та розробки додатків.</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Намагатись використовувати UPnP для відображення порту, що прослуховується, на роутері (типово: %u)</translation> </message> @@ -2847,6 +3013,10 @@ <translation>Параметри гаманця:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Увага: Поточна версія застаріла, необхідне оновлення!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>Вам необхідно перебудувати базу даних з використанням -reindex для того, щоб змінити -txindex</translation> </message> @@ -2879,6 +3049,10 @@ <translation>Створювати нові файли з типовими для системи атрибутами доступу замість маски 077 (діє тільки при вимкненому гаманці)</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Визначити власні IP-адреси (типово: 1 при прослуховуванні та за відсутності -externalip або -proxy)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>Помилка: Не вдалося налаштувати прослуховування вхідних підключень (listen повернув помилку: %s)</translation> </message> @@ -2895,22 +3069,30 @@ <translation>Комісії (в BTC/КБ), що менші за вказану, вважатимуться нульовими (для ретрансляції) (типово: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>Комісії (в BTC/КБ), що менші за вказану, вважатимуться нульовими (для створення транзакції) (типово: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Якщо параметр paytxfee не встановлено, включити комісію для отримання перших підтверджень транзакцій протягом n блоків (типово: %u)</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source> + <translation>Неприпустима сума для -maxtxfee = <amount>: «%s» ( плата повинна бути, принаймні %s, щоб запобігти зависанню транзакцій)</translation> + </message> + <message> <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> <translation>Максимальний розмір даних в транзакціях носіїв даних, що ми передаємо і добуваємо (за замовчуванням: %u)</translation> </message> <message> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>Встановлений розмір ланцюжка блоків є замалим (менший за %d МБ). Будь ласка, виберіть більше число.</translation> + </message> + <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Дізнаватися адреси учасників через DNS при замалій кількості відомих адрес (типово: 1 за відсутності -connect)</translation> </message> <message> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Надавати випадкові дані доступу для кожного проксі-з'єднання. Це дозволяє ввімкнути ізоляцію потоків Tor'у (типово: %u)</translation> + </message> + <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Встановити максимальний розмір транзакцій з високим пріоритетом та низькою комісією (в байтах) (типово: %d)</translation> </message> @@ -2919,6 +3101,10 @@ <translation>Встановити кількість потоків для генерації монет (-1 = кількості ядер, типово: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>Залишок від суми транзакції зі сплатою комісії занадто малий </translation> + </message> + <message> <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source> <translation>Цей продукт включає в себе програмне забезпечення, розроблене в рамках проекту OpenSSL <https://www.openssl.org/>, криптографічне програмне забезпечення, написане Еріком Янгом, та функції для роботи з UPnP, написані Томасом Бернардом.</translation> </message> @@ -2959,10 +3145,26 @@ rpcpassword=%s <translation>Учасники, що знаходяться в білому списку, не можуть бути заблоковані за DoS та їхні транзакції завжди ретранслюватимуться (навіть якщо вони є в пам'яті), що може бути корисним, наприклад, для шлюзу</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>Вам необхідно перебудувати базу даних з використанням -reindex для завантаження повного ланцюжка блоків.</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(типово: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>Приймати публічні REST-запити (типово: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>Активація найкращого ланцюжка...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>Використання гаманця зі скороченим ланцюжком блоків неможливе.</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Не вдалося розпізнати адресу для -whitebind: «%s»</translation> </message> @@ -2987,6 +3189,10 @@ rpcpassword=%s <translation>Помилка при завантаженні wallet.dat: Гаманець потребує новішої версії Bitcoin Core</translation> </message> <message> + <source>Error reading from database, shutting down.</source> + <translation>Помилка читання бази даних, припиняю роботу.</translation> + </message> + <message> <source>Error: Unsupported argument -tor found, use -onion.</source> <translation>Помилка: Параметр -tor не підтримується, використовуйте -onion</translation> </message> @@ -3004,7 +3210,7 @@ rpcpassword=%s </message> <message> <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> - <translation>Неприпустима сума для -maxtxfee = <amount>: '%s'</translation> + <translation>Неприпустима сума для -maxtxfee = <amount>: «%s»</translation> </message> <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> @@ -3043,12 +3249,16 @@ rpcpassword=%s <translation>Параметри сервера RPC:</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>Випадковим чином відкидати 1 з <n> мережевих повідомлень</translation> + <source>RPC support for HTTP persistent connections (default: %d)</source> + <translation>Підтримка RPC для постійних HTTP-з'єднань (типово: %d)</translation> + </message> + <message> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>При запуску перебудувати індекс ланцюжка блоків з поточних файлів blk000??.dat</translation> </message> <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>Випадковим чином пошкоджувати 1 з <n> мережевих повідомлень</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Отримувати та відображати попередження з мережі (типово: %u)</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3087,6 +3297,10 @@ rpcpassword=%s <translation>Запускати згорнутим</translation> </message> <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>Неможливо сплатити комісію із-за малої суми транзакції</translation> + </message> + <message> <source>This is experimental software.</source> <translation>Це програмне забезпечення є експериментальним.</translation> </message> @@ -3107,6 +3321,10 @@ rpcpassword=%s <translation>Транзакція занадто велика</translation> </message> <message> + <source>UI Options:</source> + <translation>Параметри інтерфейсу:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Неможливо прив'язатися до %s на цьому комп'ютері (bind повернув помилку: %s)</translation> </message> @@ -3187,18 +3405,10 @@ rpcpassword=%s <translation>(1 = утримувати метадані транзакцій (до яких відноситься інформація про власника рахунку та запити платежів), 2 - відкинути)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Записувати зміни в базі даних до файлу кожні <n> мегабайтів (типово: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Рівень ретельності перевірки блоків (0-4, типово: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>Записувати в лог-файл пріоритет транзакції та комісію за кБ під час добування блоків (типово: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>Утримувати повний індекс транзакцій (використовується RPC-викликом getrawtransaction) (типово: %u)</translation> </message> @@ -3227,18 +3437,10 @@ rpcpassword=%s <translation>Завжди дізнаватися адреси учасників через DNS (типово: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>Вимкнути безпечний режим та ігнорувати події, що здатні ввімкнути його (типово: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Помилка при завантаженні wallet.dat</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>Ввімкнути безпечний режим (типово: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>Генерація монет (типово: %u)</translation> </message> @@ -3255,10 +3457,6 @@ rpcpassword=%s <translation>Помилка в адресі проксі-сервера: «%s»</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>Обмежити розмір кешу підписів до <n> записів (типово: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>Прослуховувати <port> для JSON-RPC з'єднань (типово: %u, для тестової мережі: %u)</translation> </message> @@ -3271,6 +3469,10 @@ rpcpassword=%s <translation>Підтримувати щонайбільше <n> з'єднань з учасниками (типово: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>Дозволити гаманцю розповсюджувати транзакції</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>Максимальний розмір вхідного буферу на одне з'єднання, <n>*1000 байтів (типово: %u)</translation> </message> @@ -3279,10 +3481,6 @@ rpcpassword=%s <translation>Максимальний розмір вихідного буферу на одне з'єднання, <n>*1000 байтів (типово: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>Приймати тільки той ланцюжок блоків, що не суперечить вбудованим контрольним точкам (типово: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>Доповнювати налагоджувальний вивід відміткою часу (типово: %u)</translation> </message> @@ -3295,10 +3493,6 @@ rpcpassword=%s <translation>Ретранслювати не-P2SH транзакції з мультипідписом (типово: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>Запустити потік для періодичного збереження даних гаманця (типово: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>Файл сертифіката сервера (типово: %s)</translation> </message> @@ -3319,10 +3513,6 @@ rpcpassword=%s <translation>Встановити число потоків для обслуговування викликів RPC (типово: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Встановити прапорець DB_PRIVATE в середовищі бази даних гаманця (типово: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>Вказати файл конфігурації (типово: %s)</translation> </message> @@ -3339,10 +3529,6 @@ rpcpassword=%s <translation>Витрачати непідтверджену решту при відправленні транзакцій (типово: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>Вимкнутися після імпорту блоків з диску (типово: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>Поріг відключення учасників з поганою поведінкою (типово: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_ur_PK.ts b/src/qt/locale/bitcoin_ur_PK.ts index 9148626f57..d4242d5e3c 100644 --- a/src/qt/locale/bitcoin_ur_PK.ts +++ b/src/qt/locale/bitcoin_ur_PK.ts @@ -1,7 +1,11 @@ -<TS language="ur_PK" version="2.1"> +<TS language="ur_PK" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>پتہ تبدیل کرے کے لیے دائیاں کلک کریں</translation> + </message> + <message> <source>Create a new address</source> <translation>نیا ایڈریس بنائیں</translation> </message> @@ -10,6 +14,10 @@ <translation>نیا</translation> </message> <message> + <source>Copy the currently selected address to the system clipboard</source> + <translation>سلیکٹڈ پتے کو کمپوٹر کی عارضی جگہ رکھیں</translation> + </message> + <message> <source>&Copy</source> <translation>نقل</translation> </message> @@ -22,6 +30,14 @@ <translation>کاپی پتہ</translation> </message> <message> + <source>Delete the currently selected address from the list</source> + <translation>سلیکٹڈ پتے کو مٹائیں</translation> + </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>موجودہ ڈیٹا کو فائیل میں محفوظ کریں</translation> + </message> + <message> <source>&Export</source> <translation>برآمد</translation> </message> @@ -30,9 +46,21 @@ <translation>مٹا</translation> </message> <message> + <source>Choose the address to send coins to</source> + <translation>کوئین وصول کرنے والے کا پتہ</translation> + </message> + <message> + <source>Choose the address to receive coins with</source> + <translation>کوئین بھیجنے والے کا پتہ</translation> + </message> + <message> <source>C&hoose</source> <translation>چننا</translation> </message> + <message> + <source>Sending addresses</source> + <translation>جس پتے پر بھیجنے ہیں</translation> + </message> </context> <context> <name>AddressTableModel</name> @@ -315,6 +343,10 @@ <source>&Export</source> <translation>برآمد</translation> </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>موجودہ ڈیٹا کو فائیل میں محفوظ کریں</translation> + </message> </context> <context> <name>bitcoin-core</name> diff --git a/src/qt/locale/bitcoin_uz@Cyrl.ts b/src/qt/locale/bitcoin_uz@Cyrl.ts index b8807afb13..cc0a4bba08 100644 --- a/src/qt/locale/bitcoin_uz@Cyrl.ts +++ b/src/qt/locale/bitcoin_uz@Cyrl.ts @@ -1,7 +1,11 @@ -<TS language="uz@Cyrl" version="2.1"> +<TS language="uz@Cyrl" version="2.0"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>Манзил ёки ёрлиқни таҳрирлаш учун икки марта босинг</translation> + </message> + <message> <source>Create a new address</source> <translation>Янги манзил яратинг</translation> </message> diff --git a/src/qt/locale/bitcoin_vi.ts b/src/qt/locale/bitcoin_vi.ts index 38ebd77b71..64d11d4645 100644 --- a/src/qt/locale/bitcoin_vi.ts +++ b/src/qt/locale/bitcoin_vi.ts @@ -1,4 +1,4 @@ -<TS language="vi" version="2.1"> +<TS language="vi" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -6,10 +6,22 @@ <translation>Tạo một địa chỉ mới</translation> </message> <message> + <source>&New</source> + <translation>Tạo mới</translation> + </message> + <message> <source>Copy the currently selected address to the system clipboard</source> <translation>Sao chép các địa chỉ đã được chọn vào bộ nhớ tạm thời của hệ thống</translation> </message> <message> + <source>&Copy</source> + <translation>Sao chép</translation> + </message> + <message> + <source>&Copy Address</source> + <translation>Sao chép địa chỉ</translation> + </message> + <message> <source>&Delete</source> <translation>&Xóa</translation> </message> diff --git a/src/qt/locale/bitcoin_vi_VN.ts b/src/qt/locale/bitcoin_vi_VN.ts index 18d1a252e7..7bcded7448 100644 --- a/src/qt/locale/bitcoin_vi_VN.ts +++ b/src/qt/locale/bitcoin_vi_VN.ts @@ -1,4 +1,4 @@ -<TS language="vi_VN" version="2.1"> +<TS language="vi_VN" version="2.0"> <context> <name>AddressBookPage</name> <message> diff --git a/src/qt/locale/bitcoin_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts index 3bcce1faab..4470b2601b 100644 --- a/src/qt/locale/bitcoin_zh_CN.ts +++ b/src/qt/locale/bitcoin_zh_CN.ts @@ -1,4 +1,4 @@ -<TS language="zh_CN" version="2.1"> +<TS language="zh_CN" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -67,7 +67,7 @@ </message> <message> <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> - <translation>这是您用来付款的比特币地址。在付款前,请总是核实付款金额和收款地址。</translation> + <translation>这是您用来付款的比特币地址。在付款前,请仔细核实付款金额和收款地址。</translation> </message> <message> <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> @@ -2102,6 +2102,10 @@ <translation>移除此项</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>交易费将从发送总额中扣除。接收人将收到比您在金额框中输入的更少的比特币。如果选中了多个收件人,交易费平分。</translation> + </message> + <message> <source>S&ubtract fee from amount</source> <translation>从金额中减去交易费(&U)</translation> </message> @@ -2156,6 +2160,10 @@ <translation>签名消息(&S)</translation> </message> <message> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>您可以用你的地址对消息/协议进行签名,以证明您可以接收发送到该地址的比特币。注意不要对任何模棱两可或者随机的消息进行签名,以免遭受钓鱼式攻击。请确保消息内容准确的表达了您的真实意愿。</translation> + </message> + <message> <source>The Bitcoin address to sign the message with</source> <translation>用来对消息签名的地址 </translation> </message> @@ -2815,10 +2823,6 @@ <translation>绑定指定的IP地址开始监听。IPv6地址请使用[host]:port 格式</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)</source> - <translation>自由交易不断的速率限制为<n>*1000 字节每分钟(默认值: %u)</translation> - </message> - <message> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <translation>删除钱包的所有交易记录,且只有用 -rescan参数启动客户端才能重新取回交易记录 </translation> </message> @@ -2827,18 +2831,10 @@ <translation>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>进入回归测试模式,它采用一种特殊的可立即解决的区块链模拟情况。</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>当最佳区块变化时执行命令 (命令行中的 %s 会被替换成区块哈希值)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>在-genproclimit这种模式下控制产出多少区块</translation> - </message> - <message> <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> <translation>单次交易最多使用交易费;设置太低可能导致大宗交易中止 (默认: %s)</translation> </message> @@ -2859,6 +2855,14 @@ <translation>无法 %s的绑定到电脑上,比特币核心钱包可能已经在运行。</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>警告:数据块生成数量异常,最近 %d 小时收到了 %d 个数据块(预期为 %d 个)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>警告:请检查您的网络连接,最近 %d 小时收到了 %d 个数据块(预期为 %d 个)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>警告:-paytxfee 交易费设置得太高了!每笔交易都将支付交易费。</translation> </message> @@ -2995,10 +2999,6 @@ <translation>指定钱包文件(数据目录内)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>这是用于回归测试和应用开发目的。</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>使用UPnp映射监听端口 (默认: %u) </translation> </message> @@ -3075,10 +3075,6 @@ <translation>交易费(BTC/kb)比这更小的交易在转发时将被视为零费交易 (默认: %s) </translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>交易费(BTC/kb)比这更小的交易在生成交易时将被视为零费交易 (默认: %s) </translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>如果未设置交易费用,自动添加足够的交易费以确保交易在平均n个数据块内被确认 (默认: %u) </translation> </message> @@ -3103,10 +3099,6 @@ <translation>为每个代理连接随机化凭据。这将启用 Tor 流隔离 (默认: %u)</translation> </message> <message> - <source>Require high priority for relaying free or low-fee transactions (default: %u)</source> - <translation>免费中继和低费率交易需要高优先级 (默认: %u)</translation> - </message> - <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>设置 高优先级/低交易费 交易的最大字节 (缺省: %d)</translation> </message> @@ -3175,10 +3167,6 @@ rpcpassword=%s <translation>正在激活最佳数据链...</translation> </message> <message> - <source>Allow self signed root certificates (default: 0)</source> - <translation>允许自签名根证书 (默认: 0)</translation> - </message> - <message> <source>Can't run with a wallet in prune mode.</source> <translation>不能在修剪模式下运行一个钱包。</translation> </message> @@ -3267,18 +3255,14 @@ rpcpassword=%s <translation>RPC 支持 HTTP 持久连接 (默认: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>随机每1个丢失测试<n>网络信息</translation> - </message> - <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>随机每1个模拟测试<n>网络信息</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>启动时重新为当前的 blk000??.dat 文件建立索引</translation> </message> <message> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>收到并且显示P2P网络的告警(默认:%u)</translation> + </message> + <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>跟踪/调试信息输出到控制台,不输出到 debug.log 文件</translation> </message> @@ -3426,18 +3410,10 @@ rpcpassword=%s <translation>(1 = 保留 tx meta data , 如 account owner 和 payment request information, 2 = 不保留 tx meta data) </translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>数据块验证 严密级别 -checkblocks (0-4, 默认: %u) </translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>挖矿时,记录交易优先级 和 每kb交易费 (默认: %u) </translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>维护一份完整的交易索引, 用于 getrawtransaction RPC调用 (默认: %u)</translation> </message> @@ -3462,18 +3438,10 @@ rpcpassword=%s <translation>可接受的密码算法 (默认: %s) </translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>禁止使用安全模式,重新写入一个真正的安全模式日志(默认: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>wallet.dat 钱包文件加载出错</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>强制安全模式 (默认: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>生成比特币 (默认: %u)</translation> </message> @@ -3490,10 +3458,6 @@ rpcpassword=%s <translation>无效的代理地址:%s</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>签名缓冲区大小限制最多 <n> 条 (默认: %u) </translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>使用 <port>端口监听 JSON-RPC 连接 (默认: %u ; testnet: %u) </translation> </message> @@ -3518,10 +3482,6 @@ rpcpassword=%s <translation>每个连接的最大发送缓存,<n>*1000 字节 (默认: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>仅接受符合客户端检查点设置 的数据块链 (默认: %u) </translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>输出调试信息时,前面加上时间戳 (默认: %u)</translation> </message> @@ -3534,10 +3494,6 @@ rpcpassword=%s <translation>是否转发 非P2SH格式的多签名交易 (默认: %u) </translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>运行一个线程,定时清理钱包 (默认: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>服务器证书文件 (默认: %s) </translation> </message> @@ -3558,10 +3514,6 @@ rpcpassword=%s <translation>设置RPC服务线程数 (默认: %d) </translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>指定配置文件 (默认: %s) </translation> </message> @@ -3578,10 +3530,6 @@ rpcpassword=%s <translation>付款时允许使用未确认的零钱 (默认: %u) </translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>从磁盘导入数据块后退出 (默认: %u) </translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>断开 非礼节点的阀值 (默认: %u) </translation> </message> diff --git a/src/qt/locale/bitcoin_zh_HK.ts b/src/qt/locale/bitcoin_zh_HK.ts index dfdbb7d1da..7062377f45 100644 --- a/src/qt/locale/bitcoin_zh_HK.ts +++ b/src/qt/locale/bitcoin_zh_HK.ts @@ -1,4 +1,4 @@ -<TS language="zh_HK" version="2.1"> +<TS language="zh_HK" version="2.0"> <context> <name>AddressBookPage</name> </context> diff --git a/src/qt/locale/bitcoin_zh_TW.ts b/src/qt/locale/bitcoin_zh_TW.ts index 3792a76095..9a93d896fe 100644 --- a/src/qt/locale/bitcoin_zh_TW.ts +++ b/src/qt/locale/bitcoin_zh_TW.ts @@ -1,4 +1,4 @@ -<TS language="zh_TW" version="2.1"> +<TS language="zh_TW" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -168,6 +168,10 @@ <translation>你確定要把錢包加密嗎?</translation> </message> <message> + <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>位元幣核心現在要關閉,好完成加密程序。請注意,加密錢包不能完全防止入侵你的電腦的惡意程式偷取位元幣。</translation> + </message> + <message> <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source> <translation>重要: 請改用新產生有加密的錢包檔,來取代舊錢包檔的備份。為了安全性的理由,當你開始使用新的有加密的錢包後,舊錢包檔的備份就不能再使用了。</translation> </message> @@ -184,6 +188,10 @@ <translation>輸入錢包的新密碼。<br/>密碼請用<b>10 個以上的字元</b>,或是<b>8 個以上的字詞</b>。</translation> </message> <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>請輸入錢包的舊密碼和新密碼。</translation> + </message> + <message> <source>Wallet encryption failed</source> <translation>錢包加密失敗</translation> </message> @@ -391,6 +399,10 @@ <translation>關於位元幣核心</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>修改位元幣核心的設定選項</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>顯示已使用過的付款位址和標記的清單</translation> </message> @@ -419,6 +431,10 @@ <translation>沒有可用的區塊來源...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>已經處理了 %n 個區塊的交易紀錄。</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n 個小時</numerusform></translation> </message> @@ -471,6 +487,36 @@ <translation>正在趕進度...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>日期: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>金額: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>種類: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>標記: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>位址: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>付款交易</translation> </message> @@ -669,6 +715,18 @@ <translation>無</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>當交易大小大於 1000 位元組時,文字會變紅色。</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>當優先度低於「中等」時,文字會變紅色。</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>當任何一個收款金額小於 %1 時,文字會變紅色。</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>每組輸入可能有 +/- %1 個 satoshi 的誤差。</translation> </message> @@ -919,6 +977,14 @@ <translation>代理伺服器的網際網路位址(像是 IPv4 的 127.0.0.1 或 IPv6 的 ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>當視窗關閉時,把應用程式縮到最小,而不是結束。當勾選這個選項時,只能夠用選單中的結束來關掉應用程式。</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>可以在這裡設定使用者介面的語言。這個設定在重啓位元幣核心後才會生效。</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>在交易頁籤的情境選單出現的第三方(比如說區塊探索網站)網址連結。網址中的 %s 會被取代為交易的雜湊值。可以用直線符號 | 來分隔多個連結。</translation> </message> @@ -943,6 +1009,14 @@ <translation>網路</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>在登入系統後自動啓動位元幣核心。</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>系統登入時啟動位元幣核心</translation> + </message> + <message> <source>(0 = auto, <0 = leave that many cores free)</source> <translation>(0 表示程式自動決定,小於 0 表示保留處理器核心不用的數目)</translation> </message> @@ -1055,6 +1129,10 @@ <translation>需要重新啟動客戶端軟體來讓改變生效。</translation> </message> <message> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>客戶端軟體就要關掉了。繼續做下去嗎?</translation> + </message> + <message> <source>This change would require a client restart.</source> <translation>這項改變需要重新啟動客戶端軟體。</translation> </message> @@ -1189,10 +1267,18 @@ <translation>沒辦法讀取付款要求檔案!可能是無效的檔案造成的。</translation> </message> <message> + <source>Payment request expired.</source> + <translation>付款的要求過期了。</translation> + </message> + <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> <translation>不支援含有自訂付款指令碼,且沒驗證過的付款要求。</translation> </message> <message> + <source>Invalid payment request.</source> + <translation>付款的要求無效。</translation> + </message> + <message> <source>Refund from %1</source> <translation>來自 %1 的退款</translation> </message> @@ -1232,6 +1318,10 @@ <translation>使用者代理</translation> </message> <message> + <source>Node/Service</source> + <translation>節點/服務</translation> + </message> + <message> <source>Ping Time</source> <translation>Ping 時間</translation> </message> @@ -1353,6 +1443,10 @@ <translation>目前區塊數</translation> </message> <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>從目前的資料目錄下開啓位元幣核心的除錯紀錄檔。當紀錄檔很大時,可能會花好幾秒的時間。</translation> + </message> + <message> <source>Received</source> <translation>收款</translation> </message> @@ -1421,6 +1515,10 @@ <translation>Ping 時間</translation> </message> <message> + <source>Time Offset</source> + <translation>時間差</translation> + </message> + <message> <source>Last block time</source> <translation>最近區塊時間</translation> </message> @@ -1465,6 +1563,10 @@ <translation>清主控台</translation> </message> <message> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>歡迎使用位元幣核心 RPC 主控台。</translation> + </message> + <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>請用上下游標鍵來瀏覽先前指令的紀錄,並用 <b>Ctrl-L</b> 來清畫面。</translation> </message> @@ -1761,6 +1863,10 @@ <translation>如果自訂手續費設定為 1000 satoshi, 而交易資料大小只有 250 個位元組的話,那麽選擇「每千位元組」就只會付 250 satoshi 的手續費,換做選「總共至少」就會付 1000 satoshi. 但是如果交易資料大小超過一千個位元組,那麽兩者都是每千位元組的費用。</translation> </message> <message> + <source>Hide</source> + <translation>隱藏</translation> + </message> + <message> <source>total at least</source> <translation>總共最少</translation> </message> @@ -1901,10 +2007,26 @@ <translation>交易被拒絕了!有時候會發生這種錯誤,是因為你錢包中的一些錢已經被花掉了。比如說你複製了錢包檔 wallet.dat, 然後用複製的錢包花掉了錢,你現在所用的原來的錢包中,卻沒有那筆錢已經花掉的紀錄。</translation> </message> <message> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>高於 %1 的手續費會被認為是不合理。</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>付款的要求過期了。</translation> + </message> + <message> <source>Pay only the minimum fee of %1</source> <translation>只付最低手續費 %1</translation> </message> <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>收款位址無效。請再檢查看看。</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>發現有重複的位址: 每個位址只能出現一次。</translation> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>警告: 位元幣位址無效</translation> </message> @@ -1976,10 +2098,26 @@ <translation>刪掉這個項目</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>手續費會從要付款出去的金額中扣掉。因此收款人會收到比輸入的金額還要少的位元幣。如果有多個收款人的話,手續費會平均分配來扣除。</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>從付款金額減去手續費</translation> + </message> + <message> <source>Message:</source> <translation>訊息:</translation> </message> <message> + <source>This is an unauthenticated payment request.</source> + <translation>這是個沒驗證過的付款要求。</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>這是個已驗證的付款要求。</translation> + </message> + <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>請輸入這個位址的標記,來把它加進去已使用過位址的清單。</translation> </message> @@ -2018,6 +2156,10 @@ <translation>簽署訊息</translation> </message> <message> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>你可以用自己的位址簽署訊息或合約,來證明你可以從該位址收款。但是請小心,不要簽署語意含糊不清,或隨機產生的內容,因為釣魚式詐騙可能會用騙你簽署的手法來冒充是你。只有在語句中的細節你都同意時才簽署。</translation> + </message> + <message> <source>The Bitcoin address to sign the message with</source> <translation>用來簽署訊息的位元幣位址</translation> </message> @@ -2070,6 +2212,10 @@ <translation>驗證訊息</translation> </message> <message> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>請在下面輸入收款人的位址,訊息(請確定完整複製了所包含的換行,空格,跳位符號等等),以及簽章,來驗證這個訊息。請小心,除了訊息內容以外,不要對簽章本身過度解讀,以避免被用「中間人攻擊法」詐騙。請注意,通過驗證的簽章只能證明簽章人確實可以從該位址收款,不能證明任何交易中的付款人身份!</translation> + </message> + <message> <source>The Bitcoin address the message was signed with</source> <translation>簽署這個訊息的位元幣位址</translation> </message> @@ -2421,6 +2567,10 @@ <translation>不論如何有一個只能觀看的地只有參與這次的交易</translation> </message> <message> + <source>User-defined intent/purpose of the transaction.</source> + <translation>使用者定義的交易動機或理由。</translation> + </message> + <message> <source>Amount removed from or added to balance.</source> <translation>要減掉或加進餘額的金額。</translation> </message> @@ -2672,16 +2822,16 @@ <translation>這套軟體是依據 MIT 軟體授權條款散布,詳情請見附帶的 COPYING 檔案,或是以下網站: <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> - <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> - <translation>進入回歸測試模式,使用可以立即解出區塊的特殊區塊鏈。</translation> - </message> - <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> <translation>當錢包有交易改變時要執行的指令(指令中的 %s 會被取代成交易識別碼)</translation> </message> <message> - <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> - <translation>在這個運作模式下,-genproclimit 選項控制立刻產生出的區塊數目。</translation> + <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>一次錢包交易允許付出最高的總手續費;設定太低的話,可能會無法進行資料量大的交易(預設值: %s)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>修剪(刪除)掉老舊區塊來減少儲存空間的需求。這種模式會關閉錢包功能,並且和 -txindex 參數不相容。警告: 從這種模式還原會需要重新下載一整個區塊鏈。(預設值: 0 表示不修剪區塊,>%u 表示為區塊檔案的目標大小,單位是百萬位元組 MiB)</translation> </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> @@ -2696,6 +2846,14 @@ <translation>沒辦法繫結在這台電腦上的 %s 。位元幣核心可能已經在執行了。</translation> </message> <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>警告: 收到了不尋常地多的 %d 個區塊在過去 %d 小時內生產出來(預期是 %d 個)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>警告: 請檢查你的網路連線狀況,收到了 %d 個區塊是在過去 %d 小時內生產出來(預期是 %d 個)</translation> + </message> + <message> <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> <translation>警告: -paytxfee 設定了很高的金額!這可是你交易付款所要付的手續費。</translation> </message> @@ -2812,6 +2970,14 @@ <translation>只有連接到網絡節點 <net> (IPv4,IPv6或onion)</translation> </message> <message> + <source>Prune cannot be configured with a negative value.</source> + <translation>修剪值不能設定為負的。</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>修剪模式和 -txindex 參數不相容。</translation> + </message> + <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation>設定資料庫快取大小是多少百萬位元組(MB,範圍: %d 到 %d,預設值: %d)</translation> </message> @@ -2824,10 +2990,6 @@ <translation>指定錢包檔(會在資料目錄中)</translation> </message> <message> - <source>This is intended for regression testing tools and app development.</source> - <translation>這是設計用來給回歸測試工具和應用程式開發用的。</translation> - </message> - <message> <source>Verifying blocks...</source> <translation>正在驗證區塊資料...</translation> </message> @@ -2844,6 +3006,10 @@ <translation>錢包選項:</translation> </message> <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>警告: 這個版本已經被淘汰了;必須要升級!</translation> + </message> + <message> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>改變 -txindex 參數後,必須要用 -reindex 參數來重建資料庫</translation> </message> @@ -2876,6 +3042,10 @@ <translation>用系統預設權限來造出新的檔案,而不是用使用者權限罩遮(umask)值 077 (只有在關掉錢包功能時才有作用)。</translation> </message> <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>找出自己的網際網路位址(預設值: 當有聽候連線且沒有指定 -externalip 或 -proxy 時為 1)</translation> + </message> + <message> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation>錯誤: 聽候外來連線失敗(回傳錯誤 %s)</translation> </message> @@ -2892,10 +3062,6 @@ <translation>當處理轉發的交易時,如果每千位元組(Kb)的手續費比這個值低,就視為沒付手續費 (預設值: %s)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> - <translation>當製造交易時,如果每千位元組(Kb)的手續費比這個值低,就視為沒付手續費 (預設值: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>當沒有設定 paytxfee 時,自動包含可以讓交易能在平均 n 個區塊內開始確認的手續費(預設值: %u)</translation> </message> @@ -2908,10 +3074,18 @@ <translation>轉發和開採時,對只帶資料的交易的大小上限(預設值: %u)</translation> </message> <message> + <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> + <translation>設定的修剪值小於最小需求的 %d MB. 請指定大一點的數字。</translation> + </message> + <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>是否允許在節點位址數目不足時,使用域名查詢來搜尋節點 (預設值: 當沒用 -connect 時為 1)</translation> </message> <message> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>對每個代理連線使用隨機產生的憑證。這個選項會開啟 Tor 的串流隔離(預設值: %u)</translation> + </message> + <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>設定高優先度或低手續費的交易資料大小上限成多少位元組(預設值: %d)</translation> </message> @@ -2920,6 +3094,10 @@ <translation>設定產生錢幣的執行緒數目(-1 表示處理器核心數,預設值: %d)</translation> </message> <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>扣除手續費後的交易金額太少而不能傳送</translation> + </message> + <message> <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source> <translation>此產品也包含了由 OpenSSL Project 所開發的 OpenSSL Toolkit 軟體 <https://www.openssl.org/>, 和由 Eric Young 撰寫的加解密軟體,以及由 Thomas Bernard 所撰寫的 UPnP 軟體。</translation> </message> @@ -2960,10 +3138,26 @@ rpcpassword=%s <translation>在白名單中的節點不會因為偵測到阻斷服務攻擊而被停用。來自這些節點的交易也一定會被轉發,即使說交易本來就在記憶池裡了也一樣。適用於像是閘道伺服器。</translation> </message> <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>回到非修剪的模式需要用 -reindex 參數來重建資料庫。這會導致重新下載整個區塊鏈。</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(預設值: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>接受公開的REST請求 (預設值: %u)</translation> </message> <message> + <source>Activating best chain...</source> + <translation>啟用最佳鏈結...</translation> + </message> + <message> + <source>Can't run with a wallet in prune mode.</source> + <translation>不能在有錢包時執行修剪模式。</translation> + </message> + <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>沒辦法解析 -whitebind 指定的位址: '%s'</translation> </message> @@ -3052,12 +3246,8 @@ rpcpassword=%s <translation>RPC 是否支援 HTTP 持久連線(預設值: %d)</translation> </message> <message> - <source>Randomly drop 1 of every <n> network messages</source> - <translation>隨機丟掉 <n> 分之一的網路訊息</translation> - </message> - <message> - <source>Randomly fuzz 1 of every <n> network messages</source> - <translation>隨機亂動 <n> 分之一的網路訊息裡的資料</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>啟動時從目前的區塊檔 blk000??.dat 重建區塊鏈的索引</translation> </message> <message> <source>Send trace/debug info to console instead of debug.log file</source> @@ -3096,6 +3286,10 @@ rpcpassword=%s <translation>啓動時縮到最小</translation> </message> <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>交易金額太少而付不起手續費</translation> + </message> + <message> <source>This is experimental software.</source> <translation>這套軟體屬於實驗性質。</translation> </message> @@ -3116,6 +3310,10 @@ rpcpassword=%s <translation>交易位元量太大</translation> </message> <message> + <source>UI Options:</source> + <translation>使用介面選項:</translation> + </message> + <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>無法和這台電腦上的 %s 繫結(回傳錯誤 %s)</translation> </message> @@ -3196,18 +3394,10 @@ rpcpassword=%s <translation>(1 表示保留交易描述資料,像是帳戶使用者和付款請求資訊;2 表示丟掉交易描述資料)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source> - <translation>每當累積到 <n> 百萬位元組(MB)時,才將資料庫的變動從記憶體暫存池中寫進磁碟紀錄檔(預設值: %u)</translation> - </message> - <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>使用 -checkblocks 檢查區塊的仔細程度(0 到 4,預設值: %u)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source> - <translation>開採區塊的時候,紀錄交易的優先度以及每千位元組(kB)的手續費(預設值: %u)</translation> - </message> - <message> <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> <translation>維護全部交易的索引,用在 getrawtransaction 這個 RPC 請求(預設值: %u)</translation> </message> @@ -3236,18 +3426,10 @@ rpcpassword=%s <translation>是否一定要用域名查詢來搜尋節點(預設值: %u)</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: %u)</source> - <translation>不進入安全模式,用在真的發生需要進入安全模式的事件時,強制不進入(預設值: %u)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>載入錢包檔 wallet.dat 時發生錯誤</translation> </message> <message> - <source>Force safe mode (default: %u)</source> - <translation>強制進入安全模式(預設值: %u)</translation> - </message> - <message> <source>Generate coins (default: %u)</source> <translation>生產位元幣(預設值: %u)</translation> </message> @@ -3264,10 +3446,6 @@ rpcpassword=%s <translation>無效的 -proxy 位址: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: %u)</source> - <translation>限制簽章快取大小為 <n> 筆(預設值: %u)</translation> - </message> - <message> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation>在通訊埠 <port> 聽候 JSON-RPC 連線(預設值: %u, 或若為測試網路: %u)</translation> </message> @@ -3280,6 +3458,10 @@ rpcpassword=%s <translation>維持與節點連線數的上限為 <n> 個(預設值: %u)</translation> </message> <message> + <source>Make the wallet broadcast transactions</source> + <translation>讓錢包能公告交易</translation> + </message> + <message> <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> <translation>每個連線的接收緩衝區大小上限為 <n>*1000 個位元組(預設值: %u)</translation> </message> @@ -3288,10 +3470,6 @@ rpcpassword=%s <translation>每個連線的傳送緩衝區大小上限為 <n>*1000 個位元組(預設值: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: %u)</source> - <translation>只接受與內建的檢查段點吻合的區塊鎖鏈(預設值: %u)</translation> - </message> - <message> <source>Prepend debug output with timestamp (default: %u)</source> <translation>在除錯輸出內容前附加時間(預設值: %u)</translation> </message> @@ -3304,10 +3482,6 @@ rpcpassword=%s <translation>允許轉發非 P2SH 的多簽章交易(預設值: %u)</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: %u)</source> - <translation>啟用定期將變動寫入錢包檔的執行緒(預設值: %u)</translation> - </message> - <message> <source>Server certificate file (default: %s)</source> <translation>伺服器憑證檔(預設值: %s)</translation> </message> @@ -3328,10 +3502,6 @@ rpcpassword=%s <translation>設定處理 RPC 服務請求的執行緒數目(預設值: %d)</translation> </message> <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source> - <translation>在錢包資料庫環境變數設定 DB_PRIVATE 旗標(預設值: %u)</translation> - </message> - <message> <source>Specify configuration file (default: %s)</source> <translation>指定設定檔(預設值: %s)</translation> </message> @@ -3348,10 +3518,6 @@ rpcpassword=%s <translation>傳送交易時可以花還沒確認的零錢(預設值: %u)</translation> </message> <message> - <source>Stop running after importing blocks from disk (default: %u)</source> - <translation>從磁碟匯入區塊資料後停止執行(預設值: %u)</translation> - </message> - <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation>與亂搞的節點斷線的臨界值 (預設: %u)</translation> </message> diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp index e28f903b2e..4541c75886 100644 --- a/src/qt/networkstyle.cpp +++ b/src/qt/networkstyle.cpp @@ -5,7 +5,6 @@ #include "networkstyle.h" #include "guiconstants.h" -#include "scicon.h" #include <QApplication> diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 062c4540ee..f57c1203f6 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -35,7 +35,7 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : ui(new Ui::OptionsDialog), model(0), mapper(0), - fProxyIpValid(true) + fProxyIpsValid(true) { ui->setupUi(this); @@ -54,10 +54,18 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : ui->proxyPort->setEnabled(false); ui->proxyPort->setValidator(new QIntValidator(1, 65535, this)); + ui->proxyIpTor->setEnabled(false); + ui->proxyPortTor->setEnabled(false); + ui->proxyPortTor->setValidator(new QIntValidator(1, 65535, this)); + connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyIp, SLOT(setEnabled(bool))); connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyPort, SLOT(setEnabled(bool))); + connect(ui->connectSocksTor, SIGNAL(toggled(bool)), ui->proxyIpTor, SLOT(setEnabled(bool))); + connect(ui->connectSocksTor, SIGNAL(toggled(bool)), ui->proxyPortTor, SLOT(setEnabled(bool))); + ui->proxyIp->installEventFilter(this); + ui->proxyIpTor->installEventFilter(this); /* Window elements init */ #ifdef Q_OS_MAC @@ -110,7 +118,7 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit); mapper->setOrientation(Qt::Vertical); - /* setup/change UI elements when proxy IP is invalid/valid */ + /* setup/change UI elements when proxy IPs are invalid/valid */ connect(this, SIGNAL(proxyIpChecks(QValidatedLineEdit *, int)), this, SLOT(doProxyIpChecks(QValidatedLineEdit *, int))); } @@ -137,6 +145,8 @@ void OptionsDialog::setModel(OptionsModel *model) mapper->setModel(model); setMapper(); mapper->toFirst(); + + updateDefaultProxyNets(); } /* warn when one of the following settings changes by user action (placed here so init via mapper doesn't trigger them) */ @@ -149,6 +159,7 @@ void OptionsDialog::setModel(OptionsModel *model) /* Network */ connect(ui->allowIncoming, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning())); connect(ui->connectSocks, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning())); + connect(ui->connectSocksTor, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning())); /* Display */ connect(ui->lang, SIGNAL(valueChanged()), this, SLOT(showRestartWarning())); connect(ui->thirdPartyTxUrls, SIGNAL(textChanged(const QString &)), this, SLOT(showRestartWarning())); @@ -173,6 +184,10 @@ void OptionsDialog::setMapper() mapper->addMapping(ui->proxyIp, OptionsModel::ProxyIP); mapper->addMapping(ui->proxyPort, OptionsModel::ProxyPort); + mapper->addMapping(ui->connectSocksTor, OptionsModel::ProxyUseTor); + mapper->addMapping(ui->proxyIpTor, OptionsModel::ProxyIPTor); + mapper->addMapping(ui->proxyPortTor, OptionsModel::ProxyPortTor); + /* Window */ #ifndef Q_OS_MAC mapper->addMapping(ui->minimizeToTray, OptionsModel::MinimizeToTray); @@ -188,7 +203,7 @@ void OptionsDialog::setMapper() void OptionsDialog::enableOkButton() { /* prevent enabling of the OK button when data modified, if there is an invalid proxy address present */ - if(fProxyIpValid) + if(fProxyIpsValid) setOkButtonState(true); } @@ -224,6 +239,7 @@ void OptionsDialog::on_okButton_clicked() { mapper->submit(); accept(); + updateDefaultProxyNets(); } void OptionsDialog::on_cancelButton_clicked() @@ -257,11 +273,10 @@ void OptionsDialog::doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPo { Q_UNUSED(nProxyPort); - const std::string strAddrProxy = pUiProxyIp->text().toStdString(); CService addrProxy; /* Check for a valid IPv4 / IPv6 address */ - if (!(fProxyIpValid = LookupNumeric(strAddrProxy.c_str(), addrProxy))) + if (!(fProxyIpsValid = LookupNumeric(pUiProxyIp->text().toStdString().c_str(), addrProxy))) { disableOkButton(); pUiProxyIp->setValid(false); @@ -275,6 +290,28 @@ void OptionsDialog::doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPo } } +void OptionsDialog::updateDefaultProxyNets() +{ + proxyType proxy; + std::string strProxy; + QString strDefaultProxyGUI; + + GetProxy(NET_IPV4, proxy); + strProxy = proxy.proxy.ToStringIP() + ":" + proxy.proxy.ToStringPort(); + strDefaultProxyGUI = ui->proxyIp->text() + ":" + ui->proxyPort->text(); + (strProxy == strDefaultProxyGUI.toStdString()) ? ui->proxyReachIPv4->setChecked(true) : ui->proxyReachIPv4->setChecked(false); + + GetProxy(NET_IPV6, proxy); + strProxy = proxy.proxy.ToStringIP() + ":" + proxy.proxy.ToStringPort(); + strDefaultProxyGUI = ui->proxyIp->text() + ":" + ui->proxyPort->text(); + (strProxy == strDefaultProxyGUI.toStdString()) ? ui->proxyReachIPv6->setChecked(true) : ui->proxyReachIPv6->setChecked(false); + + GetProxy(NET_TOR, proxy); + strProxy = proxy.proxy.ToStringIP() + ":" + proxy.proxy.ToStringPort(); + strDefaultProxyGUI = ui->proxyIp->text() + ":" + ui->proxyPort->text(); + (strProxy == strDefaultProxyGUI.toStdString()) ? ui->proxyReachTor->setChecked(true) : ui->proxyReachTor->setChecked(false); +} + bool OptionsDialog::eventFilter(QObject *object, QEvent *event) { if(event->type() == QEvent::FocusOut) @@ -283,6 +320,10 @@ bool OptionsDialog::eventFilter(QObject *object, QEvent *event) { Q_EMIT proxyIpChecks(ui->proxyIp, ui->proxyPort->text().toInt()); } + else if(object == ui->proxyIpTor) + { + Q_EMIT proxyIpChecks(ui->proxyIpTor, ui->proxyPortTor->text().toInt()); + } } return QDialog::eventFilter(object, event); } diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h index fa983e798c..348489c599 100644 --- a/src/qt/optionsdialog.h +++ b/src/qt/optionsdialog.h @@ -47,6 +47,8 @@ private Q_SLOTS: void showRestartWarning(bool fPersistent = false); void clearStatusLabel(); void doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort); + /* query the networks, for which the default proxy is used */ + void updateDefaultProxyNets(); Q_SIGNALS: void proxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort); @@ -55,7 +57,7 @@ private: Ui::OptionsDialog *ui; OptionsModel *model; QDataWidgetMapper *mapper; - bool fProxyIpValid; + bool fProxyIpsValid; }; #endif // BITCOIN_QT_OPTIONSDIALOG_H diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 6191edc44c..65e490570e 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -117,6 +117,16 @@ void OptionsModel::Init() else if(!settings.value("fUseProxy").toBool() && !GetArg("-proxy", "").empty()) addOverriddenOption("-proxy"); + if (!settings.contains("fUseSeparateProxyTor")) + settings.setValue("fUseSeparateProxyTor", false); + if (!settings.contains("addrSeparateProxyTor")) + settings.setValue("addrSeparateProxyTor", "127.0.0.1:9050"); + // Only try to set -onion, if user has enabled fUseSeparateProxyTor + if (settings.value("fUseSeparateProxyTor").toBool() && !SoftSetArg("-onion", settings.value("addrSeparateProxyTor").toString().toStdString())) + addOverriddenOption("-onion"); + else if(!settings.value("fUseSeparateProxyTor").toBool() && !GetArg("-onion", "").empty()) + addOverriddenOption("-onion"); + // Display if (!settings.contains("language")) settings.setValue("language", ""); @@ -178,6 +188,20 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const return strlIpPort.at(1); } + // separate Tor proxy + case ProxyUseTor: + return settings.value("fUseSeparateProxyTor", false); + case ProxyIPTor: { + // contains IP at index 0 and port at index 1 + QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts); + return strlIpPort.at(0); + } + case ProxyPortTor: { + // contains IP at index 0 and port at index 1 + QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts); + return strlIpPort.at(1); + } + #ifdef ENABLE_WALLET case SpendZeroConfChange: return settings.value("bSpendZeroConfChange"); @@ -259,6 +283,39 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in } } break; + + // separate Tor proxy + case ProxyUseTor: + if (settings.value("fUseSeparateProxyTor") != value) { + settings.setValue("fUseSeparateProxyTor", value.toBool()); + setRestartRequired(true); + } + break; + case ProxyIPTor: { + // contains current IP at index 0 and current port at index 1 + QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts); + // if that key doesn't exist or has a changed IP + if (!settings.contains("addrSeparateProxyTor") || strlIpPort.at(0) != value.toString()) { + // construct new value from new IP and current port + QString strNewValue = value.toString() + ":" + strlIpPort.at(1); + settings.setValue("addrSeparateProxyTor", strNewValue); + setRestartRequired(true); + } + } + break; + case ProxyPortTor: { + // contains current IP at index 0 and current port at index 1 + QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts); + // if that key doesn't exist or has a changed port + if (!settings.contains("addrSeparateProxyTor") || strlIpPort.at(1) != value.toString()) { + // construct new value from current IP and new port + QString strNewValue = strlIpPort.at(0) + ":" + value.toString(); + settings.setValue("addrSeparateProxyTor", strNewValue); + setRestartRequired(true); + } + } + break; + #ifdef ENABLE_WALLET case SpendZeroConfChange: if (settings.value("bSpendZeroConfChange") != value) { diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index fc26d65b04..8448cad8de 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -34,6 +34,9 @@ public: ProxyUse, // bool ProxyIP, // QString ProxyPort, // int + ProxyUseTor, // bool + ProxyIPTor, // QString + ProxyPortTor, // int DisplayUnit, // BitcoinUnits::Unit ThirdPartyTxUrls, // QString Language, // QString diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index bbd95ef478..a56c80ac63 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -10,7 +10,7 @@ #include "guiconstants.h" #include "guiutil.h" #include "optionsmodel.h" -#include "scicon.h" +#include "platformstyle.h" #include "transactionfilterproxy.h" #include "transactiontablemodel.h" #include "walletmodel.h" @@ -25,7 +25,9 @@ class TxViewDelegate : public QAbstractItemDelegate { Q_OBJECT public: - TxViewDelegate(): QAbstractItemDelegate(), unit(BitcoinUnits::BTC) + TxViewDelegate(const PlatformStyle *platformStyle): + QAbstractItemDelegate(), unit(BitcoinUnits::BTC), + platformStyle(platformStyle) { } @@ -43,7 +45,7 @@ public: int halfheight = (mainRect.height() - 2*ypad)/2; QRect amountRect(mainRect.left() + xspace, mainRect.top()+ypad, mainRect.width() - xspace, halfheight); QRect addressRect(mainRect.left() + xspace, mainRect.top()+ypad+halfheight, mainRect.width() - xspace, halfheight); - icon = SingleColorIcon(icon, SingleColor()); + icon = platformStyle->SingleColorIcon(icon); icon.paint(painter, decorationRect); QDateTime date = index.data(TransactionTableModel::DateRole).toDateTime(); @@ -101,11 +103,12 @@ public: } int unit; + const PlatformStyle *platformStyle; }; #include "overviewpage.moc" -OverviewPage::OverviewPage(QWidget *parent) : +OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) : QWidget(parent), ui(new Ui::OverviewPage), clientModel(0), @@ -116,13 +119,13 @@ OverviewPage::OverviewPage(QWidget *parent) : currentWatchOnlyBalance(-1), currentWatchUnconfBalance(-1), currentWatchImmatureBalance(-1), - txdelegate(new TxViewDelegate()), + txdelegate(new TxViewDelegate(platformStyle)), filter(0) { ui->setupUi(this); // use a SingleColorIcon for the "out of sync warning" icon - QIcon icon = SingleColorIcon(":/icons/warning"); + QIcon icon = platformStyle->SingleColorIcon(":/icons/warning"); icon.addPixmap(icon.pixmap(QSize(64,64), QIcon::Normal), QIcon::Disabled); // also set the disabled icon because we are using a disabled QPushButton to work around missing HiDPI support of QLabel (https://bugreports.qt.io/browse/QTBUG-42503) ui->labelTransactionsStatus->setIcon(icon); ui->labelWalletStatus->setIcon(icon); diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index de5ac345da..4139eb35d3 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -12,6 +12,7 @@ class ClientModel; class TransactionFilterProxy; class TxViewDelegate; +class PlatformStyle; class WalletModel; namespace Ui { @@ -28,7 +29,7 @@ class OverviewPage : public QWidget Q_OBJECT public: - explicit OverviewPage(QWidget *parent = 0); + explicit OverviewPage(const PlatformStyle *platformStyle, QWidget *parent = 0); ~OverviewPage(); void setClientModel(ClientModel *clientModel); diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 0827d99125..31a6d65a8d 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -509,12 +509,7 @@ bool PaymentServer::readPaymentRequestFromFile(const QString& filename, PaymentR } // BIP70 DoS protection - if (f.size() > BIP70_MAX_PAYMENTREQUEST_SIZE) { - qWarning() << QString("PaymentServer::%1: Payment request %2 is too large (%3 bytes, allowed %4 bytes).") - .arg(__func__) - .arg(filename) - .arg(f.size()) - .arg(BIP70_MAX_PAYMENTREQUEST_SIZE); + if (!verifySize(f.size())) { return false; } @@ -685,14 +680,13 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply) reply->deleteLater(); // BIP70 DoS protection - if (reply->size() > BIP70_MAX_PAYMENTREQUEST_SIZE) { - QString msg = tr("Payment request %1 is too large (%2 bytes, allowed %3 bytes).") - .arg(reply->request().url().toString()) - .arg(reply->size()) - .arg(BIP70_MAX_PAYMENTREQUEST_SIZE); - - qWarning() << QString("PaymentServer::%1:").arg(__func__) << msg; - Q_EMIT message(tr("Payment request DoS protection"), msg, CClientUIInterface::MSG_ERROR); + if (!verifySize(reply->size())) { + Q_EMIT message(tr("Payment request rejected"), + tr("Payment request %1 is too large (%2 bytes, allowed %3 bytes).") + .arg(reply->request().url().toString()) + .arg(reply->size()) + .arg(BIP70_MAX_PAYMENTREQUEST_SIZE), + CClientUIInterface::MSG_ERROR); return; } @@ -762,7 +756,7 @@ void PaymentServer::setOptionsModel(OptionsModel *optionsModel) void PaymentServer::handlePaymentACK(const QString& paymentACKMsg) { - // currently we don't futher process or store the paymentACK message + // currently we don't further process or store the paymentACK message Q_EMIT message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL); } @@ -790,6 +784,18 @@ bool PaymentServer::verifyExpired(const payments::PaymentDetails& requestDetails return fVerified; } +bool PaymentServer::verifySize(qint64 requestSize) +{ + bool fVerified = (requestSize <= BIP70_MAX_PAYMENTREQUEST_SIZE); + if (!fVerified) { + qWarning() << QString("PaymentServer::%1: Payment request too large (%2 bytes, allowed %3 bytes).") + .arg(__func__) + .arg(requestSize) + .arg(BIP70_MAX_PAYMENTREQUEST_SIZE); + } + return fVerified; +} + bool PaymentServer::verifyAmount(const CAmount& requestAmount) { bool fVerified = MoneyRange(requestAmount); diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index 5df0a14cf7..fa120a435c 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -88,13 +88,12 @@ public: // OptionsModel is used for getting proxy settings and display unit void setOptionsModel(OptionsModel *optionsModel); - // This is now public, because we use it in paymentservertests.cpp - static bool readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request); - // Verify that the payment request network matches the client network static bool verifyNetwork(const payments::PaymentDetails& requestDetails); // Verify if the payment request is expired static bool verifyExpired(const payments::PaymentDetails& requestDetails); + // Verify the payment request size is valid as per BIP70 + static bool verifySize(qint64 requestSize); // Verify the payment request amount is valid static bool verifyAmount(const CAmount& requestAmount); @@ -131,6 +130,7 @@ protected: bool eventFilter(QObject *object, QEvent *event); private: + static bool readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request); bool processPaymentRequest(const PaymentRequestPlus& request, SendCoinsRecipient& recipient); void fetchRequest(const QUrl& url); diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index 85339166b0..770a860544 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -8,7 +8,6 @@ #include "guiconstants.h" #include "guiutil.h" -#include "net.h" #include "sync.h" #include <QDebug> @@ -96,18 +95,17 @@ public: mapNodeRows.insert(std::pair<NodeId, int>(stats.nodeStats.nodeid, row++)); } - int size() + int size() const { return cachedNodeStats.size(); } CNodeCombinedStats *index(int idx) { - if(idx >= 0 && idx < cachedNodeStats.size()) { + if (idx >= 0 && idx < cachedNodeStats.size()) return &cachedNodeStats[idx]; - } else { - return 0; - } + + return 0; } }; @@ -171,7 +169,7 @@ QVariant PeerTableModel::data(const QModelIndex &index, int role) const } } else if (role == Qt::TextAlignmentRole) { if (index.column() == Ping) - return (int)(Qt::AlignRight | Qt::AlignVCenter); + return (QVariant)(Qt::AlignRight | Qt::AlignVCenter); } return QVariant(); @@ -204,13 +202,8 @@ QModelIndex PeerTableModel::index(int row, int column, const QModelIndex &parent CNodeCombinedStats *data = priv->index(row); if (data) - { return createIndex(row, column, data); - } - else - { - return QModelIndex(); - } + return QModelIndex(); } const CNodeCombinedStats *PeerTableModel::getNodeStats(int idx) diff --git a/src/qt/platformstyle.cpp b/src/qt/platformstyle.cpp new file mode 100644 index 0000000000..11cbc7a47c --- /dev/null +++ b/src/qt/platformstyle.cpp @@ -0,0 +1,147 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "platformstyle.h" + +#include "guiconstants.h" + +#include <QApplication> +#include <QColor> +#include <QIcon> +#include <QImage> +#include <QPalette> +#include <QPixmap> + +static const struct { + const char *platformId; + /** Show images on push buttons */ + const bool imagesOnButtons; + /** Colorize single-color icons */ + const bool colorizeIcons; + /** Extra padding/spacing in transactionview */ + const bool useExtraSpacing; +} platform_styles[] = { + {"macosx", false, false, true}, + {"windows", true, false, false}, + /* Other: linux, unix, ... */ + {"other", true, true, false} +}; +static const unsigned platform_styles_count = sizeof(platform_styles)/sizeof(*platform_styles); + +namespace { +/* Local functions for colorizing single-color images */ + +void MakeSingleColorImage(QImage& img, const QColor& colorbase) +{ + img = img.convertToFormat(QImage::Format_ARGB32); + for (int x = img.width(); x--; ) + { + for (int y = img.height(); y--; ) + { + const QRgb rgb = img.pixel(x, y); + img.setPixel(x, y, qRgba(colorbase.red(), colorbase.green(), colorbase.blue(), qAlpha(rgb))); + } + } +} + +QIcon ColorizeIcon(const QIcon& ico, const QColor& colorbase) +{ + QIcon new_ico; + QSize sz; + Q_FOREACH(sz, ico.availableSizes()) + { + QImage img(ico.pixmap(sz).toImage()); + MakeSingleColorImage(img, colorbase); + new_ico.addPixmap(QPixmap::fromImage(img)); + } + return new_ico; +} + +QImage ColorizeImage(const QString& filename, const QColor& colorbase) +{ + QImage img(filename); + MakeSingleColorImage(img, colorbase); + return img; +} + +QIcon ColorizeIcon(const QString& filename, const QColor& colorbase) +{ + return QIcon(QPixmap::fromImage(ColorizeImage(filename, colorbase))); +} + +} + + +PlatformStyle::PlatformStyle(const QString &name, bool imagesOnButtons, bool colorizeIcons, bool useExtraSpacing): + name(name), + imagesOnButtons(imagesOnButtons), + colorizeIcons(colorizeIcons), + useExtraSpacing(useExtraSpacing), + singleColor(0,0,0), + textColor(0,0,0) +{ + // Determine icon highlighting color + if (colorizeIcons) { + const QColor colorHighlightBg(QApplication::palette().color(QPalette::Highlight)); + const QColor colorHighlightFg(QApplication::palette().color(QPalette::HighlightedText)); + const QColor colorText(QApplication::palette().color(QPalette::WindowText)); + const int colorTextLightness = colorText.lightness(); + QColor colorbase; + if (abs(colorHighlightBg.lightness() - colorTextLightness) < abs(colorHighlightFg.lightness() - colorTextLightness)) + colorbase = colorHighlightBg; + else + colorbase = colorHighlightFg; + singleColor = colorbase; + } + // Determine text color + textColor = QColor(QApplication::palette().color(QPalette::WindowText)); +} + +QImage PlatformStyle::SingleColorImage(const QString& filename) const +{ + if (!colorizeIcons) + return QImage(filename); + return ColorizeImage(filename, SingleColor()); +} + +QIcon PlatformStyle::SingleColorIcon(const QString& filename) const +{ + if (!colorizeIcons) + return QIcon(filename); + return ColorizeIcon(filename, SingleColor()); +} + +QIcon PlatformStyle::SingleColorIcon(const QIcon& icon) const +{ + if (!colorizeIcons) + return icon; + return ColorizeIcon(icon, SingleColor()); +} + +QIcon PlatformStyle::TextColorIcon(const QString& filename) const +{ + return ColorizeIcon(filename, TextColor()); +} + +QIcon PlatformStyle::TextColorIcon(const QIcon& icon) const +{ + return ColorizeIcon(icon, TextColor()); +} + +const PlatformStyle *PlatformStyle::instantiate(const QString &platformId) +{ + for (unsigned x=0; x<platform_styles_count; ++x) + { + if (platformId == platform_styles[x].platformId) + { + return new PlatformStyle( + platform_styles[x].platformId, + platform_styles[x].imagesOnButtons, + platform_styles[x].colorizeIcons, + platform_styles[x].useExtraSpacing); + } + } + return 0; +} + diff --git a/src/qt/platformstyle.h b/src/qt/platformstyle.h new file mode 100644 index 0000000000..4e763e760e --- /dev/null +++ b/src/qt/platformstyle.h @@ -0,0 +1,55 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_QT_PLATFORMSTYLE_H +#define BITCOIN_QT_PLATFORMSTYLE_H + +#include <QIcon> +#include <QPixmap> +#include <QString> + +/* Coin network-specific GUI style information */ +class PlatformStyle +{ +public: + /** Get style associated with provided platform name, or 0 if not known */ + static const PlatformStyle *instantiate(const QString &platformId); + + const QString &getName() const { return name; } + + bool getImagesOnButtons() const { return imagesOnButtons; } + bool getUseExtraSpacing() const { return useExtraSpacing; } + + QColor TextColor() const { return textColor; } + QColor SingleColor() const { return singleColor; } + + /** Colorize an image (given filename) with the icon color */ + QImage SingleColorImage(const QString& filename) const; + + /** Colorize an icon (given filename) with the icon color */ + QIcon SingleColorIcon(const QString& filename) const; + + /** Colorize an icon (given object) with the icon color */ + QIcon SingleColorIcon(const QIcon& icon) const; + + /** Colorize an icon (given filename) with the text color */ + QIcon TextColorIcon(const QString& filename) const; + + /** Colorize an icon (given object) with the text color */ + QIcon TextColorIcon(const QIcon& icon) const; + +private: + PlatformStyle(const QString &name, bool imagesOnButtons, bool colorizeIcons, bool useExtraSpacing); + + QString name; + bool imagesOnButtons; + bool colorizeIcons; + bool useExtraSpacing; + QColor singleColor; + QColor textColor; + /* ... more to come later */ +}; + +#endif // BITCOIN_QT_PLATFORMSTYLE_H + diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index 43b46c63b5..7fb68cc32a 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -10,9 +10,9 @@ #include "bitcoinunits.h" #include "guiutil.h" #include "optionsmodel.h" +#include "platformstyle.h" #include "receiverequestdialog.h" #include "recentrequeststablemodel.h" -#include "scicon.h" #include "walletmodel.h" #include <QAction> @@ -22,24 +22,25 @@ #include <QScrollBar> #include <QTextDocument> -ReceiveCoinsDialog::ReceiveCoinsDialog(QWidget *parent) : +ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent) : QDialog(parent), ui(new Ui::ReceiveCoinsDialog), - model(0) + model(0), + platformStyle(platformStyle) { ui->setupUi(this); -#ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac - ui->clearButton->setIcon(QIcon()); - ui->receiveButton->setIcon(QIcon()); - ui->showRequestButton->setIcon(QIcon()); - ui->removeRequestButton->setIcon(QIcon()); -#else - ui->clearButton->setIcon(SingleColorIcon(":/icons/remove")); - ui->receiveButton->setIcon(SingleColorIcon(":/icons/receiving_addresses")); - ui->showRequestButton->setIcon(SingleColorIcon(":/icons/edit")); - ui->removeRequestButton->setIcon(SingleColorIcon(":/icons/remove")); -#endif + if (!platformStyle->getImagesOnButtons()) { + ui->clearButton->setIcon(QIcon()); + ui->receiveButton->setIcon(QIcon()); + ui->showRequestButton->setIcon(QIcon()); + ui->removeRequestButton->setIcon(QIcon()); + } else { + ui->clearButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); + ui->receiveButton->setIcon(platformStyle->SingleColorIcon(":/icons/receiving_addresses")); + ui->showRequestButton->setIcon(platformStyle->SingleColorIcon(":/icons/edit")); + ui->removeRequestButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); + } // context menu actions QAction *copyLabelAction = new QAction(tr("Copy label"), this); @@ -132,7 +133,7 @@ void ReceiveCoinsDialog::on_receiveButton_clicked() if(ui->reuseAddress->isChecked()) { /* Choose existing receiving address */ - AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this); + AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this); dlg.setModel(model->getAddressTableModel()); if(dlg.exec()) { diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h index 6bb159482b..eaaf129a91 100644 --- a/src/qt/receivecoinsdialog.h +++ b/src/qt/receivecoinsdialog.h @@ -16,6 +16,7 @@ #include <QVariant> class OptionsModel; +class PlatformStyle; class WalletModel; namespace Ui { @@ -39,7 +40,7 @@ public: MINIMUM_COLUMN_WIDTH = 130 }; - explicit ReceiveCoinsDialog(QWidget *parent = 0); + explicit ReceiveCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent = 0); ~ReceiveCoinsDialog(); void setModel(WalletModel *model); @@ -57,6 +58,8 @@ private: GUIUtil::TableViewLastColumnResizingFixer *columnResizingFixer; WalletModel *model; QMenu *contextMenu; + const PlatformStyle *platformStyle; + void copyColumnToClipboard(int column); virtual void resizeEvent(QResizeEvent *event); diff --git a/src/qt/res/icons/about_qt.png b/src/qt/res/icons/about_qt.png Binary files differindex dd27a99d0a..c40abfd3a6 100644 --- a/src/qt/res/icons/about_qt.png +++ b/src/qt/res/icons/about_qt.png diff --git a/src/qt/res/icons/clock1.png b/src/qt/res/icons/clock1.png Binary files differindex ceae5ed0d9..162204d1bb 100644 --- a/src/qt/res/icons/clock1.png +++ b/src/qt/res/icons/clock1.png diff --git a/src/qt/res/icons/clock2.png b/src/qt/res/icons/clock2.png Binary files differindex 159f69a8fc..8f4263a31c 100644 --- a/src/qt/res/icons/clock2.png +++ b/src/qt/res/icons/clock2.png diff --git a/src/qt/res/icons/clock3.png b/src/qt/res/icons/clock3.png Binary files differindex d668e35ffc..7f11a7566c 100644 --- a/src/qt/res/icons/clock3.png +++ b/src/qt/res/icons/clock3.png diff --git a/src/qt/res/icons/clock4.png b/src/qt/res/icons/clock4.png Binary files differindex 5ebf8ed7ac..fdd1a0fce3 100644 --- a/src/qt/res/icons/clock4.png +++ b/src/qt/res/icons/clock4.png diff --git a/src/qt/res/icons/clock5.png b/src/qt/res/icons/clock5.png Binary files differindex 96f15ef7d9..7d6556c6cf 100644 --- a/src/qt/res/icons/clock5.png +++ b/src/qt/res/icons/clock5.png diff --git a/src/qt/res/icons/connect0.png b/src/qt/res/icons/connect0.png Binary files differindex 58e2c3e965..ef708d81fb 100644 --- a/src/qt/res/icons/connect0.png +++ b/src/qt/res/icons/connect0.png diff --git a/src/qt/res/icons/connect1.png b/src/qt/res/icons/connect1.png Binary files differindex 949e7a922d..ed358e6f8e 100644 --- a/src/qt/res/icons/connect1.png +++ b/src/qt/res/icons/connect1.png diff --git a/src/qt/res/icons/connect2.png b/src/qt/res/icons/connect2.png Binary files differindex 143b2054fb..3bbb0d395c 100644 --- a/src/qt/res/icons/connect2.png +++ b/src/qt/res/icons/connect2.png diff --git a/src/qt/res/icons/connect3.png b/src/qt/res/icons/connect3.png Binary files differindex 143b2054fb..0db99ad8d3 100644 --- a/src/qt/res/icons/connect3.png +++ b/src/qt/res/icons/connect3.png diff --git a/src/qt/res/icons/connect4.png b/src/qt/res/icons/connect4.png Binary files differindex f96e3455ce..9dd19fc2bd 100644 --- a/src/qt/res/icons/connect4.png +++ b/src/qt/res/icons/connect4.png diff --git a/src/qt/res/icons/transaction0.png b/src/qt/res/icons/transaction0.png Binary files differindex 1091b86e68..72c44565ec 100644 --- a/src/qt/res/icons/transaction0.png +++ b/src/qt/res/icons/transaction0.png diff --git a/src/qt/res/icons/warning.png b/src/qt/res/icons/warning.png Binary files differindex 723a30a658..6bc5ac7895 100644 --- a/src/qt/res/icons/warning.png +++ b/src/qt/res/icons/warning.png diff --git a/src/qt/res/movies/makespinner.sh b/src/qt/res/movies/makespinner.sh index 625fb17173..a4c2fddbbf 100755 --- a/src/qt/res/movies/makespinner.sh +++ b/src/qt/res/movies/makespinner.sh @@ -1,6 +1,7 @@ -for i in {1..35} +FRAMEDIR=$(dirname $0) +for i in {0..35} do - value=$(printf "%03d" $i) + frame=$(printf "%03d" $i) angle=$(($i * 10)) - convert spinner-000.png -background "rgba(0,0,0,0.0)" -distort SRT $angle spinner-$value.png + convert $FRAMEDIR/../src/spinner.png -background "rgba(0,0,0,0.0)" -distort SRT $angle $FRAMEDIR/spinner-$frame.png done diff --git a/src/qt/res/movies/spinner-000.png b/src/qt/res/movies/spinner-000.png Binary files differindex 1e92d859da..0dc48d0d8c 100644 --- a/src/qt/res/movies/spinner-000.png +++ b/src/qt/res/movies/spinner-000.png diff --git a/src/qt/res/src/clock_1.svg b/src/qt/res/src/clock_1.svg index 4e49772d26..2a3d84c2d0 100644 --- a/src/qt/res/src/clock_1.svg +++ b/src/qt/res/src/clock_1.svg @@ -9,5 +9,7 @@ c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4
c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>
</g>
-<polygon points="478.3,253.4 297.6,184.6 297.6,420.9 534,420.9 "/>
+<path
+ d="M 478.3,253.4 297.6,184.6 c 0,0 0,78.8 0,118.2 0,117.5 -0.4,118.1 118.2,118.1 39.4,0 118.2,0 118.2,0 z"
+ id="polygon7" />
</svg>
diff --git a/src/qt/res/src/clock_2.svg b/src/qt/res/src/clock_2.svg index 995446e46e..2de8d467b7 100644 --- a/src/qt/res/src/clock_2.svg +++ b/src/qt/res/src/clock_2.svg @@ -9,6 +9,5 @@ c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4
c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>
</g>
-<polygon points="465.2,601.6 534,420.9 297.6,420.9 297.6,657.3 "/>
-<polygon points="478.3,253.4 297.6,184.6 297.6,420.9 534,420.9 "/>
+<polygon points="465.2,601.6 534,420.9 478.3,253.4 297.6,184.6 297.6,420.9 297.6,657.3 "/>
</svg>
diff --git a/src/qt/res/src/clock_3.svg b/src/qt/res/src/clock_3.svg index ea47a84730..b691043e3e 100644 --- a/src/qt/res/src/clock_3.svg +++ b/src/qt/res/src/clock_3.svg @@ -9,7 +9,7 @@ c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4
c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>
</g>
-<polygon points="117,588.5 297.6,657.3 297.6,420.9 61.3,420.9 "/>
-<polygon points="465.2,601.6 534,420.9 297.6,420.9 297.6,657.3 "/>
-<polygon points="478.3,253.4 297.6,184.6 297.6,420.9 534,420.9 "/>
+<path
+ d="M 465.2,601.6 534,420.9 478.3,253.4 297.6,184.6 c 0,0 0,78.8 0,118.2 0,117.7 0.4,118.1 -118.1,118.1 -39.4,0 -118.2,0 -118.2,0 l 55.7,167.6 180.6,68.8 z"
+ id="polygon7" />
</svg>
diff --git a/src/qt/res/src/clock_4.svg b/src/qt/res/src/clock_4.svg index 43160288d8..ea311f31e8 100644 --- a/src/qt/res/src/clock_4.svg +++ b/src/qt/res/src/clock_4.svg @@ -1,18 +1,23 @@ -<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- viewBox="0 0 841.9 841.9" enable-background="new 0 0 841.9 841.9" xml:space="preserve">
-<g>
- <path d="M297.6,677.3c-68.5,0-132.9-26.7-181.3-75.1S41.3,489.4,41.3,420.9s26.7-132.9,75.1-181.3c48.4-48.4,112.8-75.1,181.3-75.1
- s132.9,26.7,181.3,75.1c48.4,48.4,75.1,112.8,75.1,181.3s-26.7,132.9-75.1,181.3S366.1,677.3,297.6,677.3z M297.6,204.6
- c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4
- c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>
-</g>
-<polygon points="130.1,240.3 61.3,420.9 297.6,420.9 297.6,184.6 "/>
-<polygon points="117,588.5 297.6,657.3 297.6,420.9 61.3,420.9 "/>
-<polygon points="465.2,601.6 534,420.9 297.6,420.9 297.6,657.3 "/>
-<polygon points="478.3,253.4 297.6,184.6 297.6,420.9 534,420.9 "/>
-<path fill="#FFFFFF" d="M293.5,452.6h99.6c14.9,0,24.8-9.9,24.8-24.8S408,403,393.1,403h-74.8V278.2c0-14.9-9.9-24.8-24.8-24.8
- c-14.9,0-24.8,9.9-24.8,24.8v149.6C268.7,440.2,278.7,452.6,293.5,452.6z"/>
-</svg>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xml:space="preserve" + enable-background="new 0 0 841.9 841.9" + viewBox="0 0 841.9 841.9" + y="0px" + x="0px" + id="Ebene_1" + version="1.1"><metadata + id="metadata15"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs + id="defs13" /><g + id="g3"><path + id="path5" + d="M297.6,677.3c-68.5,0-132.9-26.7-181.3-75.1S41.3,489.4,41.3,420.9s26.7-132.9,75.1-181.3c48.4-48.4,112.8-75.1,181.3-75.1 s132.9,26.7,181.3,75.1c48.4,48.4,75.1,112.8,75.1,181.3s-26.7,132.9-75.1,181.3S366.1,677.3,297.6,677.3z M297.6,204.6 c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4 c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z" /></g><path + id="polygon7" + d="M 297.6 184.6 L 130.1 240.3 L 61.3 420.9 L 117 588.5 L 297.6 657.3 L 465.2 601.6 L 534 420.9 L 478.3 253.4 L 297.6 184.6 z M 293.5 253.4 C 308.4 253.4 318.3 263.3 318.3 278.2 L 318.3 403 L 393.1 403 C 408 403 417.9 412.9 417.9 427.8 C 417.9 442.7 408 452.6 393.1 452.6 L 293.5 452.6 C 278.7 452.6 268.7 440.2 268.7 427.8 L 268.7 278.2 C 268.7 263.3 278.6 253.4 293.5 253.4 z " /></svg>
\ No newline at end of file diff --git a/src/qt/res/src/connect-0.svg b/src/qt/res/src/connect-0.svg index bedbec7777..7d2afac622 100644 --- a/src/qt/res/src/connect-0.svg +++ b/src/qt/res/src/connect-0.svg @@ -1,11 +1,66 @@ -<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
-<path fill="none" stroke="#000000" stroke-miterlimit="10" d="M13.4,19.4c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0
- c-0.8,0.8-0.8,2.1,0,2.8C11.4,20.2,12.6,20.2,13.4,19.4z M7.8,15.8c-0.5,0-1-0.2-1.4-0.6c-0.8-0.8-0.8-2,0-2.8
- c3.1-3.1,8.2-3.1,11.3,0c0.8,0.8,0.8,2,0,2.8c-0.8,0.8-2,0.8-2.8,0c-1.6-1.6-4.1-1.6-5.7,0C8.8,15.6,8.3,15.8,7.8,15.8z"/>
-<path fill="none" stroke="#000000" stroke-miterlimit="10" d="M20.5,11.5c-0.5,0-1-0.2-1.4-0.6C15.2,7,8.8,7,4.9,10.9
- c-0.8,0.8-2,0.8-2.8,0c-0.8-0.8-0.8-2,0-2.8c5.5-5.5,14.3-5.5,19.8,0c0.8,0.8,0.8,2,0,2.8C21.5,11.3,21,11.5,20.5,11.5z"/>
-</svg>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + id="svg2" + viewBox="0 0 24 24" + height="24" + width="24" + version="1.2"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <g + id="g4142" + transform="matrix(0,-1,-1,0,23.96,24)"> + <g + id="g4210" + transform="matrix(-1,0,0,1,59.86,-106.6)"> + <g + id="g4289" + transform="matrix(-1,0,0,1,-16.98,0.8136)"> + <g + id="g4291"> + <path + id="path4293" + d="m -65.35,116.3 0,3 0.5,0 c 0.54,0 1,0.5 1,1 l 0,2.6 c -1.15,0.5 -2,1.6 -2,3 0,2 1.59,3.5 3.5,3.5 1.91,0 3.5,-1.5 3.5,-3.5 0,-1.4 -0.85,-2.5 -2,-3 l 0,-2.6 c 0,-2.3 -1.81,-4 -4,-4 z m 1,1.2 c 1.39,0.3 2.5,1.3 2.5,2.8 l 0,3.2 0.34,0.1 c 0.96,0.3 1.66,1.2 1.66,2.3 0,1.4 -1.11,2.5 -2.5,2.5 -1.39,0 -2.5,-1.1 -2.5,-2.5 0,-1.1 0.69,-2 1.66,-2.3 l 0.34,-0.1 0,-3.2 c 0,-0.9 -0.67,-1.5 -1.5,-1.8 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + <g + style="fill:#969696;fill-opacity:1" + id="g4295"> + <path + id="path4297" + d="m -67.35,106.1 c -1.94,0 -3.5,1.6 -3.5,3.5 0,1.4 0.85,2.5 2,3 l 0,2.7 c 0,2.2 1.79,4 4,4 l 0.5,0 0,-0.5 0,-2.5 -0.5,0 c -0.55,0 -1,-0.5 -1,-1 l 0,-2.7 c 1.15,-0.5 2,-1.6 2,-3 0,-1.9 -1.57,-3.5 -3.5,-3.5 z m 0,1 c 1.37,0 2.5,1.2 2.5,2.5 0,1.1 -0.7,2 -1.66,2.3 l -0.34,0.1 0,3.3 c 0,0.9 0.67,1.5 1.5,1.8 l 0,1 c -1.38,-0.3 -2.5,-1.4 -2.5,-2.8 l 0,-3.3 -0.34,-0.1 c -0.96,-0.3 -1.66,-1.2 -1.66,-2.3 0,-1.3 1.12,-2.5 2.5,-2.5 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + <path + id="path4299" + d="m -57.35,106.1 c -1.93,0 -3.5,1.6 -3.5,3.5 0,1.4 0.85,2.5 2,3 l 0,2.7 c 0,0.5 -0.45,1 -1,1 l -4.85,0 3.17,3 1.68,0 c 2.21,0 4,-1.8 4,-4 l 0,-2.7 c 1.15,-0.5 2,-1.6 2,-3 0,-1.9 -1.56,-3.5 -3.5,-3.5 z m 0,1 c 1.38,0 2.5,1.2 2.5,2.5 0,1.1 -0.7,2 -1.66,2.3 l -0.34,0.1 0,3.3 c 0,1.6 -1.35,3 -3,3 l -1.81,0 -2.04,-1 3.85,0 c 1.11,0 2,-0.9 2,-2 l 0,-3.3 -0.34,-0.1 c -0.96,-0.3 -1.66,-1.2 -1.66,-2.3 0,-1.3 1.13,-2.5 2.5,-2.5 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + </g> + <path + id="path4301" + d="m -69.84,116.3 c -2.19,0 -4,1.7 -4,4 l 0,2.6 c -1.14,0.6 -1.99,1.6 -1.99,3 0,2 1.6,3.5 3.51,3.5 1.91,0 3.5,-1.5 3.5,-3.5 0,-1.4 -0.85,-2.5 -2,-3 l 0,-2.6 c 0,-0.5 0.45,-1 1,-1 l 5.01,0 -3.36,-3 z m 0,1 1.84,0 2.19,1 -4.01,0 c -1.11,0 -2,0.9 -2,2 l 0,3.2 0.34,0.1 c 0.96,0.3 1.66,1.2 1.66,2.3 0,1.4 -1.11,2.5 -2.5,2.5 -1.39,0 -2.51,-1.1 -2.51,-2.5 0,-1.1 0.7,-2 1.66,-2.3 l 0.33,-0.1 0,-0.4 0,-2.8 c 0,-1.7 1.33,-3 3,-3 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + </g> + </g> + </g> + <path + id="path4165" + d="m 12,8.77 c -0.84,0 -1.66,0.341 -2.254,0.937 -0.599,0.593 -0.942,1.403 -0.945,2.253 0,0.85 0.337,1.67 0.933,2.26 a 0.6001,0.6001 0 0 0 0,0 c 0.594,0.6 1.424,0.94 2.264,0.94 0.84,0 1.67,-0.34 2.26,-0.94 0.6,-0.59 0.94,-1.41 0.94,-2.26 0,-0.84 -0.34,-1.66 -0.95,-2.253 C 13.66,9.111 12.84,8.77 12,8.77 Z" + style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + </g> +</svg> diff --git a/src/qt/res/src/connect-1.svg b/src/qt/res/src/connect-1.svg index d3d4e46a41..d17928c97d 100644 --- a/src/qt/res/src/connect-1.svg +++ b/src/qt/res/src/connect-1.svg @@ -1,21 +1,69 @@ -<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
-<g>
- <path d="M12,11c1.9,0,3.6,0.7,4.9,2c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C14.6,13.5,13.3,13,12,13
- c-1.3,0-2.6,0.5-3.5,1.5c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C8.4,11.7,10.1,11,12,11 M12,17
- c0.3,0,0.5,0.1,0.7,0.3c0.2,0.2,0.3,0.4,0.3,0.7s-0.1,0.5-0.3,0.7C12.5,18.9,12.3,19,12,19c-0.3,0-0.5-0.1-0.7-0.3
- C11.1,18.5,11,18.3,11,18c0-0.3,0.1-0.5,0.3-0.7C11.5,17.1,11.7,17,12,17 M12,10c-2,0-4.1,0.8-5.7,2.3c-0.8,0.8-0.8,2,0,2.8
- c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C10,14.4,11,14,12,14c1,0,2,0.4,2.8,1.2c0.4,0.4,0.9,0.6,1.4,0.6s1-0.2,1.4-0.6
- c0.8-0.8,0.8-2,0-2.8C16.1,10.8,14,10,12,10L12,10z M12,16c-0.5,0-1,0.2-1.4,0.6c-0.8,0.8-0.8,2.1,0,2.8C11,19.8,11.5,20,12,20
- c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C13,16.2,12.5,16,12,16L12,16z"/>
-</g>
-<g>
- <path d="M12,5c3.5,0,6.7,1.3,9.2,3.8c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C17.7,8.1,14.9,7,12,7
- c-2.9,0-5.7,1.1-7.8,3.2c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C5.3,6.4,8.5,5,12,5 M12,4
- C8.4,4,4.8,5.4,2.1,8.1c-0.8,0.8-0.8,2,0,2.8c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C6.9,9,9.4,8,12,8c2.6,0,5.1,1,7.1,2.9
- c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C19.2,5.4,15.6,4,12,4L12,4z"/>
-</g>
-</svg>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.2" + width="24" + height="24" + viewBox="0 0 24 24" + id="svg2"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <g + id="g4210" + transform="translate(0,0.25)"> + <g + id="g4142" + transform="matrix(0,-1,-1,0,23.96,23.75)"> + <g + id="g4213" + transform="matrix(-1,0,0,1,59.86,-106.6)"> + <g + id="g4289" + transform="matrix(-1,0,0,1,-16.98,0.8136)"> + <g + id="g4291"> + <path + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + d="m -65.35,116.3 0,3 0.5,0 c 0.54,0 1,0.5 1,1 l 0,2.6 c -1.15,0.5 -2,1.6 -2,3 0,2 1.59,3.5 3.5,3.5 1.91,0 3.5,-1.5 3.5,-3.5 0,-1.4 -0.85,-2.5 -2,-3 l 0,-2.6 c 0,-2.3 -1.81,-4 -4,-4 z m 1,1.2 c 1.39,0.3 2.5,1.3 2.5,2.8 l 0,3.2 0.34,0.1 c 0.96,0.3 1.66,1.2 1.66,2.3 0,1.4 -1.11,2.5 -2.5,2.5 -1.39,0 -2.5,-1.1 -2.5,-2.5 0,-1.1 0.69,-2 1.66,-2.3 l 0.34,-0.1 0,-3.2 c 0,-0.9 -0.67,-1.5 -1.5,-1.8 z" + id="path4293" /> + <g + id="g4295"> + <path + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + d="m -67.35,106.1 c -1.94,0 -3.5,1.6 -3.5,3.5 0,1.4 0.85,2.5 2,3 l 0,2.7 c 0,2.2 1.79,4 4,4 l 0.5,0 0,-0.5 0,-2.5 -0.5,0 c -0.55,0 -1,-0.5 -1,-1 l 0,-2.7 c 1.15,-0.5 2,-1.6 2,-3 0,-1.9 -1.57,-3.5 -3.5,-3.5 z m 0,1 c 1.37,0 2.5,1.2 2.5,2.5 0,1.1 -0.7,2 -1.66,2.3 l -0.34,0.1 0,3.3 c 0,0.9 0.67,1.5 1.5,1.8 l 0,1 c -1.38,-0.3 -2.5,-1.4 -2.5,-2.8 l 0,-3.3 -0.34,-0.1 c -0.96,-0.3 -1.66,-1.2 -1.66,-2.3 0,-1.3 1.12,-2.5 2.5,-2.5 z" + id="path4297" /> + <path + id="path4145" + d="m -57.35,106 c -1.99,0 -3.6,1.7 -3.6,3.6 0,1.4 0.83,2.6 2,3.2 l 0,2.5 c 0,0.5 -0.41,0.9 -0.9,0.9 l -4.35,0 a 0.6001,0.6001 0 0 0 -0.6,0.6 l 0,2 a 0.6001,0.6001 0 0 0 0.6,0.6 l 4.35,0 c 2.26,0 4.1,-1.9 4.1,-4.1 l 0,-2.5 c 1.17,-0.6 2,-1.8 2,-3.2 0,-1.9 -1.6,-3.6 -3.6,-3.6 z" + style="" /> + </g> + <path + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + d="m -69.84,116.3 c -2.19,0 -4,1.7 -4,4 l 0,2.6 c -1.14,0.6 -1.99,1.6 -1.99,3 0,2 1.6,3.5 3.51,3.5 1.91,0 3.5,-1.5 3.5,-3.5 0,-1.4 -0.85,-2.5 -2,-3 l 0,-2.6 c 0,-0.5 0.45,-1 1,-1 l 5.01,0 -3.34,-3 z m 0,1 2.02,0 2.01,1 -4.01,0 c -1.11,0 -2,0.9 -2,2 l 0,3.2 0.34,0.1 c 0.96,0.3 1.66,1.2 1.66,2.3 0,1.4 -1.11,2.5 -2.5,2.5 -1.39,0 -2.51,-1.1 -2.51,-2.5 0,-1.1 0.7,-2 1.66,-2.3 l 0.33,-0.1 0,-0.4 0,-2.8 c 0,-1.7 1.33,-3 3,-3 z" + id="path4301" /> + </g> + </g> + </g> + <path + id="path4173" + d="m 12,8.764 c -0.84,0 -1.67,0.336 -2.264,0.931 a 0.6001,0.6001 0 0 0 -0,0 C 9.138,10.29 8.802,11.11 8.801,11.96 c 0,0.85 0.337,1.67 0.933,2.26 a 0.6001,0.6001 0 0 0 0,0 c 0.594,0.6 1.424,0.94 2.264,0.94 0.84,0 1.67,-0.34 2.26,-0.94 0.6,-0.59 0.94,-1.41 0.94,-2.26 0,-0.84 -0.34,-1.67 -0.94,-2.265 C 13.67,9.1 12.84,8.764 12,8.764 Z" + style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + </g> + </g> +</svg> diff --git a/src/qt/res/src/connect-2.svg b/src/qt/res/src/connect-2.svg index d5becc52b7..841ca6071d 100644 --- a/src/qt/res/src/connect-2.svg +++ b/src/qt/res/src/connect-2.svg @@ -1,22 +1,59 @@ -<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
-<path d="M13.4,19.4c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0c-0.8,0.8-0.8,2.1,0,2.8C11.4,20.2,12.6,20.2,13.4,19.4z"/>
-<g>
- <path d="M12,11c1.9,0,3.6,0.7,4.9,2c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C14.6,13.5,13.3,13,12,13
- c-1.3,0-2.6,0.5-3.5,1.5c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C8.4,11.7,10.1,11,12,11 M12,17
- c0.3,0,0.5,0.1,0.7,0.3c0.2,0.2,0.3,0.4,0.3,0.7s-0.1,0.5-0.3,0.7C12.5,18.9,12.3,19,12,19c-0.3,0-0.5-0.1-0.7-0.3
- C11.1,18.5,11,18.3,11,18c0-0.3,0.1-0.5,0.3-0.7C11.5,17.1,11.7,17,12,17 M12,10c-2,0-4.1,0.8-5.7,2.3c-0.8,0.8-0.8,2,0,2.8
- c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C10,14.4,11,14,12,14c1,0,2,0.4,2.8,1.2c0.4,0.4,0.9,0.6,1.4,0.6s1-0.2,1.4-0.6
- c0.8-0.8,0.8-2,0-2.8C16.1,10.8,14,10,12,10L12,10z M12,16c-0.5,0-1,0.2-1.4,0.6c-0.8,0.8-0.8,2.1,0,2.8C11,19.8,11.5,20,12,20
- c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C13,16.2,12.5,16,12,16L12,16z"/>
-</g>
-<g>
- <path d="M12,5c3.5,0,6.7,1.3,9.2,3.8c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C17.7,8.1,14.9,7,12,7
- c-2.9,0-5.7,1.1-7.8,3.2c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C5.3,6.4,8.5,5,12,5 M12,4
- C8.4,4,4.8,5.4,2.1,8.1c-0.8,0.8-0.8,2,0,2.8c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C6.9,9,9.4,8,12,8c2.6,0,5.1,1,7.1,2.9
- c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C19.2,5.4,15.6,4,12,4L12,4z"/>
-</g>
-</svg>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.2" + width="24" + height="24" + viewBox="0 0 24 24" + id="svg2"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <g + id="g4210" + transform="matrix(0,1,-1,0,130.6,-35.86)"> + <g + id="g4289" + transform="matrix(-1,0,0,1,-16.98,0.8136)"> + <g + id="g4291"> + <path + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + d="m -65.35,116.3 0,3 0.5,0 c 0.54,0 1,0.5 1,1 l 0,2.6 c -1.15,0.5 -2,1.6 -2,3 0,2 1.59,3.5 3.5,3.5 1.91,0 3.5,-1.5 3.5,-3.5 0,-1.4 -0.85,-2.5 -2,-3 l 0,-2.6 c 0,-2.3 -1.81,-4 -4,-4 z m 1,1.2 c 1.39,0.3 2.5,1.3 2.5,2.8 l 0,3.2 0.34,0.1 c 0.96,0.3 1.66,1.2 1.66,2.3 0,1.4 -1.11,2.5 -2.5,2.5 -1.39,0 -2.5,-1.1 -2.5,-2.5 0,-1.1 0.69,-2 1.66,-2.3 l 0.34,-0.1 0,-3.2 c 0,-0.9 -0.67,-1.5 -1.5,-1.8 z" + id="path4293" /> + <g + id="g4295"> + <path + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + d="m -67.35,106.1 c -1.94,0 -3.5,1.6 -3.5,3.5 0,1.4 0.85,2.5 2,3 l 0,2.7 c 0,2.2 1.79,4 4,4 l 0.5,0 0,-0.5 0,-2.5 -0.5,0 c -0.55,0 -1,-0.5 -1,-1 l 0,-2.7 c 1.15,-0.5 2,-1.6 2,-3 0,-1.9 -1.57,-3.5 -3.5,-3.5 z m 0,1 c 1.37,0 2.5,1.2 2.5,2.5 0,1.1 -0.7,2 -1.66,2.3 l -0.34,0.1 0,3.3 c 0,0.9 0.67,1.5 1.5,1.8 l 0,1 c -1.38,-0.3 -2.5,-1.4 -2.5,-2.8 l 0,-3.3 -0.34,-0.1 c -0.96,-0.3 -1.66,-1.2 -1.66,-2.3 0,-1.3 1.12,-2.5 2.5,-2.5 z" + id="path4297" /> + <path + id="path4142" + d="m -57.35,106 c -1.99,0 -3.6,1.7 -3.6,3.6 0,1.4 0.83,2.6 2,3.2 l 0,2.5 c 0,0.5 -0.41,0.9 -0.9,0.9 l -4.35,0 a 0.6001,0.6001 0 0 0 -0.6,0.6 l 0,2 a 0.6001,0.6001 0 0 0 0.6,0.6 l 4.35,0 c 2.26,0 4.1,-1.9 4.1,-4.1 l 0,-2.5 c 1.17,-0.6 2,-1.8 2,-3.2 0,-1.9 -1.6,-3.6 -3.6,-3.6 z" /> + </g> + <path + id="path4148" + d="m -69.84,116.2 c -2.24,0 -4.1,1.8 -4.1,4.1 l 0,2.5 c -1.17,0.5 -1.99,1.7 -1.99,3.1 0,2 1.64,3.6 3.61,3.6 1.96,0 3.6,-1.6 3.6,-3.6 0,-1.4 -0.83,-2.6 -2,-3.2 l 0,-2.4 c 0,-0.5 0.41,-0.9 0.9,-0.9 l 4.51,0 a 0.6001,0.6001 0 0 0 0.6,-0.6 l 0,-2 a 0.6001,0.6001 0 0 0 -0.6,-0.6 l -4.53,0 z" /> + </g> + </g> + <path + id="path4170" + d="m 47.86,115.4 c -0.84,0 -1.65,0.4 -2.24,1 -0.64,0.5 -0.96,1.3 -0.96,2.2 0,0.9 0.32,1.7 0.96,2.2 0.59,0.6 1.4,1 2.24,1 0.84,0 1.65,-0.4 2.24,-1 0.64,-0.5 0.96,-1.3 0.96,-2.2 0,-0.9 -0.32,-1.7 -0.96,-2.2 -0.59,-0.6 -1.4,-1 -2.24,-1 z" + style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + </g> +</svg> diff --git a/src/qt/res/src/connect-3.svg b/src/qt/res/src/connect-3.svg index 9bfa04721f..b06e67daf8 100644 --- a/src/qt/res/src/connect-3.svg +++ b/src/qt/res/src/connect-3.svg @@ -1,16 +1,72 @@ -<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
-<path d="M13.4,19.4c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0c-0.8,0.8-0.8,2.1,0,2.8C11.4,20.2,12.6,20.2,13.4,19.4z"/>
-<path d="M13.4,19.4c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0c-0.8,0.8-0.8,2.1,0,2.8C11.4,20.2,12.6,20.2,13.4,19.4z M7.8,15.8
- c-0.5,0-1-0.2-1.4-0.6c-0.8-0.8-0.8-2,0-2.8c3.1-3.1,8.2-3.1,11.3,0c0.8,0.8,0.8,2,0,2.8c-0.8,0.8-2,0.8-2.8,0
- c-1.6-1.6-4.1-1.6-5.7,0C8.8,15.6,8.3,15.8,7.8,15.8z"/>
-<g>
- <path d="M12,5c3.5,0,6.7,1.3,9.2,3.8c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C17.7,8.1,14.9,7,12,7
- c-2.9,0-5.7,1.1-7.8,3.2c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C5.3,6.4,8.5,5,12,5 M12,4
- C8.4,4,4.8,5.4,2.1,8.1c-0.8,0.8-0.8,2,0,2.8c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C6.9,9,9.4,8,12,8c2.6,0,5.1,1,7.1,2.9
- c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C19.2,5.4,15.6,4,12,4L12,4z"/>
-</g>
-</svg>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + id="svg2" + viewBox="0 0 24 24" + height="24" + width="24" + version="1.2"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <g + transform="translate(0.2636,0.29)" + id="g4160"> + <g + id="g4210" + transform="matrix(0,1,-1,0,130.3,-36.15)"> + <g + id="g4289" + transform="matrix(-1,0,0,1,-16.98,0.8136)"> + <g + id="g4291"> + <path + id="path4147" + d="m -64.85,116.2 a 0.6001,0.6001 0 0 0 -0.6,0.6 l 0,2 a 0.6001,0.6001 0 0 0 0.6,0.6 c 0.48,0 0.9,0.4 0.9,0.9 l 0,2.4 c -1.18,0.6 -2,1.8 -2,3.2 0,2 1.64,3.6 3.6,3.6 1.97,0 3.6,-1.6 3.6,-3.6 0,-1.4 -0.83,-2.6 -2,-3.2 l 0,-2.4 c 0,-2.3 -1.86,-4.1 -4.1,-4.1 z" + style="" /> + <g + id="g4295"> + <path + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + d="m -67.35,106.1 c -1.94,0 -3.5,1.6 -3.5,3.5 0,1.4 0.85,2.5 2,3 l 0,2.7 c 0,2.2 1.79,4 4,4 l 0.5,0 0,-0.5 0,-2.5 -0.5,0 c -0.55,0 -1,-0.5 -1,-1 l 0,-2.7 c 1.15,-0.5 2,-1.6 2,-3 0,-1.9 -1.57,-3.5 -3.5,-3.5 z m 0,1 c 1.37,0 2.5,1.2 2.5,2.5 0,1.1 -0.7,2 -1.66,2.3 l -0.34,0.1 0,3.3 c 0,0.9 0.67,1.5 1.5,1.8 l 0,1 c -1.38,-0.3 -2.5,-1.4 -2.5,-2.8 l 0,-3.3 -0.34,-0.1 c -0.96,-0.3 -1.66,-1.2 -1.66,-2.3 0,-1.3 1.12,-2.5 2.5,-2.5 z" + id="path4297" /> + <path + id="path4145" + d="m -57.35,106 c -1.99,0 -3.6,1.7 -3.6,3.6 0,1.4 0.83,2.6 2,3.2 l 0,2.5 c 0,0.5 -0.41,0.9 -0.9,0.9 l -4.35,0 a 0.6001,0.6001 0 0 0 -0.6,0.6 l 0,2 a 0.6001,0.6001 0 0 0 0.6,0.6 l 4.35,0 c 2.26,0 4.1,-1.9 4.1,-4.1 l 0,-2.5 c 1.17,-0.6 2,-1.8 2,-3.2 0,-1.9 -1.6,-3.6 -3.6,-3.6 z" + style="" /> + </g> + <path + id="path4149" + d="m -69.84,116.2 c -2.24,0 -4.1,1.8 -4.1,4.1 l 0,2.5 c -1.17,0.5 -1.99,1.7 -1.99,3.1 0,2 1.64,3.6 3.61,3.6 1.96,0 3.6,-1.6 3.6,-3.6 0,-1.4 -0.83,-2.6 -2,-3.2 l 0,-2.4 c 0,-0.5 0.41,-0.9 0.9,-0.9 l 4.51,0 a 0.6001,0.6001 0 0 0 0.6,-0.6 l 0,-2 a 0.6001,0.6001 0 0 0 -0.6,-0.6 l -4.53,0 z" + style="" /> + </g> + </g> + </g> + <g + transform="matrix(0,1,1,0,-106.3,-36.15)" + id="g4142"> + <g + transform="matrix(-1,0,0,1,-16.98,0.8136)" + id="g4144" /> + </g> + </g> + <path + id="path4170" + d="m 15.2,12 c 0,-0.84 -0.4,-1.65 -1,-2.242 -0.5,-0.64 -1.3,-0.96 -2.2,-0.96 -0.9,0 -1.7,0.32 -2.2,0.96 -0.6,0.592 -1,1.402 -1,2.242 0,0.84 0.4,1.65 1,2.24 0.5,0.64 1.3,0.96 2.2,0.96 0.9,0 1.7,-0.32 2.2,-0.96 0.6,-0.59 1,-1.4 1,-2.24 z" + style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> +</svg> diff --git a/src/qt/res/src/connect-4.svg b/src/qt/res/src/connect-4.svg new file mode 100644 index 0000000000..0abc7955fd --- /dev/null +++ b/src/qt/res/src/connect-4.svg @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.2" + width="24" + height="24" + viewBox="0 0 24 24" + id="svg2"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <g + id="g4142" + transform="matrix(0,-1,-1,0,23.96,24)"> + <g + transform="matrix(-1,0,0,1,59.86,-106.6)" + id="g4210"> + <g + transform="matrix(-1,0,0,1,-16.98,0.8136)" + id="g4289"> + <g + id="g4291"> + <path + id="path4153" + d="m -64.85,116.2 a 0.6001,0.6001 0 0 0 -0.6,0.6 l 0,2 a 0.6001,0.6001 0 0 0 0.6,0.6 c 0.48,0 0.9,0.4 0.9,0.9 l 0,2.4 c -1.18,0.6 -2,1.8 -2,3.2 0,2 1.64,3.6 3.6,3.6 1.97,0 3.6,-1.6 3.6,-3.6 0,-1.4 -0.83,-2.6 -2,-3.2 l 0,-2.4 c 0,-2.3 -1.86,-4.1 -4.1,-4.1 z" + style="" /> + <g + id="g4295"> + <path + id="path4149" + d="m -67.35,106 c -2,0 -3.6,1.7 -3.6,3.6 0,1.4 0.83,2.6 2,3.2 l 0,2.5 c 0,2.2 1.84,4.1 4.1,4.1 a 0.6001,0.6001 0 0 0 0.6,-0.6 l 0,-2 a 0.6001,0.6001 0 0 0 -0.6,-0.6 c -0.49,0 -0.9,-0.4 -0.9,-0.9 l 0,-2.5 c 1.17,-0.6 2,-1.8 2,-3.2 0,-1.9 -1.61,-3.6 -3.6,-3.6 z" + style="" /> + <path + id="path4147" + d="m -57.35,106 c -1.99,0 -3.6,1.7 -3.6,3.6 0,1.4 0.83,2.6 2,3.2 l 0,2.5 c 0,0.5 -0.41,0.9 -0.9,0.9 l -4.35,0 a 0.6001,0.6001 0 0 0 -0.6,0.6 l 0,2 a 0.6001,0.6001 0 0 0 0.6,0.6 l 4.35,0 c 2.26,0 4.1,-1.9 4.1,-4.1 l 0,-2.5 c 1.17,-0.6 2,-1.8 2,-3.2 0,-1.9 -1.6,-3.6 -3.6,-3.6 z" + style="" /> + </g> + <path + id="path4155" + d="m -69.84,116.2 c -2.24,0 -4.1,1.8 -4.1,4.1 l 0,2.5 c -1.17,0.5 -1.99,1.7 -1.99,3.1 0,2 1.64,3.6 3.61,3.6 1.96,0 3.6,-1.6 3.6,-3.6 0,-1.4 -0.83,-2.6 -2,-3.2 l 0,-2.4 c 0,-0.5 0.41,-0.9 0.9,-0.9 l 4.51,0 a 0.6001,0.6001 0 0 0 0.6,-0.6 l 0,-2 a 0.6001,0.6001 0 0 0 -0.6,-0.6 l -4.53,0 z" + style="" /> + </g> + </g> + </g> + </g> + <path + id="path4170" + d="m 15.2,12 c 0,-0.84 -0.4,-1.65 -1,-2.24 C 13.7,9.12 12.9,8.8 12,8.8 c -0.9,0 -1.7,0.32 -2.2,0.96 -0.6,0.59 -1,1.4 -1,2.24 0,0.84 0.4,1.65 1,2.24 0.5,0.64 1.3,0.96 2.2,0.96 0.9,0 1.7,-0.32 2.2,-0.96 0.6,-0.59 1,-1.4 1,-2.24 z" + style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> +</svg> diff --git a/src/qt/res/src/qt.svg b/src/qt/res/src/qt.svg index 9ef54f493c..373c91f0c6 100644 --- a/src/qt/res/src/qt.svg +++ b/src/qt/res/src/qt.svg @@ -1,25 +1,26 @@ -<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- viewBox="0 0 841.9 595.3" enable-background="new 0 0 841.9 595.3" xml:space="preserve">
-<g>
- <path d="M182.8,310c0-74.4,0-148.8,0-220.7c0-19.8,5-39.7,19.8-54.6c12.4-12.4,27.3-17.4,44.6-19.8c37.2-5,74.4,2.5,109.1,7.4
- C428.4,34.7,497.8,44.6,569.8,57c27.3,5,57,9.9,84.3,12.4c7.4,0,5,5,5,9.9c0,91.8,0,181.1,0,272.8c0,32.2,0,64.5,0,99.2
- c0,14.9-5,29.8-12.4,44.6c-9.9,14.9-22.3,22.3-39.7,27.3c-69.4,12.4-138.9,22.3-208.3,34.7c-57,9.9-114.1,19.8-171.1,29.8
- c-2.5,0-5,0-7.4-2.5c-12.4-14.9-22.3-24.8-32.2-34.7c-2.5-2.5-2.5-7.4-2.5-9.9c0-71.9,0-143.9,0-215.8
- C182.8,320,182.8,315,182.8,310z M430.9,436.5c9.9-7.4,19.8-12.4,29.8-19.8c14.9-14.9,24.8-32.2,29.8-54.6
- c12.4-54.6,14.9-111.6,0-166.2c-12.4-47.1-42.2-74.4-84.3-79.4c-37.2-2.5-67,7.4-86.8,39.7c-7.4,14.9-12.4,29.8-14.9,44.6
- c-9.9,39.7-9.9,81.9-5,121.5c2.5,22.3,7.4,44.6,17.4,67c12.4,24.8,29.8,42.2,54.6,49.6c2.5,0,5,2.5,5,5c5,12.4,7.4,22.3,12.4,34.7
- s17.4,19.8,32.2,22.3c14.9,2.5,27.3,2.5,42.2,0c2.5,0,2.5-2.5,2.5-2.5c0-9.9,0-22.3,0-32.2C438.3,461.3,433.3,456.4,430.9,436.5z
- M505.3,191c0,12.4,0,22.3,0,34.7c0,2.5,2.5,2.5,5,2.5c5,0,7.4,0,12.4,0c0,2.5,0,5,0,9.9c0,44.6,0,86.8,0,131.5
- c0,7.4,0,17.4,2.5,24.8c2.5,12.4,12.4,22.3,24.8,24.8c19.8,5,37.2-2.5,54.6-9.9l2.5-2.5c0-9.9,0-19.8,0-29.8
- c-7.4,2.5-14.9,5-22.3,5s-12.4-2.5-14.9-9.9c0-5-2.5-9.9-2.5-14.9c0-39.7,0-79.4,0-119.1c0-2.5,0-5,0-7.4c9.9,0,19.8,0,29.8,2.5
- c5,0,7.4-2.5,7.4-7.4c0-7.4,0-14.9,0-22.3c0-5-2.5-7.4-7.4-7.4c-7.4,0-14.9-2.5-22.3-2.5c-5,0-7.4-2.5-7.4-7.4
- c0-14.9,0-29.8,0-42.2c0-5-2.5-5-5-7.4c-5,0-12.4,0-17.4-2.5s-7.4,0-9.9,7.4c-2.5,17.4-7.4,32.2-12.4,49.6
- C520.2,191,512.7,191,505.3,191z"/>
- <path d="M443.3,277.8c-2.5,27.3-5,57-9.9,84.3c0,7.4-5,17.4-9.9,24.8c-12.4,17.4-32.2,14.9-44.6-2.5c-9.9-14.9-12.4-32.2-14.9-49.6
- c-5-42.2-5-81.9,0-124c5-12.4,7.4-24.8,14.9-37.2c12.4-17.4,34.7-17.4,47.1-2.5c2.5,5,7.4,9.9,7.4,14.9c2.5,9.9,5,19.8,7.4,32.2
- c2.5,9.9,2.5,22.3,2.5,34.7C440.8,260.4,440.8,270.4,443.3,277.8L443.3,277.8z"/>
-</g>
-</svg>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.1" + id="Ebene_1" + x="0px" + y="0px" + viewBox="0 0 609.4 609.4" + enable-background="new 0 0 841.9 595.3" + xml:space="preserve" + width="609.4" + height="609.4"><metadata + id="metadata13"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs + id="defs11" /><g + id="g4151" + transform="matrix(2.553,0,0,2.553,-2149,281.5)"><path + id="path26" + transform="matrix(0.3917,0,0,0.3917,841.8,-110.3)" + d="M 153.7 16.9 C 115 16.44 69.7 31.67 67.96 86.81 L 67.96 550.7 L 105 592.4 L 495.9 526.7 C 521.4 522.1 541.9 490.2 541.9 455.9 L 541.9 77.77 L 183.4 18.97 C 179.4 18.3 161.4 17 157.5 16.99 C 156.2 16.94 155 16.91 153.7 16.9 z M 273.5 124.1 C 278.1 124.1 282.7 124.3 287.3 124.9 L 287.3 125 C 320 128.8 343.7 144.2 359.3 170.9 C 374.6 197.1 382 234.6 382 284 C 382 329.2 376.4 364.7 365.4 390.7 C 354.2 417.2 337.1 434.6 313.4 442.8 C 315.9 455 319.5 463.2 324.1 467.5 C 326.9 469.8 330.7 471.4 335.3 471.9 L 335.6 471.9 L 336.3 471.9 L 341.5 471.9 C 343.5 471.9 344.5 472.4 348.3 471.9 L 348.3 507.9 L 332 510.2 C 327.2 510.7 322.6 510.9 318.2 510.9 C 303.9 510.9 292.4 507.6 283.5 500.5 C 272 491.3 263.6 473.4 258.2 447.1 C 233.2 441.8 213.5 425.9 200 399.1 C 186.5 372.1 179.3 332.2 179.3 280.4 C 179.3 224.5 189 183.2 207.7 157 C 223.8 134.9 245.7 124.1 273.5 124.1 z M 424.4 143.5 L 455.1 146.9 L 455.1 202.2 L 488.2 204.8 L 488.2 239.5 L 455.1 237.8 L 455.1 364.7 C 455.1 375.6 457.6 382.8 460.2 386.1 C 460.2 388.9 465.3 390.4 467.8 390.4 L 470.4 390.4 C 478 389.9 485.7 387.9 493.4 384.1 L 493.4 415.7 C 478 422.1 465.3 425.7 450 426.9 C 450 427.2 447.4 427.2 444.8 427.2 C 432.1 427.2 424.4 423.6 416.8 416.5 C 409.1 408.1 404 394.5 404 376.1 L 404 235.6 L 390.2 234.8 L 390.2 197.6 L 411.7 199.1 L 424.4 143.5 z M 284.5 166.4 C 272.5 166.4 263.3 173.3 256.9 187.3 C 250.1 202.5 246.7 233.9 246.7 281.7 C 246.7 327.6 250.1 360.3 256.9 379.5 C 263.3 397.8 273 406.8 285.8 406.8 L 287.3 406.8 C 300.1 406 309.5 397.1 316.2 380.5 C 322.6 363.9 325.6 331.5 325.6 283 C 325.6 239.4 322.6 209.5 316.2 193 C 309.8 176.4 300.1 167.5 287.3 166.4 L 284.5 166.4 z " + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></svg>
\ No newline at end of file diff --git a/src/qt/res/spinner.png b/src/qt/res/src/spinner.png Binary files differindex b296a58481..b296a58481 100644 --- a/src/qt/res/spinner.png +++ b/src/qt/res/src/spinner.png diff --git a/src/qt/res/src/transaction0.svg b/src/qt/res/src/transaction0.svg new file mode 100644 index 0000000000..e7fcd8214c --- /dev/null +++ b/src/qt/res/src/transaction0.svg @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.1" + id="svg4142" + viewBox="0 0 128 127.9" + height="36.12mm" + width="36.12mm"> + <defs + id="defs4144" /> + <metadata + id="metadata4147"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + id="layer1" + transform="translate(-284.4,-501.6)"> + <path + id="path4792" + d="m 348.8,513.8 c -12.7,-0.7 -24.9,9.1 -27,21.7 -3.8,8.8 7.2,13.7 13.7,9.2 3.1,-7.5 9.4,-17.9 18.9,-11.6 9.7,6.1 2.1,17.6 -3,24.1 -6.1,7.8 -11.4,14.8 -8.9,23 5.4,17.7 10.8,3.7 12.8,-0.1 4.3,-8.2 6,-8.8 11.5,-16.1 6.4,-8.6 11.6,-19.9 7.7,-30.8 -2.8,-11.5 -13.9,-19.9 -25.7,-19.4 z m -0.7,84.7 c -11.4,2.4 -9.1,19.5 2.7,17.1 11.8,-2.4 8.7,-19.5 -2.7,-17.1 z" + style="fill:#000000" /> + </g> +</svg> diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index b2717558ca..72a3023c9a 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -3,12 +3,13 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "rpcconsole.h" -#include "ui_rpcconsole.h" +#include "ui_debugwindow.h" +#include "bantablemodel.h" #include "clientmodel.h" #include "guiutil.h" -#include "peertablemodel.h" -#include "scicon.h" +#include "platformstyle.h" +#include "bantablemodel.h" #include "chainparams.h" #include "rpcserver.h" @@ -26,8 +27,10 @@ #include <QKeyEvent> #include <QMenu> #include <QScrollBar> +#include <QSignalMapper> #include <QThread> #include <QTime> +#include <QTimer> #if QT_VERSION < 0x050000 #include <QUrl> @@ -66,6 +69,40 @@ Q_SIGNALS: void reply(int category, const QString &command); }; +/** Class for handling RPC timers + * (used for e.g. re-locking the wallet after a timeout) + */ +class QtRPCTimerBase: public QObject, public RPCTimerBase +{ + Q_OBJECT +public: + QtRPCTimerBase(boost::function<void(void)>& func, int64_t millis): + func(func) + { + timer.setSingleShot(true); + connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); + timer.start(millis); + } + ~QtRPCTimerBase() {} +private Q_SLOTS: + void timeout() { func(); } +private: + QTimer timer; + boost::function<void(void)> func; +}; + +class QtRPCTimerInterface: public RPCTimerInterface +{ +public: + ~QtRPCTimerInterface() {} + const char *Name() { return "Qt"; } + RPCTimerBase* NewTimer(boost::function<void(void)>& func, int64_t millis) + { + return new QtRPCTimerBase(func, millis); + } +}; + + #include "rpcconsole.moc" /** @@ -200,21 +237,23 @@ void RPCExecutor::request(const QString &command) } } -RPCConsole::RPCConsole(QWidget *parent) : +RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : QWidget(parent), ui(new Ui::RPCConsole), clientModel(0), historyPtr(0), cachedNodeid(-1), - contextMenu(0) + platformStyle(platformStyle), + peersTableContextMenu(0), + banTableContextMenu(0) { ui->setupUi(this); GUIUtil::restoreWindowGeometry("nRPCConsoleWindow", this->size(), this); -#ifndef Q_OS_MAC - ui->openDebugLogfileButton->setIcon(SingleColorIcon(":/icons/export")); -#endif - ui->clearButton->setIcon(SingleColorIcon(":/icons/remove")); + if (platformStyle->getImagesOnButtons()) { + ui->openDebugLogfileButton->setIcon(platformStyle->SingleColorIcon(":/icons/export")); + } + ui->clearButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); // Install event filter for up and down arrow ui->lineEdit->installEventFilter(this); @@ -231,6 +270,9 @@ RPCConsole::RPCConsole(QWidget *parent) : ui->label_berkeleyDBVersion->hide(); ui->berkeleyDBVersion->hide(); #endif + // Register RPC timer interface + rpcTimerInterface = new QtRPCTimerInterface(); + RPCRegisterTimerInterface(rpcTimerInterface); startExecutor(); setTrafficGraphRange(INITIAL_TRAFFIC_GRAPH_MINS); @@ -245,6 +287,8 @@ RPCConsole::~RPCConsole() { GUIUtil::saveWindowGeometry("nRPCConsoleWindow", this); Q_EMIT stopExecutor(); + RPCUnregisterTimerInterface(rpcTimerInterface); + delete rpcTimerInterface; delete ui; } @@ -288,8 +332,7 @@ void RPCConsole::setClientModel(ClientModel *model) { clientModel = model; ui->trafficGraph->setClientModel(model); - if(model) - { + if (model && clientModel->getPeerTableModel() && clientModel->getBanTableModel()) { // Keep up to date with client setNumConnections(model->getNumConnections()); connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); @@ -310,29 +353,81 @@ void RPCConsole::setClientModel(ClientModel *model) ui->peerWidget->setColumnWidth(PeerTableModel::Address, ADDRESS_COLUMN_WIDTH); ui->peerWidget->setColumnWidth(PeerTableModel::Subversion, SUBVERSION_COLUMN_WIDTH); ui->peerWidget->setColumnWidth(PeerTableModel::Ping, PING_COLUMN_WIDTH); + ui->peerWidget->horizontalHeader()->setStretchLastSection(true); - // create context menu actions + // create peer table context menu actions QAction* disconnectAction = new QAction(tr("&Disconnect Node"), this); - - // create context menu - contextMenu = new QMenu(); - contextMenu->addAction(disconnectAction); - - // context menu signals - connect(ui->peerWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showMenu(const QPoint&))); + QAction* banAction1h = new QAction(tr("Ban Node for") + " " + tr("1 &hour"), this); + QAction* banAction24h = new QAction(tr("Ban Node for") + " " + tr("1 &day"), this); + QAction* banAction7d = new QAction(tr("Ban Node for") + " " + tr("1 &week"), this); + QAction* banAction365d = new QAction(tr("Ban Node for") + " " + tr("1 &year"), this); + + // create peer table context menu + peersTableContextMenu = new QMenu(); + peersTableContextMenu->addAction(disconnectAction); + peersTableContextMenu->addAction(banAction1h); + peersTableContextMenu->addAction(banAction24h); + peersTableContextMenu->addAction(banAction7d); + peersTableContextMenu->addAction(banAction365d); + + // Add a signal mapping to allow dynamic context menu arguments. + // We need to use int (instead of int64_t), because signal mapper only supports + // int or objects, which is okay because max bantime (1 year) is < int_max. + QSignalMapper* signalMapper = new QSignalMapper(this); + signalMapper->setMapping(banAction1h, 60*60); + signalMapper->setMapping(banAction24h, 60*60*24); + signalMapper->setMapping(banAction7d, 60*60*24*7); + signalMapper->setMapping(banAction365d, 60*60*24*365); + connect(banAction1h, SIGNAL(triggered()), signalMapper, SLOT(map())); + connect(banAction24h, SIGNAL(triggered()), signalMapper, SLOT(map())); + connect(banAction7d, SIGNAL(triggered()), signalMapper, SLOT(map())); + connect(banAction365d, SIGNAL(triggered()), signalMapper, SLOT(map())); + connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(banSelectedNode(int))); + + // peer table context menu signals + connect(ui->peerWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showPeersTableContextMenu(const QPoint&))); connect(disconnectAction, SIGNAL(triggered()), this, SLOT(disconnectSelectedNode())); - // connect the peerWidget selection model to our peerSelected() handler + // peer table signal handling - update peer details when selecting new node connect(ui->peerWidget->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), - this, SLOT(peerSelected(const QItemSelection &, const QItemSelection &))); + this, SLOT(peerSelected(const QItemSelection &, const QItemSelection &))); + // peer table signal handling - update peer details when new nodes are added to the model connect(model->getPeerTableModel(), SIGNAL(layoutChanged()), this, SLOT(peerLayoutChanged())); + // set up ban table + ui->banlistWidget->setModel(model->getBanTableModel()); + ui->banlistWidget->verticalHeader()->hide(); + ui->banlistWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); + ui->banlistWidget->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->banlistWidget->setSelectionMode(QAbstractItemView::SingleSelection); + ui->banlistWidget->setContextMenuPolicy(Qt::CustomContextMenu); + ui->banlistWidget->setColumnWidth(BanTableModel::Address, BANSUBNET_COLUMN_WIDTH); + ui->banlistWidget->setColumnWidth(BanTableModel::Bantime, BANTIME_COLUMN_WIDTH); + ui->banlistWidget->horizontalHeader()->setStretchLastSection(true); + + // create ban table context menu action + QAction* unbanAction = new QAction(tr("&Unban Node"), this); + + // create ban table context menu + banTableContextMenu = new QMenu(); + banTableContextMenu->addAction(unbanAction); + + // ban table context menu signals + connect(ui->banlistWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showBanTableContextMenu(const QPoint&))); + connect(unbanAction, SIGNAL(triggered()), this, SLOT(unbanSelectedNode())); + + // ban table signal handling - clear peer details when clicking a peer in the ban table + connect(ui->banlistWidget, SIGNAL(clicked(const QModelIndex&)), this, SLOT(clearSelectedNode())); + // ban table signal handling - ensure ban table is shown or hidden (if empty) + connect(model->getBanTableModel(), SIGNAL(layoutChanged()), this, SLOT(showOrHideBanTableIfRequired())); + showOrHideBanTableIfRequired(); + // Provide initial values ui->clientVersion->setText(model->formatFullVersion()); + ui->clientUserAgent->setText(model->formatSubVersion()); ui->clientName->setText(model->clientName()); ui->buildDate->setText(model->formatBuildDate()); ui->startupTime->setText(model->formatClientStartupTime()); - ui->networkName->setText(QString::fromStdString(Params().NetworkIDString())); } } @@ -363,7 +458,7 @@ void RPCConsole::clear() ui->messagesWidget->document()->addResource( QTextDocument::ImageResource, QUrl(ICON_MAPPING[i].url), - SingleColorImage(ICON_MAPPING[i].source, SingleColor()).scaled(ICON_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + platformStyle->SingleColorImage(ICON_MAPPING[i].source).scaled(ICON_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); } // Set default style sheet @@ -536,7 +631,7 @@ void RPCConsole::peerSelected(const QItemSelection &selected, const QItemSelecti { Q_UNUSED(deselected); - if (!clientModel || selected.indexes().isEmpty()) + if (!clientModel || !clientModel->getPeerTableModel() || selected.indexes().isEmpty()) return; const CNodeCombinedStats *stats = clientModel->getPeerTableModel()->getNodeStats(selected.indexes().first().row()); @@ -546,7 +641,7 @@ void RPCConsole::peerSelected(const QItemSelection &selected, const QItemSelecti void RPCConsole::peerLayoutChanged() { - if (!clientModel) + if (!clientModel || !clientModel->getPeerTableModel()) return; const CNodeCombinedStats *stats = NULL; @@ -569,7 +664,7 @@ void RPCConsole::peerLayoutChanged() if (detailNodeRow < 0) { - // detail node dissapeared from table (node disconnected) + // detail node disappeared from table (node disconnected) fUnselect = true; } else @@ -655,7 +750,7 @@ void RPCConsole::showEvent(QShowEvent *event) { QWidget::showEvent(event); - if (!clientModel) + if (!clientModel || !clientModel->getPeerTableModel()) return; // start PeerTableModel auto refresh @@ -666,18 +761,25 @@ void RPCConsole::hideEvent(QHideEvent *event) { QWidget::hideEvent(event); - if (!clientModel) + if (!clientModel || !clientModel->getPeerTableModel()) return; // stop PeerTableModel auto refresh clientModel->getPeerTableModel()->stopAutoRefresh(); } -void RPCConsole::showMenu(const QPoint& point) +void RPCConsole::showPeersTableContextMenu(const QPoint& point) { QModelIndex index = ui->peerWidget->indexAt(point); if (index.isValid()) - contextMenu->exec(QCursor::pos()); + peersTableContextMenu->exec(QCursor::pos()); +} + +void RPCConsole::showBanTableContextMenu(const QPoint& point) +{ + QModelIndex index = ui->banlistWidget->indexAt(point); + if (index.isValid()) + banTableContextMenu->exec(QCursor::pos()); } void RPCConsole::disconnectSelectedNode() @@ -691,6 +793,46 @@ void RPCConsole::disconnectSelectedNode() } } +void RPCConsole::banSelectedNode(int bantime) +{ + if (!clientModel) + return; + + // Get currently selected peer address + QString strNode = GUIUtil::getEntryData(ui->peerWidget, 0, PeerTableModel::Address); + // Find possible nodes, ban it and clear the selected node + if (CNode *bannedNode = FindNode(strNode.toStdString())) { + std::string nStr = strNode.toStdString(); + std::string addr; + int port = 0; + SplitHostPort(nStr, port, addr); + + CNode::Ban(CNetAddr(addr), BanReasonManuallyAdded, bantime); + bannedNode->fDisconnect = true; + DumpBanlist(); + + clearSelectedNode(); + clientModel->getBanTableModel()->refresh(); + } +} + +void RPCConsole::unbanSelectedNode() +{ + if (!clientModel) + return; + + // Get currently selected ban address + QString strNode = GUIUtil::getEntryData(ui->banlistWidget, 0, BanTableModel::Address); + CSubNet possibleSubnet(strNode.toStdString()); + + if (possibleSubnet.IsValid()) + { + CNode::Unban(possibleSubnet); + DumpBanlist(); + clientModel->getBanTableModel()->refresh(); + } +} + void RPCConsole::clearSelectedNode() { ui->peerWidget->selectionModel()->clearSelection(); @@ -698,3 +840,13 @@ void RPCConsole::clearSelectedNode() ui->detailWidget->hide(); ui->peerHeading->setText(tr("Select a peer to view detailed information.")); } + +void RPCConsole::showOrHideBanTableIfRequired() +{ + if (!clientModel) + return; + + bool visible = clientModel->getBanTableModel()->shouldShow(); + ui->banlistWidget->setVisible(visible); + ui->banHeading->setVisible(visible); +}
\ No newline at end of file diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 6f42aa08b7..b86f776786 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -13,6 +13,8 @@ #include <QWidget> class ClientModel; +class PlatformStyle; +class RPCTimerInterface; namespace Ui { class RPCConsole; @@ -29,7 +31,7 @@ class RPCConsole: public QWidget Q_OBJECT public: - explicit RPCConsole(QWidget *parent); + explicit RPCConsole(const PlatformStyle *platformStyle, QWidget *parent); ~RPCConsole(); void setClientModel(ClientModel *model); @@ -59,7 +61,13 @@ private Q_SLOTS: void showEvent(QShowEvent *event); void hideEvent(QHideEvent *event); /** Show custom context menu on Peers tab */ - void showMenu(const QPoint& point); + void showPeersTableContextMenu(const QPoint& point); + /** Show custom context menu on Bans tab */ + void showBanTableContextMenu(const QPoint& point); + /** Hides ban table if no bans are present */ + void showOrHideBanTableIfRequired(); + /** clear the selected node */ + void clearSelectedNode(); public Q_SLOTS: void clear(); @@ -78,6 +86,10 @@ public Q_SLOTS: void peerLayoutChanged(); /** Disconnect a selected node on the Peers tab */ void disconnectSelectedNode(); + /** Ban a selected node on the Peers tab */ + void banSelectedNode(int bantime); + /** Unban a selected node on the Bans tab */ + void unbanSelectedNode(); Q_SIGNALS: // For RPC command executor @@ -90,14 +102,15 @@ private: void setTrafficGraphRange(int mins); /** show detailed information on ui about selected node */ void updateNodeDetail(const CNodeCombinedStats *stats); - /** clear the selected node */ - void clearSelectedNode(); enum ColumnWidths { ADDRESS_COLUMN_WIDTH = 200, SUBVERSION_COLUMN_WIDTH = 100, - PING_COLUMN_WIDTH = 80 + PING_COLUMN_WIDTH = 80, + BANSUBNET_COLUMN_WIDTH = 200, + BANTIME_COLUMN_WIDTH = 250 + }; Ui::RPCConsole *ui; @@ -105,7 +118,10 @@ private: QStringList history; int historyPtr; NodeId cachedNodeid; - QMenu *contextMenu; + const PlatformStyle *platformStyle; + RPCTimerInterface *rpcTimerInterface; + QMenu *peersTableContextMenu; + QMenu *banTableContextMenu; }; #endif // BITCOIN_QT_RPCCONSOLE_H diff --git a/src/qt/scicon.cpp b/src/qt/scicon.cpp deleted file mode 100644 index c493b5569e..0000000000 --- a/src/qt/scicon.cpp +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "scicon.h" - -#include <QApplication> -#include <QColor> -#include <QIcon> -#include <QImage> -#include <QPalette> -#include <QPixmap> - -namespace { - -void MakeSingleColorImage(QImage& img, const QColor& colorbase) -{ - img = img.convertToFormat(QImage::Format_ARGB32); - for (int x = img.width(); x--; ) - { - for (int y = img.height(); y--; ) - { - const QRgb rgb = img.pixel(x, y); - img.setPixel(x, y, qRgba(colorbase.red(), colorbase.green(), colorbase.blue(), qAlpha(rgb))); - } - } -} - -} - -QImage SingleColorImage(const QString& filename, const QColor& colorbase) -{ - QImage img(filename); -#if !defined(WIN32) && !defined(MAC_OSX) - MakeSingleColorImage(img, colorbase); -#endif - return img; -} - -QIcon SingleColorIcon(const QIcon& ico, const QColor& colorbase) -{ -#if defined(WIN32) || defined(MAC_OSX) - return ico; -#else - QIcon new_ico; - QSize sz; - Q_FOREACH(sz, ico.availableSizes()) - { - QImage img(ico.pixmap(sz).toImage()); - MakeSingleColorImage(img, colorbase); - new_ico.addPixmap(QPixmap::fromImage(img)); - } - return new_ico; -#endif -} - -QIcon SingleColorIcon(const QString& filename, const QColor& colorbase) -{ - return QIcon(QPixmap::fromImage(SingleColorImage(filename, colorbase))); -} - -QColor SingleColor() -{ -#if defined(WIN32) || defined(MAC_OSX) - return QColor(0,0,0); -#else - const QColor colorHighlightBg(QApplication::palette().color(QPalette::Highlight)); - const QColor colorHighlightFg(QApplication::palette().color(QPalette::HighlightedText)); - const QColor colorText(QApplication::palette().color(QPalette::WindowText)); - const int colorTextLightness = colorText.lightness(); - QColor colorbase; - if (abs(colorHighlightBg.lightness() - colorTextLightness) < abs(colorHighlightFg.lightness() - colorTextLightness)) - colorbase = colorHighlightBg; - else - colorbase = colorHighlightFg; - return colorbase; -#endif -} - -QIcon SingleColorIcon(const QString& filename) -{ - return SingleColorIcon(filename, SingleColor()); -} - -static QColor TextColor() -{ - return QColor(QApplication::palette().color(QPalette::WindowText)); -} - -QIcon TextColorIcon(const QString& filename) -{ - return SingleColorIcon(filename, TextColor()); -} - -QIcon TextColorIcon(const QIcon& ico) -{ - return SingleColorIcon(ico, TextColor()); -} diff --git a/src/qt/scicon.h b/src/qt/scicon.h deleted file mode 100644 index 1388069ddb..0000000000 --- a/src/qt/scicon.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_QT_SCICON_H -#define BITCOIN_QT_SCICON_H - -#include <QtCore> - -QT_BEGIN_NAMESPACE -class QColor; -class QIcon; -class QString; -QT_END_NAMESPACE - -QImage SingleColorImage(const QString& filename, const QColor&); -QIcon SingleColorIcon(const QIcon&, const QColor&); -QIcon SingleColorIcon(const QString& filename, const QColor&); -QColor SingleColor(); -QIcon SingleColorIcon(const QString& filename); -QIcon TextColorIcon(const QIcon&); -QIcon TextColorIcon(const QString& filename); - -#endif // BITCOIN_QT_SCICON_H diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 2407fcbc4a..a083a6f80e 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -11,7 +11,7 @@ #include "coincontroldialog.h" #include "guiutil.h" #include "optionsmodel.h" -#include "scicon.h" +#include "platformstyle.h" #include "sendcoinsentry.h" #include "walletmodel.h" @@ -27,25 +27,26 @@ #include <QSettings> #include <QTextDocument> -SendCoinsDialog::SendCoinsDialog(QWidget *parent) : +SendCoinsDialog::SendCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent) : QDialog(parent), ui(new Ui::SendCoinsDialog), clientModel(0), model(0), fNewRecipientAllowed(true), - fFeeMinimized(true) + fFeeMinimized(true), + platformStyle(platformStyle) { ui->setupUi(this); -#ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac - ui->addButton->setIcon(QIcon()); - ui->clearButton->setIcon(QIcon()); - ui->sendButton->setIcon(QIcon()); -#else - ui->addButton->setIcon(SingleColorIcon(":/icons/add")); - ui->clearButton->setIcon(SingleColorIcon(":/icons/remove")); - ui->sendButton->setIcon(SingleColorIcon(":/icons/send")); -#endif + if (!platformStyle->getImagesOnButtons()) { + ui->addButton->setIcon(QIcon()); + ui->clearButton->setIcon(QIcon()); + ui->sendButton->setIcon(QIcon()); + } else { + ui->addButton->setIcon(platformStyle->SingleColorIcon(":/icons/add")); + ui->clearButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); + ui->sendButton->setIcon(platformStyle->SingleColorIcon(":/icons/send")); + } GUIUtil::setupAddressWidget(ui->lineEditCoinControlChange, this); @@ -311,9 +312,9 @@ void SendCoinsDialog::on_sendButton_clicked() if(u != model->getOptionsModel()->getDisplayUnit()) alternativeUnits.append(BitcoinUnits::formatHtmlWithUnit(u, totalAmount)); } - questionString.append(tr("Total Amount %1 (= %2)") + questionString.append(tr("Total Amount %1<span style='font-size:10pt;font-weight:normal;'><br />(=%2)</span>") .arg(BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), totalAmount)) - .arg(alternativeUnits.join(" " + tr("or") + " "))); + .arg(alternativeUnits.join(" " + tr("or") + "<br />"))); QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm send coins"), questionString.arg(formatted.join("<br />")), @@ -364,7 +365,7 @@ void SendCoinsDialog::accept() SendCoinsEntry *SendCoinsDialog::addEntry() { - SendCoinsEntry *entry = new SendCoinsEntry(this); + SendCoinsEntry *entry = new SendCoinsEntry(platformStyle, this); entry->setModel(model); ui->entries->addWidget(entry); connect(entry, SIGNAL(removeEntry(SendCoinsEntry*)), this, SLOT(removeEntry(SendCoinsEntry*))); @@ -711,7 +712,7 @@ void SendCoinsDialog::coinControlFeatureChanged(bool checked) // Coin Control: button inputs -> show actual coin control dialog void SendCoinsDialog::coinControlButtonClicked() { - CoinControlDialog dlg; + CoinControlDialog dlg(platformStyle); dlg.setModel(model); dlg.exec(); coinControlUpdateLabels(); @@ -753,10 +754,9 @@ void SendCoinsDialog::coinControlChangeEdited(const QString& text) } else // Valid address { - CPubKey pubkey; CKeyID keyid; addr.GetKeyID(keyid); - if (!model->getPubKey(keyid, pubkey)) // Unknown change address + if (!model->havePrivKey(keyid)) // Unknown change address { ui->labelCoinControlChangeLabel->setText(tr("Warning: Unknown change address")); } diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index c833da84b2..391905ffcd 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -12,6 +12,7 @@ class ClientModel; class OptionsModel; +class PlatformStyle; class SendCoinsEntry; class SendCoinsRecipient; @@ -31,7 +32,7 @@ class SendCoinsDialog : public QDialog Q_OBJECT public: - explicit SendCoinsDialog(QWidget *parent = 0); + explicit SendCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent = 0); ~SendCoinsDialog(); void setClientModel(ClientModel *clientModel); @@ -60,6 +61,7 @@ private: WalletModel *model; bool fNewRecipientAllowed; bool fFeeMinimized; + const PlatformStyle *platformStyle; // Process WalletModel::SendCoinsReturn and generate a pair consisting // of a message and message flags for use in Q_EMIT message(). diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index 90a8cbdc4e..44aa8ad1af 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -9,30 +9,30 @@ #include "addresstablemodel.h" #include "guiutil.h" #include "optionsmodel.h" -#include "scicon.h" +#include "platformstyle.h" #include "walletmodel.h" #include <QApplication> #include <QClipboard> -SendCoinsEntry::SendCoinsEntry(QWidget *parent) : +SendCoinsEntry::SendCoinsEntry(const PlatformStyle *platformStyle, QWidget *parent) : QStackedWidget(parent), ui(new Ui::SendCoinsEntry), - model(0) + model(0), + platformStyle(platformStyle) { ui->setupUi(this); - ui->addressBookButton->setIcon(SingleColorIcon(":/icons/address-book")); - ui->pasteButton->setIcon(SingleColorIcon(":/icons/editpaste")); - ui->deleteButton->setIcon(SingleColorIcon(":/icons/remove")); - ui->deleteButton_is->setIcon(SingleColorIcon(":/icons/remove")); - ui->deleteButton_s->setIcon(SingleColorIcon(":/icons/remove")); + ui->addressBookButton->setIcon(platformStyle->SingleColorIcon(":/icons/address-book")); + ui->pasteButton->setIcon(platformStyle->SingleColorIcon(":/icons/editpaste")); + ui->deleteButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); + ui->deleteButton_is->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); + ui->deleteButton_s->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); setCurrentWidget(ui->SendCoins); -#ifdef Q_OS_MAC - ui->payToLayout->setSpacing(4); -#endif + if (platformStyle->getUseExtraSpacing()) + ui->payToLayout->setSpacing(4); #if QT_VERSION >= 0x040700 ui->addAsLabel->setPlaceholderText(tr("Enter a label for this address to add it to your address book")); #endif @@ -65,7 +65,7 @@ void SendCoinsEntry::on_addressBookButton_clicked() { if(!model) return; - AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::SendingTab, this); + AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::SendingTab, this); dlg.setModel(model->getAddressTableModel()); if(dlg.exec()) { diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h index d7e655fdc3..107ab70158 100644 --- a/src/qt/sendcoinsentry.h +++ b/src/qt/sendcoinsentry.h @@ -10,6 +10,7 @@ #include <QStackedWidget> class WalletModel; +class PlatformStyle; namespace Ui { class SendCoinsEntry; @@ -25,7 +26,7 @@ class SendCoinsEntry : public QStackedWidget Q_OBJECT public: - explicit SendCoinsEntry(QWidget *parent = 0); + explicit SendCoinsEntry(const PlatformStyle *platformStyle, QWidget *parent = 0); ~SendCoinsEntry(); void setModel(WalletModel *model); @@ -64,6 +65,7 @@ private: SendCoinsRecipient recipient; Ui::SendCoinsEntry *ui; WalletModel *model; + const PlatformStyle *platformStyle; bool updateLabel(const QString &address); }; diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index d3984923a8..60e8e36ebe 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -7,7 +7,7 @@ #include "addressbookpage.h" #include "guiutil.h" -#include "scicon.h" +#include "platformstyle.h" #include "walletmodel.h" #include "base58.h" @@ -20,21 +20,22 @@ #include <QClipboard> -SignVerifyMessageDialog::SignVerifyMessageDialog(QWidget *parent) : +SignVerifyMessageDialog::SignVerifyMessageDialog(const PlatformStyle *platformStyle, QWidget *parent) : QDialog(parent), ui(new Ui::SignVerifyMessageDialog), - model(0) + model(0), + platformStyle(platformStyle) { ui->setupUi(this); - ui->addressBookButton_SM->setIcon(SingleColorIcon(":/icons/address-book")); - ui->pasteButton_SM->setIcon(SingleColorIcon(":/icons/editpaste")); - ui->copySignatureButton_SM->setIcon(SingleColorIcon(":/icons/editcopy")); - ui->signMessageButton_SM->setIcon(SingleColorIcon(":/icons/edit")); - ui->clearButton_SM->setIcon(SingleColorIcon(":/icons/remove")); - ui->addressBookButton_VM->setIcon(SingleColorIcon(":/icons/address-book")); - ui->verifyMessageButton_VM->setIcon(SingleColorIcon(":/icons/transaction_0")); - ui->clearButton_VM->setIcon(SingleColorIcon(":/icons/remove")); + ui->addressBookButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/address-book")); + ui->pasteButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/editpaste")); + ui->copySignatureButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/editcopy")); + ui->signMessageButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/edit")); + ui->clearButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); + ui->addressBookButton_VM->setIcon(platformStyle->SingleColorIcon(":/icons/address-book")); + ui->verifyMessageButton_VM->setIcon(platformStyle->SingleColorIcon(":/icons/transaction_0")); + ui->clearButton_VM->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); #if QT_VERSION >= 0x040700 ui->signatureOut_SM->setPlaceholderText(tr("Click \"Sign Message\" to generate signature")); @@ -94,7 +95,7 @@ void SignVerifyMessageDialog::on_addressBookButton_SM_clicked() { if (model && model->getAddressTableModel()) { - AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this); + AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this); dlg.setModel(model->getAddressTableModel()); if (dlg.exec()) { @@ -185,7 +186,7 @@ void SignVerifyMessageDialog::on_addressBookButton_VM_clicked() { if (model && model->getAddressTableModel()) { - AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::SendingTab, this); + AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::SendingTab, this); dlg.setModel(model->getAddressTableModel()); if (dlg.exec()) { diff --git a/src/qt/signverifymessagedialog.h b/src/qt/signverifymessagedialog.h index bf841e4f8b..d651d5049b 100644 --- a/src/qt/signverifymessagedialog.h +++ b/src/qt/signverifymessagedialog.h @@ -7,6 +7,7 @@ #include <QDialog> +class PlatformStyle; class WalletModel; namespace Ui { @@ -18,7 +19,7 @@ class SignVerifyMessageDialog : public QDialog Q_OBJECT public: - explicit SignVerifyMessageDialog(QWidget *parent); + explicit SignVerifyMessageDialog(const PlatformStyle *platformStyle, QWidget *parent); ~SignVerifyMessageDialog(); void setModel(WalletModel *model); @@ -34,6 +35,7 @@ protected: private: Ui::SignVerifyMessageDialog *ui; WalletModel *model; + const PlatformStyle *platformStyle; private Q_SLOTS: /* sign message */ diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 8430e017c1..c15b64c327 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -57,7 +57,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) QPainter pixPaint(&pixmap); pixPaint.setPen(QColor(100,100,100)); - // draw a slighly radial gradient + // draw a slightly radial gradient QRadialGradient gradient(QPoint(0,0), splashSize.width()/devicePixelRatio); gradient.setColorAt(0, Qt::white); gradient.setColorAt(1, QColor(247,247,247)); diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp index b28934cd31..fa5696325d 100644 --- a/src/qt/test/paymentservertests.cpp +++ b/src/qt/test/paymentservertests.cpp @@ -185,7 +185,8 @@ void PaymentServerTests::paymentServerTests() tempFile.open(); tempFile.write((const char*)randData, sizeof(randData)); tempFile.close(); - QCOMPARE(PaymentServer::readPaymentRequestFromFile(tempFile.fileName(), r.paymentRequest), false); + // compares 50001 <= BIP70_MAX_PAYMENTREQUEST_SIZE == false + QCOMPARE(PaymentServer::verifySize(tempFile.size()), false); // Payment request with amount overflow (amount is set to 21000001 BTC): data = DecodeBase64(paymentrequest5_cert2_BASE64); diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index bb768f1325..f91de2008c 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -17,6 +17,8 @@ #include <QObject> #include <QTest> +#include <openssl/ssl.h> + #if defined(QT_STATICPLUGIN) && QT_VERSION < 0x050000 #include <QtPlugin> Q_IMPORT_PLUGIN(qcncodecs) @@ -36,6 +38,8 @@ int main(int argc, char *argv[]) QCoreApplication app(argc, argv); app.setApplicationName("Bitcoin-Qt-test"); + SSL_library_init(); + URITests test1; if (QTest::qExec(&test1) != 0) fInvalid = true; diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index af78a51d0f..801c6c62d2 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -165,7 +165,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco if (fAllFromMe) { - if(fAllFromMe == ISMINE_WATCH_ONLY) + if(fAllFromMe & ISMINE_WATCH_ONLY) strHTML += "<b>" + tr("From") + ":</b> " + tr("watch-only") + "<br>"; // @@ -190,7 +190,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString()); if(toSelf == ISMINE_SPENDABLE) strHTML += " (own address)"; - else if(toSelf == ISMINE_WATCH_ONLY) + else if(toSelf & ISMINE_WATCH_ONLY) strHTML += " (watch-only)"; strHTML += "<br>"; } diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 15d13e9fc9..d8623daf5d 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -56,7 +56,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet * CTxDestination address; sub.idx = parts.size(); // sequence number sub.credit = txout.nValue; - sub.involvesWatchAddress = mine == ISMINE_WATCH_ONLY; + sub.involvesWatchAddress = mine & ISMINE_WATCH_ONLY; if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address)) { // Received by Bitcoin Address @@ -86,7 +86,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet * BOOST_FOREACH(const CTxIn& txin, wtx.vin) { isminetype mine = wallet->IsMine(txin); - if(mine == ISMINE_WATCH_ONLY) involvesWatchAddress = true; + if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true; if(fAllFromMe > mine) fAllFromMe = mine; } @@ -94,7 +94,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet * BOOST_FOREACH(const CTxOut& txout, wtx.vout) { isminetype mine = wallet->IsMine(txout); - if(mine == ISMINE_WATCH_ONLY) involvesWatchAddress = true; + if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true; if(fAllToMe > mine) fAllToMe = mine; } diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index f384562a50..98ad1a44b6 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -8,7 +8,7 @@ #include "guiconstants.h" #include "guiutil.h" #include "optionsmodel.h" -#include "scicon.h" +#include "platformstyle.h" #include "transactiondesc.h" #include "transactionrecord.h" #include "walletmodel.h" @@ -222,12 +222,13 @@ public: } }; -TransactionTableModel::TransactionTableModel(CWallet* wallet, WalletModel *parent): +TransactionTableModel::TransactionTableModel(const PlatformStyle *platformStyle, CWallet* wallet, WalletModel *parent): QAbstractTableModel(parent), wallet(wallet), walletModel(parent), priv(new TransactionTablePriv(wallet, this)), - fProcessingQueuedTransactions(false) + fProcessingQueuedTransactions(false), + platformStyle(platformStyle) { columns << QString() << QString() << tr("Date") << tr("Type") << tr("Label") << BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit()); priv->refreshWallet(); @@ -521,7 +522,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const case Qt::DecorationRole: { QIcon icon = qvariant_cast<QIcon>(index.data(RawDecorationRole)); - return TextColorIcon(icon); + return platformStyle->TextColorIcon(icon); } case Qt::DisplayRole: switch(index.column()) diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index 25c82c764b..2089f703a6 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -10,6 +10,7 @@ #include <QAbstractTableModel> #include <QStringList> +class PlatformStyle; class TransactionRecord; class TransactionTablePriv; class WalletModel; @@ -23,7 +24,7 @@ class TransactionTableModel : public QAbstractTableModel Q_OBJECT public: - explicit TransactionTableModel(CWallet* wallet, WalletModel *parent = 0); + explicit TransactionTableModel(const PlatformStyle *platformStyle, CWallet* wallet, WalletModel *parent = 0); ~TransactionTableModel(); enum ColumnIndex { @@ -82,6 +83,7 @@ private: QStringList columns; TransactionTablePriv *priv; bool fProcessingQueuedTransactions; + const PlatformStyle *platformStyle; void subscribeToCoreSignals(); void unsubscribeFromCoreSignals(); diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 998789b3ae..54e5a82720 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -10,7 +10,7 @@ #include "editaddressdialog.h" #include "guiutil.h" #include "optionsmodel.h" -#include "scicon.h" +#include "platformstyle.h" #include "transactiondescdialog.h" #include "transactionfilterproxy.h" #include "transactionrecord.h" @@ -35,7 +35,7 @@ #include <QUrl> #include <QVBoxLayout> -TransactionView::TransactionView(QWidget *parent) : +TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *parent) : QWidget(parent), model(0), transactionProxyModel(0), transactionView(0) { @@ -44,27 +44,28 @@ TransactionView::TransactionView(QWidget *parent) : QHBoxLayout *hlayout = new QHBoxLayout(); hlayout->setContentsMargins(0,0,0,0); -#ifdef Q_OS_MAC - hlayout->setSpacing(5); - hlayout->addSpacing(26); -#else - hlayout->setSpacing(0); - hlayout->addSpacing(23); -#endif + + if (platformStyle->getUseExtraSpacing()) { + hlayout->setSpacing(5); + hlayout->addSpacing(26); + } else { + hlayout->setSpacing(0); + hlayout->addSpacing(23); + } watchOnlyWidget = new QComboBox(this); watchOnlyWidget->setFixedWidth(24); watchOnlyWidget->addItem("", TransactionFilterProxy::WatchOnlyFilter_All); - watchOnlyWidget->addItem(SingleColorIcon(":/icons/eye_plus"), "", TransactionFilterProxy::WatchOnlyFilter_Yes); - watchOnlyWidget->addItem(SingleColorIcon(":/icons/eye_minus"), "", TransactionFilterProxy::WatchOnlyFilter_No); + watchOnlyWidget->addItem(platformStyle->SingleColorIcon(":/icons/eye_plus"), "", TransactionFilterProxy::WatchOnlyFilter_Yes); + watchOnlyWidget->addItem(platformStyle->SingleColorIcon(":/icons/eye_minus"), "", TransactionFilterProxy::WatchOnlyFilter_No); hlayout->addWidget(watchOnlyWidget); dateWidget = new QComboBox(this); -#ifdef Q_OS_MAC - dateWidget->setFixedWidth(121); -#else - dateWidget->setFixedWidth(120); -#endif + if (platformStyle->getUseExtraSpacing()) { + dateWidget->setFixedWidth(121); + } else { + dateWidget->setFixedWidth(120); + } dateWidget->addItem(tr("All"), All); dateWidget->addItem(tr("Today"), Today); dateWidget->addItem(tr("This week"), ThisWeek); @@ -75,11 +76,11 @@ TransactionView::TransactionView(QWidget *parent) : hlayout->addWidget(dateWidget); typeWidget = new QComboBox(this); -#ifdef Q_OS_MAC - typeWidget->setFixedWidth(121); -#else - typeWidget->setFixedWidth(120); -#endif + if (platformStyle->getUseExtraSpacing()) { + typeWidget->setFixedWidth(121); + } else { + typeWidget->setFixedWidth(120); + } typeWidget->addItem(tr("All"), TransactionFilterProxy::ALL_TYPES); typeWidget->addItem(tr("Received with"), TransactionFilterProxy::TYPE(TransactionRecord::RecvWithAddress) | @@ -102,11 +103,11 @@ TransactionView::TransactionView(QWidget *parent) : #if QT_VERSION >= 0x040700 amountWidget->setPlaceholderText(tr("Min amount")); #endif -#ifdef Q_OS_MAC - amountWidget->setFixedWidth(97); -#else - amountWidget->setFixedWidth(100); -#endif + if (platformStyle->getUseExtraSpacing()) { + amountWidget->setFixedWidth(97); + } else { + amountWidget->setFixedWidth(100); + } amountWidget->setValidator(new QDoubleValidator(0, 1e20, 8, this)); hlayout->addWidget(amountWidget); @@ -121,11 +122,11 @@ TransactionView::TransactionView(QWidget *parent) : vlayout->setSpacing(0); int width = view->verticalScrollBar()->sizeHint().width(); // Cover scroll bar width with spacing -#ifdef Q_OS_MAC - hlayout->addSpacing(width+2); -#else - hlayout->addSpacing(width); -#endif + if (platformStyle->getUseExtraSpacing()) { + hlayout->addSpacing(width+2); + } else { + hlayout->addSpacing(width); + } // Always show scroll bar view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); view->setTabKeyNavigation(false); diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h index 6c35362be4..ac157fb98d 100644 --- a/src/qt/transactionview.h +++ b/src/qt/transactionview.h @@ -10,6 +10,7 @@ #include <QWidget> #include <QKeyEvent> +class PlatformStyle; class TransactionFilterProxy; class WalletModel; @@ -32,7 +33,7 @@ class TransactionView : public QWidget Q_OBJECT public: - explicit TransactionView(QWidget *parent = 0); + explicit TransactionView(const PlatformStyle *platformStyle, QWidget *parent = 0); void setModel(WalletModel *model); diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp index 892947bf3a..ba8c28464d 100644 --- a/src/qt/walletframe.cpp +++ b/src/qt/walletframe.cpp @@ -12,9 +12,10 @@ #include <QHBoxLayout> #include <QLabel> -WalletFrame::WalletFrame(BitcoinGUI *_gui) : +WalletFrame::WalletFrame(const PlatformStyle *platformStyle, BitcoinGUI *_gui) : QFrame(_gui), - gui(_gui) + gui(_gui), + platformStyle(platformStyle) { // Leave HBox hook for adding a list view later QHBoxLayout *walletFrameLayout = new QHBoxLayout(this); @@ -42,7 +43,7 @@ bool WalletFrame::addWallet(const QString& name, WalletModel *walletModel) if (!gui || !clientModel || !walletModel || mapWalletViews.count(name) > 0) return false; - WalletView *walletView = new WalletView(this); + WalletView *walletView = new WalletView(platformStyle, this); walletView->setBitcoinGUI(gui); walletView->setClientModel(clientModel); walletView->setWalletModel(walletModel); diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h index 5a5e2ab944..9a56e97f9c 100644 --- a/src/qt/walletframe.h +++ b/src/qt/walletframe.h @@ -10,6 +10,7 @@ class BitcoinGUI; class ClientModel; +class PlatformStyle; class SendCoinsRecipient; class WalletModel; class WalletView; @@ -23,7 +24,7 @@ class WalletFrame : public QFrame Q_OBJECT public: - explicit WalletFrame(BitcoinGUI *_gui = 0); + explicit WalletFrame(const PlatformStyle *platformStyle, BitcoinGUI *_gui = 0); ~WalletFrame(); void setClientModel(ClientModel *clientModel); @@ -45,6 +46,8 @@ private: bool bOutOfSync; + const PlatformStyle *platformStyle; + WalletView *currentWalletView(); public Q_SLOTS: diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 7820047b6b..5c21db8bdf 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -27,7 +27,7 @@ #include <boost/foreach.hpp> -WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent) : +WalletModel::WalletModel(const PlatformStyle *platformStyle, CWallet *wallet, OptionsModel *optionsModel, QObject *parent) : QObject(parent), wallet(wallet), optionsModel(optionsModel), addressTableModel(0), transactionTableModel(0), recentRequestsTableModel(0), @@ -39,7 +39,7 @@ WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *p fForceCheckBalanceChanged = false; addressTableModel = new AddressTableModel(wallet, this); - transactionTableModel = new TransactionTableModel(wallet, this); + transactionTableModel = new TransactionTableModel(platformStyle, wallet, this); recentRequestsTableModel = new RecentRequestsTableModel(wallet, this); // This timer will be fired repeatedly to update the balance @@ -556,6 +556,11 @@ bool WalletModel::getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const return wallet->GetPubKey(address, vchPubKeyOut); } +bool WalletModel::havePrivKey(const CKeyID &address) const +{ + return wallet->HaveKey(address); +} + // returns a list of COutputs from COutPoints void WalletModel::getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs) { diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 40bc623543..a5e877d81f 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -17,6 +17,7 @@ class AddressTableModel; class OptionsModel; +class PlatformStyle; class RecentRequestsTableModel; class TransactionTableModel; class WalletModelTransaction; @@ -100,7 +101,7 @@ class WalletModel : public QObject Q_OBJECT public: - explicit WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0); + explicit WalletModel(const PlatformStyle *platformStyle, CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0); ~WalletModel(); enum StatusCode // Returned by sendCoins @@ -186,6 +187,7 @@ public: UnlockContext requestUnlock(); bool getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const; + bool havePrivKey(const CKeyID &address) const; void getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs); bool isSpent(const COutPoint& outpoint) const; void listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const; diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index c5f556b444..77efdb5cdd 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -11,8 +11,8 @@ #include "guiutil.h" #include "optionsmodel.h" #include "overviewpage.h" +#include "platformstyle.h" #include "receivecoinsdialog.h" -#include "scicon.h" #include "sendcoinsdialog.h" #include "signverifymessagedialog.h" #include "transactiontablemodel.h" @@ -29,31 +29,35 @@ #include <QPushButton> #include <QVBoxLayout> -WalletView::WalletView(QWidget *parent): +WalletView::WalletView(const PlatformStyle *platformStyle, QWidget *parent): QStackedWidget(parent), clientModel(0), - walletModel(0) + walletModel(0), + platformStyle(platformStyle) { // Create tabs - overviewPage = new OverviewPage(); + overviewPage = new OverviewPage(platformStyle); transactionsPage = new QWidget(this); QVBoxLayout *vbox = new QVBoxLayout(); QHBoxLayout *hbox_buttons = new QHBoxLayout(); - transactionView = new TransactionView(this); + transactionView = new TransactionView(platformStyle, this); vbox->addWidget(transactionView); QPushButton *exportButton = new QPushButton(tr("&Export"), this); exportButton->setToolTip(tr("Export the data in the current tab to a file")); -#ifndef Q_OS_MAC // Icons on push buttons are very uncommon on Mac - exportButton->setIcon(SingleColorIcon(":/icons/export")); -#endif + if (platformStyle->getImagesOnButtons()) { + exportButton->setIcon(platformStyle->SingleColorIcon(":/icons/export")); + } hbox_buttons->addStretch(); hbox_buttons->addWidget(exportButton); vbox->addLayout(hbox_buttons); transactionsPage->setLayout(vbox); - receiveCoinsPage = new ReceiveCoinsDialog(); - sendCoinsPage = new SendCoinsDialog(); + receiveCoinsPage = new ReceiveCoinsDialog(platformStyle); + sendCoinsPage = new SendCoinsDialog(platformStyle); + + usedSendingAddressesPage = new AddressBookPage(platformStyle, AddressBookPage::ForEditing, AddressBookPage::SendingTab, this); + usedReceivingAddressesPage = new AddressBookPage(platformStyle, AddressBookPage::ForEditing, AddressBookPage::ReceivingTab, this); addWidget(overviewPage); addWidget(transactionsPage); @@ -114,6 +118,8 @@ void WalletView::setWalletModel(WalletModel *walletModel) overviewPage->setWalletModel(walletModel); receiveCoinsPage->setModel(walletModel); sendCoinsPage->setModel(walletModel); + usedReceivingAddressesPage->setModel(walletModel->getAddressTableModel()); + usedSendingAddressesPage->setModel(walletModel->getAddressTableModel()); if (walletModel) { @@ -182,7 +188,7 @@ void WalletView::gotoSendCoinsPage(QString addr) void WalletView::gotoSignMessageTab(QString addr) { // calls show() in showTab_SM() - SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(this); + SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(platformStyle, this); signVerifyMessageDialog->setAttribute(Qt::WA_DeleteOnClose); signVerifyMessageDialog->setModel(walletModel); signVerifyMessageDialog->showTab_SM(true); @@ -194,7 +200,7 @@ void WalletView::gotoSignMessageTab(QString addr) void WalletView::gotoVerifyMessageTab(QString addr) { // calls show() in showTab_VM() - SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(this); + SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(platformStyle, this); signVerifyMessageDialog->setAttribute(Qt::WA_DeleteOnClose); signVerifyMessageDialog->setModel(walletModel); signVerifyMessageDialog->showTab_VM(true); @@ -272,20 +278,20 @@ void WalletView::usedSendingAddresses() { if(!walletModel) return; - AddressBookPage *dlg = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::SendingTab, this); - dlg->setAttribute(Qt::WA_DeleteOnClose); - dlg->setModel(walletModel->getAddressTableModel()); - dlg->show(); + + usedSendingAddressesPage->show(); + usedSendingAddressesPage->raise(); + usedSendingAddressesPage->activateWindow(); } void WalletView::usedReceivingAddresses() { if(!walletModel) return; - AddressBookPage *dlg = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::ReceivingTab, this); - dlg->setAttribute(Qt::WA_DeleteOnClose); - dlg->setModel(walletModel->getAddressTableModel()); - dlg->show(); + + usedReceivingAddressesPage->show(); + usedReceivingAddressesPage->raise(); + usedReceivingAddressesPage->activateWindow(); } void WalletView::showProgress(const QString &title, int nProgress) diff --git a/src/qt/walletview.h b/src/qt/walletview.h index 87c5d7bfbf..2a6a6a2df2 100644 --- a/src/qt/walletview.h +++ b/src/qt/walletview.h @@ -12,11 +12,13 @@ class BitcoinGUI; class ClientModel; class OverviewPage; +class PlatformStyle; class ReceiveCoinsDialog; class SendCoinsDialog; class SendCoinsRecipient; class TransactionView; class WalletModel; +class AddressBookPage; QT_BEGIN_NAMESPACE class QModelIndex; @@ -34,7 +36,7 @@ class WalletView : public QStackedWidget Q_OBJECT public: - explicit WalletView(QWidget *parent); + explicit WalletView(const PlatformStyle *platformStyle, QWidget *parent); ~WalletView(); void setBitcoinGUI(BitcoinGUI *gui); @@ -60,10 +62,13 @@ private: QWidget *transactionsPage; ReceiveCoinsDialog *receiveCoinsPage; SendCoinsDialog *sendCoinsPage; + AddressBookPage *usedSendingAddressesPage; + AddressBookPage *usedReceivingAddressesPage; TransactionView *transactionView; QProgressDialog *progressDialog; + const PlatformStyle *platformStyle; public Q_SLOTS: /** Switch to overview (home) page */ diff --git a/src/rest.cpp b/src/rest.cpp index 0dd238b683..226e237fc6 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -7,6 +7,7 @@ #include "primitives/block.h" #include "primitives/transaction.h" #include "main.h" +#include "httpserver.h" #include "rpcserver.h" #include "streams.h" #include "sync.h" @@ -56,35 +57,38 @@ struct CCoin { } }; -class RestErr -{ -public: - enum HTTPStatusCode status; - string message; -}; - extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); +extern UniValue mempoolInfoToJSON(); +extern UniValue mempoolToJSON(bool fVerbose = false); extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); extern UniValue blockheaderToJSON(const CBlockIndex* blockindex); -static RestErr RESTERR(enum HTTPStatusCode status, string message) +static bool RESTERR(HTTPRequest* req, enum HTTPStatusCode status, string message) { - RestErr re; - re.status = status; - re.message = message; - return re; + req->WriteHeader("Content-Type", "text/plain"); + req->WriteReply(status, message + "\r\n"); + return false; } -static enum RetFormat ParseDataFormat(vector<string>& params, const string strReq) +static enum RetFormat ParseDataFormat(std::string& param, const std::string& strReq) { - boost::split(params, strReq, boost::is_any_of(".")); - if (params.size() > 1) { - for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++) - if (params[1] == rf_names[i].name) - return rf_names[i].rf; + const std::string::size_type pos = strReq.rfind('.'); + if (pos == std::string::npos) + { + param = strReq; + return rf_names[0].rf; } + param = strReq.substr(0, pos); + const std::string suff(strReq, pos + 1); + + for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++) + if (suff == rf_names[i].name) + return rf_names[i].rf; + + /* If no suffix is found, return original string. */ + param = strReq; return rf_names[0].rf; } @@ -113,28 +117,35 @@ static bool ParseHashStr(const string& strReq, uint256& v) return true; } -static bool rest_headers(AcceptedConnection* conn, - const std::string& strURIPart, - const std::string& strRequest, - const std::map<std::string, std::string>& mapHeaders, - bool fRun) +static bool CheckWarmup(HTTPRequest* req) { - vector<string> params; - const RetFormat rf = ParseDataFormat(params, strURIPart); + std::string statusmessage; + if (RPCIsInWarmup(&statusmessage)) + return RESTERR(req, HTTP_SERVICE_UNAVAILABLE, "Service temporarily unavailable: " + statusmessage); + return true; +} + +static bool rest_headers(HTTPRequest* req, + const std::string& strURIPart) +{ + if (!CheckWarmup(req)) + return false; + std::string param; + const RetFormat rf = ParseDataFormat(param, strURIPart); vector<string> path; - boost::split(path, params[0], boost::is_any_of("/")); + boost::split(path, param, boost::is_any_of("/")); if (path.size() != 2) - throw RESTERR(HTTP_BAD_REQUEST, "No header count specified. Use /rest/headers/<count>/<hash>.<ext>."); + return RESTERR(req, HTTP_BAD_REQUEST, "No header count specified. Use /rest/headers/<count>/<hash>.<ext>."); long count = strtol(path[0].c_str(), NULL, 10); if (count < 1 || count > 2000) - throw RESTERR(HTTP_BAD_REQUEST, "Header count out of range: " + path[0]); + return RESTERR(req, HTTP_BAD_REQUEST, "Header count out of range: " + path[0]); string hashStr = path[1]; uint256 hash; if (!ParseHashStr(hashStr, hash)) - throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); + return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); std::vector<const CBlockIndex *> headers; headers.reserve(count); @@ -158,28 +169,29 @@ static bool rest_headers(AcceptedConnection* conn, switch (rf) { case RF_BINARY: { string binaryHeader = ssHeader.str(); - conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryHeader.size(), "application/octet-stream") << binaryHeader << std::flush; + req->WriteHeader("Content-Type", "application/octet-stream"); + req->WriteReply(HTTP_OK, binaryHeader); return true; } case RF_HEX: { string strHex = HexStr(ssHeader.begin(), ssHeader.end()) + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush; + req->WriteHeader("Content-Type", "text/plain"); + req->WriteReply(HTTP_OK, strHex); return true; } - case RF_JSON: { UniValue jsonHeaders(UniValue::VARR); BOOST_FOREACH(const CBlockIndex *pindex, headers) { jsonHeaders.push_back(blockheaderToJSON(pindex)); } string strJSON = jsonHeaders.write() + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strJSON); return true; } - default: { - throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: .bin, .hex)"); + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: .bin, .hex)"); } } @@ -187,34 +199,32 @@ static bool rest_headers(AcceptedConnection* conn, return true; // continue to process further HTTP reqs on this cxn } -static bool rest_block(AcceptedConnection* conn, +static bool rest_block(HTTPRequest* req, const std::string& strURIPart, - const std::string& strRequest, - const std::map<std::string, std::string>& mapHeaders, - bool fRun, bool showTxDetails) { - vector<string> params; - const RetFormat rf = ParseDataFormat(params, strURIPart); + if (!CheckWarmup(req)) + return false; + std::string hashStr; + const RetFormat rf = ParseDataFormat(hashStr, strURIPart); - string hashStr = params[0]; uint256 hash; if (!ParseHashStr(hashStr, hash)) - throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); + return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); CBlock block; CBlockIndex* pblockindex = NULL; { LOCK(cs_main); if (mapBlockIndex.count(hash) == 0) - throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found"); + return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); pblockindex = mapBlockIndex[hash]; if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) - throw RESTERR(HTTP_NOT_FOUND, hashStr + " not available (pruned data)"); + return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)"); if (!ReadBlockFromDisk(block, pblockindex)) - throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found"); + return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); } CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); @@ -223,25 +233,28 @@ static bool rest_block(AcceptedConnection* conn, switch (rf) { case RF_BINARY: { string binaryBlock = ssBlock.str(); - conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryBlock.size(), "application/octet-stream") << binaryBlock << std::flush; + req->WriteHeader("Content-Type", "application/octet-stream"); + req->WriteReply(HTTP_OK, binaryBlock); return true; } case RF_HEX: { string strHex = HexStr(ssBlock.begin(), ssBlock.end()) + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush; + req->WriteHeader("Content-Type", "text/plain"); + req->WriteReply(HTTP_OK, strHex); return true; } case RF_JSON: { UniValue objBlock = blockToJSON(block, pblockindex, showTxDetails); string strJSON = objBlock.write() + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strJSON); return true; } default: { - throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); } } @@ -249,43 +262,34 @@ static bool rest_block(AcceptedConnection* conn, return true; // continue to process further HTTP reqs on this cxn } -static bool rest_block_extended(AcceptedConnection* conn, - const std::string& strURIPart, - const std::string& strRequest, - const std::map<std::string, std::string>& mapHeaders, - bool fRun) +static bool rest_block_extended(HTTPRequest* req, const std::string& strURIPart) { - return rest_block(conn, strURIPart, strRequest, mapHeaders, fRun, true); + return rest_block(req, strURIPart, true); } -static bool rest_block_notxdetails(AcceptedConnection* conn, - const std::string& strURIPart, - const std::string& strRequest, - const std::map<std::string, std::string>& mapHeaders, - bool fRun) +static bool rest_block_notxdetails(HTTPRequest* req, const std::string& strURIPart) { - return rest_block(conn, strURIPart, strRequest, mapHeaders, fRun, false); + return rest_block(req, strURIPart, false); } -static bool rest_chaininfo(AcceptedConnection* conn, - const std::string& strURIPart, - const std::string& strRequest, - const std::map<std::string, std::string>& mapHeaders, - bool fRun) +static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart) { - vector<string> params; - const RetFormat rf = ParseDataFormat(params, strURIPart); + if (!CheckWarmup(req)) + return false; + std::string param; + const RetFormat rf = ParseDataFormat(param, strURIPart); switch (rf) { case RF_JSON: { UniValue rpcParams(UniValue::VARR); UniValue chainInfoObject = getblockchaininfo(rpcParams, false); string strJSON = chainInfoObject.write() + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strJSON); return true; } default: { - throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: json)"); + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)"); } } @@ -293,24 +297,71 @@ static bool rest_chaininfo(AcceptedConnection* conn, return true; // continue to process further HTTP reqs on this cxn } -static bool rest_tx(AcceptedConnection* conn, - const std::string& strURIPart, - const std::string& strRequest, - const std::map<std::string, std::string>& mapHeaders, - bool fRun) +static bool rest_mempool_info(HTTPRequest* req, const std::string& strURIPart) { - vector<string> params; - const RetFormat rf = ParseDataFormat(params, strURIPart); + if (!CheckWarmup(req)) + return false; + std::string param; + const RetFormat rf = ParseDataFormat(param, strURIPart); + + switch (rf) { + case RF_JSON: { + UniValue mempoolInfoObject = mempoolInfoToJSON(); + + string strJSON = mempoolInfoObject.write() + "\n"; + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strJSON); + return true; + } + default: { + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)"); + } + } + + // not reached + return true; // continue to process further HTTP reqs on this cxn +} + +static bool rest_mempool_contents(HTTPRequest* req, const std::string& strURIPart) +{ + if (!CheckWarmup(req)) + return false; + std::string param; + const RetFormat rf = ParseDataFormat(param, strURIPart); + + switch (rf) { + case RF_JSON: { + UniValue mempoolObject = mempoolToJSON(true); + + string strJSON = mempoolObject.write() + "\n"; + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strJSON); + return true; + } + default: { + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)"); + } + } + + // not reached + return true; // continue to process further HTTP reqs on this cxn +} + +static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) +{ + if (!CheckWarmup(req)) + return false; + std::string hashStr; + const RetFormat rf = ParseDataFormat(hashStr, strURIPart); - string hashStr = params[0]; uint256 hash; if (!ParseHashStr(hashStr, hash)) - throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); + return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); CTransaction tx; uint256 hashBlock = uint256(); if (!GetTransaction(hash, tx, hashBlock, true)) - throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found"); + return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); ssTx << tx; @@ -318,13 +369,15 @@ static bool rest_tx(AcceptedConnection* conn, switch (rf) { case RF_BINARY: { string binaryTx = ssTx.str(); - conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryTx.size(), "application/octet-stream") << binaryTx << std::flush; + req->WriteHeader("Content-Type", "application/octet-stream"); + req->WriteReply(HTTP_OK, binaryTx); return true; } case RF_HEX: { string strHex = HexStr(ssTx.begin(), ssTx.end()) + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush; + req->WriteHeader("Content-Type", "text/plain"); + req->WriteReply(HTTP_OK, strHex); return true; } @@ -332,12 +385,13 @@ static bool rest_tx(AcceptedConnection* conn, UniValue objTx(UniValue::VOBJ); TxToJSON(tx, hashBlock, objTx); string strJSON = objTx.write() + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strJSON); return true; } default: { - throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); } } @@ -345,25 +399,24 @@ static bool rest_tx(AcceptedConnection* conn, return true; // continue to process further HTTP reqs on this cxn } -static bool rest_getutxos(AcceptedConnection* conn, - const std::string& strURIPart, - const std::string& strRequest, - const std::map<std::string, std::string>& mapHeaders, - bool fRun) +static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) { - vector<string> params; - enum RetFormat rf = ParseDataFormat(params, strURIPart); + if (!CheckWarmup(req)) + return false; + std::string param; + const RetFormat rf = ParseDataFormat(param, strURIPart); vector<string> uriParts; - if (params.size() > 0 && params[0].length() > 1) + if (param.length() > 1) { - std::string strUriParams = params[0].substr(1); + std::string strUriParams = param.substr(1); boost::split(uriParts, strUriParams, boost::is_any_of("/")); } // throw exception in case of a empty request - if (strRequest.length() == 0 && uriParts.size() == 0) - throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); + std::string strRequestMutable = req->ReadBody(); + if (strRequestMutable.length() == 0 && uriParts.size() == 0) + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); bool fInputParsed = false; bool fCheckMemPool = false; @@ -387,7 +440,7 @@ static bool rest_getutxos(AcceptedConnection* conn, std::string strOutput = uriParts[i].substr(uriParts[i].find("-")+1); if (!ParseInt32(strOutput, &nOutput) || !IsHex(strTxid)) - throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Parse error"); + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Parse error"); txid.SetHex(strTxid); vOutPoints.push_back(COutPoint(txid, (uint32_t)nOutput)); @@ -396,15 +449,13 @@ static bool rest_getutxos(AcceptedConnection* conn, if (vOutPoints.size() > 0) fInputParsed = true; else - throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); } - string strRequestMutable = strRequest; //convert const string to string for allowing hex to bin converting - switch (rf) { case RF_HEX: { // convert hex to bin, continue then with bin part - std::vector<unsigned char> strRequestV = ParseHex(strRequest); + std::vector<unsigned char> strRequestV = ParseHex(strRequestMutable); strRequestMutable.assign(strRequestV.begin(), strRequestV.end()); } @@ -414,7 +465,7 @@ static bool rest_getutxos(AcceptedConnection* conn, if (strRequestMutable.size() > 0) { if (fInputParsed) //don't allow sending input over URI and HTTP RAW DATA - throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Combination of URI scheme inputs and raw post data is not allowed"); + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Combination of URI scheme inputs and raw post data is not allowed"); CDataStream oss(SER_NETWORK, PROTOCOL_VERSION); oss << strRequestMutable; @@ -423,24 +474,24 @@ static bool rest_getutxos(AcceptedConnection* conn, } } catch (const std::ios_base::failure& e) { // abort in case of unreadable binary data - throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Parse error"); + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Parse error"); } break; } case RF_JSON: { if (!fInputParsed) - throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); break; } default: { - throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); } } // limit max outpoints if (vOutPoints.size() > MAX_GETUTXOS_OUTPOINTS) - throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, strprintf("Error: max outpoints exceeded (max: %d, tried: %d)", MAX_GETUTXOS_OUTPOINTS, vOutPoints.size())); + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, strprintf("Error: max outpoints exceeded (max: %d, tried: %d)", MAX_GETUTXOS_OUTPOINTS, vOutPoints.size())); // check spentness and form a bitmap (as well as a JSON capable human-readble string representation) vector<unsigned char> bitmap; @@ -490,7 +541,8 @@ static bool rest_getutxos(AcceptedConnection* conn, ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs; string ssGetUTXOResponseString = ssGetUTXOResponse.str(); - conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, ssGetUTXOResponseString.size(), "application/octet-stream") << ssGetUTXOResponseString << std::flush; + req->WriteHeader("Content-Type", "application/octet-stream"); + req->WriteReply(HTTP_OK, ssGetUTXOResponseString); return true; } @@ -499,7 +551,8 @@ static bool rest_getutxos(AcceptedConnection* conn, ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs; string strHex = HexStr(ssGetUTXOResponse.begin(), ssGetUTXOResponse.end()) + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush; + req->WriteHeader("Content-Type", "text/plain"); + req->WriteReply(HTTP_OK, strHex); return true; } @@ -529,11 +582,12 @@ static bool rest_getutxos(AcceptedConnection* conn, // return json string string strJSON = objGetUTXOResponse.write() + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strJSON); return true; } default: { - throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); } } @@ -543,43 +597,31 @@ static bool rest_getutxos(AcceptedConnection* conn, static const struct { const char* prefix; - bool (*handler)(AcceptedConnection* conn, - const std::string& strURIPart, - const std::string& strRequest, - const std::map<std::string, std::string>& mapHeaders, - bool fRun); + bool (*handler)(HTTPRequest* req, const std::string& strReq); } uri_prefixes[] = { {"/rest/tx/", rest_tx}, {"/rest/block/notxdetails/", rest_block_notxdetails}, {"/rest/block/", rest_block_extended}, {"/rest/chaininfo", rest_chaininfo}, + {"/rest/mempool/info", rest_mempool_info}, + {"/rest/mempool/contents", rest_mempool_contents}, {"/rest/headers/", rest_headers}, {"/rest/getutxos", rest_getutxos}, }; -bool HTTPReq_REST(AcceptedConnection* conn, - const std::string& strURI, - const string& strRequest, - const std::map<std::string, std::string>& mapHeaders, - bool fRun) +bool StartREST() { - try { - std::string statusmessage; - if (RPCIsInWarmup(&statusmessage)) - throw RESTERR(HTTP_SERVICE_UNAVAILABLE, "Service temporarily unavailable: " + statusmessage); - - for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++) { - unsigned int plen = strlen(uri_prefixes[i].prefix); - if (strURI.substr(0, plen) == uri_prefixes[i].prefix) { - string strURIPart = strURI.substr(plen); - return uri_prefixes[i].handler(conn, strURIPart, strRequest, mapHeaders, fRun); - } - } - } catch (const RestErr& re) { - conn->stream() << HTTPReply(re.status, re.message + "\r\n", false, false, "text/plain") << std::flush; - return false; - } + for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++) + RegisterHTTPHandler(uri_prefixes[i].prefix, false, uri_prefixes[i].handler); + return true; +} - conn->stream() << HTTPError(HTTP_NOT_FOUND, false) << std::flush; - return false; +void InterruptREST() +{ +} + +void StopREST() +{ + for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++) + UnregisterHTTPHandler(uri_prefixes[i].prefix, false); } diff --git a/src/reverselock.h b/src/reverselock.h new file mode 100644 index 0000000000..567636e16a --- /dev/null +++ b/src/reverselock.h @@ -0,0 +1,31 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_REVERSELOCK_H +#define BITCOIN_REVERSELOCK_H + +/** + * An RAII-style reverse lock. Unlocks on construction and locks on destruction. + */ +template<typename Lock> +class reverse_lock +{ +public: + + explicit reverse_lock(Lock& lock) : lock(lock) { + lock.unlock(); + } + + ~reverse_lock() { + lock.lock(); + } + +private: + reverse_lock(reverse_lock const&); + reverse_lock& operator=(reverse_lock const&); + + Lock& lock; +}; + +#endif // BITCOIN_REVERSELOCK_H diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 5817f0ce57..1c201ef99d 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -3,6 +3,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "amount.h" #include "chain.h" #include "chainparams.h" #include "checkpoints.h" @@ -174,53 +175,15 @@ UniValue getdifficulty(const UniValue& params, bool fHelp) return GetDifficulty(); } - -UniValue getrawmempool(const UniValue& params, bool fHelp) +UniValue mempoolToJSON(bool fVerbose = false) { - if (fHelp || params.size() > 1) - throw runtime_error( - "getrawmempool ( verbose )\n" - "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n" - "\nArguments:\n" - "1. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n" - "\nResult: (for verbose = false):\n" - "[ (json array of string)\n" - " \"transactionid\" (string) The transaction id\n" - " ,...\n" - "]\n" - "\nResult: (for verbose = true):\n" - "{ (json object)\n" - " \"transactionid\" : { (json object)\n" - " \"size\" : n, (numeric) transaction size in bytes\n" - " \"fee\" : n, (numeric) transaction fee in bitcoins\n" - " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n" - " \"height\" : n, (numeric) block height when transaction entered pool\n" - " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n" - " \"currentpriority\" : n, (numeric) transaction priority now\n" - " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n" - " \"transactionid\", (string) parent transaction id\n" - " ... ]\n" - " }, ...\n" - "}\n" - "\nExamples\n" - + HelpExampleCli("getrawmempool", "true") - + HelpExampleRpc("getrawmempool", "true") - ); - - LOCK(cs_main); - - bool fVerbose = false; - if (params.size() > 0) - fVerbose = params[0].get_bool(); - if (fVerbose) { LOCK(mempool.cs); UniValue o(UniValue::VOBJ); - BOOST_FOREACH(const PAIRTYPE(uint256, CTxMemPoolEntry)& entry, mempool.mapTx) + BOOST_FOREACH(const CTxMemPoolEntry& e, mempool.mapTx) { - const uint256& hash = entry.first; - const CTxMemPoolEntry& e = entry.second; + const uint256& hash = e.GetTx().GetHash(); UniValue info(UniValue::VOBJ); info.push_back(Pair("size", (int)e.GetTxSize())); info.push_back(Pair("fee", ValueFromAmount(e.GetFee()))); @@ -228,6 +191,9 @@ UniValue getrawmempool(const UniValue& params, bool fHelp) info.push_back(Pair("height", (int)e.GetHeight())); info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight()))); info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height()))); + info.push_back(Pair("descendantcount", e.GetCountWithDescendants())); + info.push_back(Pair("descendantsize", e.GetSizeWithDescendants())); + info.push_back(Pair("descendantfees", e.GetFeesWithDescendants())); const CTransaction& tx = e.GetTx(); set<string> setDepends; BOOST_FOREACH(const CTxIn& txin, tx.vin) @@ -260,6 +226,50 @@ UniValue getrawmempool(const UniValue& params, bool fHelp) } } +UniValue getrawmempool(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "getrawmempool ( verbose )\n" + "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n" + "\nArguments:\n" + "1. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n" + "\nResult: (for verbose = false):\n" + "[ (json array of string)\n" + " \"transactionid\" (string) The transaction id\n" + " ,...\n" + "]\n" + "\nResult: (for verbose = true):\n" + "{ (json object)\n" + " \"transactionid\" : { (json object)\n" + " \"size\" : n, (numeric) transaction size in bytes\n" + " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n" + " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n" + " \"height\" : n, (numeric) block height when transaction entered pool\n" + " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n" + " \"currentpriority\" : n, (numeric) transaction priority now\n" + " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n" + " \"descendantsize\" : n, (numeric) size of in-mempool descendants (including this one)\n" + " \"descendantfees\" : n, (numeric) fees of in-mempool descendants (including this one)\n" + " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n" + " \"transactionid\", (string) parent transaction id\n" + " ... ]\n" + " }, ...\n" + "}\n" + "\nExamples\n" + + HelpExampleCli("getrawmempool", "true") + + HelpExampleRpc("getrawmempool", "true") + ); + + LOCK(cs_main); + + bool fVerbose = false; + if (params.size() > 0) + fVerbose = params[0].get_bool(); + + return mempoolToJSON(fVerbose); +} + UniValue getblockhash(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) @@ -461,7 +471,7 @@ UniValue gettxout(const UniValue& params, bool fHelp) "{\n" " \"bestblock\" : \"hash\", (string) the block hash\n" " \"confirmations\" : n, (numeric) The number of confirmations\n" - " \"value\" : x.xxx, (numeric) The transaction value in btc\n" + " \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT + "\n" " \"scriptPubKey\" : { (json object)\n" " \"asm\" : \"code\", (string) \n" " \"hex\" : \"hex\", (string) \n" @@ -756,6 +766,16 @@ UniValue getchaintips(const UniValue& params, bool fHelp) return res; } +UniValue mempoolInfoToJSON() +{ + UniValue ret(UniValue::VOBJ); + ret.push_back(Pair("size", (int64_t) mempool.size())); + ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); + ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage())); + + return ret; +} + UniValue getmempoolinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -773,12 +793,7 @@ UniValue getmempoolinfo(const UniValue& params, bool fHelp) + HelpExampleRpc("getmempoolinfo", "") ); - UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("size", (int64_t) mempool.size())); - ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); - ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage())); - - return ret; + return mempoolInfoToJSON(); } UniValue invalidateblock(const UniValue& params, bool fHelp) diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index b41e960e8a..0c8e6d6d66 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -87,6 +87,8 @@ static const CRPCConvertParam vRPCConvertParams[] = { "lockunspent", 1 }, { "importprivkey", 2 }, { "importaddress", 2 }, + { "importaddress", 3 }, + { "importpubkey", 2 }, { "verifychain", 0 }, { "verifychain", 1 }, { "keypoolrefill", 0 }, diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index b7d4ff58fc..8dd0ff2f7e 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -119,7 +119,8 @@ UniValue generate(const UniValue& params, bool fHelp) "generate numblocks\n" "\nMine blocks immediately (before the RPC call returns)\n" "\nNote: this function can only be used on the regtest network\n" - "1. numblocks (numeric) How many blocks are generated immediately.\n" + "\nArguments:\n" + "1. numblocks (numeric, required) How many blocks are generated immediately.\n" "\nResult\n" "[ blockhashes ] (array) hashes of blocks generated\n" "\nExamples:\n" @@ -138,8 +139,12 @@ UniValue generate(const UniValue& params, bool fHelp) boost::shared_ptr<CReserveScript> coinbaseScript; GetMainSignals().ScriptForMining(coinbaseScript); + // If the keypool is exhausted, no script is returned at all. Catch this. + if (!coinbaseScript) + throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); + //throw an error if no script was provided - if (!coinbaseScript->reserveScript.size()) + if (coinbaseScript->reserveScript.empty()) throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet)"); { // Don't keep cs_main locked diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 82003e09b9..e2b6d5826c 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -60,8 +60,8 @@ UniValue getinfo(const UniValue& params, bool fHelp) " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n" " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n" " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n" - " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in btc/kb\n" - " \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n" + " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in " + CURRENCY_UNIT + "/kB\n" + " \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n" " \"errors\": \"...\" (string) any error messages\n" "}\n" "\nExamples:\n" @@ -157,13 +157,14 @@ UniValue validateaddress(const UniValue& params, bool fHelp) "1. \"bitcoinaddress\" (string, required) The bitcoin address to validate\n" "\nResult:\n" "{\n" - " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n" + " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n" " \"address\" : \"bitcoinaddress\", (string) The bitcoin address validated\n" " \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n" - " \"ismine\" : true|false, (boolean) If the address is yours or not\n" - " \"isscript\" : true|false, (boolean) If the key is a script\n" + " \"ismine\" : true|false, (boolean) If the address is yours or not\n" + " \"iswatchonly\" : true|false, (boolean) If the address is watchonly\n" + " \"isscript\" : true|false, (boolean) If the key is a script\n" " \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n" - " \"iscompressed\" : true|false, (boolean) If the address is compressed\n" + " \"iscompressed\" : true|false, (boolean) If the address is compressed\n" " \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\n" "}\n" "\nExamples:\n" diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index ed903f9fd3..5d490c70ca 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -12,6 +12,7 @@ #include "protocol.h" #include "sync.h" #include "timedata.h" +#include "ui_interface.h" #include "util.h" #include "utilstrencodings.h" #include "version.h" @@ -96,6 +97,7 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp) " \"conntime\": ttt, (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n" " \"timeoffset\": ttt, (numeric) The time offset in seconds\n" " \"pingtime\": n, (numeric) ping time\n" + " \"minping\": n, (numeric) minimum observed ping time\n" " \"pingwait\": n, (numeric) ping wait\n" " \"version\": v, (numeric) The peer version, such as 7001\n" " \"subver\": \"/Satoshi:0.8.5/\", (string) The string version\n" @@ -139,6 +141,7 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp) obj.push_back(Pair("conntime", stats.nTimeConnected)); obj.push_back(Pair("timeoffset", stats.nTimeOffset)); obj.push_back(Pair("pingtime", stats.dPingTime)); + obj.push_back(Pair("minping", stats.dPingMin)); if (stats.dPingWait > 0.0) obj.push_back(Pair("pingwait", stats.dPingWait)); obj.push_back(Pair("version", stats.nVersion)); @@ -423,7 +426,7 @@ UniValue getnetworkinfo(const UniValue& params, bool fHelp) " }\n" " ,...\n" " ],\n" - " \"relayfee\": x.xxxxxxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n" + " \"relayfee\": x.xxxxxxxx, (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n" " \"localaddresses\": [ (array) list of local addresses\n" " {\n" " \"address\": \"xxxx\", (string) network address\n" @@ -443,8 +446,7 @@ UniValue getnetworkinfo(const UniValue& params, bool fHelp) UniValue obj(UniValue::VOBJ); obj.push_back(Pair("version", CLIENT_VERSION)); - obj.push_back(Pair("subversion", - FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()))); + obj.push_back(Pair("subversion", strSubVersion)); obj.push_back(Pair("protocolversion",PROTOCOL_VERSION)); obj.push_back(Pair("localservices", strprintf("%016x", nLocalServices))); obj.push_back(Pair("timeoffset", GetTimeOffset())); @@ -530,6 +532,8 @@ UniValue setban(const UniValue& params, bool fHelp) } DumpBanlist(); //store banlist to disk + uiInterface.BannedListChanged(); + return NullUniValue; } @@ -576,6 +580,7 @@ UniValue clearbanned(const UniValue& params, bool fHelp) CNode::ClearBanned(); DumpBanlist(); //store banlist to disk + uiInterface.BannedListChanged(); return NullUniValue; } diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp index 2e5c913734..d83cd87f94 100644 --- a/src/rpcprotocol.cpp +++ b/src/rpcprotocol.cpp @@ -5,7 +5,6 @@ #include "rpcprotocol.h" -#include "clientversion.h" #include "random.h" #include "tinyformat.h" #include "util.h" @@ -16,236 +15,8 @@ #include <stdint.h> #include <fstream> -#include <boost/algorithm/string.hpp> -#include <boost/asio.hpp> -#include <boost/asio/ssl.hpp> -#include <boost/bind.hpp> -#include <boost/filesystem.hpp> -#include <boost/foreach.hpp> -#include <boost/iostreams/concepts.hpp> -#include <boost/iostreams/stream.hpp> -#include <boost/shared_ptr.hpp> - -#include "univalue/univalue.h" - using namespace std; -//! Number of bytes to allocate and read at most at once in post data -const size_t POST_READ_SIZE = 256 * 1024; - -/** - * HTTP protocol - * - * This ain't Apache. We're just using HTTP header for the length field - * and to be compatible with other JSON-RPC implementations. - */ - -string HTTPPost(const string& strMsg, const map<string,string>& mapRequestHeaders) -{ - ostringstream s; - s << "POST / HTTP/1.1\r\n" - << "User-Agent: bitcoin-json-rpc/" << FormatFullVersion() << "\r\n" - << "Host: 127.0.0.1\r\n" - << "Content-Type: application/json\r\n" - << "Content-Length: " << strMsg.size() << "\r\n" - << "Connection: close\r\n" - << "Accept: application/json\r\n"; - BOOST_FOREACH(const PAIRTYPE(string, string)& item, mapRequestHeaders) - s << item.first << ": " << item.second << "\r\n"; - s << "\r\n" << strMsg; - - return s.str(); -} - -static string rfc1123Time() -{ - return DateTimeStrFormat("%a, %d %b %Y %H:%M:%S +0000", GetTime()); -} - -static const char *httpStatusDescription(int nStatus) -{ - switch (nStatus) { - case HTTP_OK: return "OK"; - case HTTP_BAD_REQUEST: return "Bad Request"; - case HTTP_FORBIDDEN: return "Forbidden"; - case HTTP_NOT_FOUND: return "Not Found"; - case HTTP_INTERNAL_SERVER_ERROR: return "Internal Server Error"; - default: return ""; - } -} - -string HTTPError(int nStatus, bool keepalive, bool headersOnly) -{ - if (nStatus == HTTP_UNAUTHORIZED) - return strprintf("HTTP/1.0 401 Authorization Required\r\n" - "Date: %s\r\n" - "Server: bitcoin-json-rpc/%s\r\n" - "WWW-Authenticate: Basic realm=\"jsonrpc\"\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 296\r\n" - "\r\n" - "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n" - "\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">\r\n" - "<HTML>\r\n" - "<HEAD>\r\n" - "<TITLE>Error</TITLE>\r\n" - "<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=ISO-8859-1'>\r\n" - "</HEAD>\r\n" - "<BODY><H1>401 Unauthorized.</H1></BODY>\r\n" - "</HTML>\r\n", rfc1123Time(), FormatFullVersion()); - - return HTTPReply(nStatus, httpStatusDescription(nStatus), keepalive, - headersOnly, "text/plain"); -} - -string HTTPReplyHeader(int nStatus, bool keepalive, size_t contentLength, const char *contentType) -{ - return strprintf( - "HTTP/1.1 %d %s\r\n" - "Date: %s\r\n" - "Connection: %s\r\n" - "Content-Length: %u\r\n" - "Content-Type: %s\r\n" - "Server: bitcoin-json-rpc/%s\r\n" - "\r\n", - nStatus, - httpStatusDescription(nStatus), - rfc1123Time(), - keepalive ? "keep-alive" : "close", - contentLength, - contentType, - FormatFullVersion()); -} - -string HTTPReply(int nStatus, const string& strMsg, bool keepalive, - bool headersOnly, const char *contentType) -{ - if (headersOnly) - { - return HTTPReplyHeader(nStatus, keepalive, 0, contentType); - } else { - return HTTPReplyHeader(nStatus, keepalive, strMsg.size(), contentType) + strMsg; - } -} - -bool ReadHTTPRequestLine(std::basic_istream<char>& stream, int &proto, - string& http_method, string& http_uri) -{ - string str; - getline(stream, str); - - // HTTP request line is space-delimited - vector<string> vWords; - boost::split(vWords, str, boost::is_any_of(" ")); - if (vWords.size() < 2) - return false; - - // HTTP methods permitted: GET, POST - http_method = vWords[0]; - if (http_method != "GET" && http_method != "POST") - return false; - - // HTTP URI must be an absolute path, relative to current host - http_uri = vWords[1]; - if (http_uri.size() == 0 || http_uri[0] != '/') - return false; - - // parse proto, if present - string strProto = ""; - if (vWords.size() > 2) - strProto = vWords[2]; - - proto = 0; - const char *ver = strstr(strProto.c_str(), "HTTP/1."); - if (ver != NULL) - proto = atoi(ver+7); - - return true; -} - -int ReadHTTPStatus(std::basic_istream<char>& stream, int &proto) -{ - string str; - getline(stream, str); - vector<string> vWords; - boost::split(vWords, str, boost::is_any_of(" ")); - if (vWords.size() < 2) - return HTTP_INTERNAL_SERVER_ERROR; - proto = 0; - const char *ver = strstr(str.c_str(), "HTTP/1."); - if (ver != NULL) - proto = atoi(ver+7); - return atoi(vWords[1].c_str()); -} - -int ReadHTTPHeaders(std::basic_istream<char>& stream, map<string, string>& mapHeadersRet) -{ - int nLen = 0; - while (true) - { - string str; - std::getline(stream, str); - if (str.empty() || str == "\r") - break; - string::size_type nColon = str.find(":"); - if (nColon != string::npos) - { - string strHeader = str.substr(0, nColon); - boost::trim(strHeader); - boost::to_lower(strHeader); - string strValue = str.substr(nColon+1); - boost::trim(strValue); - mapHeadersRet[strHeader] = strValue; - if (strHeader == "content-length") - nLen = atoi(strValue.c_str()); - } - } - return nLen; -} - - -int ReadHTTPMessage(std::basic_istream<char>& stream, map<string, - string>& mapHeadersRet, string& strMessageRet, - int nProto, size_t max_size) -{ - mapHeadersRet.clear(); - strMessageRet = ""; - - // Read header - int nLen = ReadHTTPHeaders(stream, mapHeadersRet); - if (nLen < 0 || (size_t)nLen > max_size) - return HTTP_INTERNAL_SERVER_ERROR; - - // Read message - if (nLen > 0) - { - vector<char> vch; - size_t ptr = 0; - while (ptr < (size_t)nLen) - { - size_t bytes_to_read = std::min((size_t)nLen - ptr, POST_READ_SIZE); - vch.resize(ptr + bytes_to_read); - stream.read(&vch[ptr], bytes_to_read); - if (!stream) // Connection lost while reading - return HTTP_INTERNAL_SERVER_ERROR; - ptr += bytes_to_read; - } - strMessageRet = string(vch.begin(), vch.end()); - } - - string sConHdr = mapHeadersRet["connection"]; - - if ((sConHdr != "close") && (sConHdr != "keep-alive")) - { - if (nProto >= 1) - mapHeadersRet["connection"] = "keep-alive"; - else - mapHeadersRet["connection"] = "close"; - } - - return HTTP_OK; -} - /** * JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility, * but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were diff --git a/src/rpcprotocol.h b/src/rpcprotocol.h index 2360ec2c60..5381e4bcfd 100644 --- a/src/rpcprotocol.h +++ b/src/rpcprotocol.h @@ -10,10 +10,6 @@ #include <map> #include <stdint.h> #include <string> -#include <boost/iostreams/concepts.hpp> -#include <boost/iostreams/stream.hpp> -#include <boost/asio.hpp> -#include <boost/asio/ssl.hpp> #include <boost/filesystem.hpp> #include "univalue/univalue.h" @@ -26,6 +22,7 @@ enum HTTPStatusCode HTTP_UNAUTHORIZED = 401, HTTP_FORBIDDEN = 403, HTTP_NOT_FOUND = 404, + HTTP_BAD_METHOD = 405, HTTP_INTERNAL_SERVER_ERROR = 500, HTTP_SERVICE_UNAVAILABLE = 503, }; @@ -79,88 +76,6 @@ enum RPCErrorCode RPC_WALLET_ALREADY_UNLOCKED = -17, //! Wallet is already unlocked }; -/** - * IOStream device that speaks SSL but can also speak non-SSL - */ -template <typename Protocol> -class SSLIOStreamDevice : public boost::iostreams::device<boost::iostreams::bidirectional> { -public: - SSLIOStreamDevice(boost::asio::ssl::stream<typename Protocol::socket> &streamIn, bool fUseSSLIn) : stream(streamIn) - { - fUseSSL = fUseSSLIn; - fNeedHandshake = fUseSSLIn; - } - - void handshake(boost::asio::ssl::stream_base::handshake_type role) - { - if (!fNeedHandshake) return; - fNeedHandshake = false; - stream.handshake(role); - } - std::streamsize read(char* s, std::streamsize n) - { - handshake(boost::asio::ssl::stream_base::server); // HTTPS servers read first - if (fUseSSL) return stream.read_some(boost::asio::buffer(s, n)); - return stream.next_layer().read_some(boost::asio::buffer(s, n)); - } - std::streamsize write(const char* s, std::streamsize n) - { - handshake(boost::asio::ssl::stream_base::client); // HTTPS clients write first - if (fUseSSL) return boost::asio::write(stream, boost::asio::buffer(s, n)); - return boost::asio::write(stream.next_layer(), boost::asio::buffer(s, n)); - } - bool connect(const std::string& server, const std::string& port) - { - using namespace boost::asio::ip; - tcp::resolver resolver(stream.get_io_service()); - tcp::resolver::iterator endpoint_iterator; -#if BOOST_VERSION >= 104300 - try { -#endif - // The default query (flags address_configured) tries IPv6 if - // non-localhost IPv6 configured, and IPv4 if non-localhost IPv4 - // configured. - tcp::resolver::query query(server.c_str(), port.c_str()); - endpoint_iterator = resolver.resolve(query); -#if BOOST_VERSION >= 104300 - } catch (const boost::system::system_error&) { - // If we at first don't succeed, try blanket lookup (IPv4+IPv6 independent of configured interfaces) - tcp::resolver::query query(server.c_str(), port.c_str(), resolver_query_base::flags()); - endpoint_iterator = resolver.resolve(query); - } -#endif - boost::system::error_code error = boost::asio::error::host_not_found; - tcp::resolver::iterator end; - while (error && endpoint_iterator != end) - { - stream.lowest_layer().close(); - stream.lowest_layer().connect(*endpoint_iterator++, error); - } - if (error) - return false; - return true; - } - -private: - bool fNeedHandshake; - bool fUseSSL; - boost::asio::ssl::stream<typename Protocol::socket>& stream; -}; - -std::string HTTPPost(const std::string& strMsg, const std::map<std::string,std::string>& mapRequestHeaders); -std::string HTTPError(int nStatus, bool keepalive, - bool headerOnly = false); -std::string HTTPReplyHeader(int nStatus, bool keepalive, size_t contentLength, - const char *contentType = "application/json"); -std::string HTTPReply(int nStatus, const std::string& strMsg, bool keepalive, - bool headerOnly = false, - const char *contentType = "application/json"); -bool ReadHTTPRequestLine(std::basic_istream<char>& stream, int &proto, - std::string& http_method, std::string& http_uri); -int ReadHTTPStatus(std::basic_istream<char>& stream, int &proto); -int ReadHTTPHeaders(std::basic_istream<char>& stream, std::map<std::string, std::string>& mapHeadersRet); -int ReadHTTPMessage(std::basic_istream<char>& stream, std::map<std::string, std::string>& mapHeadersRet, - std::string& strMessageRet, int nProto, size_t max_size); std::string JSONRPCRequest(const std::string& strMethod, const UniValue& params, const UniValue& id); UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id); std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id); diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 62d2ef69ef..fa3150cd7f 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -41,7 +41,7 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fInclud vector<CTxDestination> addresses; int nRequired; - out.push_back(Pair("asm", scriptPubKey.ToString())); + out.push_back(Pair("asm", ScriptToAsmStr(scriptPubKey))); if (fIncludeHex) out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end()))); @@ -73,7 +73,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) in.push_back(Pair("txid", txin.prevout.hash.GetHex())); in.push_back(Pair("vout", (int64_t)txin.prevout.n)); UniValue o(UniValue::VOBJ); - o.push_back(Pair("asm", txin.scriptSig.ToString())); + o.push_back(Pair("asm", ScriptToAsmStr(txin.scriptSig, true))); o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); in.push_back(Pair("scriptSig", o)); } @@ -149,7 +149,7 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) " ],\n" " \"vout\" : [ (array of json objects)\n" " {\n" - " \"value\" : x.xxx, (numeric) The value in btc\n" + " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n" " \"n\" : n, (numeric) index\n" " \"scriptPubKey\" : { (json object)\n" " \"asm\" : \"asm\", (string) the asm\n" @@ -318,8 +318,9 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 2) throw runtime_error( - "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,...}\n" - "\nCreate a transaction spending the given inputs and sending to the given addresses.\n" + "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,\"data\":\"hex\",...}\n" + "\nCreate a transaction spending the given inputs and creating new outputs.\n" + "Outputs can be addresses or data.\n" "Returns hex-encoded raw transaction.\n" "Note that the transaction's inputs are not signed, and\n" "it is not stored in the wallet or transmitted to the network.\n" @@ -328,23 +329,25 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) "1. \"transactions\" (string, required) A json array of json objects\n" " [\n" " {\n" - " \"txid\":\"id\", (string, required) The transaction id\n" + " \"txid\":\"id\", (string, required) The transaction id\n" " \"vout\":n (numeric, required) The output number\n" " }\n" " ,...\n" " ]\n" - "2. \"addresses\" (string, required) a json object with addresses as keys and amounts as values\n" + "2. \"outputs\" (string, required) a json object with outputs\n" " {\n" - " \"address\": x.xxx (numeric, required) The key is the bitcoin address, the value is the btc amount\n" - " ,...\n" + " \"address\": x.xxx (numeric, required) The key is the bitcoin address, the value is the " + CURRENCY_UNIT + " amount\n" + " \"data\": \"hex\", (string, required) The key is \"data\", the value is hex encoded data\n" + " ...\n" " }\n" - "\nResult:\n" "\"transaction\" (string) hex string of the transaction\n" "\nExamples\n" + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"") + + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"data\\\":\\\"00010203\\\"}\"") + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"") + + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"data\\\":\\\"00010203\\\"}\"") ); LOCK(cs_main); @@ -375,19 +378,27 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) set<CBitcoinAddress> setAddress; vector<string> addrList = sendTo.getKeys(); BOOST_FOREACH(const string& name_, addrList) { - CBitcoinAddress address(name_); - if (!address.IsValid()) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+name_); - if (setAddress.count(address)) - throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+name_); - setAddress.insert(address); + if (name_ == "data") { + std::vector<unsigned char> data = ParseHexV(sendTo[name_].getValStr(),"Data"); + + CTxOut out(0, CScript() << OP_RETURN << data); + rawTx.vout.push_back(out); + } else { + CBitcoinAddress address(name_); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+name_); - CScript scriptPubKey = GetScriptForDestination(address.Get()); - CAmount nAmount = AmountFromValue(sendTo[name_]); + if (setAddress.count(address)) + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+name_); + setAddress.insert(address); - CTxOut out(nAmount, scriptPubKey); - rawTx.vout.push_back(out); + CScript scriptPubKey = GetScriptForDestination(address.Get()); + CAmount nAmount = AmountFromValue(sendTo[name_]); + + CTxOut out(nAmount, scriptPubKey); + rawTx.vout.push_back(out); + } } return EncodeHexTx(rawTx); @@ -422,7 +433,7 @@ UniValue decoderawtransaction(const UniValue& params, bool fHelp) " ],\n" " \"vout\" : [ (array of json objects)\n" " {\n" - " \"value\" : x.xxx, (numeric) The value in btc\n" + " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n" " \"n\" : n, (numeric) index\n" " \"scriptPubKey\" : { (json object)\n" " \"asm\" : \"asm\", (string) the asm\n" @@ -665,8 +676,8 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) CCoinsModifier coins = view.ModifyCoins(txid); if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) { string err("Previous output scriptPubKey mismatch:\n"); - err = err + coins->vout[nOut].scriptPubKey.ToString() + "\nvs:\n"+ - scriptPubKey.ToString(); + err = err + ScriptToAsmStr(coins->vout[nOut].scriptPubKey) + "\nvs:\n"+ + ScriptToAsmStr(scriptPubKey); throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err); } if ((unsigned int)nOut >= coins->vout.size()) diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 03c123a361..dbee61efc8 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -12,13 +12,9 @@ #include "ui_interface.h" #include "util.h" #include "utilstrencodings.h" -#ifdef ENABLE_WALLET -#include "wallet/wallet.h" -#endif -#include <boost/algorithm/string.hpp> -#include <boost/asio.hpp> -#include <boost/asio/ssl.hpp> +#include "univalue/univalue.h" + #include <boost/bind.hpp> #include <boost/filesystem.hpp> #include <boost/foreach.hpp> @@ -27,28 +23,20 @@ #include <boost/shared_ptr.hpp> #include <boost/signals2/signal.hpp> #include <boost/thread.hpp> +#include <boost/algorithm/string/case_conv.hpp> // for to_upper() -#include "univalue/univalue.h" - -using namespace boost::asio; using namespace RPCServer; using namespace std; -static std::string strRPCUserColonPass; - static bool fRPCRunning = false; static bool fRPCInWarmup = true; static std::string rpcWarmupStatus("RPC server started"); static CCriticalSection cs_rpcWarmup; - -//! These are created by StartRPCThreads, destroyed in StopRPCThreads -static boost::asio::io_service* rpc_io_service = NULL; -static map<string, boost::shared_ptr<deadline_timer> > deadlineTimers; -static ssl::context* rpc_ssl_context = NULL; -static boost::thread_group* rpc_worker_group = NULL; -static boost::asio::io_service::work *rpc_dummy_work = NULL; -static std::vector<CSubNet> rpc_allow_subnets; //!< List of subnets to allow RPC connections from -static std::vector< boost::shared_ptr<ip::tcp::acceptor> > rpc_acceptors; +/* Timer-creating functions */ +static std::vector<RPCTimerInterface*> timerInterfaces; +/* Map of name to timer. + * @note Can be changed to std::unique_ptr when C++11 */ +static std::map<std::string, boost::shared_ptr<RPCTimerBase> > deadlineTimers; static struct CRPCSignals { @@ -169,7 +157,6 @@ vector<unsigned char> ParseHexO(const UniValue& o, string strKey) return ParseHexV(find_value(o, strKey), strKey); } - /** * Note: This interface may still be subject to change. */ @@ -256,13 +243,12 @@ UniValue stop(const UniValue& params, bool fHelp) throw runtime_error( "stop\n" "\nStop Bitcoin server."); - // Shutdown will take long enough that the response should get back + // Event loop will exit after current HTTP requests have been handled, so + // this reply will get back to the client. StartShutdown(); return "Bitcoin server stopping"; } - - /** * Call Table */ @@ -363,6 +349,7 @@ static const CRPCCommand vRPCCommands[] = { "wallet", "importprivkey", &importprivkey, true }, { "wallet", "importwallet", &importwallet, true }, { "wallet", "importaddress", &importaddress, true }, + { "wallet", "importpubkey", &importpubkey, true }, { "wallet", "keypoolrefill", &keypoolrefill, true }, { "wallet", "listaccounts", &listaccounts, false }, { "wallet", "listaddressgroupings", &listaddressgroupings, false }, @@ -398,7 +385,7 @@ CRPCTable::CRPCTable() } } -const CRPCCommand *CRPCTable::operator[](const std::string& name) const +const CRPCCommand *CRPCTable::operator[](const std::string &name) const { map<string, const CRPCCommand*>::const_iterator it = mapCommands.find(name); if (it == mapCommands.end()) @@ -406,373 +393,26 @@ const CRPCCommand *CRPCTable::operator[](const std::string& name) const return (*it).second; } - -bool HTTPAuthorized(map<string, string>& mapHeaders) -{ - string strAuth = mapHeaders["authorization"]; - if (strAuth.substr(0,6) != "Basic ") - return false; - string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64); - string strUserPass = DecodeBase64(strUserPass64); - return TimingResistantEqual(strUserPass, strRPCUserColonPass); -} - -void ErrorReply(std::ostream& stream, const UniValue& objError, const UniValue& id) -{ - // Send error reply from json-rpc error object - int nStatus = HTTP_INTERNAL_SERVER_ERROR; - int code = find_value(objError, "code").get_int(); - if (code == RPC_INVALID_REQUEST) nStatus = HTTP_BAD_REQUEST; - else if (code == RPC_METHOD_NOT_FOUND) nStatus = HTTP_NOT_FOUND; - string strReply = JSONRPCReply(NullUniValue, objError, id); - stream << HTTPReply(nStatus, strReply, false) << std::flush; -} - -CNetAddr BoostAsioToCNetAddr(boost::asio::ip::address address) -{ - CNetAddr netaddr; - // Make sure that IPv4-compatible and IPv4-mapped IPv6 addresses are treated as IPv4 addresses - if (address.is_v6() - && (address.to_v6().is_v4_compatible() - || address.to_v6().is_v4_mapped())) - address = address.to_v6().to_v4(); - - if(address.is_v4()) - { - boost::asio::ip::address_v4::bytes_type bytes = address.to_v4().to_bytes(); - netaddr.SetRaw(NET_IPV4, &bytes[0]); - } - else - { - boost::asio::ip::address_v6::bytes_type bytes = address.to_v6().to_bytes(); - netaddr.SetRaw(NET_IPV6, &bytes[0]); - } - return netaddr; -} - -bool ClientAllowed(const boost::asio::ip::address& address) -{ - CNetAddr netaddr = BoostAsioToCNetAddr(address); - BOOST_FOREACH(const CSubNet &subnet, rpc_allow_subnets) - if (subnet.Match(netaddr)) - return true; - return false; -} - -template <typename Protocol> -class AcceptedConnectionImpl : public AcceptedConnection -{ -public: - AcceptedConnectionImpl( - boost::asio::io_service& io_service, - ssl::context &context, - bool fUseSSL) : - sslStream(io_service, context), - _d(sslStream, fUseSSL), - _stream(_d) - { - } - - virtual std::iostream& stream() - { - return _stream; - } - - virtual std::string peer_address_to_string() const - { - return peer.address().to_string(); - } - - virtual void close() - { - _stream.close(); - } - - typename Protocol::endpoint peer; - boost::asio::ssl::stream<typename Protocol::socket> sslStream; - -private: - SSLIOStreamDevice<Protocol> _d; - boost::iostreams::stream< SSLIOStreamDevice<Protocol> > _stream; -}; - -void ServiceConnection(AcceptedConnection *conn); - -//! Forward declaration required for RPCListen -template <typename Protocol, typename SocketAcceptorService> -static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor, - ssl::context& context, - bool fUseSSL, - boost::shared_ptr< AcceptedConnection > conn, - const boost::system::error_code& error); - -/** - * Sets up I/O resources to accept and handle a new connection. - */ -template <typename Protocol, typename SocketAcceptorService> -static void RPCListen(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor, - ssl::context& context, - const bool fUseSSL) -{ - // Accept connection - boost::shared_ptr< AcceptedConnectionImpl<Protocol> > conn(new AcceptedConnectionImpl<Protocol>(acceptor->get_io_service(), context, fUseSSL)); - - acceptor->async_accept( - conn->sslStream.lowest_layer(), - conn->peer, - boost::bind(&RPCAcceptHandler<Protocol, SocketAcceptorService>, - acceptor, - boost::ref(context), - fUseSSL, - conn, - _1)); -} - - -/** - * Accept and handle incoming connection. - */ -template <typename Protocol, typename SocketAcceptorService> -static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor, - ssl::context& context, - const bool fUseSSL, - boost::shared_ptr< AcceptedConnection > conn, - const boost::system::error_code& error) +bool StartRPC() { - // Immediately start accepting new connections, except when we're cancelled or our socket is closed. - if (error != boost::asio::error::operation_aborted && acceptor->is_open()) - RPCListen(acceptor, context, fUseSSL); - - AcceptedConnectionImpl<ip::tcp>* tcp_conn = dynamic_cast< AcceptedConnectionImpl<ip::tcp>* >(conn.get()); - - if (error) - { - // TODO: Actually handle errors - LogPrintf("%s: Error: %s\n", __func__, error.message()); - } - // Restrict callers by IP. It is important to - // do this before starting client thread, to filter out - // certain DoS and misbehaving clients. - else if (tcp_conn && !ClientAllowed(tcp_conn->peer.address())) - { - // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake. - if (!fUseSSL) - conn->stream() << HTTPError(HTTP_FORBIDDEN, false) << std::flush; - conn->close(); - } - else { - ServiceConnection(conn.get()); - conn->close(); - } -} - -static ip::tcp::endpoint ParseEndpoint(const std::string &strEndpoint, int defaultPort) -{ - std::string addr; - int port = defaultPort; - SplitHostPort(strEndpoint, port, addr); - return ip::tcp::endpoint(boost::asio::ip::address::from_string(addr), port); -} - -void StartRPCThreads() -{ - rpc_allow_subnets.clear(); - rpc_allow_subnets.push_back(CSubNet("127.0.0.0/8")); // always allow IPv4 local subnet - rpc_allow_subnets.push_back(CSubNet("::1")); // always allow IPv6 localhost - if (mapMultiArgs.count("-rpcallowip")) - { - const vector<string>& vAllow = mapMultiArgs["-rpcallowip"]; - BOOST_FOREACH(string strAllow, vAllow) - { - CSubNet subnet(strAllow); - if(!subnet.IsValid()) - { - uiInterface.ThreadSafeMessageBox( - strprintf("Invalid -rpcallowip subnet specification: %s. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).", strAllow), - "", CClientUIInterface::MSG_ERROR); - StartShutdown(); - return; - } - rpc_allow_subnets.push_back(subnet); - } - } - std::string strAllowed; - BOOST_FOREACH(const CSubNet &subnet, rpc_allow_subnets) - strAllowed += subnet.ToString() + " "; - LogPrint("rpc", "Allowing RPC connections from: %s\n", strAllowed); - - if (mapArgs["-rpcpassword"] == "") - { - LogPrintf("No rpcpassword set - using random cookie authentication\n"); - if (!GenerateAuthCookie(&strRPCUserColonPass)) { - uiInterface.ThreadSafeMessageBox( - _("Error: A fatal internal error occured, see debug.log for details"), // Same message as AbortNode - "", CClientUIInterface::MSG_ERROR); - StartShutdown(); - return; - } - } else { - strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; - } - - assert(rpc_io_service == NULL); - rpc_io_service = new boost::asio::io_service(); - rpc_ssl_context = new ssl::context(*rpc_io_service, ssl::context::sslv23); - - const bool fUseSSL = GetBoolArg("-rpcssl", false); - - if (fUseSSL) - { - rpc_ssl_context->set_options(ssl::context::no_sslv2 | ssl::context::no_sslv3); - - boost::filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert")); - if (!pathCertFile.is_complete()) pathCertFile = boost::filesystem::path(GetDataDir()) / pathCertFile; - if (boost::filesystem::exists(pathCertFile)) rpc_ssl_context->use_certificate_chain_file(pathCertFile.string()); - else LogPrintf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string()); - - boost::filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem")); - if (!pathPKFile.is_complete()) pathPKFile = boost::filesystem::path(GetDataDir()) / pathPKFile; - if (boost::filesystem::exists(pathPKFile)) rpc_ssl_context->use_private_key_file(pathPKFile.string(), ssl::context::pem); - else LogPrintf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string()); - - string strCiphers = GetArg("-rpcsslciphers", "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH"); - SSL_CTX_set_cipher_list(rpc_ssl_context->impl(), strCiphers.c_str()); - } - - std::vector<ip::tcp::endpoint> vEndpoints; - bool bBindAny = false; - int defaultPort = GetArg("-rpcport", BaseParams().RPCPort()); - if (!mapArgs.count("-rpcallowip")) // Default to loopback if not allowing external IPs - { - vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v6::loopback(), defaultPort)); - vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v4::loopback(), defaultPort)); - if (mapArgs.count("-rpcbind")) - { - LogPrintf("WARNING: option -rpcbind was ignored because -rpcallowip was not specified, refusing to allow everyone to connect\n"); - } - } else if (mapArgs.count("-rpcbind")) // Specific bind address - { - BOOST_FOREACH(const std::string &addr, mapMultiArgs["-rpcbind"]) - { - try { - vEndpoints.push_back(ParseEndpoint(addr, defaultPort)); - } - catch (const boost::system::system_error&) - { - uiInterface.ThreadSafeMessageBox( - strprintf(_("Could not parse -rpcbind value %s as network address"), addr), - "", CClientUIInterface::MSG_ERROR); - StartShutdown(); - return; - } - } - } else { // No specific bind address specified, bind to any - vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v6::any(), defaultPort)); - vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v4::any(), defaultPort)); - // Prefer making the socket dual IPv6/IPv4 instead of binding - // to both addresses seperately. - bBindAny = true; - } - - bool fListening = false; - std::string strerr; - std::string straddress; - BOOST_FOREACH(const ip::tcp::endpoint &endpoint, vEndpoints) - { - try { - boost::asio::ip::address bindAddress = endpoint.address(); - straddress = bindAddress.to_string(); - LogPrintf("Binding RPC on address %s port %i (IPv4+IPv6 bind any: %i)\n", straddress, endpoint.port(), bBindAny); - boost::system::error_code v6_only_error; - boost::shared_ptr<ip::tcp::acceptor> acceptor(new ip::tcp::acceptor(*rpc_io_service)); - - acceptor->open(endpoint.protocol()); - acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); - - // Try making the socket dual IPv6/IPv4 when listening on the IPv6 "any" address - acceptor->set_option(boost::asio::ip::v6_only( - !bBindAny || bindAddress != boost::asio::ip::address_v6::any()), v6_only_error); - - acceptor->bind(endpoint); - acceptor->listen(socket_base::max_connections); - - RPCListen(acceptor, *rpc_ssl_context, fUseSSL); - - fListening = true; - rpc_acceptors.push_back(acceptor); - // If dual IPv6/IPv4 bind successful, skip binding to IPv4 separately - if(bBindAny && bindAddress == boost::asio::ip::address_v6::any() && !v6_only_error) - break; - } - catch (const boost::system::system_error& e) - { - LogPrintf("ERROR: Binding RPC on address %s port %i failed: %s\n", straddress, endpoint.port(), e.what()); - strerr = strprintf(_("An error occurred while setting up the RPC address %s port %u for listening: %s"), straddress, endpoint.port(), e.what()); - } - } - - if (!fListening) { - uiInterface.ThreadSafeMessageBox(strerr, "", CClientUIInterface::MSG_ERROR); - StartShutdown(); - return; - } - - rpc_worker_group = new boost::thread_group(); - for (int i = 0; i < GetArg("-rpcthreads", 4); i++) - rpc_worker_group->create_thread(boost::bind(&boost::asio::io_service::run, rpc_io_service)); + LogPrint("rpc", "Starting RPC\n"); fRPCRunning = true; g_rpcSignals.Started(); + return true; } -void StartDummyRPCThread() +void InterruptRPC() { - if(rpc_io_service == NULL) - { - rpc_io_service = new boost::asio::io_service(); - /* Create dummy "work" to keep the thread from exiting when no timeouts active, - * see http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/reference/io_service.html#boost_asio.reference.io_service.stopping_the_io_service_from_running_out_of_work */ - rpc_dummy_work = new boost::asio::io_service::work(*rpc_io_service); - rpc_worker_group = new boost::thread_group(); - rpc_worker_group->create_thread(boost::bind(&boost::asio::io_service::run, rpc_io_service)); - fRPCRunning = true; - } + LogPrint("rpc", "Interrupting RPC\n"); + // Interrupt e.g. running longpolls + fRPCRunning = false; } -void StopRPCThreads() +void StopRPC() { - if (rpc_io_service == NULL) return; - // Set this to false first, so that longpolling loops will exit when woken up - fRPCRunning = false; - - // First, cancel all timers and acceptors - // This is not done automatically by ->stop(), and in some cases the destructor of - // boost::asio::io_service can hang if this is skipped. - boost::system::error_code ec; - BOOST_FOREACH(const boost::shared_ptr<ip::tcp::acceptor> &acceptor, rpc_acceptors) - { - acceptor->cancel(ec); - if (ec) - LogPrintf("%s: Warning: %s when cancelling acceptor", __func__, ec.message()); - } - rpc_acceptors.clear(); - BOOST_FOREACH(const PAIRTYPE(std::string, boost::shared_ptr<deadline_timer>) &timer, deadlineTimers) - { - timer.second->cancel(ec); - if (ec) - LogPrintf("%s: Warning: %s when cancelling timer", __func__, ec.message()); - } + LogPrint("rpc", "Stopping RPC\n"); deadlineTimers.clear(); - - DeleteAuthCookie(); - - rpc_io_service->stop(); g_rpcSignals.Stopped(); - if (rpc_worker_group != NULL) - rpc_worker_group->join_all(); - delete rpc_dummy_work; rpc_dummy_work = NULL; - delete rpc_worker_group; rpc_worker_group = NULL; - delete rpc_ssl_context; rpc_ssl_context = NULL; - delete rpc_io_service; rpc_io_service = NULL; } bool IsRPCRunning() @@ -801,36 +441,6 @@ bool RPCIsInWarmup(std::string *outStatus) return fRPCInWarmup; } -void RPCRunHandler(const boost::system::error_code& err, boost::function<void(void)> func) -{ - if (!err) - func(); -} - -void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds) -{ - assert(rpc_io_service != NULL); - - if (deadlineTimers.count(name) == 0) - { - deadlineTimers.insert(make_pair(name, - boost::shared_ptr<deadline_timer>(new deadline_timer(*rpc_io_service)))); - } - deadlineTimers[name]->expires_from_now(boost::posix_time::seconds(nSeconds)); - deadlineTimers[name]->async_wait(boost::bind(RPCRunHandler, _1, func)); -} - -class JSONRequest -{ -public: - UniValue id; - string strMethod; - UniValue params; - - JSONRequest() { id = NullUniValue; } - void parse(const UniValue& valRequest); -}; - void JSONRequest::parse(const UniValue& valRequest) { // Parse request @@ -861,7 +471,6 @@ void JSONRequest::parse(const UniValue& valRequest) throw JSONRPCError(RPC_INVALID_REQUEST, "Params must be an array"); } - static UniValue JSONRPCExecOne(const UniValue& req) { UniValue rpc_result(UniValue::VOBJ); @@ -886,7 +495,7 @@ static UniValue JSONRPCExecOne(const UniValue& req) return rpc_result; } -static string JSONRPCExecBatch(const UniValue& vReq) +std::string JSONRPCExecBatch(const UniValue& vReq) { UniValue ret(UniValue::VARR); for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++) @@ -895,107 +504,6 @@ static string JSONRPCExecBatch(const UniValue& vReq) return ret.write() + "\n"; } -static bool HTTPReq_JSONRPC(AcceptedConnection *conn, - string& strRequest, - map<string, string>& mapHeaders, - bool fRun) -{ - // Check authorization - if (mapHeaders.count("authorization") == 0) - { - conn->stream() << HTTPError(HTTP_UNAUTHORIZED, false) << std::flush; - return false; - } - - if (!HTTPAuthorized(mapHeaders)) - { - LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", conn->peer_address_to_string()); - /* Deter brute-forcing - We don't support exposing the RPC port, so this shouldn't result - in a DoS. */ - MilliSleep(250); - - conn->stream() << HTTPError(HTTP_UNAUTHORIZED, false) << std::flush; - return false; - } - - JSONRequest jreq; - try - { - // Parse request - UniValue valRequest; - if (!valRequest.read(strRequest)) - throw JSONRPCError(RPC_PARSE_ERROR, "Parse error"); - - string strReply; - - // singleton request - if (valRequest.isObject()) { - jreq.parse(valRequest); - - UniValue result = tableRPC.execute(jreq.strMethod, jreq.params); - - // Send reply - strReply = JSONRPCReply(result, NullUniValue, jreq.id); - - // array of requests - } else if (valRequest.isArray()) - strReply = JSONRPCExecBatch(valRequest.get_array()); - else - throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error"); - - conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, strReply.size()) << strReply << std::flush; - } - catch (const UniValue& objError) - { - ErrorReply(conn->stream(), objError, jreq.id); - return false; - } - catch (const std::exception& e) - { - ErrorReply(conn->stream(), JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); - return false; - } - return true; -} - -void ServiceConnection(AcceptedConnection *conn) -{ - bool fRun = true; - while (fRun && !ShutdownRequested()) - { - int nProto = 0; - map<string, string> mapHeaders; - string strRequest, strMethod, strURI; - - // Read HTTP request line - if (!ReadHTTPRequestLine(conn->stream(), nProto, strMethod, strURI)) - break; - - // Read HTTP message headers and body - ReadHTTPMessage(conn->stream(), mapHeaders, strRequest, nProto, MAX_SIZE); - - // HTTP Keep-Alive is false; close connection immediately - if ((mapHeaders["connection"] == "close") || (!GetBoolArg("-rpckeepalive", true))) - fRun = false; - - // Process via JSON-RPC API - if (strURI == "/") { - if (!HTTPReq_JSONRPC(conn, strRequest, mapHeaders, fRun)) - break; - - // Process via HTTP REST API - } else if (strURI.substr(0, 6) == "/rest/" && GetBoolArg("-rest", false)) { - if (!HTTPReq_REST(conn, strURI, strRequest, mapHeaders, fRun)) - break; - - } else { - conn->stream() << HTTPError(HTTP_NOT_FOUND, false) << std::flush; - break; - } - } -} - UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms) const { // Return immediately if in warmup @@ -1036,4 +544,26 @@ std::string HelpExampleRpc(const std::string& methodname, const std::string& arg "\"method\": \"" + methodname + "\", \"params\": [" + args + "] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n"; } +void RPCRegisterTimerInterface(RPCTimerInterface *iface) +{ + timerInterfaces.push_back(iface); +} + +void RPCUnregisterTimerInterface(RPCTimerInterface *iface) +{ + std::vector<RPCTimerInterface*>::iterator i = std::find(timerInterfaces.begin(), timerInterfaces.end(), iface); + assert(i != timerInterfaces.end()); + timerInterfaces.erase(i); +} + +void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds) +{ + if (timerInterfaces.empty()) + throw JSONRPCError(RPC_INTERNAL_ERROR, "No timer handler registered for RPC"); + deadlineTimers.erase(name); + RPCTimerInterface* timerInterface = timerInterfaces[0]; + LogPrint("rpc", "queue run of timer %s in %i seconds (using %s)\n", name, nSeconds, timerInterface->Name()); + deadlineTimers.insert(std::make_pair(name, timerInterface->NewTimer(func, nSeconds*1000))); +} + const CRPCTable tableRPC; diff --git a/src/rpcserver.h b/src/rpcserver.h index 89d3980223..83cc37918b 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -32,26 +32,17 @@ namespace RPCServer class CBlockIndex; class CNetAddr; -class AcceptedConnection +class JSONRequest { public: - virtual ~AcceptedConnection() {} + UniValue id; + std::string strMethod; + UniValue params; - virtual std::iostream& stream() = 0; - virtual std::string peer_address_to_string() const = 0; - virtual void close() = 0; + JSONRequest() { id = NullUniValue; } + void parse(const UniValue& valRequest); }; -/** Start RPC threads */ -void StartRPCThreads(); -/** - * Alternative to StartRPCThreads for the GUI, when no server is - * used. The RPC thread in this case is only used to handle timeouts. - * If real RPC threads have already been started this is a no-op. - */ -void StartDummyRPCThread(); -/** Stop RPC threads */ -void StopRPCThreads(); /** Query whether RPC is running */ bool IsRPCRunning(); @@ -81,15 +72,45 @@ void RPCTypeCheck(const UniValue& params, void RPCTypeCheckObj(const UniValue& o, const std::map<std::string, UniValue::VType>& typesExpected, bool fAllowNull=false); +/** Opaque base class for timers returned by NewTimerFunc. + * This provides no methods at the moment, but makes sure that delete + * cleans up the whole state. + */ +class RPCTimerBase +{ +public: + virtual ~RPCTimerBase() {} +}; + /** - * Run func nSeconds from now. Uses boost deadline timers. + * RPC timer "driver". + */ +class RPCTimerInterface +{ +public: + virtual ~RPCTimerInterface() {} + /** Implementation name */ + virtual const char *Name() = 0; + /** Factory function for timers. + * RPC will call the function to create a timer that will call func in *millis* milliseconds. + * @note As the RPC mechanism is backend-neutral, it can use different implementations of timers. + * This is needed to cope with the case in which there is no HTTP server, but + * only GUI RPC console, and to break the dependency of pcserver on httprpc. + */ + virtual RPCTimerBase* NewTimer(boost::function<void(void)>& func, int64_t millis) = 0; +}; + +/** Register factory function for timers */ +void RPCRegisterTimerInterface(RPCTimerInterface *iface); +/** Unregister factory function for timers */ +void RPCUnregisterTimerInterface(RPCTimerInterface *iface); + +/** + * Run func nSeconds from now. * Overrides previous timer <name> (if any). */ void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds); -//! Convert boost::asio address to CNetAddr -extern CNetAddr BoostAsioToCNetAddr(boost::asio::ip::address address); - typedef UniValue(*rpcfn_type)(const UniValue& params, bool fHelp); class CRPCCommand @@ -134,9 +155,6 @@ extern uint256 ParseHashO(const UniValue& o, std::string strKey); extern std::vector<unsigned char> ParseHexV(const UniValue& v, std::string strName); extern std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey); -extern void InitRPCMining(); -extern void ShutdownRPCMining(); - extern int64_t nWalletUnlockTime; extern CAmount AmountFromValue(const UniValue& value); extern UniValue ValueFromAmount(const CAmount& amount); @@ -161,6 +179,7 @@ extern UniValue clearbanned(const UniValue& params, bool fHelp); extern UniValue dumpprivkey(const UniValue& params, bool fHelp); // in rpcdump.cpp extern UniValue importprivkey(const UniValue& params, bool fHelp); extern UniValue importaddress(const UniValue& params, bool fHelp); +extern UniValue importpubkey(const UniValue& params, bool fHelp); extern UniValue dumpwallet(const UniValue& params, bool fHelp); extern UniValue importwallet(const UniValue& params, bool fHelp); @@ -243,11 +262,9 @@ extern UniValue getchaintips(const UniValue& params, bool fHelp); extern UniValue invalidateblock(const UniValue& params, bool fHelp); extern UniValue reconsiderblock(const UniValue& params, bool fHelp); -// in rest.cpp -extern bool HTTPReq_REST(AcceptedConnection *conn, - const std::string& strURI, - const std::string& strRequest, - const std::map<std::string, std::string>& mapHeaders, - bool fRun); +bool StartRPC(); +void InterruptRPC(); +void StopRPC(); +std::string JSONRPCExecBatch(const UniValue& vReq); #endif // BITCOIN_RPCSERVER_H diff --git a/src/scheduler.cpp b/src/scheduler.cpp index d5bb588b71..184ddc28ab 100644 --- a/src/scheduler.cpp +++ b/src/scheduler.cpp @@ -4,6 +4,8 @@ #include "scheduler.h" +#include "reverselock.h" + #include <assert.h> #include <boost/bind.hpp> #include <utility> @@ -65,11 +67,12 @@ void CScheduler::serviceQueue() Function f = taskQueue.begin()->second; taskQueue.erase(taskQueue.begin()); - // Unlock before calling f, so it can reschedule itself or another task - // without deadlocking: - lock.unlock(); - f(); - lock.lock(); + { + // Unlock before calling f, so it can reschedule itself or another task + // without deadlocking: + reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock); + f(); + } } catch (...) { --nThreadsServicingQueue; throw; diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 0b78fdf5a8..d3aec26020 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -188,7 +188,7 @@ bool static IsDefinedHashtypeSignature(const valtype &vchSig) { return true; } -bool static CheckSignatureEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) { +bool CheckSignatureEncoding(const vector<unsigned char> &vchSig, unsigned int flags, ScriptError* serror) { // Empty signature. Not strictly DER encoded, but allowed to provide a // compact way to provide an invalid signature for use with CHECK(MULTI)SIG if (vchSig.size() == 0) { @@ -1128,7 +1128,7 @@ bool TransactionSignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) const { - // There are two times of nLockTime: lock-by-blockheight + // There are two kinds of nLockTime: lock-by-blockheight // and lock-by-blocktime, distinguished by whether // nLockTime < LOCKTIME_THRESHOLD. // diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 35d572f0ad..213e8c7651 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -83,6 +83,8 @@ enum SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), }; +bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, unsigned int flags, ScriptError* serror); + uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); class BaseSignatureChecker diff --git a/src/script/script.cpp b/src/script/script.cpp index fd33924732..58dbade0e2 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -8,16 +8,6 @@ #include "tinyformat.h" #include "utilstrencodings.h" -namespace { -inline std::string ValueString(const std::vector<unsigned char>& vch) -{ - if (vch.size() <= 4) - return strprintf("%d", CScriptNum(vch, false).getint()); - else - return HexStr(vch); -} -} // anon namespace - using namespace std; const char* GetOpName(opcodetype opcode) @@ -237,26 +227,3 @@ bool CScript::IsPushOnly() const } return true; } - -std::string CScript::ToString() const -{ - std::string str; - opcodetype opcode; - std::vector<unsigned char> vch; - const_iterator pc = begin(); - while (pc < end()) - { - if (!str.empty()) - str += " "; - if (!GetOp(pc, opcode, vch)) - { - str += "[error]"; - return str; - } - if (0 <= opcode && opcode <= OP_PUSHDATA4) - str += ValueString(vch); - else - str += GetOpName(opcode); - } - return str; -} diff --git a/src/script/script.h b/src/script/script.h index e39ca57f4f..f0725bbbf6 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -601,7 +601,6 @@ public: return (size() > 0 && *begin() == OP_RETURN); } - std::string ToString() const; void clear() { // The default std::vector::clear() does not release memory. diff --git a/src/script/standard.cpp b/src/script/standard.cpp index 66657127ab..1d5aac7b34 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -286,6 +286,11 @@ CScript GetScriptForDestination(const CTxDestination& dest) return script; } +CScript GetScriptForRawPubKey(const CPubKey& pubKey) +{ + return CScript() << std::vector<unsigned char>(pubKey.begin(), pubKey.end()) << OP_CHECKSIG; +} + CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys) { CScript script; diff --git a/src/script/standard.h b/src/script/standard.h index 46ae5f9f10..9e17dac700 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -73,6 +73,7 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet); CScript GetScriptForDestination(const CTxDestination& dest); +CScript GetScriptForRawPubKey(const CPubKey& pubkey); CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys); #endif // BITCOIN_SCRIPT_STANDARD_H diff --git a/src/sync.h b/src/sync.h index 705647e4a5..68a9443084 100644 --- a/src/sync.h +++ b/src/sync.h @@ -16,7 +16,7 @@ //////////////////////////////////////////////// // // -// THE SIMPLE DEFINITON, EXCLUDING DEBUG CODE // +// THE SIMPLE DEFINITION, EXCLUDING DEBUG CODE // // // //////////////////////////////////////////////// diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp index 703cf307d1..0a23c430ed 100644 --- a/src/test/Checkpoints_tests.cpp +++ b/src/test/Checkpoints_tests.cpp @@ -20,7 +20,7 @@ BOOST_FIXTURE_TEST_SUITE(Checkpoints_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(sanity) { - const Checkpoints::CCheckpointData& checkpoints = Params(CBaseChainParams::MAIN).Checkpoints(); + const CCheckpointData& checkpoints = Params(CBaseChainParams::MAIN).Checkpoints(); BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate(checkpoints) >= 134444); } diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp index b8d5606cc3..dd3c51d09b 100644 --- a/src/test/alert_tests.cpp +++ b/src/test/alert_tests.cpp @@ -162,8 +162,8 @@ BOOST_AUTO_TEST_CASE(AlertNotify) SetMockTime(11); const std::vector<unsigned char>& alertKey = Params(CBaseChainParams::MAIN).AlertKey(); - boost::filesystem::path temp = GetTempPath() / "alertnotify.txt"; - boost::filesystem::remove(temp); + boost::filesystem::path temp = GetTempPath() / + boost::filesystem::unique_path("alertnotify-%%%%.txt"); mapArgs["-alertnotify"] = std::string("echo %s >> ") + temp.string(); diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index 1bda8a7ea1..6b30d6aa8a 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -469,7 +469,7 @@ static std::vector<unsigned char> RandomData() BOOST_AUTO_TEST_CASE(rolling_bloom) { // last-100-entry, 1% false positive: - CRollingBloomFilter rb1(100, 0.01, 0); + CRollingBloomFilter rb1(100, 0.01); // Overfill: static const int DATASIZE=399; @@ -500,7 +500,7 @@ BOOST_AUTO_TEST_CASE(rolling_bloom) BOOST_CHECK(nHits < 175); BOOST_CHECK(rb1.contains(data[DATASIZE-1])); - rb1.clear(); + rb1.reset(); BOOST_CHECK(!rb1.contains(data[DATASIZE-1])); // Now roll through data, make sure last 100 entries @@ -527,7 +527,7 @@ BOOST_AUTO_TEST_CASE(rolling_bloom) BOOST_CHECK(nHits < 100); // last-1000-entry, 0.01% false positive: - CRollingBloomFilter rb2(1000, 0.001, 0); + CRollingBloomFilter rb2(1000, 0.001); for (int i = 0; i < DATASIZE; i++) { rb2.insert(data[i]); } diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json index afd35af503..3bf80ca434 100644 --- a/src/test/data/bitcoin-util-test.json +++ b/src/test/data/bitcoin-util-test.json @@ -56,5 +56,35 @@ "sign=ALL", "outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"], "output_cmp": "txcreatesign.hex" + }, + { "exec": "./bitcoin-tx", + "args": + ["-create", + "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", + "outdata=4:badhexdata"], + "return_code": 1 + }, + { "exec": "./bitcoin-tx", + "args": + ["-create", + "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", + "outdata=badhexdata"], + "return_code": 1 + }, + { "exec": "./bitcoin-tx", + "args": + ["-create", + "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", + "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o", + "outdata=4:54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"], + "output_cmp": "txcreatedata1.hex" + }, + { "exec": "./bitcoin-tx", + "args": + ["-create", + "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", + "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o", + "outdata=54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"], + "output_cmp": "txcreatedata2.hex" } ] diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index 20bdbd08a5..5cad5af7c3 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -128,7 +128,7 @@ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000fe64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], -["By-time locks, with argument just beyond tx nLockTime (but within numerical boundries)"], +["By-time locks, with argument just beyond tx nLockTime (but within numerical boundaries)"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000001 NOP2 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]], @@ -181,7 +181,7 @@ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP2 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffff7f", "P2SH,CHECKLOCKTIMEVERIFY"], -["6 byte non-minimally-encoded arguments are invalid even in their contents are valid"], +["6 byte non-minimally-encoded arguments are invalid even if their contents are valid"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x06 0x000000000000 NOP2 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index 24fff575c1..9744a3c848 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -197,7 +197,7 @@ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], -["By-time locks, with argument just beyond tx nLockTime (but within numerical boundries)"], +["By-time locks, with argument just beyond tx nLockTime (but within numerical boundaries)"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]], diff --git a/src/test/data/txcreatedata1.hex b/src/test/data/txcreatedata1.hex new file mode 100644 index 0000000000..eccc7604e6 --- /dev/null +++ b/src/test/data/txcreatedata1.hex @@ -0,0 +1 @@ +01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0084d71700000000526a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e00000000 diff --git a/src/test/data/txcreatedata2.hex b/src/test/data/txcreatedata2.hex new file mode 100644 index 0000000000..3c7644c297 --- /dev/null +++ b/src/test/data/txcreatedata2.hex @@ -0,0 +1 @@ +01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0000000000000000526a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e00000000 diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp index a0c5592a95..eb61a2884d 100644 --- a/src/test/getarg_tests.cpp +++ b/src/test/getarg_tests.cpp @@ -60,18 +60,18 @@ BOOST_AUTO_TEST_CASE(boolarg) BOOST_CHECK(!GetBoolArg("-foo", false)); BOOST_CHECK(!GetBoolArg("-foo", true)); - ResetArgs("-foo -nofoo"); // -foo should win - BOOST_CHECK(GetBoolArg("-foo", false)); - BOOST_CHECK(GetBoolArg("-foo", true)); - - ResetArgs("-foo=1 -nofoo=1"); // -foo should win - BOOST_CHECK(GetBoolArg("-foo", false)); - BOOST_CHECK(GetBoolArg("-foo", true)); + ResetArgs("-foo -nofoo"); // -nofoo should win + BOOST_CHECK(!GetBoolArg("-foo", false)); + BOOST_CHECK(!GetBoolArg("-foo", true)); - ResetArgs("-foo=0 -nofoo=0"); // -foo should win + ResetArgs("-foo=1 -nofoo=1"); // -nofoo should win BOOST_CHECK(!GetBoolArg("-foo", false)); BOOST_CHECK(!GetBoolArg("-foo", true)); + ResetArgs("-foo=0 -nofoo=0"); // -nofoo=0 should win + BOOST_CHECK(GetBoolArg("-foo", false)); + BOOST_CHECK(GetBoolArg("-foo", true)); + // New 0.6 feature: treat -- same as -: ResetArgs("--foo=1"); BOOST_CHECK(GetBoolArg("-foo", false)); @@ -150,9 +150,9 @@ BOOST_AUTO_TEST_CASE(boolargno) BOOST_CHECK(GetBoolArg("-foo", true)); BOOST_CHECK(GetBoolArg("-foo", false)); - ResetArgs("-foo --nofoo"); - BOOST_CHECK(GetBoolArg("-foo", true)); - BOOST_CHECK(GetBoolArg("-foo", false)); + ResetArgs("-foo --nofoo"); // --nofoo should win + BOOST_CHECK(!GetBoolArg("-foo", true)); + BOOST_CHECK(!GetBoolArg("-foo", false)); ResetArgs("-nofoo -foo"); // foo always wins: BOOST_CHECK(GetBoolArg("-foo", true)); diff --git a/src/test/limitedmap_tests.cpp b/src/test/limitedmap_tests.cpp new file mode 100644 index 0000000000..faaddffad8 --- /dev/null +++ b/src/test/limitedmap_tests.cpp @@ -0,0 +1,101 @@ +// Copyright (c) 2012-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "limitedmap.h" + +#include "test/test_bitcoin.h" + +#include <boost/test/unit_test.hpp> + +BOOST_FIXTURE_TEST_SUITE(limitedmap_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(limitedmap_test) +{ + // create a limitedmap capped at 10 items + limitedmap<int, int> map(10); + + // check that the max size is 10 + BOOST_CHECK(map.max_size() == 10); + + // check that it's empty + BOOST_CHECK(map.size() == 0); + + // insert (-1, -1) + map.insert(std::pair<int, int>(-1, -1)); + + // make sure that the size is updated + BOOST_CHECK(map.size() == 1); + + // make sure that the new items is in the map + BOOST_CHECK(map.count(-1) == 1); + + // insert 10 new items + for (int i = 0; i < 10; i++) { + map.insert(std::pair<int, int>(i, i + 1)); + } + + // make sure that the map now contains 10 items... + BOOST_CHECK(map.size() == 10); + + // ...and that the first item has been discarded + BOOST_CHECK(map.count(-1) == 0); + + // iterate over the map, both with an index and an iterator + limitedmap<int, int>::const_iterator it = map.begin(); + for (int i = 0; i < 10; i++) { + // make sure the item is present + BOOST_CHECK(map.count(i) == 1); + + // use the iterator to check for the expected key adn value + BOOST_CHECK(it->first == i); + BOOST_CHECK(it->second == i + 1); + + // use find to check for the value + BOOST_CHECK(map.find(i)->second == i + 1); + + // update and recheck + map.update(it, i + 2); + BOOST_CHECK(map.find(i)->second == i + 2); + + it++; + } + + // check that we've exhausted the iterator + BOOST_CHECK(it == map.end()); + + // resize the map to 5 items + map.max_size(5); + + // check that the max size and size are now 5 + BOOST_CHECK(map.max_size() == 5); + BOOST_CHECK(map.size() == 5); + + // check that items less than 5 have been discarded + // and items greater than 5 are retained + for (int i = 0; i < 10; i++) { + if (i < 5) { + BOOST_CHECK(map.count(i) == 0); + } else { + BOOST_CHECK(map.count(i) == 1); + } + } + + // erase some items not in the map + for (int i = 100; i < 1000; i += 100) { + map.erase(i); + } + + // check that the size is unaffected + BOOST_CHECK(map.size() == 5); + + // erase the remaining elements + for (int i = 5; i < 10; i++) { + map.erase(i); + } + + // check that the map is now empty + BOOST_CHECK(map.empty()); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp index 2439689d7f..5bf1e98e8f 100644 --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -9,6 +9,7 @@ #include <boost/test/unit_test.hpp> #include <list> +#include <vector> BOOST_FIXTURE_TEST_SUITE(mempool_tests, TestingSetup) @@ -100,4 +101,184 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) removed.clear(); } +void CheckSort(CTxMemPool &pool, std::vector<std::string> &sortedOrder) +{ + BOOST_CHECK_EQUAL(pool.size(), sortedOrder.size()); + CTxMemPool::indexed_transaction_set::nth_index<1>::type::iterator it = pool.mapTx.get<1>().begin(); + int count=0; + for (; it != pool.mapTx.get<1>().end(); ++it, ++count) { + BOOST_CHECK_EQUAL(it->GetTx().GetHash().ToString(), sortedOrder[count]); + } +} + +BOOST_AUTO_TEST_CASE(MempoolIndexingTest) +{ + CTxMemPool pool(CFeeRate(0)); + + /* 3rd highest fee */ + CMutableTransaction tx1 = CMutableTransaction(); + tx1.vout.resize(1); + tx1.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx1.vout[0].nValue = 10 * COIN; + pool.addUnchecked(tx1.GetHash(), CTxMemPoolEntry(tx1, 10000LL, 0, 10.0, 1, true)); + + /* highest fee */ + CMutableTransaction tx2 = CMutableTransaction(); + tx2.vout.resize(1); + tx2.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx2.vout[0].nValue = 2 * COIN; + pool.addUnchecked(tx2.GetHash(), CTxMemPoolEntry(tx2, 20000LL, 0, 9.0, 1, true)); + + /* lowest fee */ + CMutableTransaction tx3 = CMutableTransaction(); + tx3.vout.resize(1); + tx3.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx3.vout[0].nValue = 5 * COIN; + pool.addUnchecked(tx3.GetHash(), CTxMemPoolEntry(tx3, 0LL, 0, 100.0, 1, true)); + + /* 2nd highest fee */ + CMutableTransaction tx4 = CMutableTransaction(); + tx4.vout.resize(1); + tx4.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx4.vout[0].nValue = 6 * COIN; + pool.addUnchecked(tx4.GetHash(), CTxMemPoolEntry(tx4, 15000LL, 0, 1.0, 1, true)); + + /* equal fee rate to tx1, but newer */ + CMutableTransaction tx5 = CMutableTransaction(); + tx5.vout.resize(1); + tx5.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx5.vout[0].nValue = 11 * COIN; + pool.addUnchecked(tx5.GetHash(), CTxMemPoolEntry(tx5, 10000LL, 1, 10.0, 1, true)); + BOOST_CHECK_EQUAL(pool.size(), 5); + + std::vector<std::string> sortedOrder; + sortedOrder.resize(5); + sortedOrder[0] = tx2.GetHash().ToString(); // 20000 + sortedOrder[1] = tx4.GetHash().ToString(); // 15000 + sortedOrder[2] = tx1.GetHash().ToString(); // 10000 + sortedOrder[3] = tx5.GetHash().ToString(); // 10000 + sortedOrder[4] = tx3.GetHash().ToString(); // 0 + CheckSort(pool, sortedOrder); + + /* low fee but with high fee child */ + /* tx6 -> tx7 -> tx8, tx9 -> tx10 */ + CMutableTransaction tx6 = CMutableTransaction(); + tx6.vout.resize(1); + tx6.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx6.vout[0].nValue = 20 * COIN; + pool.addUnchecked(tx6.GetHash(), CTxMemPoolEntry(tx6, 0LL, 1, 10.0, 1, true)); + BOOST_CHECK_EQUAL(pool.size(), 6); + // Check that at this point, tx6 is sorted low + sortedOrder.push_back(tx6.GetHash().ToString()); + CheckSort(pool, sortedOrder); + + CTxMemPool::setEntries setAncestors; + setAncestors.insert(pool.mapTx.find(tx6.GetHash())); + CMutableTransaction tx7 = CMutableTransaction(); + tx7.vin.resize(1); + tx7.vin[0].prevout = COutPoint(tx6.GetHash(), 0); + tx7.vin[0].scriptSig = CScript() << OP_11; + tx7.vout.resize(2); + tx7.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx7.vout[0].nValue = 10 * COIN; + tx7.vout[1].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx7.vout[1].nValue = 1 * COIN; + + CTxMemPool::setEntries setAncestorsCalculated; + std::string dummy; + CTxMemPoolEntry entry7(tx7, 2000000LL, 1, 10.0, 1, true); + BOOST_CHECK_EQUAL(pool.CalculateMemPoolAncestors(entry7, setAncestorsCalculated, 100, 1000000, 1000, 1000000, dummy), true); + BOOST_CHECK(setAncestorsCalculated == setAncestors); + + pool.addUnchecked(tx7.GetHash(), CTxMemPoolEntry(tx7, 2000000LL, 1, 10.0, 1, true), setAncestors); + BOOST_CHECK_EQUAL(pool.size(), 7); + + // Now tx6 should be sorted higher (high fee child): tx7, tx6, tx2, ... + sortedOrder.erase(sortedOrder.end()-1); + sortedOrder.insert(sortedOrder.begin(), tx6.GetHash().ToString()); + sortedOrder.insert(sortedOrder.begin(), tx7.GetHash().ToString()); + CheckSort(pool, sortedOrder); + + /* low fee child of tx7 */ + CMutableTransaction tx8 = CMutableTransaction(); + tx8.vin.resize(1); + tx8.vin[0].prevout = COutPoint(tx7.GetHash(), 0); + tx8.vin[0].scriptSig = CScript() << OP_11; + tx8.vout.resize(1); + tx8.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx8.vout[0].nValue = 10 * COIN; + setAncestors.insert(pool.mapTx.find(tx7.GetHash())); + pool.addUnchecked(tx8.GetHash(), CTxMemPoolEntry(tx8, 0LL, 2, 10.0, 1, true), setAncestors); + + // Now tx8 should be sorted low, but tx6/tx both high + sortedOrder.push_back(tx8.GetHash().ToString()); + CheckSort(pool, sortedOrder); + + /* low fee child of tx7 */ + CMutableTransaction tx9 = CMutableTransaction(); + tx9.vin.resize(1); + tx9.vin[0].prevout = COutPoint(tx7.GetHash(), 1); + tx9.vin[0].scriptSig = CScript() << OP_11; + tx9.vout.resize(1); + tx9.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx9.vout[0].nValue = 1 * COIN; + pool.addUnchecked(tx9.GetHash(), CTxMemPoolEntry(tx9, 0LL, 3, 10.0, 1, true), setAncestors); + + // tx9 should be sorted low + BOOST_CHECK_EQUAL(pool.size(), 9); + sortedOrder.push_back(tx9.GetHash().ToString()); + CheckSort(pool, sortedOrder); + + std::vector<std::string> snapshotOrder = sortedOrder; + + setAncestors.insert(pool.mapTx.find(tx8.GetHash())); + setAncestors.insert(pool.mapTx.find(tx9.GetHash())); + /* tx10 depends on tx8 and tx9 and has a high fee*/ + CMutableTransaction tx10 = CMutableTransaction(); + tx10.vin.resize(2); + tx10.vin[0].prevout = COutPoint(tx8.GetHash(), 0); + tx10.vin[0].scriptSig = CScript() << OP_11; + tx10.vin[1].prevout = COutPoint(tx9.GetHash(), 0); + tx10.vin[1].scriptSig = CScript() << OP_11; + tx10.vout.resize(1); + tx10.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx10.vout[0].nValue = 10 * COIN; + + setAncestorsCalculated.clear(); + CTxMemPoolEntry entry10(tx10, 200000LL, 4, 10.0, 1, true); + BOOST_CHECK_EQUAL(pool.CalculateMemPoolAncestors(entry10, setAncestorsCalculated, 100, 1000000, 1000, 1000000, dummy), true); + BOOST_CHECK(setAncestorsCalculated == setAncestors); + + pool.addUnchecked(tx10.GetHash(), CTxMemPoolEntry(tx10, 200000LL, 4, 10.0, 1, true), setAncestors); + + /** + * tx8 and tx9 should both now be sorted higher + * Final order after tx10 is added: + * + * tx7 = 2.2M (4 txs) + * tx6 = 2.2M (5 txs) + * tx10 = 200k (1 tx) + * tx8 = 200k (2 txs) + * tx9 = 200k (2 txs) + * tx2 = 20000 (1) + * tx4 = 15000 (1) + * tx1 = 10000 (1) + * tx5 = 10000 (1) + * tx3 = 0 (1) + */ + sortedOrder.erase(sortedOrder.end()-2, sortedOrder.end()); // take out tx8, tx9 from the end + sortedOrder.insert(sortedOrder.begin()+2, tx10.GetHash().ToString()); // tx10 is after tx6 + sortedOrder.insert(sortedOrder.begin()+3, tx9.GetHash().ToString()); + sortedOrder.insert(sortedOrder.begin()+3, tx8.GetHash().ToString()); + CheckSort(pool, sortedOrder); + + // there should be 10 transactions in the mempool + BOOST_CHECK_EQUAL(pool.size(), 10); + + // Now try removing tx10 and verify the sort order returns to normal + std::list<CTransaction> removed; + pool.remove(pool.mapTx.find(tx10.GetHash())->GetTx(), removed, true); + CheckSort(pool, snapshotOrder); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index ad79a558c2..91a3a5738e 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -87,7 +87,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) pblock->vtx[0] = CTransaction(txCoinbase); if (txFirst.size() < 2) txFirst.push_back(new CTransaction(pblock->vtx[0])); - pblock->hashMerkleRoot = pblock->BuildMerkleTree(); + pblock->hashMerkleRoot = pblock->ComputeMerkleRoot(); pblock->nNonce = blockinfo[i].nonce; CValidationState state; BOOST_CHECK(ProcessNewBlock(state, NULL, pblock, true, NULL)); diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index 7154476c7c..b1ef0ed24a 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -7,6 +7,7 @@ #include <string> +#include <boost/assign/list_of.hpp> #include <boost/test/unit_test.hpp> using namespace std; @@ -148,12 +149,106 @@ BOOST_AUTO_TEST_CASE(subnet_test) BOOST_CHECK(CSubNet(CNetAddr("127.0.0.1")).IsValid()); BOOST_CHECK(CSubNet(CNetAddr("127.0.0.1")).Match(CNetAddr("127.0.0.1"))); BOOST_CHECK(!CSubNet(CNetAddr("127.0.0.1")).Match(CNetAddr("127.0.0.2"))); - BOOST_CHECK(CSubNet(CNetAddr("127.0.0.1")).ToString() == "127.0.0.1/255.255.255.255"); + BOOST_CHECK(CSubNet(CNetAddr("127.0.0.1")).ToString() == "127.0.0.1/32"); BOOST_CHECK(CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).IsValid()); BOOST_CHECK(CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).Match(CNetAddr("1:2:3:4:5:6:7:8"))); BOOST_CHECK(!CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).Match(CNetAddr("1:2:3:4:5:6:7:9"))); - BOOST_CHECK(CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).ToString() == "1:2:3:4:5:6:7:8/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); + BOOST_CHECK(CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).ToString() == "1:2:3:4:5:6:7:8/128"); + + CSubNet subnet = CSubNet("1.2.3.4/255.255.255.255"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/32"); + subnet = CSubNet("1.2.3.4/255.255.255.254"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/31"); + subnet = CSubNet("1.2.3.4/255.255.255.252"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/30"); + subnet = CSubNet("1.2.3.4/255.255.255.248"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/29"); + subnet = CSubNet("1.2.3.4/255.255.255.240"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/28"); + subnet = CSubNet("1.2.3.4/255.255.255.224"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/27"); + subnet = CSubNet("1.2.3.4/255.255.255.192"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/26"); + subnet = CSubNet("1.2.3.4/255.255.255.128"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/25"); + subnet = CSubNet("1.2.3.4/255.255.255.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/24"); + subnet = CSubNet("1.2.3.4/255.255.254.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.2.0/23"); + subnet = CSubNet("1.2.3.4/255.255.252.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/22"); + subnet = CSubNet("1.2.3.4/255.255.248.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/21"); + subnet = CSubNet("1.2.3.4/255.255.240.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/20"); + subnet = CSubNet("1.2.3.4/255.255.224.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/19"); + subnet = CSubNet("1.2.3.4/255.255.192.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/18"); + subnet = CSubNet("1.2.3.4/255.255.128.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/17"); + subnet = CSubNet("1.2.3.4/255.255.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/16"); + subnet = CSubNet("1.2.3.4/255.254.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/15"); + subnet = CSubNet("1.2.3.4/255.252.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/14"); + subnet = CSubNet("1.2.3.4/255.248.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/13"); + subnet = CSubNet("1.2.3.4/255.240.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/12"); + subnet = CSubNet("1.2.3.4/255.224.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/11"); + subnet = CSubNet("1.2.3.4/255.192.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/10"); + subnet = CSubNet("1.2.3.4/255.128.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/9"); + subnet = CSubNet("1.2.3.4/255.0.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/8"); + subnet = CSubNet("1.2.3.4/254.0.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/7"); + subnet = CSubNet("1.2.3.4/252.0.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/6"); + subnet = CSubNet("1.2.3.4/248.0.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/5"); + subnet = CSubNet("1.2.3.4/240.0.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/4"); + subnet = CSubNet("1.2.3.4/224.0.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/3"); + subnet = CSubNet("1.2.3.4/192.0.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/2"); + subnet = CSubNet("1.2.3.4/128.0.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/1"); + subnet = CSubNet("1.2.3.4/0.0.0.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/0"); + + subnet = CSubNet("1:2:3:4:5:6:7:8/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1:2:3:4:5:6:7:8/128"); + subnet = CSubNet("1:2:3:4:5:6:7:8/ffff:0000:0000:0000:0000:0000:0000:0000"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1::/16"); + subnet = CSubNet("1:2:3:4:5:6:7:8/0000:0000:0000:0000:0000:0000:0000:0000"); + BOOST_CHECK_EQUAL(subnet.ToString(), "::/0"); + subnet = CSubNet("1.2.3.4/255.255.232.0"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/255.255.232.0"); + subnet = CSubNet("1:2:3:4:5:6:7:8/ffff:ffff:ffff:fffe:ffff:ffff:ffff:ff0f"); + BOOST_CHECK_EQUAL(subnet.ToString(), "1:2:3:4:5:6:7:8/ffff:ffff:ffff:fffe:ffff:ffff:ffff:ff0f"); +} + +BOOST_AUTO_TEST_CASE(netbase_getgroup) +{ + BOOST_CHECK(CNetAddr("127.0.0.1").GetGroup() == boost::assign::list_of(0)); // Local -> !Routable() + BOOST_CHECK(CNetAddr("257.0.0.1").GetGroup() == boost::assign::list_of(0)); // !Valid -> !Routable() + BOOST_CHECK(CNetAddr("10.0.0.1").GetGroup() == boost::assign::list_of(0)); // RFC1918 -> !Routable() + BOOST_CHECK(CNetAddr("169.254.1.1").GetGroup() == boost::assign::list_of(0)); // RFC3927 -> !Routable() + BOOST_CHECK(CNetAddr("1.2.3.4").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // IPv4 + BOOST_CHECK(CNetAddr("::FFFF:0:102:304").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6145 + BOOST_CHECK(CNetAddr("64:FF9B::102:304").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6052 + BOOST_CHECK(CNetAddr("2002:102:304:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC3964 + BOOST_CHECK(CNetAddr("2001:0:9999:9999:9999:9999:FEFD:FCFB").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC4380 + BOOST_CHECK(CNetAddr("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetGroup() == boost::assign::list_of((unsigned char)NET_TOR)(239)); // Tor + BOOST_CHECK(CNetAddr("2001:470:abcd:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV6)(32)(1)(4)(112)(175)); //he.net + BOOST_CHECK(CNetAddr("2001:2001:9999:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV6)(32)(1)(32)(1)); //IPv6 } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp index f6d06d6805..d9f3c3e467 100644 --- a/src/test/pmt_tests.cpp +++ b/src/test/pmt_tests.cpp @@ -48,7 +48,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1) } // calculate actual merkle root and height - uint256 merkleRoot1 = block.BuildMerkleTree(); + uint256 merkleRoot1 = block.ComputeMerkleRoot(); std::vector<uint256> vTxid(nTx, uint256()); for (unsigned int j=0; j<nTx; j++) vTxid[j] = block.vtx[j].GetHash(); diff --git a/src/test/reverselock_tests.cpp b/src/test/reverselock_tests.cpp new file mode 100644 index 0000000000..e7e627ae0f --- /dev/null +++ b/src/test/reverselock_tests.cpp @@ -0,0 +1,64 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "reverselock.h" +#include "test/test_bitcoin.h" + +#include <boost/test/unit_test.hpp> + +BOOST_FIXTURE_TEST_SUITE(reverselock_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(reverselock_basics) +{ + boost::mutex mutex; + boost::unique_lock<boost::mutex> lock(mutex); + + BOOST_CHECK(lock.owns_lock()); + { + reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock); + BOOST_CHECK(!lock.owns_lock()); + } + BOOST_CHECK(lock.owns_lock()); +} + +BOOST_AUTO_TEST_CASE(reverselock_errors) +{ + boost::mutex mutex; + boost::unique_lock<boost::mutex> lock(mutex); + + // Make sure trying to reverse lock an unlocked lock fails + lock.unlock(); + + BOOST_CHECK(!lock.owns_lock()); + + bool failed = false; + try { + reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock); + } catch(...) { + failed = true; + } + + BOOST_CHECK(failed); + BOOST_CHECK(!lock.owns_lock()); + + // Make sure trying to lock a lock after it has been reverse locked fails + failed = false; + bool locked = false; + + lock.lock(); + BOOST_CHECK(lock.owns_lock()); + + try { + reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock); + lock.lock(); + locked = true; + } catch(...) { + failed = true; + } + + BOOST_CHECK(locked && failed); + BOOST_CHECK(lock.owns_lock()); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 7946b02855..1bd59497ff 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -110,6 +110,24 @@ BOOST_AUTO_TEST_CASE(rpc_rawsign) BOOST_CHECK(find_value(r.get_obj(), "complete").get_bool() == true); } +BOOST_AUTO_TEST_CASE(rpc_createraw_op_return) +{ + BOOST_CHECK_NO_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"data\":\"68656c6c6f776f726c64\"}")); + + // Allow more than one data transaction output + BOOST_CHECK_NO_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"data\":\"68656c6c6f776f726c64\",\"data\":\"68656c6c6f776f726c64\"}")); + + // Key not "data" (bad address) + BOOST_CHECK_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"somedata\":\"68656c6c6f776f726c64\"}"), runtime_error); + + // Bad hex encoding of data output + BOOST_CHECK_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"data\":\"12345\"}"), runtime_error); + BOOST_CHECK_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"data\":\"12345g\"}"), runtime_error); + + // Data 81 bytes long + BOOST_CHECK_NO_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"data\":\"010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081\"}")); +} + BOOST_AUTO_TEST_CASE(rpc_format_monetary_values) { BOOST_CHECK(ValueFromAmount(0LL).write() == "0.00000000"); @@ -206,21 +224,6 @@ BOOST_AUTO_TEST_CASE(json_parse_errors) BOOST_CHECK_THROW(ParseNonRFCJSONValue("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNL"), std::runtime_error); } -BOOST_AUTO_TEST_CASE(rpc_boostasiotocnetaddr) -{ - // Check IPv4 addresses - BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("1.2.3.4")).ToString(), "1.2.3.4"); - BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("127.0.0.1")).ToString(), "127.0.0.1"); - // Check IPv6 addresses - BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("::1")).ToString(), "::1"); - BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("123:4567:89ab:cdef:123:4567:89ab:cdef")).ToString(), - "123:4567:89ab:cdef:123:4567:89ab:cdef"); - // v4 compatible must be interpreted as IPv4 - BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("::0:127.0.0.1")).ToString(), "127.0.0.1"); - // v4 mapped must be interpreted as IPv4 - BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("::ffff:127.0.0.1")).ToString(), "127.0.0.1"); -} - BOOST_AUTO_TEST_CASE(rpc_ban) { BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned"))); @@ -232,7 +235,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) UniValue ar = r.get_array(); UniValue o1 = ar[0].get_obj(); UniValue adr = find_value(o1, "address"); - BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/255.255.255.255"); + BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/32"); BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0 remove")));; BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); ar = r.get_array(); @@ -244,7 +247,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) o1 = ar[0].get_obj(); adr = find_value(o1, "address"); UniValue banned_until = find_value(o1, "banned_until"); - BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/255.255.255.0"); + BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/24"); BOOST_CHECK_EQUAL(banned_until.get_int64(), 1607731200); // absolute time check BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned"))); @@ -255,7 +258,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) o1 = ar[0].get_obj(); adr = find_value(o1, "address"); banned_until = find_value(o1, "banned_until"); - BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/255.255.255.0"); + BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/24"); int64_t now = GetTime(); BOOST_CHECK(banned_until.get_int64() > now); BOOST_CHECK(banned_until.get_int64()-now <= 200); @@ -285,15 +288,15 @@ BOOST_AUTO_TEST_CASE(rpc_ban) ar = r.get_array(); o1 = ar[0].get_obj(); adr = find_value(o1, "address"); - BOOST_CHECK_EQUAL(adr.get_str(), "fe80::202:b3ff:fe1e:8329/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); + BOOST_CHECK_EQUAL(adr.get_str(), "fe80::202:b3ff:fe1e:8329/128"); BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned"))); - BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 2001:db8::/30 add"))); + BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 2001:db8::/ffff:fffc:0:0:0:0:0:0 add"))); BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); ar = r.get_array(); o1 = ar[0].get_obj(); adr = find_value(o1, "address"); - BOOST_CHECK_EQUAL(adr.get_str(), "2001:db8::/ffff:fffc:0:0:0:0:0:0"); + BOOST_CHECK_EQUAL(adr.get_str(), "2001:db8::/30"); BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned"))); BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/128 add"))); @@ -301,7 +304,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) ar = r.get_array(); o1 = ar[0].get_obj(); adr = find_value(o1, "address"); - BOOST_CHECK_EQUAL(adr.get_str(), "2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); + BOOST_CHECK_EQUAL(adr.get_str(), "2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/128"); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index 9368963ff2..52f41be8ae 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -27,8 +27,6 @@ BOOST_FIXTURE_TEST_SUITE(rpc_wallet_tests, TestingSetup) BOOST_AUTO_TEST_CASE(rpc_addmultisig) { - LOCK(pwalletMain->cs_wallet); - rpcfn_type addmultisig = tableRPC["addmultisigaddress"]->actor; // old, 65-byte-long: @@ -68,25 +66,28 @@ BOOST_AUTO_TEST_CASE(rpc_wallet) { // Test RPC calls for various wallet statistics UniValue r; - - LOCK2(cs_main, pwalletMain->cs_wallet); - - CPubKey demoPubkey = pwalletMain->GenerateNewKey(); - CBitcoinAddress demoAddress = CBitcoinAddress(CTxDestination(demoPubkey.GetID())); + CPubKey demoPubkey; + CBitcoinAddress demoAddress; UniValue retValue; string strAccount = "walletDemoAccount"; - string strPurpose = "receive"; - BOOST_CHECK_NO_THROW({ /*Initialize Wallet with an account */ - CWalletDB walletdb(pwalletMain->strWalletFile); - CAccount account; - account.vchPubKey = demoPubkey; - pwalletMain->SetAddressBook(account.vchPubKey.GetID(), strAccount, strPurpose); - walletdb.WriteAccount(strAccount, account); - }); - - CPubKey setaccountDemoPubkey = pwalletMain->GenerateNewKey(); - CBitcoinAddress setaccountDemoAddress = CBitcoinAddress(CTxDestination(setaccountDemoPubkey.GetID())); - + CBitcoinAddress setaccountDemoAddress; + { + LOCK(pwalletMain->cs_wallet); + + demoPubkey = pwalletMain->GenerateNewKey(); + demoAddress = CBitcoinAddress(CTxDestination(demoPubkey.GetID())); + string strPurpose = "receive"; + BOOST_CHECK_NO_THROW({ /*Initialize Wallet with an account */ + CWalletDB walletdb(pwalletMain->strWalletFile); + CAccount account; + account.vchPubKey = demoPubkey; + pwalletMain->SetAddressBook(account.vchPubKey.GetID(), strAccount, strPurpose); + walletdb.WriteAccount(strAccount, account); + }); + + CPubKey setaccountDemoPubkey = pwalletMain->GenerateNewKey(); + setaccountDemoAddress = CBitcoinAddress(CTxDestination(setaccountDemoPubkey.GetID())); + } /********************************* * setaccount *********************************/ diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 37c046935f..225da0801a 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -840,7 +840,7 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23); BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); -} +} BOOST_AUTO_TEST_CASE(script_combineSigs) { @@ -983,4 +983,34 @@ BOOST_AUTO_TEST_CASE(script_IsPushOnly_on_invalid_scripts) BOOST_CHECK(!CScript(direct, direct+sizeof(direct)).IsPushOnly()); } +BOOST_AUTO_TEST_CASE(script_GetScriptAsm) +{ + BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_NOP2, true)); + BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY, true)); + BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_NOP2)); + BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY)); + + string derSig("304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090"); + string pubKey("03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2"); + vector<unsigned char> vchPubKey = ToByteVector(ParseHex(pubKey)); + + BOOST_CHECK_EQUAL(derSig + "00 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "00")) << vchPubKey, true)); + BOOST_CHECK_EQUAL(derSig + "80 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "80")) << vchPubKey, true)); + BOOST_CHECK_EQUAL(derSig + "[ALL] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "01")) << vchPubKey, true)); + BOOST_CHECK_EQUAL(derSig + "[NONE] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "02")) << vchPubKey, true)); + BOOST_CHECK_EQUAL(derSig + "[SINGLE] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "03")) << vchPubKey, true)); + BOOST_CHECK_EQUAL(derSig + "[ALL|ANYONECANPAY] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "81")) << vchPubKey, true)); + BOOST_CHECK_EQUAL(derSig + "[NONE|ANYONECANPAY] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "82")) << vchPubKey, true)); + BOOST_CHECK_EQUAL(derSig + "[SINGLE|ANYONECANPAY] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "83")) << vchPubKey, true)); + + BOOST_CHECK_EQUAL(derSig + "00 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "00")) << vchPubKey)); + BOOST_CHECK_EQUAL(derSig + "80 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "80")) << vchPubKey)); + BOOST_CHECK_EQUAL(derSig + "01 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "01")) << vchPubKey)); + BOOST_CHECK_EQUAL(derSig + "02 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "02")) << vchPubKey)); + BOOST_CHECK_EQUAL(derSig + "03 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "03")) << vchPubKey)); + BOOST_CHECK_EQUAL(derSig + "81 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "81")) << vchPubKey)); + BOOST_CHECK_EQUAL(derSig + "82 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "82")) << vchPubKey)); + BOOST_CHECK_EQUAL(derSig + "83 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "83")) << vchPubKey)); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp index 67cb9b9623..ee31c0955b 100644 --- a/src/test/univalue_tests.cpp +++ b/src/test/univalue_tests.cpp @@ -314,6 +314,21 @@ BOOST_AUTO_TEST_CASE(univalue_readwrite) BOOST_CHECK(obj["key3"].isObject()); BOOST_CHECK_EQUAL(strJson1, v.write()); + + /* Check for (correctly reporting) a parsing error if the initial + JSON construct is followed by more stuff. Note that whitespace + is, of course, exempt. */ + + BOOST_CHECK(v.read(" {}\n ")); + BOOST_CHECK(v.isObject()); + BOOST_CHECK(v.read(" []\n ")); + BOOST_CHECK(v.isArray()); + + BOOST_CHECK(!v.read("@{}")); + BOOST_CHECK(!v.read("{} garbage")); + BOOST_CHECK(!v.read("[]{}")); + BOOST_CHECK(!v.read("{}[]")); + BOOST_CHECK(!v.read("{} 42")); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index e956cc5b90..997dc31931 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -413,10 +413,10 @@ BOOST_AUTO_TEST_CASE(test_FormatSubVersion) comments.push_back(std::string("comment1")); std::vector<std::string> comments2; comments2.push_back(std::string("comment1")); - comments2.push_back(std::string("comment2")); + comments2.push_back(SanitizeString(std::string("Comment2; .,_?@-; !\"#$%&'()*+/<=>[]\\^`{|}~"), SAFE_CHARS_UA_COMMENT)); // Semicolon is discouraged but not forbidden by BIP-0014 BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, std::vector<std::string>()),std::string("/Test:0.9.99/")); BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments),std::string("/Test:0.9.99(comment1)/")); - BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments2),std::string("/Test:0.9.99(comment1; comment2)/")); + BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments2),std::string("/Test:0.9.99(comment1; Comment2; .,_?@-; )/")); } BOOST_AUTO_TEST_CASE(test_ParseFixedPoint) diff --git a/src/timedata.cpp b/src/timedata.cpp index c3e9c75f6e..0641009537 100644 --- a/src/timedata.cpp +++ b/src/timedata.cpp @@ -40,16 +40,20 @@ static int64_t abs64(int64_t n) return (n >= 0 ? n : -n); } +#define BITCOIN_TIMEDATA_MAX_SAMPLES 200 + void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample) { LOCK(cs_nTimeOffset); // Ignore duplicates static set<CNetAddr> setKnown; + if (setKnown.size() == BITCOIN_TIMEDATA_MAX_SAMPLES) + return; if (!setKnown.insert(ip).second) return; // Add data - static CMedianFilter<int64_t> vTimeOffsets(200,0); + static CMedianFilter<int64_t> vTimeOffsets(BITCOIN_TIMEDATA_MAX_SAMPLES, 0); vTimeOffsets.input(nOffsetSample); LogPrintf("Added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60); @@ -95,9 +99,8 @@ void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample) if (!fMatch) { fDone = true; - string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly."); + string strMessage = _("Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly."); strMiscWarning = strMessage; - LogPrintf("*** %s\n", strMessage); uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING); } } diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 5bc06e5056..1370cab0c0 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -17,12 +17,6 @@ using namespace std; -CTxMemPoolEntry::CTxMemPoolEntry(): - nFee(0), nTxSize(0), nModSize(0), nUsageSize(0), nTime(0), dPriority(0.0), hadNoDependencies(false) -{ - nHeight = MEMPOOL_HEIGHT; -} - CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, int64_t _nTime, double _dPriority, unsigned int _nHeight, bool poolHasNoInputsOf): @@ -32,6 +26,10 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); nModSize = tx.CalculateModifiedSize(nTxSize); nUsageSize = RecursiveDynamicUsage(tx); + + nCountWithDescendants = 1; + nSizeWithDescendants = nTxSize; + nFeesWithDescendants = nFee; } CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other) @@ -48,6 +46,265 @@ CTxMemPoolEntry::GetPriority(unsigned int currentHeight) const return dResult; } +// Update the given tx for any in-mempool descendants. +// Assumes that setMemPoolChildren is correct for the given tx and all +// descendants. +bool CTxMemPool::UpdateForDescendants(txiter updateIt, int maxDescendantsToVisit, cacheMap &cachedDescendants, const std::set<uint256> &setExclude) +{ + // Track the number of entries (outside setExclude) that we'd need to visit + // (will bail out if it exceeds maxDescendantsToVisit) + int nChildrenToVisit = 0; + + setEntries stageEntries, setAllDescendants; + stageEntries = GetMemPoolChildren(updateIt); + + while (!stageEntries.empty()) { + const txiter cit = *stageEntries.begin(); + if (cit->IsDirty()) { + // Don't consider any more children if any descendant is dirty + return false; + } + setAllDescendants.insert(cit); + stageEntries.erase(cit); + const setEntries &setChildren = GetMemPoolChildren(cit); + BOOST_FOREACH(const txiter childEntry, setChildren) { + cacheMap::iterator cacheIt = cachedDescendants.find(childEntry); + if (cacheIt != cachedDescendants.end()) { + // We've already calculated this one, just add the entries for this set + // but don't traverse again. + BOOST_FOREACH(const txiter cacheEntry, cacheIt->second) { + // update visit count only for new child transactions + // (outside of setExclude and stageEntries) + if (setAllDescendants.insert(cacheEntry).second && + !setExclude.count(cacheEntry->GetTx().GetHash()) && + !stageEntries.count(cacheEntry)) { + nChildrenToVisit++; + } + } + } else if (!setAllDescendants.count(childEntry)) { + // Schedule for later processing and update our visit count + if (stageEntries.insert(childEntry).second && !setExclude.count(childEntry->GetTx().GetHash())) { + nChildrenToVisit++; + } + } + if (nChildrenToVisit > maxDescendantsToVisit) { + return false; + } + } + } + // setAllDescendants now contains all in-mempool descendants of updateIt. + // Update and add to cached descendant map + int64_t modifySize = 0; + CAmount modifyFee = 0; + int64_t modifyCount = 0; + BOOST_FOREACH(txiter cit, setAllDescendants) { + if (!setExclude.count(cit->GetTx().GetHash())) { + modifySize += cit->GetTxSize(); + modifyFee += cit->GetFee(); + modifyCount++; + cachedDescendants[updateIt].insert(cit); + } + } + mapTx.modify(updateIt, update_descendant_state(modifySize, modifyFee, modifyCount)); + return true; +} + +// vHashesToUpdate is the set of transaction hashes from a disconnected block +// which has been re-added to the mempool. +// for each entry, look for descendants that are outside hashesToUpdate, and +// add fee/size information for such descendants to the parent. +void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<uint256> &vHashesToUpdate) +{ + LOCK(cs); + // For each entry in vHashesToUpdate, store the set of in-mempool, but not + // in-vHashesToUpdate transactions, so that we don't have to recalculate + // descendants when we come across a previously seen entry. + cacheMap mapMemPoolDescendantsToUpdate; + + // Use a set for lookups into vHashesToUpdate (these entries are already + // accounted for in the state of their ancestors) + std::set<uint256> setAlreadyIncluded(vHashesToUpdate.begin(), vHashesToUpdate.end()); + + // Iterate in reverse, so that whenever we are looking at at a transaction + // we are sure that all in-mempool descendants have already been processed. + // This maximizes the benefit of the descendant cache and guarantees that + // setMemPoolChildren will be updated, an assumption made in + // UpdateForDescendants. + BOOST_REVERSE_FOREACH(const uint256 &hash, vHashesToUpdate) { + // we cache the in-mempool children to avoid duplicate updates + setEntries setChildren; + // calculate children from mapNextTx + txiter it = mapTx.find(hash); + if (it == mapTx.end()) { + continue; + } + std::map<COutPoint, CInPoint>::iterator iter = mapNextTx.lower_bound(COutPoint(hash, 0)); + // First calculate the children, and update setMemPoolChildren to + // include them, and update their setMemPoolParents to include this tx. + for (; iter != mapNextTx.end() && iter->first.hash == hash; ++iter) { + const uint256 &childHash = iter->second.ptx->GetHash(); + txiter childIter = mapTx.find(childHash); + assert(childIter != mapTx.end()); + // We can skip updating entries we've encountered before or that + // are in the block (which are already accounted for). + if (setChildren.insert(childIter).second && !setAlreadyIncluded.count(childHash)) { + UpdateChild(it, childIter, true); + UpdateParent(childIter, it, true); + } + } + if (!UpdateForDescendants(it, 100, mapMemPoolDescendantsToUpdate, setAlreadyIncluded)) { + // Mark as dirty if we can't do the calculation. + mapTx.modify(it, set_dirty()); + } + } +} + +bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents /* = true */) +{ + setEntries parentHashes; + const CTransaction &tx = entry.GetTx(); + + if (fSearchForParents) { + // Get parents of this transaction that are in the mempool + // GetMemPoolParents() is only valid for entries in the mempool, so we + // iterate mapTx to find parents. + for (unsigned int i = 0; i < tx.vin.size(); i++) { + txiter piter = mapTx.find(tx.vin[i].prevout.hash); + if (piter != mapTx.end()) { + parentHashes.insert(piter); + if (parentHashes.size() + 1 > limitAncestorCount) { + errString = strprintf("too many unconfirmed parents [limit: %u]", limitAncestorCount); + return false; + } + } + } + } else { + // If we're not searching for parents, we require this to be an + // entry in the mempool already. + txiter it = mapTx.iterator_to(entry); + parentHashes = GetMemPoolParents(it); + } + + size_t totalSizeWithAncestors = entry.GetTxSize(); + + while (!parentHashes.empty()) { + txiter stageit = *parentHashes.begin(); + + setAncestors.insert(stageit); + parentHashes.erase(stageit); + totalSizeWithAncestors += stageit->GetTxSize(); + + if (stageit->GetSizeWithDescendants() + entry.GetTxSize() > limitDescendantSize) { + errString = strprintf("exceeds descendant size limit for tx %s [limit: %u]", stageit->GetTx().GetHash().ToString(), limitDescendantSize); + return false; + } else if (stageit->GetCountWithDescendants() + 1 > limitDescendantCount) { + errString = strprintf("too many descendants for tx %s [limit: %u]", stageit->GetTx().GetHash().ToString(), limitDescendantCount); + return false; + } else if (totalSizeWithAncestors > limitAncestorSize) { + errString = strprintf("exceeds ancestor size limit [limit: %u]", limitAncestorSize); + return false; + } + + const setEntries & setMemPoolParents = GetMemPoolParents(stageit); + BOOST_FOREACH(const txiter &phash, setMemPoolParents) { + // If this is a new ancestor, add it. + if (setAncestors.count(phash) == 0) { + parentHashes.insert(phash); + } + if (parentHashes.size() + setAncestors.size() + 1 > limitAncestorCount) { + errString = strprintf("too many unconfirmed ancestors [limit: %u]", limitAncestorCount); + return false; + } + } + } + + return true; +} + +void CTxMemPool::UpdateAncestorsOf(bool add, txiter it, setEntries &setAncestors) +{ + setEntries parentIters = GetMemPoolParents(it); + // add or remove this tx as a child of each parent + BOOST_FOREACH(txiter piter, parentIters) { + UpdateChild(piter, it, add); + } + const int64_t updateCount = (add ? 1 : -1); + const int64_t updateSize = updateCount * it->GetTxSize(); + const CAmount updateFee = updateCount * it->GetFee(); + BOOST_FOREACH(txiter ancestorIt, setAncestors) { + mapTx.modify(ancestorIt, update_descendant_state(updateSize, updateFee, updateCount)); + } +} + +void CTxMemPool::UpdateChildrenForRemoval(txiter it) +{ + const setEntries &setMemPoolChildren = GetMemPoolChildren(it); + BOOST_FOREACH(txiter updateIt, setMemPoolChildren) { + UpdateParent(updateIt, it, false); + } +} + +void CTxMemPool::UpdateForRemoveFromMempool(const setEntries &entriesToRemove) +{ + // For each entry, walk back all ancestors and decrement size associated with this + // transaction + const uint64_t nNoLimit = std::numeric_limits<uint64_t>::max(); + BOOST_FOREACH(txiter removeIt, entriesToRemove) { + setEntries setAncestors; + const CTxMemPoolEntry &entry = *removeIt; + std::string dummy; + // Since this is a tx that is already in the mempool, we can call CMPA + // with fSearchForParents = false. If the mempool is in a consistent + // state, then using true or false should both be correct, though false + // should be a bit faster. + // However, if we happen to be in the middle of processing a reorg, then + // the mempool can be in an inconsistent state. In this case, the set + // of ancestors reachable via mapLinks will be the same as the set of + // ancestors whose packages include this transaction, because when we + // add a new transaction to the mempool in addUnchecked(), we assume it + // has no children, and in the case of a reorg where that assumption is + // false, the in-mempool children aren't linked to the in-block tx's + // until UpdateTransactionsFromBlock() is called. + // So if we're being called during a reorg, ie before + // UpdateTransactionsFromBlock() has been called, then mapLinks[] will + // differ from the set of mempool parents we'd calculate by searching, + // and it's important that we use the mapLinks[] notion of ancestor + // transactions as the set of things to update for removal. + CalculateMemPoolAncestors(entry, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy, false); + // Note that UpdateAncestorsOf severs the child links that point to + // removeIt in the entries for the parents of removeIt. This is + // fine since we don't need to use the mempool children of any entries + // to walk back over our ancestors (but we do need the mempool + // parents!) + UpdateAncestorsOf(false, removeIt, setAncestors); + } + // After updating all the ancestor sizes, we can now sever the link between each + // transaction being removed and any mempool children (ie, update setMemPoolParents + // for each direct child of a transaction being removed). + BOOST_FOREACH(txiter removeIt, entriesToRemove) { + UpdateChildrenForRemoval(removeIt); + } +} + +void CTxMemPoolEntry::SetDirty() +{ + nCountWithDescendants = 0; + nSizeWithDescendants = nTxSize; + nFeesWithDescendants = nFee; +} + +void CTxMemPoolEntry::UpdateState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount) +{ + if (!IsDirty()) { + nSizeWithDescendants += modifySize; + assert(int64_t(nSizeWithDescendants) > 0); + nFeesWithDescendants += modifyFee; + assert(nFeesWithDescendants >= 0); + nCountWithDescendants += modifyCount; + assert(int64_t(nCountWithDescendants) > 0); + } +} + CTxMemPool::CTxMemPool(const CFeeRate& _minRelayFee) : nTransactionsUpdated(0) { @@ -89,34 +346,103 @@ void CTxMemPool::AddTransactionsUpdated(unsigned int n) nTransactionsUpdated += n; } - -bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate) +bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool fCurrentEstimate) { // Add to memory pool without checking anything. // Used by main.cpp AcceptToMemoryPool(), which DOES do // all the appropriate checks. LOCK(cs); - mapTx[hash] = entry; - const CTransaction& tx = mapTx[hash].GetTx(); - for (unsigned int i = 0; i < tx.vin.size(); i++) + indexed_transaction_set::iterator newit = mapTx.insert(entry).first; + mapLinks.insert(make_pair(newit, TxLinks())); + + // Update cachedInnerUsage to include contained transaction's usage. + // (When we update the entry for in-mempool parents, memory usage will be + // further updated.) + cachedInnerUsage += entry.DynamicMemoryUsage(); + + const CTransaction& tx = newit->GetTx(); + std::set<uint256> setParentTransactions; + for (unsigned int i = 0; i < tx.vin.size(); i++) { mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i); + setParentTransactions.insert(tx.vin[i].prevout.hash); + } + // Don't bother worrying about child transactions of this one. + // Normal case of a new transaction arriving is that there can't be any + // children, because such children would be orphans. + // An exception to that is if a transaction enters that used to be in a block. + // In that case, our disconnect block logic will call UpdateTransactionsFromBlock + // to clean up the mess we're leaving here. + + // Update ancestors with information about this tx + BOOST_FOREACH (const uint256 &phash, setParentTransactions) { + txiter pit = mapTx.find(phash); + if (pit != mapTx.end()) { + UpdateParent(newit, pit, true); + } + } + UpdateAncestorsOf(true, newit, setAncestors); + nTransactionsUpdated++; totalTxSize += entry.GetTxSize(); - cachedInnerUsage += entry.DynamicMemoryUsage(); minerPolicyEstimator->processTransaction(entry, fCurrentEstimate); return true; } +void CTxMemPool::removeUnchecked(txiter it) +{ + const uint256 hash = it->GetTx().GetHash(); + BOOST_FOREACH(const CTxIn& txin, it->GetTx().vin) + mapNextTx.erase(txin.prevout); + + totalTxSize -= it->GetTxSize(); + cachedInnerUsage -= it->DynamicMemoryUsage(); + cachedInnerUsage -= memusage::DynamicUsage(mapLinks[it].parents) + memusage::DynamicUsage(mapLinks[it].children); + mapLinks.erase(it); + mapTx.erase(it); + nTransactionsUpdated++; + minerPolicyEstimator->removeTx(hash); +} + +// Calculates descendants of entry that are not already in setDescendants, and adds to +// setDescendants. Assumes entryit is already a tx in the mempool and setMemPoolChildren +// is correct for tx and all descendants. +// Also assumes that if an entry is in setDescendants already, then all +// in-mempool descendants of it are already in setDescendants as well, so that we +// can save time by not iterating over those entries. +void CTxMemPool::CalculateDescendants(txiter entryit, setEntries &setDescendants) +{ + setEntries stage; + if (setDescendants.count(entryit) == 0) { + stage.insert(entryit); + } + // Traverse down the children of entry, only adding children that are not + // accounted for in setDescendants already (because those children have either + // already been walked, or will be walked in this iteration). + while (!stage.empty()) { + txiter it = *stage.begin(); + setDescendants.insert(it); + stage.erase(it); + + const setEntries &setChildren = GetMemPoolChildren(it); + BOOST_FOREACH(const txiter &childiter, setChildren) { + if (!setDescendants.count(childiter)) { + stage.insert(childiter); + } + } + } +} void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& removed, bool fRecursive) { // Remove transaction from memory pool { LOCK(cs); - std::deque<uint256> txToRemove; - txToRemove.push_back(origTx.GetHash()); - if (fRecursive && !mapTx.count(origTx.GetHash())) { + setEntries txToRemove; + txiter origit = mapTx.find(origTx.GetHash()); + if (origit != mapTx.end()) { + txToRemove.insert(origit); + } else if (fRecursive) { // If recursively removing but origTx isn't in the mempool // be sure to remove any children that are in the pool. This can // happen during chain re-orgs if origTx isn't re-accepted into @@ -125,34 +451,23 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& rem std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(origTx.GetHash(), i)); if (it == mapNextTx.end()) continue; - txToRemove.push_back(it->second.ptx->GetHash()); + txiter nextit = mapTx.find(it->second.ptx->GetHash()); + assert(nextit != mapTx.end()); + txToRemove.insert(nextit); } } - while (!txToRemove.empty()) - { - uint256 hash = txToRemove.front(); - txToRemove.pop_front(); - if (!mapTx.count(hash)) - continue; - const CTransaction& tx = mapTx[hash].GetTx(); - if (fRecursive) { - for (unsigned int i = 0; i < tx.vout.size(); i++) { - std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(hash, i)); - if (it == mapNextTx.end()) - continue; - txToRemove.push_back(it->second.ptx->GetHash()); - } + setEntries setAllRemoves; + if (fRecursive) { + BOOST_FOREACH(txiter it, txToRemove) { + CalculateDescendants(it, setAllRemoves); } - BOOST_FOREACH(const CTxIn& txin, tx.vin) - mapNextTx.erase(txin.prevout); - - removed.push_back(tx); - totalTxSize -= mapTx[hash].GetTxSize(); - cachedInnerUsage -= mapTx[hash].DynamicMemoryUsage(); - mapTx.erase(hash); - nTransactionsUpdated++; - minerPolicyEstimator->removeTx(hash); + } else { + setAllRemoves.swap(txToRemove); } + BOOST_FOREACH(txiter it, setAllRemoves) { + removed.push_back(it->GetTx()); + } + RemoveStaged(setAllRemoves); } } @@ -161,10 +476,10 @@ void CTxMemPool::removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned in // Remove transactions spending a coinbase which are now immature LOCK(cs); list<CTransaction> transactionsToRemove; - for (std::map<uint256, CTxMemPoolEntry>::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { - const CTransaction& tx = it->second.GetTx(); + for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { + const CTransaction& tx = it->GetTx(); BOOST_FOREACH(const CTxIn& txin, tx.vin) { - std::map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(txin.prevout.hash); + indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash); if (it2 != mapTx.end()) continue; const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash); @@ -209,8 +524,10 @@ void CTxMemPool::removeForBlock(const std::vector<CTransaction>& vtx, unsigned i BOOST_FOREACH(const CTransaction& tx, vtx) { uint256 hash = tx.GetHash(); - if (mapTx.count(hash)) - entries.push_back(mapTx[hash]); + + indexed_transaction_set::iterator i = mapTx.find(hash); + if (i != mapTx.end()) + entries.push_back(*i); } BOOST_FOREACH(const CTransaction& tx, vtx) { @@ -226,6 +543,7 @@ void CTxMemPool::removeForBlock(const std::vector<CTransaction>& vtx, unsigned i void CTxMemPool::clear() { LOCK(cs); + mapLinks.clear(); mapTx.clear(); mapNextTx.clear(); totalTxSize = 0; @@ -247,19 +565,25 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const LOCK(cs); list<const CTxMemPoolEntry*> waitingOnDependants; - for (std::map<uint256, CTxMemPoolEntry>::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { + for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { unsigned int i = 0; - checkTotal += it->second.GetTxSize(); - innerUsage += it->second.DynamicMemoryUsage(); - const CTransaction& tx = it->second.GetTx(); + checkTotal += it->GetTxSize(); + innerUsage += it->DynamicMemoryUsage(); + const CTransaction& tx = it->GetTx(); + txlinksMap::const_iterator linksiter = mapLinks.find(it); + assert(linksiter != mapLinks.end()); + const TxLinks &links = linksiter->second; + innerUsage += memusage::DynamicUsage(links.parents) + memusage::DynamicUsage(links.children); bool fDependsWait = false; + setEntries setParentCheck; BOOST_FOREACH(const CTxIn &txin, tx.vin) { // Check that every mempool transaction's inputs refer to available coins, or other mempool tx's. - std::map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(txin.prevout.hash); + indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash); if (it2 != mapTx.end()) { - const CTransaction& tx2 = it2->second.GetTx(); + const CTransaction& tx2 = it2->GetTx(); assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull()); fDependsWait = true; + setParentCheck.insert(it2); } else { const CCoins* coins = pcoins->AccessCoins(txin.prevout.hash); assert(coins && coins->IsAvailable(txin.prevout.n)); @@ -271,8 +595,35 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const assert(it3->second.n == i); i++; } + assert(setParentCheck == GetMemPoolParents(it)); + // Check children against mapNextTx + CTxMemPool::setEntries setChildrenCheck; + std::map<COutPoint, CInPoint>::const_iterator iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetHash(), 0)); + int64_t childSizes = 0; + CAmount childFees = 0; + for (; iter != mapNextTx.end() && iter->first.hash == it->GetTx().GetHash(); ++iter) { + txiter childit = mapTx.find(iter->second.ptx->GetHash()); + assert(childit != mapTx.end()); // mapNextTx points to in-mempool transactions + if (setChildrenCheck.insert(childit).second) { + childSizes += childit->GetTxSize(); + childFees += childit->GetFee(); + } + } + assert(setChildrenCheck == GetMemPoolChildren(it)); + // Also check to make sure size/fees is greater than sum with immediate children. + // just a sanity check, not definitive that this calc is correct... + // also check that the size is less than the size of the entire mempool. + if (!it->IsDirty()) { + assert(it->GetSizeWithDescendants() >= childSizes + it->GetTxSize()); + assert(it->GetFeesWithDescendants() >= childFees + it->GetFee()); + } else { + assert(it->GetSizeWithDescendants() == it->GetTxSize()); + assert(it->GetFeesWithDescendants() == it->GetFee()); + } + assert(it->GetFeesWithDescendants() >= 0); + if (fDependsWait) - waitingOnDependants.push_back(&it->second); + waitingOnDependants.push_back(&(*it)); else { CValidationState state; assert(CheckInputs(tx, state, mempoolDuplicate, false, 0, false, NULL)); @@ -296,8 +647,8 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const } for (std::map<COutPoint, CInPoint>::const_iterator it = mapNextTx.begin(); it != mapNextTx.end(); it++) { uint256 hash = it->second.ptx->GetHash(); - map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(hash); - const CTransaction& tx = it2->second.GetTx(); + indexed_transaction_set::const_iterator it2 = mapTx.find(hash); + const CTransaction& tx = it2->GetTx(); assert(it2 != mapTx.end()); assert(&tx == it->second.ptx); assert(tx.vin.size() > it->second.n); @@ -314,16 +665,16 @@ void CTxMemPool::queryHashes(vector<uint256>& vtxid) LOCK(cs); vtxid.reserve(mapTx.size()); - for (map<uint256, CTxMemPoolEntry>::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) - vtxid.push_back((*mi).first); + for (indexed_transaction_set::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) + vtxid.push_back(mi->GetTx().GetHash()); } bool CTxMemPool::lookup(uint256 hash, CTransaction& result) const { LOCK(cs); - map<uint256, CTxMemPoolEntry>::const_iterator i = mapTx.find(hash); + indexed_transaction_set::const_iterator i = mapTx.find(hash); if (i == mapTx.end()) return false; - result = i->second.GetTx(); + result = i->GetTx(); return true; } @@ -348,7 +699,7 @@ CTxMemPool::WriteFeeEstimates(CAutoFile& fileout) const minerPolicyEstimator->Write(fileout); } catch (const std::exception&) { - LogPrintf("CTxMemPool::WriteFeeEstimates(): unable to write policy estimator data (non-fatal)"); + LogPrintf("CTxMemPool::WriteFeeEstimates(): unable to write policy estimator data (non-fatal)\n"); return false; } return true; @@ -367,7 +718,7 @@ CTxMemPool::ReadFeeEstimates(CAutoFile& filein) minerPolicyEstimator->Read(filein); } catch (const std::exception&) { - LogPrintf("CTxMemPool::ReadFeeEstimates(): unable to read policy estimator data (non-fatal)"); + LogPrintf("CTxMemPool::ReadFeeEstimates(): unable to read policy estimator data (non-fatal)\n"); return false; } return true; @@ -429,5 +780,60 @@ bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) const { size_t CTxMemPool::DynamicMemoryUsage() const { LOCK(cs); - return memusage::DynamicUsage(mapTx) + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + cachedInnerUsage; + // Estimate the overhead of mapTx to be 9 pointers + an allocation, as no exact formula for boost::multi_index_contained is implemented. + return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 9 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(mapLinks) + cachedInnerUsage; +} + +void CTxMemPool::RemoveStaged(setEntries &stage) { + AssertLockHeld(cs); + UpdateForRemoveFromMempool(stage); + BOOST_FOREACH(const txiter& it, stage) { + removeUnchecked(it); + } +} + +bool CTxMemPool::addUnchecked(const uint256&hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate) +{ + LOCK(cs); + setEntries setAncestors; + uint64_t nNoLimit = std::numeric_limits<uint64_t>::max(); + std::string dummy; + CalculateMemPoolAncestors(entry, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy); + return addUnchecked(hash, entry, setAncestors, fCurrentEstimate); +} + +void CTxMemPool::UpdateChild(txiter entry, txiter child, bool add) +{ + setEntries s; + if (add && mapLinks[entry].children.insert(child).second) { + cachedInnerUsage += memusage::IncrementalDynamicUsage(s); + } else if (!add && mapLinks[entry].children.erase(child)) { + cachedInnerUsage -= memusage::IncrementalDynamicUsage(s); + } +} + +void CTxMemPool::UpdateParent(txiter entry, txiter parent, bool add) +{ + setEntries s; + if (add && mapLinks[entry].parents.insert(parent).second) { + cachedInnerUsage += memusage::IncrementalDynamicUsage(s); + } else if (!add && mapLinks[entry].parents.erase(parent)) { + cachedInnerUsage -= memusage::IncrementalDynamicUsage(s); + } +} + +const CTxMemPool::setEntries & CTxMemPool::GetMemPoolParents(txiter entry) const +{ + assert (entry != mapTx.end()); + txlinksMap::const_iterator it = mapLinks.find(entry); + assert(it != mapLinks.end()); + return it->second.parents; +} + +const CTxMemPool::setEntries & CTxMemPool::GetMemPoolChildren(txiter entry) const +{ + assert (entry != mapTx.end()); + txlinksMap::const_iterator it = mapLinks.find(entry); + assert(it != mapLinks.end()); + return it->second.children; } diff --git a/src/txmempool.h b/src/txmempool.h index ea36ce1ad5..c0eef0dd22 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -7,12 +7,17 @@ #define BITCOIN_TXMEMPOOL_H #include <list> +#include <set> #include "amount.h" #include "coins.h" #include "primitives/transaction.h" #include "sync.h" +#undef foreach +#include "boost/multi_index_container.hpp" +#include "boost/multi_index/ordered_index.hpp" + class CAutoFile; inline double AllowFreeThreshold() @@ -30,9 +35,25 @@ inline bool AllowFree(double dPriority) /** Fake height value used in CCoins to signify they are only in the memory pool (since 0.8) */ static const unsigned int MEMPOOL_HEIGHT = 0x7FFFFFFF; -/** - * CTxMemPool stores these: +class CTxMemPool; + +/** \class CTxMemPoolEntry + * + * CTxMemPoolEntry stores data about the correponding transaction, as well + * as data about all in-mempool transactions that depend on the transaction + * ("descendant" transactions). + * + * When a new entry is added to the mempool, we update the descendant state + * (nCountWithDescendants, nSizeWithDescendants, and nFeesWithDescendants) for + * all ancestors of the newly added transaction. + * + * If updating the descendant state is skipped, we can mark the entry as + * "dirty", and set nSizeWithDescendants/nFeesWithDescendants to equal nTxSize/ + * nTxFee. (This can potentially happen during a reorg, where we limit the + * amount of work we're willing to do to avoid consuming too much CPU.) + * */ + class CTxMemPoolEntry { private: @@ -46,10 +67,18 @@ private: unsigned int nHeight; //! Chain height when entering the mempool bool hadNoDependencies; //! Not dependent on any other txs when it entered the mempool + // Information about descendants of this transaction that are in the + // mempool; if we remove this transaction we must remove all of these + // descendants as well. if nCountWithDescendants is 0, treat this entry as + // dirty, and nSizeWithDescendants and nFeesWithDescendants will not be + // correct. + uint64_t nCountWithDescendants; //! number of descendant transactions + uint64_t nSizeWithDescendants; //! ... and size + CAmount nFeesWithDescendants; //! ... and total fees (all including us) + public: CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, int64_t _nTime, double _dPriority, unsigned int _nHeight, bool poolHasNoInputsOf = false); - CTxMemPoolEntry(); CTxMemPoolEntry(const CTxMemPoolEntry& other); const CTransaction& GetTx() const { return this->tx; } @@ -60,6 +89,98 @@ public: unsigned int GetHeight() const { return nHeight; } bool WasClearAtEntry() const { return hadNoDependencies; } size_t DynamicMemoryUsage() const { return nUsageSize; } + + // Adjusts the descendant state, if this entry is not dirty. + void UpdateState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount); + + /** We can set the entry to be dirty if doing the full calculation of in- + * mempool descendants will be too expensive, which can potentially happen + * when re-adding transactions from a block back to the mempool. + */ + void SetDirty(); + bool IsDirty() const { return nCountWithDescendants == 0; } + + uint64_t GetCountWithDescendants() const { return nCountWithDescendants; } + uint64_t GetSizeWithDescendants() const { return nSizeWithDescendants; } + CAmount GetFeesWithDescendants() const { return nFeesWithDescendants; } +}; + +// Helpers for modifying CTxMemPool::mapTx, which is a boost multi_index. +struct update_descendant_state +{ + update_descendant_state(int64_t _modifySize, CAmount _modifyFee, int64_t _modifyCount) : + modifySize(_modifySize), modifyFee(_modifyFee), modifyCount(_modifyCount) + {} + + void operator() (CTxMemPoolEntry &e) + { e.UpdateState(modifySize, modifyFee, modifyCount); } + + private: + int64_t modifySize; + CAmount modifyFee; + int64_t modifyCount; +}; + +struct set_dirty +{ + void operator() (CTxMemPoolEntry &e) + { e.SetDirty(); } +}; + +// extracts a TxMemPoolEntry's transaction hash +struct mempoolentry_txid +{ + typedef uint256 result_type; + result_type operator() (const CTxMemPoolEntry &entry) const + { + return entry.GetTx().GetHash(); + } +}; + +/** \class CompareTxMemPoolEntryByFee + * + * Sort an entry by max(feerate of entry's tx, feerate with all descendants). + */ +class CompareTxMemPoolEntryByFee +{ +public: + bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) + { + bool fUseADescendants = UseDescendantFeeRate(a); + bool fUseBDescendants = UseDescendantFeeRate(b); + + double aFees = fUseADescendants ? a.GetFeesWithDescendants() : a.GetFee(); + double aSize = fUseADescendants ? a.GetSizeWithDescendants() : a.GetTxSize(); + + double bFees = fUseBDescendants ? b.GetFeesWithDescendants() : b.GetFee(); + double bSize = fUseBDescendants ? b.GetSizeWithDescendants() : b.GetTxSize(); + + // Avoid division by rewriting (a/b > c/d) as (a*d > c*b). + double f1 = aFees * bSize; + double f2 = aSize * bFees; + + if (f1 == f2) { + return a.GetTime() < b.GetTime(); + } + return f1 > f2; + } + + // Calculate which feerate to use for an entry (avoiding division). + bool UseDescendantFeeRate(const CTxMemPoolEntry &a) + { + double f1 = (double)a.GetFee() * a.GetSizeWithDescendants(); + double f2 = (double)a.GetFeesWithDescendants() * a.GetTxSize(); + return f2 > f1; + } +}; + +class CompareTxMemPoolEntryByEntryTime +{ +public: + bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) + { + return a.GetTime() < b.GetTime(); + } }; class CBlockPolicyEstimator; @@ -87,6 +208,71 @@ public: * are added to the pool: if a new transaction double-spends * an input of a transaction in the pool, it is dropped, * as are non-standard transactions. + * + * CTxMemPool::mapTx, and CTxMemPoolEntry bookkeeping: + * + * mapTx is a boost::multi_index that sorts the mempool on 2 criteria: + * - transaction hash + * - feerate [we use max(feerate of tx, feerate of tx with all descendants)] + * + * Note: the term "descendant" refers to in-mempool transactions that depend on + * this one, while "ancestor" refers to in-mempool transactions that a given + * transaction depends on. + * + * In order for the feerate sort to remain correct, we must update transactions + * in the mempool when new descendants arrive. To facilitate this, we track + * the set of in-mempool direct parents and direct children in mapLinks. Within + * each CTxMemPoolEntry, we track the size and fees of all descendants. + * + * Usually when a new transaction is added to the mempool, it has no in-mempool + * children (because any such children would be an orphan). So in + * addUnchecked(), we: + * - update a new entry's setMemPoolParents to include all in-mempool parents + * - update the new entry's direct parents to include the new tx as a child + * - update all ancestors of the transaction to include the new tx's size/fee + * + * When a transaction is removed from the mempool, we must: + * - update all in-mempool parents to not track the tx in setMemPoolChildren + * - update all ancestors to not include the tx's size/fees in descendant state + * - update all in-mempool children to not include it as a parent + * + * These happen in UpdateForRemoveFromMempool(). (Note that when removing a + * transaction along with its descendants, we must calculate that set of + * transactions to be removed before doing the removal, or else the mempool can + * be in an inconsistent state where it's impossible to walk the ancestors of + * a transaction.) + * + * In the event of a reorg, the assumption that a newly added tx has no + * in-mempool children is false. In particular, the mempool is in an + * inconsistent state while new transactions are being added, because there may + * be descendant transactions of a tx coming from a disconnected block that are + * unreachable from just looking at transactions in the mempool (the linking + * transactions may also be in the disconnected block, waiting to be added). + * Because of this, there's not much benefit in trying to search for in-mempool + * children in addUnchecked(). Instead, in the special case of transactions + * being added from a disconnected block, we require the caller to clean up the + * state, to account for in-mempool, out-of-block descendants for all the + * in-block transactions by calling UpdateTransactionsFromBlock(). Note that + * until this is called, the mempool state is not consistent, and in particular + * mapLinks may not be correct (and therefore functions like + * CalculateMemPoolAncestors() and CalculateDescendants() that rely + * on them to walk the mempool are not generally safe to use). + * + * Computational limits: + * + * Updating all in-mempool ancestors of a newly added transaction can be slow, + * if no bound exists on how many in-mempool ancestors there may be. + * CalculateMemPoolAncestors() takes configurable limits that are designed to + * prevent these calculations from being too CPU intensive. + * + * Adding transactions from a disconnected block can be very time consuming, + * because we don't have a way to limit the number of in-mempool descendants. + * To bound CPU processing, we limit the amount of work we're willing to do + * to properly update the descendant information for a tx being added from + * a disconnected block. If we would exceed the limit, then we instead mark + * the entry as "dirty", and set the feerate for sorting purposes to be equal + * the feerate of the transaction without any descendants. + * */ class CTxMemPool { @@ -99,8 +285,46 @@ private: uint64_t cachedInnerUsage; //! sum of dynamic memory usage of all the map elements (NOT the maps themselves) public: + typedef boost::multi_index_container< + CTxMemPoolEntry, + boost::multi_index::indexed_by< + // sorted by txid + boost::multi_index::ordered_unique<mempoolentry_txid>, + // sorted by fee rate + boost::multi_index::ordered_non_unique< + boost::multi_index::identity<CTxMemPoolEntry>, + CompareTxMemPoolEntryByFee + > + > + > indexed_transaction_set; + mutable CCriticalSection cs; - std::map<uint256, CTxMemPoolEntry> mapTx; + indexed_transaction_set mapTx; + typedef indexed_transaction_set::nth_index<0>::type::iterator txiter; + struct CompareIteratorByHash { + bool operator()(const txiter &a, const txiter &b) const { + return a->GetTx().GetHash() < b->GetTx().GetHash(); + } + }; + typedef std::set<txiter, CompareIteratorByHash> setEntries; + +private: + typedef std::map<txiter, setEntries, CompareIteratorByHash> cacheMap; + + struct TxLinks { + setEntries parents; + setEntries children; + }; + + typedef std::map<txiter, TxLinks, CompareIteratorByHash> txlinksMap; + txlinksMap mapLinks; + + const setEntries & GetMemPoolParents(txiter entry) const; + const setEntries & GetMemPoolChildren(txiter entry) const; + void UpdateParent(txiter entry, txiter parent, bool add); + void UpdateChild(txiter entry, txiter child, bool add); + +public: std::map<COutPoint, CInPoint> mapNextTx; std::map<uint256, std::pair<double, CAmount> > mapDeltas; @@ -116,7 +340,13 @@ public: void check(const CCoinsViewCache *pcoins) const; void setSanityCheck(bool _fSanityCheck) { fSanityCheck = _fSanityCheck; } + // addUnchecked must updated state for all ancestors of a given transaction, + // to track size/count of descendant transactions. First version of + // addUnchecked can be used to have it call CalculateMemPoolAncestors(), and + // then invoke the second version. bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate = true); + bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool fCurrentEstimate = true); + void remove(const CTransaction &tx, std::list<CTransaction>& removed, bool fRecursive = false); void removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight); void removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed); @@ -138,6 +368,35 @@ public: void ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta); void ClearPrioritisation(const uint256 hash); +public: + /** Remove a set of transactions from the mempool. + * If a transaction is in this set, then all in-mempool descendants must + * also be in the set.*/ + void RemoveStaged(setEntries &stage); + + /** When adding transactions from a disconnected block back to the mempool, + * new mempool entries may have children in the mempool (which is generally + * not the case when otherwise adding transactions). + * UpdateTransactionsFromBlock() will find child transactions and update the + * descendant state for each transaction in hashesToUpdate (excluding any + * child transactions present in hashesToUpdate, which are already accounted + * for). Note: hashesToUpdate should be the set of transactions from the + * disconnected block that have been accepted back into the mempool. + */ + void UpdateTransactionsFromBlock(const std::vector<uint256> &hashesToUpdate); + + /** Try to calculate all in-mempool ancestors of entry. + * (these are all calculated including the tx itself) + * limitAncestorCount = max number of ancestors + * limitAncestorSize = max size of ancestors + * limitDescendantCount = max number of descendants any ancestor can have + * limitDescendantSize = max size of descendants any ancestor can have + * errString = populated with error reason if any limits are hit + * fSearchForParents = whether to search a tx's vin for in-mempool parents, or + * look up parents from mapLinks. Must be true for entries not in the mempool + */ + bool CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents = true); + unsigned long size() { LOCK(cs); @@ -169,6 +428,48 @@ public: bool ReadFeeEstimates(CAutoFile& filein); size_t DynamicMemoryUsage() const; + +private: + /** UpdateForDescendants is used by UpdateTransactionsFromBlock to update + * the descendants for a single transaction that has been added to the + * mempool but may have child transactions in the mempool, eg during a + * chain reorg. setExclude is the set of descendant transactions in the + * mempool that must not be accounted for (because any descendants in + * setExclude were added to the mempool after the transaction being + * updated and hence their state is already reflected in the parent + * state). + * + * If updating an entry requires looking at more than maxDescendantsToVisit + * transactions, outside of the ones in setExclude, then give up. + * + * cachedDescendants will be updated with the descendants of the transaction + * being updated, so that future invocations don't need to walk the + * same transaction again, if encountered in another transaction chain. + */ + bool UpdateForDescendants(txiter updateIt, + int maxDescendantsToVisit, + cacheMap &cachedDescendants, + const std::set<uint256> &setExclude); + /** Update ancestors of hash to add/remove it as a descendant transaction. */ + void UpdateAncestorsOf(bool add, txiter hash, setEntries &setAncestors); + /** For each transaction being removed, update ancestors and any direct children. */ + void UpdateForRemoveFromMempool(const setEntries &entriesToRemove); + /** Sever link between specified transaction and direct children. */ + void UpdateChildrenForRemoval(txiter entry); + /** Populate setDescendants with all in-mempool descendants of hash. + * Assumes that setDescendants includes all in-mempool descendants of anything + * already in it. */ + void CalculateDescendants(txiter it, setEntries &setDescendants); + + /** Before calling removeUnchecked for a given transaction, + * UpdateForRemoveFromMempool must be called on the entire (dependent) set + * of transactions being removed at the same time. We use each + * CTxMemPoolEntry's setMemPoolParents in order to walk ancestors of a + * given transaction that is removed, so we can't remove intermediate + * transactions in a chain before we've updated all the state for the + * removal. + */ + void removeUnchecked(txiter entry); }; /** diff --git a/src/ui_interface.h b/src/ui_interface.h index 32a92a4b81..e402479933 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -95,6 +95,9 @@ public: /** New block has been accepted */ boost::signals2::signal<void (const uint256& hash)> NotifyBlockTip; + + /** Banlist did change. */ + boost::signals2::signal<void (void)> BannedListChanged; }; extern CClientUIInterface uiInterface; diff --git a/src/univalue/univalue_read.cpp b/src/univalue/univalue_read.cpp index 261771811d..64591234cb 100644 --- a/src/univalue/univalue_read.cpp +++ b/src/univalue/univalue_read.cpp @@ -244,16 +244,16 @@ bool UniValue::read(const char *raw) bool expectColon = false; vector<UniValue*> stack; + string tokenVal; + unsigned int consumed; enum jtokentype tok = JTOK_NONE; enum jtokentype last_tok = JTOK_NONE; - while (1) { + do { last_tok = tok; - string tokenVal; - unsigned int consumed; tok = getJsonToken(tokenVal, consumed, raw); if (tok == JTOK_NONE || tok == JTOK_ERR) - break; + return false; raw += consumed; switch (tok) { @@ -377,9 +377,11 @@ bool UniValue::read(const char *raw) default: return false; } - } + } while (!stack.empty ()); - if (stack.size() != 0) + /* Check that nothing follows the initial construct (parsed above). */ + tok = getJsonToken(tokenVal, consumed, raw); + if (tok != JTOK_NONE) return false; return true; diff --git a/src/util.cpp b/src/util.cpp index 37d52037c0..f50d25e17a 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -315,18 +315,21 @@ int LogPrintStr(const std::string &str) return ret; } -static void InterpretNegativeSetting(string name, map<string, string>& mapSettingsRet) +/** Interpret string as boolean, for argument parsing */ +static bool InterpretBool(const std::string& strValue) { - // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set - if (name.find("-no") == 0) + if (strValue.empty()) + return true; + return (atoi(strValue) != 0); +} + +/** Turn -noX into -X=0 */ +static void InterpretNegativeSetting(std::string& strKey, std::string& strValue) +{ + if (strKey.length()>3 && strKey[0]=='-' && strKey[1]=='n' && strKey[2]=='o') { - std::string positive("-"); - positive.append(name.begin()+3, name.end()); - if (mapSettingsRet.count(positive) == 0) - { - bool value = !GetBoolArg(name, false); - mapSettingsRet[positive] = (value ? "1" : "0"); - } + strKey = "-" + strKey.substr(3); + strValue = InterpretBool(strValue) ? "0" : "1"; } } @@ -358,17 +361,11 @@ void ParseParameters(int argc, const char* const argv[]) // If both --foo and -foo are set, the last takes effect. if (str.length() > 1 && str[1] == '-') str = str.substr(1); + InterpretNegativeSetting(str, strValue); mapArgs[str] = strValue; mapMultiArgs[str].push_back(strValue); } - - // New 0.6 features: - BOOST_FOREACH(const PAIRTYPE(string,string)& entry, mapArgs) - { - // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set - InterpretNegativeSetting(entry.first, mapArgs); - } } std::string GetArg(const std::string& strArg, const std::string& strDefault) @@ -388,11 +385,7 @@ int64_t GetArg(const std::string& strArg, int64_t nDefault) bool GetBoolArg(const std::string& strArg, bool fDefault) { if (mapArgs.count(strArg)) - { - if (mapArgs[strArg].empty()) - return true; - return (atoi(mapArgs[strArg]) != 0); - } + return InterpretBool(mapArgs[strArg]); return fDefault; } @@ -543,13 +536,11 @@ void ReadConfigFile(map<string, string>& mapSettingsRet, { // Don't overwrite existing settings so command line settings override bitcoin.conf string strKey = string("-") + it->string_key; + string strValue = it->value[0]; + InterpretNegativeSetting(strKey, strValue); if (mapSettingsRet.count(strKey) == 0) - { - mapSettingsRet[strKey] = it->value[0]; - // interpret nofoo=1 as foo=0 (and nofoo=0 as foo=1) as long as foo not set) - InterpretNegativeSetting(strKey, mapSettingsRet); - } - mapMultiSettingsRet[strKey].push_back(it->value[0]); + mapSettingsRet[strKey] = strValue; + mapMultiSettingsRet[strKey].push_back(strValue); } // If datadir is changed in .conf file: ClearDatadirCache(); @@ -803,6 +794,18 @@ void SetupEnvironment() boost::filesystem::path::imbue(loc); } +bool SetupNetworking() +{ +#ifdef WIN32 + // Initialize Windows Sockets + WSADATA wsadata; + int ret = WSAStartup(MAKEWORD(2,2), &wsadata); + if (ret != NO_ERROR || LOBYTE(wsadata.wVersion ) != 2 || HIBYTE(wsadata.wVersion) != 2) + return false; +#endif + return true; +} + void SetThreadPriority(int nPriority) { #ifdef WIN32 diff --git a/src/util.h b/src/util.h index afc9a378bb..0b2dc01ac6 100644 --- a/src/util.h +++ b/src/util.h @@ -59,6 +59,7 @@ inline std::string _(const char* psz) } void SetupEnvironment(); +bool SetupNetworking(); /** Return true if log accepts specified category */ bool LogAcceptCategory(const char* category); diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index 1f7a2cae2c..c5a2b5cdbb 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -14,17 +14,20 @@ using namespace std; -string SanitizeString(const string& str) +static const string CHARS_ALPHA_NUM = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + +static const string SAFE_CHARS[] = +{ + CHARS_ALPHA_NUM + " .,;-_/:?@()", // SAFE_CHARS_DEFAULT + CHARS_ALPHA_NUM + " .,;-_?@" // SAFE_CHARS_UA_COMMENT +}; + +string SanitizeString(const string& str, int rule) { - /** - * safeChars chosen to allow simple messages/URLs/email addresses, but avoid anything - * even possibly remotely dangerous like & or > - */ - static string safeChars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 .,;_/:?@()"); string strResult; for (std::string::size_type i = 0; i < str.size(); i++) { - if (safeChars.find(str[i]) != std::string::npos) + if (SAFE_CHARS[rule].find(str[i]) != std::string::npos) strResult.push_back(str[i]); } return strResult; diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h index dcd56751f2..ce93e83497 100644 --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -22,7 +22,21 @@ /** This is needed because the foreach macro can't get over the comma in pair<t1, t2> */ #define PAIRTYPE(t1, t2) std::pair<t1, t2> -std::string SanitizeString(const std::string& str); +/** Used by SanitizeString() */ +enum SafeChars +{ + SAFE_CHARS_DEFAULT, //!< The full set of allowed chars + SAFE_CHARS_UA_COMMENT //!< BIP-0014 subset +}; + +/** +* Remove unsafe chars. Safe chars chosen to allow simple messages/URLs/email +* addresses, but avoid anything even possibly remotely dangerous like & or > +* @param[in] str The string to sanitize +* @param[in] rule The set of safe chars to choose (default: least restrictive) +* @return A new string without unsafe chars +*/ +std::string SanitizeString(const std::string& str, int rule = SAFE_CHARS_DEFAULT); std::vector<unsigned char> ParseHex(const char* psz); std::vector<unsigned char> ParseHex(const std::string& str); signed char HexDigit(char c); diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index d365f03008..81f3b775f4 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -13,6 +13,7 @@ CMainSignals& GetMainSignals() } void RegisterValidationInterface(CValidationInterface* pwalletIn) { + g_signals.UpdatedBlockTip.connect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1)); g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2)); g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); @@ -32,6 +33,7 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn) { g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2)); + g_signals.UpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1)); } void UnregisterAllValidationInterfaces() { @@ -43,6 +45,7 @@ void UnregisterAllValidationInterfaces() { g_signals.SetBestChain.disconnect_all_slots(); g_signals.UpdatedTransaction.disconnect_all_slots(); g_signals.SyncTransaction.disconnect_all_slots(); + g_signals.UpdatedBlockTip.disconnect_all_slots(); } void SyncWithWallets(const CTransaction &tx, const CBlock *pblock) { diff --git a/src/validationinterface.h b/src/validationinterface.h index fb0ce0bdaa..ffb56d266b 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -11,6 +11,7 @@ class CBlock; struct CBlockLocator; +class CBlockIndex; class CReserveScript; class CTransaction; class CValidationInterface; @@ -30,6 +31,7 @@ void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL); class CValidationInterface { protected: + virtual void UpdatedBlockTip(const CBlockIndex *pindex) {} virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {} virtual void SetBestChain(const CBlockLocator &locator) {} virtual void UpdatedTransaction(const uint256 &hash) {} @@ -44,6 +46,8 @@ protected: }; struct CMainSignals { + /** Notifies listeners of updated block chain tip */ + boost::signals2::signal<void (const CBlockIndex *)> UpdatedBlockTip; /** Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. */ boost::signals2::signal<void (const CTransaction &, const CBlock *)> SyncTransaction; /** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */ diff --git a/src/version.h b/src/version.h index 38b3d2e734..6cdddf9255 100644 --- a/src/version.h +++ b/src/version.h @@ -9,7 +9,7 @@ * network protocol versioning */ -static const int PROTOCOL_VERSION = 70002; +static const int PROTOCOL_VERSION = 70011; //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209; @@ -34,4 +34,7 @@ static const int BIP0031_VERSION = 60000; //! "mempool" command, enhanced "getdata" behavior starts with this version static const int MEMPOOL_GD_VERSION = 60002; +//! "filter*" commands are disabled without NODE_BLOOM after and including this version +static const int NO_BLOOM_VERSION = 70011; + #endif // BITCOIN_VERSION_H diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index c7f7e21679..c86ad9758e 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -186,7 +186,7 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) } if (keyPass && keyFail) { - LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all."); + LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all.\n"); assert(false); } if (keyFail || !keyPass) @@ -255,7 +255,7 @@ bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) co { LOCK(cs_KeyStore); if (!IsCrypted()) - return CKeyStore::GetPubKey(address, vchPubKeyOut); + return CBasicKeyStore::GetPubKey(address, vchPubKeyOut); CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address); if (mi != mapCryptedKeys.end()) @@ -263,6 +263,8 @@ bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) co vchPubKeyOut = (*mi).second.first; return true; } + // Check for watch-only pubkeys + return CBasicKeyStore::GetPubKey(address, vchPubKeyOut); } return false; } diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index dbe36a2be1..7e22faac37 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -97,8 +97,6 @@ UniValue importprivkey(const UniValue& params, bool fHelp) + HelpExampleRpc("importprivkey", "\"mykey\", \"testing\", false") ); - if (fPruneMode) - throw JSONRPCError(RPC_WALLET_ERROR, "Importing keys is disabled in pruned mode"); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -114,6 +112,9 @@ UniValue importprivkey(const UniValue& params, bool fHelp) if (params.size() > 2) fRescan = params[2].get_bool(); + if (fRescan && fPruneMode) + throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode"); + CBitcoinSecret vchSecret; bool fGood = vchSecret.SetString(strSecret); @@ -149,46 +150,123 @@ UniValue importprivkey(const UniValue& params, bool fHelp) return NullUniValue; } +void ImportAddress(const CBitcoinAddress& address, const string& strLabel); +void ImportScript(const CScript& script, const string& strLabel, bool isRedeemScript) +{ + if (!isRedeemScript && ::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE) + throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); + + pwalletMain->MarkDirty(); + + if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script)) + throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); + + if (isRedeemScript) { + if (!pwalletMain->HaveCScript(script) && !pwalletMain->AddCScript(script)) + throw JSONRPCError(RPC_WALLET_ERROR, "Error adding p2sh redeemScript to wallet"); + ImportAddress(CBitcoinAddress(CScriptID(script)), strLabel); + } +} + +void ImportAddress(const CBitcoinAddress& address, const string& strLabel) +{ + CScript script = GetScriptForDestination(address.Get()); + ImportScript(script, strLabel, false); + // add to address book or update label + if (address.IsValid()) + pwalletMain->SetAddressBook(address.Get(), strLabel, "receive"); +} + UniValue importaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - if (fHelp || params.size() < 1 || params.size() > 3) + if (fHelp || params.size() < 1 || params.size() > 4) throw runtime_error( - "importaddress \"address\" ( \"label\" rescan )\n" - "\nAdds an address or script (in hex) that can be watched as if it were in your wallet but cannot be used to spend.\n" + "importaddress \"address\" ( \"label\" rescan p2sh )\n" + "\nAdds a script (in hex) or address that can be watched as if it were in your wallet but cannot be used to spend.\n" "\nArguments:\n" - "1. \"address\" (string, required) The address\n" + "1. \"script\" (string, required) The hex-encoded script (or address)\n" "2. \"label\" (string, optional, default=\"\") An optional label\n" "3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n" + "4. p2sh (boolean, optional, default=false) Add the P2SH version of the script as well\n" "\nNote: This call can take minutes to complete if rescan is true.\n" + "If you have the full public key, you should call importpublickey instead of this.\n" "\nExamples:\n" - "\nImport an address with rescan\n" - + HelpExampleCli("importaddress", "\"myaddress\"") + + "\nImport a script with rescan\n" + + HelpExampleCli("importaddress", "\"myscript\"") + "\nImport using a label without rescan\n" - + HelpExampleCli("importaddress", "\"myaddress\" \"testing\" false") + + + HelpExampleCli("importaddress", "\"myscript\" \"testing\" false") + "\nAs a JSON-RPC call\n" - + HelpExampleRpc("importaddress", "\"myaddress\", \"testing\", false") + + HelpExampleRpc("importaddress", "\"myscript\", \"testing\", false") ); - if (fPruneMode) - throw JSONRPCError(RPC_WALLET_ERROR, "Importing addresses is disabled in pruned mode"); - LOCK2(cs_main, pwalletMain->cs_wallet); + string strLabel = ""; + if (params.size() > 1) + strLabel = params[1].get_str(); + + // Whether to perform rescan after import + bool fRescan = true; + if (params.size() > 2) + fRescan = params[2].get_bool(); - CScript script; + if (fRescan && fPruneMode) + throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode"); + + // Whether to import a p2sh version, too + bool fP2SH = false; + if (params.size() > 3) + fP2SH = params[3].get_bool(); + + LOCK2(cs_main, pwalletMain->cs_wallet); CBitcoinAddress address(params[0].get_str()); if (address.IsValid()) { - script = GetScriptForDestination(address.Get()); + if (fP2SH) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot use the p2sh flag with an address - use a script instead"); + ImportAddress(address, strLabel); } else if (IsHex(params[0].get_str())) { std::vector<unsigned char> data(ParseHex(params[0].get_str())); - script = CScript(data.begin(), data.end()); + ImportScript(CScript(data.begin(), data.end()), strLabel, fP2SH); } else { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script"); } + if (fRescan) + { + pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true); + pwalletMain->ReacceptWalletTransactions(); + } + + return NullUniValue; +} + +UniValue importpubkey(const UniValue& params, bool fHelp) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() < 1 || params.size() > 4) + throw runtime_error( + "importpubkey \"pubkey\" ( \"label\" rescan )\n" + "\nAdds a public key (in hex) that can be watched as if it were in your wallet but cannot be used to spend.\n" + "\nArguments:\n" + "1. \"pubkey\" (string, required) The hex-encoded public key\n" + "2. \"label\" (string, optional, default=\"\") An optional label\n" + "3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n" + "\nNote: This call can take minutes to complete if rescan is true.\n" + "\nExamples:\n" + "\nImport a public key with rescan\n" + + HelpExampleCli("importpubkey", "\"mypubkey\"") + + "\nImport using a label without rescan\n" + + HelpExampleCli("importpubkey", "\"mypubkey\" \"testing\" false") + + "\nAs a JSON-RPC call\n" + + HelpExampleRpc("importpubkey", "\"mypubkey\", \"testing\", false") + ); + + string strLabel = ""; if (params.size() > 1) strLabel = params[1].get_str(); @@ -198,33 +276,31 @@ UniValue importaddress(const UniValue& params, bool fHelp) if (params.size() > 2) fRescan = params[2].get_bool(); - { - if (::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE) - throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); - - // add to address book or update label - if (address.IsValid()) - pwalletMain->SetAddressBook(address.Get(), strLabel, "receive"); + if (fRescan && fPruneMode) + throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode"); - // Don't throw error in case an address is already there - if (pwalletMain->HaveWatchOnly(script)) - return NullUniValue; + if (!IsHex(params[0].get_str())) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey must be a hex string"); + std::vector<unsigned char> data(ParseHex(params[0].get_str())); + CPubKey pubKey(data.begin(), data.end()); + if (!pubKey.IsFullyValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey is not a valid public key"); - pwalletMain->MarkDirty(); + LOCK2(cs_main, pwalletMain->cs_wallet); - if (!pwalletMain->AddWatchOnly(script)) - throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); + ImportAddress(CBitcoinAddress(pubKey.GetID()), strLabel); + ImportScript(GetScriptForRawPubKey(pubKey), strLabel, false); - if (fRescan) - { - pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true); - pwalletMain->ReacceptWalletTransactions(); - } + if (fRescan) + { + pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true); + pwalletMain->ReacceptWalletTransactions(); } return NullUniValue; } + UniValue importwallet(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 342ce13af1..5d182f3d42 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -390,7 +390,7 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp) + HelpRequiringPassphrase() + "\nArguments:\n" "1. \"bitcoinaddress\" (string, required) The bitcoin address to send to.\n" - "2. \"amount\" (numeric, required) The amount in btc to send. eg 0.1\n" + "2. \"amount\" (numeric, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n" "3. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" " This is not part of the transaction, just kept in your wallet.\n" "4. \"comment-to\" (string, optional) A comment to store the name of the person or organization \n" @@ -452,7 +452,7 @@ UniValue listaddressgroupings(const UniValue& params, bool fHelp) " [\n" " [\n" " \"bitcoinaddress\", (string) The bitcoin address\n" - " amount, (numeric) The amount in btc\n" + " amount, (numeric) The amount in " + CURRENCY_UNIT + "\n" " \"account\" (string, optional) The account (DEPRECATED)\n" " ]\n" " ,...\n" @@ -556,7 +556,7 @@ UniValue getreceivedbyaddress(const UniValue& params, bool fHelp) "1. \"bitcoinaddress\" (string, required) The bitcoin address for transactions.\n" "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" "\nResult:\n" - "amount (numeric) The total amount in btc received at this address.\n" + "amount (numeric) The total amount in " + CURRENCY_UNIT + " received at this address.\n" "\nExamples:\n" "\nThe amount from transactions with at least 1 confirmation\n" + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"") + @@ -614,7 +614,7 @@ UniValue getreceivedbyaccount(const UniValue& params, bool fHelp) "1. \"account\" (string, required) The selected account, may be the default account using \"\".\n" "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" "\nResult:\n" - "amount (numeric) The total amount in btc received for this account.\n" + "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n" "\nExamples:\n" "\nAmount received by the default account with at least 1 confirmation\n" + HelpExampleCli("getreceivedbyaccount", "\"\"") + @@ -707,7 +707,7 @@ UniValue getbalance(const UniValue& params, bool fHelp) "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" "3. includeWatchonly (bool, optional, default=false) Also include balance in watchonly addresses (see 'importaddress')\n" "\nResult:\n" - "amount (numeric) The total amount in btc received for this account.\n" + "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n" "\nExamples:\n" "\nThe total amount in the wallet\n" + HelpExampleCli("getbalance", "") + @@ -793,14 +793,15 @@ UniValue movecmd(const UniValue& params, bool fHelp) "\nArguments:\n" "1. \"fromaccount\" (string, required) The name of the account to move funds from. May be the default account using \"\".\n" "2. \"toaccount\" (string, required) The name of the account to move funds to. May be the default account using \"\".\n" - "3. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n" - "4. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n" + "3. amount (numeric) Quantity of " + CURRENCY_UNIT + " to move between accounts.\n" + "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n" + "5. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n" "\nResult:\n" - "true|false (boolean) true if successfull.\n" + "true|false (boolean) true if successful.\n" "\nExamples:\n" - "\nMove 0.01 btc from the default account to the account named tabby\n" + "\nMove 0.01 " + CURRENCY_UNIT + " from the default account to the account named tabby\n" + HelpExampleCli("move", "\"\" \"tabby\" 0.01") + - "\nMove 0.01 btc timotei to akiko with a comment and funds have 6 confirmations\n" + "\nMove 0.01 " + CURRENCY_UNIT + " timotei to akiko with a comment and funds have 6 confirmations\n" + HelpExampleCli("move", "\"timotei\" \"akiko\" 0.01 6 \"happy birthday!\"") + "\nAs a json rpc call\n" + HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"") @@ -867,7 +868,7 @@ UniValue sendfrom(const UniValue& params, bool fHelp) "\nArguments:\n" "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n" "2. \"tobitcoinaddress\" (string, required) The bitcoin address to send funds to.\n" - "3. amount (numeric, required) The amount in btc. (transaction fee is added on top).\n" + "3. amount (numeric, required) The amount in " + CURRENCY_UNIT + " (transaction fee is added on top).\n" "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n" "5. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" " This is not part of the transaction, just kept in your wallet.\n" @@ -877,7 +878,7 @@ UniValue sendfrom(const UniValue& params, bool fHelp) "\nResult:\n" "\"transactionid\" (string) The transaction id.\n" "\nExamples:\n" - "\nSend 0.01 btc from the default account to the address, must have at least 1 confirmation\n" + "\nSend 0.01 " + CURRENCY_UNIT + " from the default account to the address, must have at least 1 confirmation\n" + HelpExampleCli("sendfrom", "\"\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01") + "\nSend 0.01 from the tabby account to the given address, funds must have at least 6 confirmations\n" + HelpExampleCli("sendfrom", "\"tabby\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01 6 \"donation\" \"seans outpost\"") + @@ -932,7 +933,7 @@ UniValue sendmany(const UniValue& params, bool fHelp) "1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n" "2. \"amounts\" (string, required) A json object with addresses and amounts\n" " {\n" - " \"address\":amount (numeric) The bitcoin address is the key, the numeric amount in btc is the value\n" + " \"address\":amount (numeric) The bitcoin address is the key, the numeric amount in " + CURRENCY_UNIT + " is the value\n" " ,...\n" " }\n" "3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n" @@ -1233,7 +1234,7 @@ UniValue listreceivedbyaddress(const UniValue& params, bool fHelp) " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n" " \"address\" : \"receivingaddress\", (string) The receiving address\n" " \"account\" : \"accountname\", (string) DEPRECATED. The account of the receiving address. The default account is \"\".\n" - " \"amount\" : x.xxx, (numeric) The total amount in btc received by the address\n" + " \"amount\" : x.xxx, (numeric) The total amount in " + CURRENCY_UNIT + " received by the address\n" " \"confirmations\" : n (numeric) The number of confirmations of the most recent transaction included\n" " }\n" " ,...\n" @@ -1405,11 +1406,11 @@ UniValue listtransactions(const UniValue& params, bool fHelp) " transaction between accounts, and not associated with an address,\n" " transaction id or block. 'send' and 'receive' transactions are \n" " associated with an address, transaction id and block details\n" - " \"amount\": x.xxx, (numeric) The amount in btc. This is negative for the 'send' category, and for the\n" + " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the\n" " 'move' category for moves outbound. It is positive for the 'receive' category,\n" " and for the 'move' category for inbound funds.\n" " \"vout\" : n, (numeric) the vout value\n" - " \"fee\": x.xxx, (numeric) The amount of the fee in btc. This is negative and only available for the \n" + " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n" " 'send' category of transactions.\n" " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and \n" " 'receive' category of transactions.\n" @@ -1600,10 +1601,10 @@ UniValue listsinceblock(const UniValue& params, bool fHelp) " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n" " \"address\":\"bitcoinaddress\", (string) The bitcoin address of the transaction. Not present for move transactions (category = move).\n" " \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n" - " \"amount\": x.xxx, (numeric) The amount in btc. This is negative for the 'send' category, and for the 'move' category for moves \n" + " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the 'move' category for moves \n" " outbound. It is positive for the 'receive' category, and for the 'move' category for inbound funds.\n" " \"vout\" : n, (numeric) the vout value\n" - " \"fee\": x.xxx, (numeric) The amount of the fee in btc. This is negative and only available for the 'send' category of transactions.\n" + " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the 'send' category of transactions.\n" " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and 'receive' category of transactions.\n" " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n" " \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive' category of transactions.\n" @@ -1686,7 +1687,7 @@ UniValue gettransaction(const UniValue& params, bool fHelp) "2. \"includeWatchonly\" (bool, optional, default=false) Whether to include watchonly addresses in balance calculation and details[]\n" "\nResult:\n" "{\n" - " \"amount\" : x.xxx, (numeric) The transaction amount in btc\n" + " \"amount\" : x.xxx, (numeric) The transaction amount in " + CURRENCY_UNIT + "\n" " \"confirmations\" : n, (numeric) The number of confirmations\n" " \"blockhash\" : \"hash\", (string) The block hash\n" " \"blockindex\" : xx, (numeric) The block index\n" @@ -1699,7 +1700,7 @@ UniValue gettransaction(const UniValue& params, bool fHelp) " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n" " \"address\" : \"bitcoinaddress\", (string) The bitcoin address involved in the transaction\n" " \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n" - " \"amount\" : x.xxx (numeric) The amount in btc\n" + " \"amount\" : x.xxx (numeric) The amount in " + CURRENCY_UNIT + "\n" " \"vout\" : n, (numeric) the vout value\n" " }\n" " ,...\n" @@ -2165,7 +2166,7 @@ UniValue settxfee(const UniValue& params, bool fHelp) "settxfee amount\n" "\nSet the transaction fee per kB.\n" "\nArguments:\n" - "1. amount (numeric, required) The transaction fee in BTC/kB rounded to the nearest 0.00000001\n" + "1. amount (numeric, required) The transaction fee in " + CURRENCY_UNIT + "/kB rounded to the nearest 0.00000001\n" "\nResult\n" "true|false (boolean) Returns true if successful\n" "\nExamples:\n" @@ -2194,14 +2195,14 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) "\nResult:\n" "{\n" " \"walletversion\": xxxxx, (numeric) the wallet version\n" - " \"balance\": xxxxxxx, (numeric) the total confirmed bitcoin balance of the wallet\n" - " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed bitcoin balance of the wallet\n" - " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet\n" + " \"balance\": xxxxxxx, (numeric) the total confirmed balance of the wallet in " + CURRENCY_UNIT + "\n" + " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed balance of the wallet in " + CURRENCY_UNIT + "\n" + " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet in " + CURRENCY_UNIT + "\n" " \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n" " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n" " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n" " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n" - " \"paytxfee\": x.xxxx, (numeric) the transaction fee configuration, set in btc/kb\n" + " \"paytxfee\": x.xxxx, (numeric) the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB\n" "}\n" "\nExamples:\n" + HelpExampleCli("getwalletinfo", "") @@ -2278,7 +2279,7 @@ UniValue listunspent(const UniValue& params, bool fHelp) " \"address\" : \"address\", (string) the bitcoin address\n" " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n" " \"scriptPubKey\" : \"key\", (string) the script key\n" - " \"amount\" : x.xxx, (numeric) the transaction amount in btc\n" + " \"amount\" : x.xxx, (numeric) the transaction amount in " + CURRENCY_UNIT + "\n" " \"confirmations\" : n (numeric) The number of confirmations\n" " }\n" " ,...\n" @@ -2367,15 +2368,20 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - if (fHelp || params.size() != 1) + if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( - "fundrawtransaction \"hexstring\"\n" + "fundrawtransaction \"hexstring\" includeWatching\n" "\nAdd inputs to a transaction until it has enough in value to meet its out value.\n" "This will not modify existing inputs, and will add one change output to the outputs.\n" "Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n" "The inputs added will not be signed, use signrawtransaction for that.\n" + "Note that all existing inputs must have their previous output transaction be in the wallet.\n" + "Note that all inputs selected must be of standard form and P2SH scripts must be" + "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n" + "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n" "\nArguments:\n" - "1. \"hexstring\" (string, required) The hex string of the raw transaction\n" + "1. \"hexstring\" (string, required) The hex string of the raw transaction\n" + "2. includeWatching (boolean, optional, default false) Also select inputs which are watch only\n" "\nResult:\n" "{\n" " \"hex\": \"value\", (string) The resulting raw transaction (hex-encoded string)\n" @@ -2394,18 +2400,22 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"") ); - RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VBOOL)); // parse hex string from parameter CTransaction origTx; if (!DecodeHexTx(origTx, params[0].get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); + bool includeWatching = false; + if (params.size() > 1) + includeWatching = true; + CMutableTransaction tx(origTx); CAmount nFee; string strFailReason; int nChangePos = -1; - if(!pwalletMain->FundTransaction(tx, nFee, nChangePos, strFailReason)) + if(!pwalletMain->FundTransaction(tx, nFee, nChangePos, strFailReason, includeWatching)) throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason); UniValue result(UniValue::VOBJ); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 58b9ccc078..bd3004061b 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -114,6 +114,9 @@ bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey) script = GetScriptForDestination(pubkey.GetID()); if (HaveWatchOnly(script)) RemoveWatchOnly(script); + script = GetScriptForRawPubKey(pubkey); + if (HaveWatchOnly(script)) + RemoveWatchOnly(script); if (!fFileBacked) return true; @@ -699,9 +702,8 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD wtx.hashBlock = wtxIn.hashBlock; fUpdated = true; } - if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex)) + if (wtxIn.nIndex != -1 && (wtxIn.nIndex != wtx.nIndex)) { - wtx.vMerkleBranch = wtxIn.vMerkleBranch; wtx.nIndex = wtxIn.nIndex; fUpdated = true; } @@ -1527,7 +1529,9 @@ void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO && !IsLockedCoin((*it).first, i) && (pcoin->vout[i].nValue > 0 || fIncludeZeroValue) && (!coinControl || !coinControl->HasSelected() || coinControl->fAllowOtherInputs || coinControl->IsSelected((*it).first, i))) - vCoins.push_back(COutput(pcoin, i, nDepth, (mine & ISMINE_SPENDABLE) != ISMINE_NO)); + vCoins.push_back(COutput(pcoin, i, nDepth, + ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || + (coinControl && coinControl->fAllowWatchOnly && (mine & ISMINE_WATCH_SOLVABLE) != ISMINE_NO))); } } } @@ -1743,7 +1747,7 @@ bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx* return res; } -bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nChangePosRet, std::string& strFailReason) +bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nChangePosRet, std::string& strFailReason, bool includeWatching) { vector<CRecipient> vecSend; @@ -1756,6 +1760,7 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nC CCoinControl coinControl; coinControl.fAllowOtherInputs = true; + coinControl.fAllowWatchOnly = includeWatching; BOOST_FOREACH(const CTxIn& txin, tx.vin) coinControl.Select(txin.prevout); @@ -1847,9 +1852,9 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt nChangePosRet = -1; bool fFirst = true; - CAmount nTotalValue = nValue; + CAmount nValueToSelect = nValue; if (nSubtractFeeFromAmount == 0) - nTotalValue += nFeeRet; + nValueToSelect += nFeeRet; double dPriority = 0; // vouts to the payees BOOST_FOREACH (const CRecipient& recipient, vecSend) @@ -1886,7 +1891,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt // Choose coins to use set<pair<const CWalletTx*,unsigned int> > setCoins; CAmount nValueIn = 0; - if (!SelectCoins(nTotalValue, setCoins, nValueIn, coinControl)) + if (!SelectCoins(nValueToSelect, setCoins, nValueIn, coinControl)) { strFailReason = _("Insufficient funds"); return false; @@ -1904,10 +1909,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt dPriority += (double)nCredit * age; } - CAmount nChange = nValueIn - nValue; - if (nSubtractFeeFromAmount == 0) - nChange -= nFeeRet; - + const CAmount nChange = nValueIn - nValueToSelect; if (nChange > 0) { // Fill a vout to ourself @@ -2109,7 +2111,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) if (!wtxNew.AcceptToMemoryPool(false)) { // This must not fail. The transaction has already been signed and recorded. - LogPrintf("CommitTransaction(): Error: Transaction not valid"); + LogPrintf("CommitTransaction(): Error: Transaction not valid\n"); return false; } wtxNew.RelayWalletTransaction(); @@ -2806,15 +2808,11 @@ int CMerkleTx::SetMerkleBranch(const CBlock& block) break; if (nIndex == (int)block.vtx.size()) { - vMerkleBranch.clear(); nIndex = -1; LogPrintf("ERROR: SetMerkleBranch(): couldn't find tx in block\n"); return 0; } - // Fill in merkle branch - vMerkleBranch = block.GetMerkleBranch(nIndex); - // Is the tx in a block that's in the main chain BlockMap::iterator mi = mapBlockIndex.find(hashBlock); if (mi == mapBlockIndex.end()) @@ -2840,14 +2838,6 @@ int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const if (!pindex || !chainActive.Contains(pindex)) return 0; - // Make sure the merkle branch connects to this block - if (!fMerkleVerified) - { - if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot) - return 0; - fMerkleVerified = true; - } - pindexRet = pindex; return chainActive.Height() - pindex->nHeight + 1; } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index ae007e4673..34e98cfb81 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -151,13 +151,8 @@ private: public: uint256 hashBlock; - std::vector<uint256> vMerkleBranch; int nIndex; - // memory only - mutable bool fMerkleVerified; - - CMerkleTx() { Init(); @@ -172,13 +167,13 @@ public: { hashBlock = uint256(); nIndex = -1; - fMerkleVerified = false; } ADD_SERIALIZE_METHODS; template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + std::vector<uint256> vMerkleBranch; // For compatibility with older versions. READWRITE(*(CTransaction*)this); nVersion = this->nVersion; READWRITE(hashBlock); @@ -627,7 +622,7 @@ public: CAmount GetWatchOnlyBalance() const; CAmount GetUnconfirmedWatchOnlyBalance() const; CAmount GetImmatureWatchOnlyBalance() const; - bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason); + bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, bool includeWatching); bool CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, const CCoinControl *coinControl = NULL, bool sign = true); bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); diff --git a/src/wallet/wallet_ismine.cpp b/src/wallet/wallet_ismine.cpp index 5482348e35..d27b1531e3 100644 --- a/src/wallet/wallet_ismine.cpp +++ b/src/wallet/wallet_ismine.cpp @@ -9,6 +9,7 @@ #include "keystore.h" #include "script/script.h" #include "script/standard.h" +#include "script/sign.h" #include <boost/foreach.hpp> @@ -40,7 +41,7 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) txnouttype whichType; if (!Solver(scriptPubKey, whichType, vSolutions)) { if (keystore.HaveWatchOnly(scriptPubKey)) - return ISMINE_WATCH_ONLY; + return ISMINE_WATCH_UNSOLVABLE; return ISMINE_NO; } @@ -85,7 +86,10 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) } } - if (keystore.HaveWatchOnly(scriptPubKey)) - return ISMINE_WATCH_ONLY; + if (keystore.HaveWatchOnly(scriptPubKey)) { + // TODO: This could be optimized some by doing some work after the above solver + CScript scriptSig; + return ProduceSignature(DummySignatureCreator(&keystore), scriptPubKey, scriptSig) ? ISMINE_WATCH_SOLVABLE : ISMINE_WATCH_UNSOLVABLE; + } return ISMINE_NO; } diff --git a/src/wallet/wallet_ismine.h b/src/wallet/wallet_ismine.h index 7846565f8d..9f45f76c6b 100644 --- a/src/wallet/wallet_ismine.h +++ b/src/wallet/wallet_ismine.h @@ -17,8 +17,12 @@ class CScript; enum isminetype { ISMINE_NO = 0, - ISMINE_WATCH_ONLY = 1, - ISMINE_SPENDABLE = 2, + //! Indicates that we dont know how to create a scriptSig that would solve this if we were given the appropriate private keys + ISMINE_WATCH_UNSOLVABLE = 1, + //! Indicates that we know how to create a scriptSig that would solve this if we were given the appropriate private keys + ISMINE_WATCH_SOLVABLE = 2, + ISMINE_WATCH_ONLY = ISMINE_WATCH_SOLVABLE | ISMINE_WATCH_UNSOLVABLE, + ISMINE_SPENDABLE = 4, ISMINE_ALL = ISMINE_WATCH_ONLY | ISMINE_SPENDABLE }; /** used for bitflags of isminetype */ diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index c1eb184581..0624e442d1 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -131,12 +131,14 @@ bool CWalletDB::EraseWatchOnly(const CScript &dest) bool CWalletDB::WriteBestBlock(const CBlockLocator& locator) { nWalletDBUpdated++; - return Write(std::string("bestblock"), locator); + Write(std::string("bestblock"), CBlockLocator()); // Write empty block locator so versions that require a merkle branch automatically rescan + return Write(std::string("bestblock_nomerkle"), locator); } bool CWalletDB::ReadBestBlock(CBlockLocator& locator) { - return Read(std::string("bestblock"), locator); + if (Read(std::string("bestblock"), locator) && !locator.vHave.empty()) return true; + return Read(std::string("bestblock_nomerkle"), locator); } bool CWalletDB::WriteOrderPosNext(int64_t nOrderPosNext) diff --git a/src/zmq/zmqabstractnotifier.cpp b/src/zmq/zmqabstractnotifier.cpp new file mode 100644 index 0000000000..9f5cb3ba67 --- /dev/null +++ b/src/zmq/zmqabstractnotifier.cpp @@ -0,0 +1,22 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "zmqabstractnotifier.h" +#include "util.h" + + +CZMQAbstractNotifier::~CZMQAbstractNotifier() +{ + assert(!psocket); +} + +bool CZMQAbstractNotifier::NotifyBlock(const CBlockIndex * /*CBlockIndex*/) +{ + return true; +} + +bool CZMQAbstractNotifier::NotifyTransaction(const CTransaction &/*transaction*/) +{ + return true; +} diff --git a/src/zmq/zmqabstractnotifier.h b/src/zmq/zmqabstractnotifier.h new file mode 100644 index 0000000000..77cf5141e2 --- /dev/null +++ b/src/zmq/zmqabstractnotifier.h @@ -0,0 +1,44 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H +#define BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H + +#include "zmqconfig.h" + +class CBlockIndex; +class CZMQAbstractNotifier; + +typedef CZMQAbstractNotifier* (*CZMQNotifierFactory)(); + +class CZMQAbstractNotifier +{ +public: + CZMQAbstractNotifier() : psocket(0) { } + virtual ~CZMQAbstractNotifier(); + + template <typename T> + static CZMQAbstractNotifier* Create() + { + return new T(); + } + + std::string GetType() const { return type; } + void SetType(const std::string &t) { type = t; } + std::string GetAddress() const { return address; } + void SetAddress(const std::string &a) { address = a; } + + virtual bool Initialize(void *pcontext) = 0; + virtual void Shutdown() = 0; + + virtual bool NotifyBlock(const CBlockIndex *pindex); + virtual bool NotifyTransaction(const CTransaction &transaction); + +protected: + void *psocket; + std::string type; + std::string address; +}; + +#endif // BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H diff --git a/src/zmq/zmqconfig.h b/src/zmq/zmqconfig.h new file mode 100644 index 0000000000..6057f5d1a0 --- /dev/null +++ b/src/zmq/zmqconfig.h @@ -0,0 +1,24 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_ZMQ_ZMQCONFIG_H +#define BITCOIN_ZMQ_ZMQCONFIG_H + +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + +#include <stdarg.h> +#include <string> + +#if ENABLE_ZMQ +#include <zmq.h> +#endif + +#include "primitives/block.h" +#include "primitives/transaction.h" + +void zmqError(const char *str); + +#endif // BITCOIN_ZMQ_ZMQCONFIG_H diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp new file mode 100644 index 0000000000..388b86707b --- /dev/null +++ b/src/zmq/zmqnotificationinterface.cpp @@ -0,0 +1,155 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "zmqnotificationinterface.h" +#include "zmqpublishnotifier.h" + +#include "version.h" +#include "main.h" +#include "streams.h" +#include "util.h" + +void zmqError(const char *str) +{ + LogPrint("zmq", "Error: %s, errno=%s\n", str, zmq_strerror(errno)); +} + +CZMQNotificationInterface::CZMQNotificationInterface() : pcontext(NULL) +{ +} + +CZMQNotificationInterface::~CZMQNotificationInterface() +{ + // ensure Shutdown if Initialize is called + assert(!pcontext); + + for (std::list<CZMQAbstractNotifier*>::iterator i=notifiers.begin(); i!=notifiers.end(); ++i) + { + delete *i; + } +} + +CZMQNotificationInterface* CZMQNotificationInterface::CreateWithArguments(const std::map<std::string, std::string> &args) +{ + CZMQNotificationInterface* notificationInterface = NULL; + std::map<std::string, CZMQNotifierFactory> factories; + std::list<CZMQAbstractNotifier*> notifiers; + + factories["pubhashblock"] = CZMQAbstractNotifier::Create<CZMQPublishHashBlockNotifier>; + factories["pubhashtx"] = CZMQAbstractNotifier::Create<CZMQPublishHashTransactionNotifier>; + factories["pubrawblock"] = CZMQAbstractNotifier::Create<CZMQPublishRawBlockNotifier>; + factories["pubrawtx"] = CZMQAbstractNotifier::Create<CZMQPublishRawTransactionNotifier>; + + for (std::map<std::string, CZMQNotifierFactory>::const_iterator i=factories.begin(); i!=factories.end(); ++i) + { + std::map<std::string, std::string>::const_iterator j = args.find("-zmq" + i->first); + if (j!=args.end()) + { + CZMQNotifierFactory factory = i->second; + std::string address = j->second; + CZMQAbstractNotifier *notifier = factory(); + notifier->SetType(i->first); + notifier->SetAddress(address); + notifiers.push_back(notifier); + } + } + + if (!notifiers.empty()) + { + notificationInterface = new CZMQNotificationInterface(); + notificationInterface->notifiers = notifiers; + } + + return notificationInterface; +} + +// Called at startup to conditionally set up ZMQ socket(s) +bool CZMQNotificationInterface::Initialize() +{ + LogPrint("zmq", "Initialize notification interface\n"); + assert(!pcontext); + + pcontext = zmq_init(1); + + if (!pcontext) + { + zmqError("Unable to initialize context"); + return false; + } + + std::list<CZMQAbstractNotifier*>::iterator i=notifiers.begin(); + for (; i!=notifiers.end(); ++i) + { + CZMQAbstractNotifier *notifier = *i; + if (notifier->Initialize(pcontext)) + { + LogPrint("zmq", " Notifier %s ready (address = %s)\n", notifier->GetType(), notifier->GetAddress()); + } + else + { + LogPrint("zmq", " Notifier %s failed (address = %s)\n", notifier->GetType(), notifier->GetAddress()); + break; + } + } + + if (i!=notifiers.end()) + { + Shutdown(); + return false; + } + + return false; +} + +// Called during shutdown sequence +void CZMQNotificationInterface::Shutdown() +{ + LogPrint("zmq", "Shutdown notification interface\n"); + if (pcontext) + { + for (std::list<CZMQAbstractNotifier*>::iterator i=notifiers.begin(); i!=notifiers.end(); ++i) + { + CZMQAbstractNotifier *notifier = *i; + LogPrint("zmq", " Shutdown notifier %s at %s\n", notifier->GetType(), notifier->GetAddress()); + notifier->Shutdown(); + } + zmq_ctx_destroy(pcontext); + + pcontext = 0; + } +} + +void CZMQNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindex) +{ + for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); ) + { + CZMQAbstractNotifier *notifier = *i; + if (notifier->NotifyBlock(pindex)) + { + i++; + } + else + { + notifier->Shutdown(); + i = notifiers.erase(i); + } + } +} + +void CZMQNotificationInterface::SyncTransaction(const CTransaction &tx, const CBlock *pblock) +{ + for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); ) + { + CZMQAbstractNotifier *notifier = *i; + if (notifier->NotifyTransaction(tx)) + { + i++; + } + else + { + notifier->Shutdown(); + i = notifiers.erase(i); + } + } +} diff --git a/src/zmq/zmqnotificationinterface.h b/src/zmq/zmqnotificationinterface.h new file mode 100644 index 0000000000..8eea15c068 --- /dev/null +++ b/src/zmq/zmqnotificationinterface.h @@ -0,0 +1,36 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_ZMQ_ZMQNOTIFICATIONINTERFACE_H +#define BITCOIN_ZMQ_ZMQNOTIFICATIONINTERFACE_H + +#include "validationinterface.h" +#include <string> +#include <map> + +class CBlockIndex; +class CZMQAbstractNotifier; + +class CZMQNotificationInterface : public CValidationInterface +{ +public: + virtual ~CZMQNotificationInterface(); + + static CZMQNotificationInterface* CreateWithArguments(const std::map<std::string, std::string> &args); + + bool Initialize(); + void Shutdown(); + +protected: // CValidationInterface + void SyncTransaction(const CTransaction &tx, const CBlock *pblock); + void UpdatedBlockTip(const CBlockIndex *pindex); + +private: + CZMQNotificationInterface(); + + void *pcontext; + std::list<CZMQAbstractNotifier*> notifiers; +}; + +#endif // BITCOIN_ZMQ_ZMQNOTIFICATIONINTERFACE_H diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp new file mode 100644 index 0000000000..4c3eb8f2d9 --- /dev/null +++ b/src/zmq/zmqpublishnotifier.cpp @@ -0,0 +1,170 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "zmqpublishnotifier.h" +#include "main.h" +#include "util.h" + +static std::multimap<std::string, CZMQAbstractPublishNotifier*> mapPublishNotifiers; + +// Internal function to send multipart message +static int zmq_send_multipart(void *sock, const void* data, size_t size, ...) +{ + va_list args; + va_start(args, size); + + while (1) + { + zmq_msg_t msg; + + int rc = zmq_msg_init_size(&msg, size); + if (rc != 0) + { + zmqError("Unable to initialize ZMQ msg"); + return -1; + } + + void *buf = zmq_msg_data(&msg); + memcpy(buf, data, size); + + data = va_arg(args, const void*); + + rc = zmq_msg_send(&msg, sock, data ? ZMQ_SNDMORE : 0); + if (rc == -1) + { + zmqError("Unable to send ZMQ msg"); + zmq_msg_close(&msg); + return -1; + } + + zmq_msg_close(&msg); + + if (!data) + break; + + size = va_arg(args, size_t); + } + return 0; +} + +bool CZMQAbstractPublishNotifier::Initialize(void *pcontext) +{ + assert(!psocket); + + // check if address is being used by other publish notifier + std::multimap<std::string, CZMQAbstractPublishNotifier*>::iterator i = mapPublishNotifiers.find(address); + + if (i==mapPublishNotifiers.end()) + { + psocket = zmq_socket(pcontext, ZMQ_PUB); + if (!psocket) + { + zmqError("Failed to create socket"); + return false; + } + + int rc = zmq_bind(psocket, address.c_str()); + if (rc!=0) + { + zmqError("Failed to bind address"); + return false; + } + + // register this notifier for the address, so it can be reused for other publish notifier + mapPublishNotifiers.insert(std::make_pair(address, this)); + return true; + } + else + { + LogPrint("zmq", " Reuse socket for address %s\n", address); + + psocket = i->second->psocket; + mapPublishNotifiers.insert(std::make_pair(address, this)); + + return true; + } +} + +void CZMQAbstractPublishNotifier::Shutdown() +{ + assert(psocket); + + int count = mapPublishNotifiers.count(address); + + // remove this notifier from the list of publishers using this address + typedef std::multimap<std::string, CZMQAbstractPublishNotifier*>::iterator iterator; + std::pair<iterator, iterator> iterpair = mapPublishNotifiers.equal_range(address); + + for (iterator it = iterpair.first; it != iterpair.second; ++it) + { + if (it->second==this) + { + mapPublishNotifiers.erase(it); + break; + } + } + + if (count == 1) + { + LogPrint("zmq", "Close socket at address %s\n", address); + int linger = 0; + zmq_setsockopt(psocket, ZMQ_LINGER, &linger, sizeof(linger)); + zmq_close(psocket); + } + + psocket = 0; +} + +bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex) +{ + uint256 hash = pindex->GetBlockHash(); + LogPrint("zmq", "Publish hash block %s\n", hash.GetHex()); + char data[32]; + for (unsigned int i = 0; i < 32; i++) + data[31 - i] = hash.begin()[i]; + int rc = zmq_send_multipart(psocket, "hashblock", 9, data, 32, 0); + return rc == 0; +} + +bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &transaction) +{ + uint256 hash = transaction.GetHash(); + LogPrint("zmq", "Publish hash transaction %s\n", hash.GetHex()); + char data[32]; + for (unsigned int i = 0; i < 32; i++) + data[31 - i] = hash.begin()[i]; + int rc = zmq_send_multipart(psocket, "hashtx", 6, data, 32, 0); + return rc == 0; +} + +bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) +{ + LogPrint("zmq", "Publish raw block %s\n", pindex->GetBlockHash().GetHex()); + + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + { + LOCK(cs_main); + CBlock block; + if(!ReadBlockFromDisk(block, pindex)) + { + zmqError("Can't read block from disk"); + return false; + } + + ss << block; + } + + int rc = zmq_send_multipart(psocket, "rawblock", 8, &(*ss.begin()), ss.size(), 0); + return rc == 0; +} + +bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &transaction) +{ + uint256 hash = transaction.GetHash(); + LogPrint("zmq", "Publish raw transaction %s\n", hash.GetHex()); + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << transaction; + int rc = zmq_send_multipart(psocket, "rawtx", 5, &(*ss.begin()), ss.size(), 0); + return rc == 0; +} diff --git a/src/zmq/zmqpublishnotifier.h b/src/zmq/zmqpublishnotifier.h new file mode 100644 index 0000000000..44d5cbea67 --- /dev/null +++ b/src/zmq/zmqpublishnotifier.h @@ -0,0 +1,43 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_ZMQ_ZMQPUBLISHNOTIFIER_H +#define BITCOIN_ZMQ_ZMQPUBLISHNOTIFIER_H + +#include "zmqabstractnotifier.h" + +class CBlockIndex; + +class CZMQAbstractPublishNotifier : public CZMQAbstractNotifier +{ +public: + bool Initialize(void *pcontext); + void Shutdown(); +}; + +class CZMQPublishHashBlockNotifier : public CZMQAbstractPublishNotifier +{ +public: + bool NotifyBlock(const CBlockIndex *pindex); +}; + +class CZMQPublishHashTransactionNotifier : public CZMQAbstractPublishNotifier +{ +public: + bool NotifyTransaction(const CTransaction &transaction); +}; + +class CZMQPublishRawBlockNotifier : public CZMQAbstractPublishNotifier +{ +public: + bool NotifyBlock(const CBlockIndex *pindex); +}; + +class CZMQPublishRawTransactionNotifier : public CZMQAbstractPublishNotifier +{ +public: + bool NotifyTransaction(const CTransaction &transaction); +}; + +#endif // BITCOIN_ZMQ_ZMQPUBLISHNOTIFIER_H |