diff --git a/INSTALL b/INSTALL deleted file mode 100644 index 07ee48427cd..00000000000 --- a/INSTALL +++ /dev/null @@ -1,5 +0,0 @@ -Building Bitcoin - -See doc/build-*.md for instructions on building bitcoind, -the intended-for-services, no-graphical-interface, reference -implementation of Bitcoin. \ No newline at end of file diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 00000000000..520a47d9607 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,5 @@ +Building Bitcoin +================ + +See doc/build-*.md for instructions on building the various +elements of the Bitcoin Core reference implementation of Bitcoin. diff --git a/Makefile.am b/Makefile.am index b10d0850664..f3dc016b933 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,3 +1,7 @@ +# Copyright (c) 2013-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + ACLOCAL_AMFLAGS = -I build-aux/m4 SUBDIRS = src .PHONY: deploy FORCE diff --git a/autogen.sh b/autogen.sh index 46e36ff5b21..27417daf769 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,4 +1,8 @@ #!/bin/sh +# Copyright (c) 2013-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + set -e srcdir="$(dirname $0)" cd "$srcdir" diff --git a/build-aux/m4/ax_boost_base.m4 b/build-aux/m4/ax_boost_base.m4 index 45d948933d1..650c94fa647 100644 --- a/build-aux/m4/ax_boost_base.m4 +++ b/build-aux/m4/ax_boost_base.m4 @@ -33,7 +33,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 26 +#serial 27 AC_DEFUN([AX_BOOST_BASE], [ @@ -96,7 +96,7 @@ if test "x$want_boost" = "xyes"; then libsubdirs="lib64 libx32 lib lib64" ;; ppc64|s390x|sparc64|aarch64|ppc64le) - libsubdirs="lib64 lib lib64 ppc64le" + libsubdirs="lib64 lib lib64" ;; esac diff --git a/build-aux/m4/bitcoin_find_bdb48.m4 b/build-aux/m4/bitcoin_find_bdb48.m4 index 2aa493a6af6..0c3d49c2bc0 100644 --- a/build-aux/m4/bitcoin_find_bdb48.m4 +++ b/build-aux/m4/bitcoin_find_bdb48.m4 @@ -1,3 +1,7 @@ +dnl Copyright (c) 2013-2015 The Bitcoin Core developers +dnl Distributed under the MIT software license, see the accompanying +dnl file COPYING or http://www.opensource.org/licenses/mit-license.php. + AC_DEFUN([BITCOIN_FIND_BDB48],[ AC_MSG_CHECKING([for Berkeley DB C++ headers]) BDB_CPPFLAGS= diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index d26136cbe9a..509283a0b9c 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -1,3 +1,7 @@ +dnl Copyright (c) 2013-2016 The Bitcoin Core developers +dnl Distributed under the MIT software license, see the accompanying +dnl file COPYING or http://www.opensource.org/licenses/mit-license.php. + dnl Helper for cases where a qt dependency is not met. dnl Output: If qt version is auto, set bitcoin_enable_qt to false. Else, exit. AC_DEFUN([BITCOIN_QT_FAIL],[ diff --git a/build-aux/m4/bitcoin_subdir_to_include.m4 b/build-aux/m4/bitcoin_subdir_to_include.m4 index 66f106c7d47..7841042ac87 100644 --- a/build-aux/m4/bitcoin_subdir_to_include.m4 +++ b/build-aux/m4/bitcoin_subdir_to_include.m4 @@ -1,3 +1,7 @@ +dnl Copyright (c) 2013-2014 The Bitcoin Core developers +dnl Distributed under the MIT software license, see the accompanying +dnl file COPYING or http://www.opensource.org/licenses/mit-license.php. + dnl BITCOIN_SUBDIR_TO_INCLUDE([CPPFLAGS-VARIABLE-NAME],[SUBDIRECTORY-NAME],[HEADER-FILE]) dnl SUBDIRECTORY-NAME must end with a path separator AC_DEFUN([BITCOIN_SUBDIR_TO_INCLUDE],[ diff --git a/build-aux/m4/l_atomic.m4 b/build-aux/m4/l_atomic.m4 new file mode 100644 index 00000000000..75c43f9a92d --- /dev/null +++ b/build-aux/m4/l_atomic.m4 @@ -0,0 +1,46 @@ +dnl Copyright (c) 2015 Tim Kosse +dnl Copying and distribution of this file, with or without modification, are +dnl permitted in any medium without royalty provided the copyright notice +dnl and this notice are preserved. This file is offered as-is, without any +dnl warranty. + +# Some versions of gcc/libstdc++ require linking with -latomic if +# using the C++ atomic library. +# +# Sourced from http://bugs.debian.org/797228 + +m4_define([_CHECK_ATOMIC_testbody], [[ + #include + #include + + int main() { + std::atomic a{}; + + int64_t v = 5; + int64_t r = a.fetch_add(v); + return static_cast(r); + } +]]) + +AC_DEFUN([CHECK_ATOMIC], [ + + AC_LANG_PUSH(C++) + + AC_MSG_CHECKING([whether std::atomic can be used without link library]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([_CHECK_ATOMIC_testbody])],[ + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + LIBS="$LIBS -latomic" + AC_MSG_CHECKING([whether std::atomic needs -latomic]) + AC_LINK_IFELSE([AC_LANG_SOURCE([_CHECK_ATOMIC_testbody])],[ + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + AC_MSG_FAILURE([cannot figure out how to use std::atomic]) + ]) + ]) + + AC_LANG_POP +]) diff --git a/configure.ac b/configure.ac index 011af6bd1bd..d4e775aefbb 100644 --- a/configure.ac +++ b/configure.ac @@ -1,10 +1,10 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) -define(_CLIENT_VERSION_MINOR, 12) -define(_CLIENT_VERSION_REVISION, 99) +define(_CLIENT_VERSION_MINOR, 13) +define(_CLIENT_VERSION_REVISION, 2) define(_CLIENT_VERSION_BUILD, 0) -define(_CLIENT_VERSION_IS_RELEASE, false) +define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2016) define(_COPYRIGHT_HOLDERS,[The %s developers]) define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[Bitcoin Core]]) @@ -45,7 +45,6 @@ else CXXFLAGS_overridden=no fi AC_PROG_CXX -m4_ifdef([AC_PROG_OBJCXX],[AC_PROG_OBJCXX]) dnl By default, libtool for mingw refuses to link static libs into a dll for dnl fear of mixing pic/non-pic objects, and import/export complications. Since @@ -57,6 +56,18 @@ case $host in esac dnl Require C++11 compiler (no GNU extensions) AX_CXX_COMPILE_STDCXX([11], [noext], [mandatory]) +dnl Check if -latomic is required for +CHECK_ATOMIC + +dnl Unless the user specified OBJCXX, force it to be the same as CXX. This ensures +dnl that we get the same -std flags for both. +m4_ifdef([AC_PROG_OBJCXX],[ +if test "x${OBJCXX+set}" = "x"; then + OBJCXX="${CXX}" +fi +AC_PROG_OBJCXX +]) + dnl Libtool init checks. LT_INIT([pic-only]) @@ -67,7 +78,8 @@ AC_PATH_TOOL(STRIP, strip) AC_PATH_TOOL(GCOV, gcov) AC_PATH_PROG(LCOV, lcov) AC_PATH_PROG(JAVA, java) -AC_PATH_PROGS([PYTHON], [python3 python2.7 python2 python]) +dnl Python 3.x is supported from 3.4 on (see https://github.com/bitcoin/bitcoin/issues/7893) +AC_PATH_PROGS([PYTHON], [python3.6 python3.5 python3.4 python3 python2.7 python2 python]) AC_PATH_PROG(GENHTML, genhtml) AC_PATH_PROG([GIT], [git]) AC_PATH_PROG(CCACHE,ccache) @@ -366,8 +378,15 @@ case $host in TARGET_OS=linux LEVELDB_TARGET_FLAGS="-DOS_LINUX" ;; + *freebsd*) + LEVELDB_TARGET_FLAGS="-DOS_FREEBSD" + ;; + *openbsd*) + LEVELDB_TARGET_FLAGS="-DOS_OPENBSD" + ;; *) OTHER_OS=`echo ${host_os} | awk '{print toupper($0)}'` + AC_MSG_WARN([Guessing LevelDB OS as OS_${OTHER_OS}, please check whether this is correct, if not add an entry to configure.ac.]) LEVELDB_TARGET_FLAGS="-DOS_${OTHER_OS}" ;; esac @@ -516,8 +535,6 @@ if test x$TARGET_OS = xdarwin; then fi AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h]) -AC_SEARCH_LIBS([getaddrinfo_a], [anl], [AC_DEFINE(HAVE_GETADDRINFO_A, 1, [Define this symbol if you have getaddrinfo_a])]) -AC_SEARCH_LIBS([inet_pton], [nsl resolv], [AC_DEFINE(HAVE_INET_PTON, 1, [Define this symbol if you have inet_pton])]) AC_CHECK_DECLS([strnlen]) @@ -598,8 +615,11 @@ fi if test x$use_boost = xyes; then +dnl Minimum required Boost version +define(MINIMUM_REQUIRED_BOOST, 1.47.0) + dnl Check for boost libs -AX_BOOST_BASE +AX_BOOST_BASE([MINIMUM_REQUIRED_BOOST]) AX_BOOST_SYSTEM AX_BOOST_FILESYSTEM AX_BOOST_PROGRAM_OPTIONS @@ -825,6 +845,12 @@ fi dnl univalue check +need_bundled_univalue=yes + +if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononono; then + need_bundled_univalue=no +else + if test x$system_univalue != xno ; then found_univalue=no if test x$use_pkgconfig = xyes; then @@ -846,6 +872,7 @@ if test x$system_univalue != xno ; then if test x$found_univalue = xyes ; then system_univalue=yes + need_bundled_univalue=no elif test x$system_univalue = xyes ; then AC_MSG_ERROR([univalue not found]) else @@ -853,22 +880,17 @@ if test x$system_univalue != xno ; then fi fi -if test x$system_univalue = xno ; then +if test x$need_bundled_univalue = xyes ; then UNIVALUE_CFLAGS='-I$(srcdir)/univalue/include' UNIVALUE_LIBS='univalue/libunivalue.la' fi -AM_CONDITIONAL([EMBEDDED_UNIVALUE],[test x$system_univalue = xno]) + +fi + +AM_CONDITIONAL([EMBEDDED_UNIVALUE],[test x$need_bundled_univalue = xyes]) AC_SUBST(UNIVALUE_CFLAGS) AC_SUBST(UNIVALUE_LIBS) -CXXFLAGS_TEMP="$CXXFLAGS" -LIBS_TEMP="$LIBS" -CXXFLAGS="$CXXFLAGS $SSL_CFLAGS $CRYPTO_CFLAGS" -LIBS="$LIBS $SSL_LIBS $CRYPTO_LIBS" -AC_CHECK_HEADER([openssl/ec.h],, AC_MSG_ERROR(OpenSSL ec header missing),) -CXXFLAGS="$CXXFLAGS_TEMP" -LIBS="$LIBS_TEMP" - BITCOIN_QT_PATH_PROGS([PROTOC], [protoc],$protoc_bin_path) AC_MSG_CHECKING([whether to build bitcoind]) @@ -1003,8 +1025,8 @@ else AC_MSG_RESULT([no]) fi -if test x$build_bitcoin_utils$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_tests = xnonononono; then - AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-gui or --enable-tests]) +if test x$build_bitcoin_utils$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_bench$use_tests = xnononononono; then + AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-gui --enable-bench or --enable-tests]) fi AM_CONDITIONAL([TARGET_DARWIN], [test x$TARGET_OS = xdarwin]) @@ -1096,7 +1118,7 @@ PKGCONFIG_LIBDIR_TEMP="$PKG_CONFIG_LIBDIR" unset PKG_CONFIG_LIBDIR PKG_CONFIG_LIBDIR="$PKGCONFIG_LIBDIR_TEMP" -if test x$system_univalue = xno; then +if test x$need_bundled_univalue = xyes; then AC_CONFIG_SUBDIRS([src/univalue]) fi diff --git a/contrib/debian/bitcoin-qt.desktop b/contrib/debian/bitcoin-qt.desktop index 61e1aca6ad0..593d7584ab0 100644 --- a/contrib/debian/bitcoin-qt.desktop +++ b/contrib/debian/bitcoin-qt.desktop @@ -1,7 +1,8 @@ [Desktop Entry] Encoding=UTF-8 -Name=Bitcoin -Comment=Bitcoin P2P Cryptocurrency +Name=Bitcoin Core +Comment=Connect to the Bitcoin P2P Network +Comment[de]=Verbinde mit dem Bitcoin peer-to-peer Netzwerk Comment[fr]=Bitcoin, monnaie virtuelle cryptographique pair à pair Comment[tr]=Bitcoin, eşten eşe kriptografik sanal para birimi Exec=bitcoin-qt %u diff --git a/contrib/debian/manpages/bitcoin-cli.1 b/contrib/debian/manpages/bitcoin-cli.1 index 16c338dd3e5..dbd4745d192 100644 --- a/contrib/debian/manpages/bitcoin-cli.1 +++ b/contrib/debian/manpages/bitcoin-cli.1 @@ -1,21 +1,84 @@ -.TH BITCOIN-CLI "1" "February 2016" "bitcoin-cli 0.12" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH BITCOIN-CLI "1" "December 2016" "bitcoin-cli v0.13.2.0" "User Commands" .SH NAME -bitcoin-cli \- a remote procedure call client for Bitcoin Core. -.SH SYNOPSIS -bitcoin-cli [options] [params] \- Send command to Bitcoin Core. -.TP -bitcoin-cli [options] help \- Asks Bitcoin Core for a list of supported commands. +bitcoin-cli \- manual page for bitcoin-cli v0.13.2.0 .SH DESCRIPTION -This manual page documents the bitcoin-cli program. bitcoin-cli is an RPC client used to send commands to Bitcoin Core. - -.SH OPTIONS +Bitcoin Core RPC client version v0.13.2.0 +.SS "Usage:" +.TP +bitcoin\-cli [options] [params] +Send command to Bitcoin Core .TP -\fB\-?\fR -Show possible options. +bitcoin\-cli [options] help +List commands +.TP +bitcoin\-cli [options] help +Get help for a command +.SH OPTIONS +.HP +\-? +.IP +This help message +.HP +\fB\-conf=\fR +.IP +Specify configuration file (default: bitcoin.conf) +.HP +\fB\-datadir=\fR +.IP +Specify data directory +.PP +Chain selection options: +.HP +\fB\-testnet\fR +.IP +Use the test chain +.HP +\fB\-regtest\fR +.IP +Enter regression test mode, which uses a special chain in which blocks +can be solved instantly. This is intended for regression testing +tools and app development. +.HP +\fB\-rpcconnect=\fR +.IP +Send commands to node running on (default: 127.0.0.1) +.HP +\fB\-rpcport=\fR +.IP +Connect to JSON\-RPC on (default: 8332 or testnet: 18332) +.HP +\fB\-rpcwait\fR +.IP +Wait for RPC server to start +.HP +\fB\-rpcuser=\fR +.IP +Username for JSON\-RPC connections +.HP +\fB\-rpcpassword=\fR +.IP +Password for JSON\-RPC connections +.HP +\fB\-rpcclienttimeout=\fR +.IP +Timeout during HTTP requests (default: 900) +.HP +\fB\-stdin\fR +.IP +Read extra arguments from standard input, one per line until EOF/Ctrl\-D +(recommended for sensitive information such as passphrases) +.SH COPYRIGHT +Copyright (C) 2009-2016 The Bitcoin Core developers + +Please contribute if you find Bitcoin Core useful. Visit + for further information about the software. +The source code is available from . -.SH "SEE ALSO" -\fBbitcoind\fP, \fBbitcoin.conf\fP -.SH AUTHOR -This manual page was written by Ciemon Dunville . Permission is granted to copy, distribute and/or modify this document under the terms of the MIT License. +This is experimental software. +Distributed under the MIT software license, see the accompanying file COPYING +or . -The complete text of the MIT License can be found on the web at \fIhttp://opensource.org/licenses/MIT\fP. +This product includes software developed by the OpenSSL Project for use in the +OpenSSL Toolkit and cryptographic software written +by Eric Young and UPnP software written by Thomas Bernard. diff --git a/contrib/debian/manpages/bitcoin-qt.1 b/contrib/debian/manpages/bitcoin-qt.1 index 685a282080e..e14e1480afd 100644 --- a/contrib/debian/manpages/bitcoin-qt.1 +++ b/contrib/debian/manpages/bitcoin-qt.1 @@ -1,13 +1,501 @@ -.TH BITCOIN-QT "1" "February 2016" "bitcoin-qt 0.12" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH BITCOIN-QT "1" "December 2016" "bitcoin-qt v0.13.2.0" "User Commands" .SH NAME -bitcoin-qt \- peer-to-peer network based digital currency +bitcoin-qt \- manual page for bitcoin-qt v0.13.2.0 .SH DESCRIPTION -.SS "Usage:" +Bitcoin Core version v0.13.2.0 (64\-bit) +Usage: .IP bitcoin\-qt [command\-line options] .SH OPTIONS -.TP +.HP \-? -List options. -.SH "SEE ALSO" -bitcoind(1) +.IP +Print this help message and exit +.HP +\fB\-version\fR +.IP +Print version and exit +.HP +\fB\-alertnotify=\fR +.IP +Execute command when a relevant alert is received or we see a really +long fork (%s in cmd is replaced by message) +.HP +\fB\-blocknotify=\fR +.IP +Execute command when the best block changes (%s in cmd is replaced by +block hash) +.HP +\fB\-checkblocks=\fR +.IP +How many blocks to check at startup (default: 6, 0 = all) +.HP +\fB\-checklevel=\fR +.IP +How thorough the block verification of \fB\-checkblocks\fR is (0\-4, default: 3) +.HP +\fB\-conf=\fR +.IP +Specify configuration file (default: bitcoin.conf) +.HP +\fB\-datadir=\fR +.IP +Specify data directory +.HP +\fB\-dbcache=\fR +.IP +Set database cache size in megabytes (4 to 16384, default: 300) +.HP +\fB\-loadblock=\fR +.IP +Imports blocks from external blk000??.dat file on startup +.HP +\fB\-maxorphantx=\fR +.IP +Keep at most unconnectable transactions in memory (default: 100) +.HP +\fB\-maxmempool=\fR +.IP +Keep the transaction memory pool below megabytes (default: 300) +.HP +\fB\-mempoolexpiry=\fR +.IP +Do not keep transactions in the mempool longer than hours (default: +72) +.HP +\fB\-par=\fR +.IP +Set the number of script verification threads (\fB\-2\fR to 16, 0 = auto, <0 = +leave that many cores free, default: 0) +.HP +\fB\-pid=\fR +.IP +Specify pid file (default: bitcoind.pid) +.HP +\fB\-prune=\fR +.IP +Reduce storage requirements by pruning (deleting) old blocks. This mode +is incompatible with \fB\-txindex\fR and \fB\-rescan\fR. Warning: Reverting +this setting requires re\-downloading the entire blockchain. +(default: 0 = disable pruning blocks, >550 = target size in MiB +to use for block files) +.HP +\fB\-reindex\-chainstate\fR +.IP +Rebuild chain state from the currently indexed blocks +.HP +\fB\-reindex\fR +.IP +Rebuild chain state and block index from the blk*.dat files on disk +.HP +\fB\-sysperms\fR +.IP +Create new files with system default permissions, instead of umask 077 +(only effective with disabled wallet functionality) +.HP +\fB\-txindex\fR +.IP +Maintain a full transaction index, used by the getrawtransaction rpc +call (default: 0) +.PP +Connection options: +.HP +\fB\-addnode=\fR +.IP +Add a node to connect to and attempt to keep the connection open +.HP +\fB\-banscore=\fR +.IP +Threshold for disconnecting misbehaving peers (default: 100) +.HP +\fB\-bantime=\fR +.IP +Number of seconds to keep misbehaving peers from reconnecting (default: +86400) +.HP +\fB\-bind=\fR +.IP +Bind to given address and always listen on it. Use [host]:port notation +for IPv6 +.HP +\fB\-connect=\fR +.IP +Connect only to the specified node(s) +.HP +\fB\-discover\fR +.IP +Discover own IP addresses (default: 1 when listening and no \fB\-externalip\fR +or \fB\-proxy\fR) +.HP +\fB\-dns\fR +.IP +Allow DNS lookups for \fB\-addnode\fR, \fB\-seednode\fR and \fB\-connect\fR (default: 1) +.HP +\fB\-dnsseed\fR +.IP +Query for peer addresses via DNS lookup, if low on addresses (default: 1 +unless \fB\-connect\fR) +.HP +\fB\-externalip=\fR +.IP +Specify your own public address +.HP +\fB\-forcednsseed\fR +.IP +Always query for peer addresses via DNS lookup (default: 0) +.HP +\fB\-listen\fR +.IP +Accept connections from outside (default: 1 if no \fB\-proxy\fR or \fB\-connect\fR) +.HP +\fB\-listenonion\fR +.IP +Automatically create Tor hidden service (default: 1) +.HP +\fB\-maxconnections=\fR +.IP +Maintain at most connections to peers (default: 125) +.HP +\fB\-maxreceivebuffer=\fR +.IP +Maximum per\-connection receive buffer, *1000 bytes (default: 5000) +.HP +\fB\-maxsendbuffer=\fR +.IP +Maximum per\-connection send buffer, *1000 bytes (default: 1000) +.HP +\fB\-maxtimeadjustment\fR +.IP +Maximum allowed median peer time offset adjustment. Local perspective of +time may be influenced by peers forward or backward by this +amount. (default: 4200 seconds) +.HP +\fB\-onion=\fR +.IP +Use separate SOCKS5 proxy to reach peers via Tor hidden services +(default: \fB\-proxy\fR) +.HP +\fB\-onlynet=\fR +.IP +Only connect to nodes in network (ipv4, ipv6 or onion) +.HP +\fB\-permitbaremultisig\fR +.IP +Relay non\-P2SH multisig (default: 1) +.HP +\fB\-peerbloomfilters\fR +.IP +Support filtering of blocks and transaction with bloom filters (default: +1) +.HP +\fB\-port=\fR +.IP +Listen for connections on (default: 8333 or testnet: 18333) +.HP +\fB\-proxy=\fR +.IP +Connect through SOCKS5 proxy +.HP +\fB\-proxyrandomize\fR +.IP +Randomize credentials for every proxy connection. This enables Tor +stream isolation (default: 1) +.HP +\fB\-rpcserialversion\fR +.IP +Sets the serialization of raw transaction or block hex returned in +non\-verbose mode, non\-segwit(0) or segwit(1) (default: 1) +.HP +\fB\-seednode=\fR +.IP +Connect to a node to retrieve peer addresses, and disconnect +.HP +\fB\-timeout=\fR +.IP +Specify connection timeout in milliseconds (minimum: 1, default: 5000) +.HP +\fB\-torcontrol=\fR: +.IP +Tor control port to use if onion listening enabled (default: +127.0.0.1:9051) +.HP +\fB\-torpassword=\fR +.IP +Tor control port password (default: empty) +.HP +\fB\-whitebind=\fR +.IP +Bind to given address and whitelist peers connecting to it. Use +[host]:port notation for IPv6 +.HP +\fB\-whitelist=\fR +.IP +Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or +CIDR notated network (e.g. 1.2.3.0/24). 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 +.HP +\fB\-whitelistrelay\fR +.IP +Accept relayed transactions received from whitelisted peers even when +not relaying transactions (default: 1) +.HP +\fB\-whitelistforcerelay\fR +.IP +Force relay of transactions from whitelisted peers even if they violate +local relay policy (default: 1) +.HP +\fB\-maxuploadtarget=\fR +.IP +Tries to keep outbound traffic under the given target (in MiB per 24h), +0 = no limit (default: 0) +.PP +Wallet options: +.HP +\fB\-disablewallet\fR +.IP +Do not load the wallet and disable wallet RPC calls +.HP +\fB\-keypool=\fR +.IP +Set key pool size to (default: 100) +.HP +\fB\-fallbackfee=\fR +.IP +A fee rate (in BTC/kB) that will be used when fee estimation has +insufficient data (default: 0.0002) +.HP +\fB\-mintxfee=\fR +.IP +Fees (in BTC/kB) smaller than this are considered zero fee for +transaction creation (default: 0.00001) +.HP +\fB\-paytxfee=\fR +.IP +Fee (in BTC/kB) to add to transactions you send (default: 0.00) +.HP +\fB\-rescan\fR +.IP +Rescan the block chain for missing wallet transactions on startup +.HP +\fB\-salvagewallet\fR +.IP +Attempt to recover private keys from a corrupt wallet on startup +.HP +\fB\-spendzeroconfchange\fR +.IP +Spend unconfirmed change when sending transactions (default: 1) +.HP +\fB\-txconfirmtarget=\fR +.IP +If paytxfee is not set, include enough fee so transactions begin +confirmation on average within n blocks (default: 2) +.HP +\fB\-usehd\fR +.IP +Use hierarchical deterministic key generation (HD) after BIP32. Only has +effect during wallet creation/first start (default: 1) +.HP +\fB\-upgradewallet\fR +.IP +Upgrade wallet to latest format on startup +.HP +\fB\-wallet=\fR +.IP +Specify wallet file (within data directory) (default: wallet.dat) +.HP +\fB\-walletbroadcast\fR +.IP +Make the wallet broadcast transactions (default: 1) +.HP +\fB\-walletnotify=\fR +.IP +Execute command when a wallet transaction changes (%s in cmd is replaced +by TxID) +.HP +\fB\-zapwallettxes=\fR +.IP +Delete all wallet transactions and only recover those parts of the +blockchain through \fB\-rescan\fR on startup (1 = keep tx meta data e.g. +account owner and payment request information, 2 = drop tx meta +data) +.PP +Debugging/Testing options: +.HP +\fB\-uacomment=\fR +.IP +Append comment to the user agent string +.HP +\fB\-debug=\fR +.IP +Output debugging information (default: 0, supplying is +optional). If is not supplied or if = 1, +output all debugging information. can be: addrman, +alert, bench, cmpctblock, coindb, db, http, libevent, lock, +mempool, mempoolrej, net, proxy, prune, rand, reindex, rpc, +selectcoins, tor, zmq, qt. +.HP +\fB\-help\-debug\fR +.IP +Show all debugging options (usage: \fB\-\-help\fR \fB\-help\-debug\fR) +.HP +\fB\-logips\fR +.IP +Include IP addresses in debug output (default: 0) +.HP +\fB\-logtimestamps\fR +.IP +Prepend debug output with timestamp (default: 1) +.HP +\fB\-minrelaytxfee=\fR +.IP +Fees (in BTC/kB) smaller than this are considered zero fee for relaying, +mining and transaction creation (default: 0.00001) +.HP +\fB\-maxtxfee=\fR +.IP +Maximum total fees (in BTC) to use in a single wallet transaction or raw +transaction; setting this too low may abort large transactions +(default: 0.10) +.HP +\fB\-printtoconsole\fR +.IP +Send trace/debug info to console instead of debug.log file +.HP +\fB\-shrinkdebugfile\fR +.IP +Shrink debug.log file on client startup (default: 1 when no \fB\-debug\fR) +.PP +Chain selection options: +.HP +\fB\-testnet\fR +.IP +Use the test chain +.PP +Node relay options: +.HP +\fB\-bytespersigop\fR +.IP +Equivalent bytes per sigop in transactions for relay and mining +(default: 20) +.HP +\fB\-datacarrier\fR +.IP +Relay and mine data carrier transactions (default: 1) +.HP +\fB\-datacarriersize\fR +.IP +Maximum size of data in data carrier transactions we relay and mine +(default: 83) +.HP +\fB\-mempoolreplacement\fR +.IP +Enable transaction replacement in the memory pool (default: 1) +.PP +Block creation options: +.HP +\fB\-blockmaxweight=\fR +.IP +Set maximum BIP141 block weight (default: 3000000) +.HP +\fB\-blockmaxsize=\fR +.IP +Set maximum block size in bytes (default: 750000) +.HP +\fB\-blockprioritysize=\fR +.IP +Set maximum size of high\-priority/low\-fee transactions in bytes +(default: 0) +.PP +RPC server options: +.HP +\fB\-server\fR +.IP +Accept command line and JSON\-RPC commands +.HP +\fB\-rest\fR +.IP +Accept public REST requests (default: 0) +.HP +\fB\-rpcbind=\fR +.IP +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) +.HP +\fB\-rpccookiefile=\fR +.IP +Location of the auth cookie (default: data dir) +.HP +\fB\-rpcuser=\fR +.IP +Username for JSON\-RPC connections +.HP +\fB\-rpcpassword=\fR +.IP +Password for JSON\-RPC connections +.HP +\fB\-rpcauth=\fR +.IP +Username and hashed password for JSON\-RPC connections. The field + comes in the format: :$. A +canonical python script is included in share/rpcuser. This option +can be specified multiple times +.HP +\fB\-rpcport=\fR +.IP +Listen for JSON\-RPC connections on (default: 8332 or testnet: +18332) +.HP +\fB\-rpcallowip=\fR +.IP +Allow JSON\-RPC connections from specified source. Valid for 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 +.HP +\fB\-rpcthreads=\fR +.IP +Set the number of threads to service RPC calls (default: 4) +.PP +UI Options: +.HP +\fB\-choosedatadir\fR +.IP +Choose data directory on startup (default: 0) +.HP +\fB\-lang=\fR +.IP +Set language, for example "de_DE" (default: system locale) +.HP +\fB\-min\fR +.IP +Start minimized +.HP +\fB\-rootcertificates=\fR +.IP +Set SSL root certificates for payment request (default: \fB\-system\-\fR) +.HP +\fB\-splash\fR +.IP +Show splash screen on startup (default: 1) +.HP +\fB\-resetguisettings\fR +.IP +Reset all settings changed in the GUI +.SH COPYRIGHT +Copyright (C) 2009-2016 The Bitcoin Core developers + +Please contribute if you find Bitcoin Core useful. Visit + for further information about the software. +The source code is available from . + +This is experimental software. +Distributed under the MIT software license, see the accompanying file COPYING +or . + +This product includes software developed by the OpenSSL Project for use in the +OpenSSL Toolkit and cryptographic software written +by Eric Young and UPnP software written by Thomas Bernard. diff --git a/contrib/debian/manpages/bitcoin-tx.1 b/contrib/debian/manpages/bitcoin-tx.1 new file mode 100644 index 00000000000..0cbb4ad58fc --- /dev/null +++ b/contrib/debian/manpages/bitcoin-tx.1 @@ -0,0 +1,107 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH BITCOIN-TX "1" "December 2016" "bitcoin-tx v0.13.2.0" "User Commands" +.SH NAME +bitcoin-tx \- manual page for bitcoin-tx v0.13.2.0 +.SH DESCRIPTION +Bitcoin Core bitcoin\-tx utility version v0.13.2.0 +.SS "Usage:" +.TP +bitcoin\-tx [options] [commands] +Update hex\-encoded bitcoin transaction +.TP +bitcoin\-tx [options] \fB\-create\fR [commands] +Create hex\-encoded bitcoin transaction +.SH OPTIONS +.HP +\-? +.IP +This help message +.HP +\fB\-create\fR +.IP +Create new, empty TX. +.HP +\fB\-json\fR +.IP +Select JSON output +.HP +\fB\-txid\fR +.IP +Output only the hex\-encoded transaction id of the resultant transaction. +.PP +Chain selection options: +.HP +\fB\-testnet\fR +.IP +Use the test chain +.HP +\fB\-regtest\fR +.IP +Enter regression test mode, which uses a special chain in which blocks +can be solved instantly. This is intended for regression testing +tools and app development. +.PP +Commands: +.IP +delin=N +.IP +Delete input N from TX +.IP +delout=N +.IP +Delete output N from TX +.IP +in=TXID:VOUT(:SEQUENCE_NUMBER) +.IP +Add input to TX +.IP +locktime=N +.IP +Set TX lock time to N +.IP +nversion=N +.IP +Set TX version to N +.IP +outaddr=VALUE:ADDRESS +.IP +Add address\-based output to TX +.IP +outdata=[VALUE:]DATA +.IP +Add data\-based output to TX +.IP +outscript=VALUE:SCRIPT +.IP +Add raw script output to TX +.IP +sign=SIGHASH\-FLAGS +.IP +Add zero or more signatures to transaction. This command requires JSON +registers:prevtxs=JSON object, privatekeys=JSON object. See +signrawtransaction docs for format of sighash flags, JSON +objects. +.PP +Register Commands: +.IP +load=NAME:FILENAME +.IP +Load JSON file FILENAME into register NAME +.IP +set=NAME:JSON\-STRING +.IP +Set register NAME to given JSON\-STRING +.SH COPYRIGHT +Copyright (C) 2009-2016 The Bitcoin Core developers + +Please contribute if you find Bitcoin Core useful. Visit + for further information about the software. +The source code is available from . + +This is experimental software. +Distributed under the MIT software license, see the accompanying file COPYING +or . + +This product includes software developed by the OpenSSL Project for use in the +OpenSSL Toolkit and cryptographic software written +by Eric Young and UPnP software written by Thomas Bernard. diff --git a/contrib/debian/manpages/bitcoind.1 b/contrib/debian/manpages/bitcoind.1 index 5c3e52f441e..3b83f52ccc4 100644 --- a/contrib/debian/manpages/bitcoind.1 +++ b/contrib/debian/manpages/bitcoind.1 @@ -1,30 +1,480 @@ -.TH BITCOIND "1" "February 2016" "bitcoind 0.12" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH BITCOIND "1" "December 2016" "bitcoind v0.13.2.0" "User Commands" .SH NAME -bitcoind \- peer-to-peer network based digital currency -.SH SYNOPSIS -bitcoin [options] [params] -.TP -bitcoin [options] help \- Get help for a command +bitcoind \- manual page for bitcoind v0.13.2.0 .SH DESCRIPTION -This manual page documents the bitcoind program. Bitcoin is an experimental new digital currency that enables instant payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer technology to operate with no central authority: managing transactions and issuing money are carried out collectively by the network. Bitcoin Core is the name of open source software which enables the use of this currency. - -.SH OPTIONS +Bitcoin Core Daemon version v0.13.2.0 +.SS "Usage:" .TP +bitcoind [options] +Start Bitcoin Core Daemon +.SH OPTIONS +.HP \-? -List of possible options. -.SH COMMANDS -.TP -\fBhelp\fR -List commands. - -.TP -\fBhelp 'command'\fR -Get help for a command. +.IP +Print this help message and exit +.HP +\fB\-version\fR +.IP +Print version and exit +.HP +\fB\-alertnotify=\fR +.IP +Execute command when a relevant alert is received or we see a really +long fork (%s in cmd is replaced by message) +.HP +\fB\-blocknotify=\fR +.IP +Execute command when the best block changes (%s in cmd is replaced by +block hash) +.HP +\fB\-checkblocks=\fR +.IP +How many blocks to check at startup (default: 6, 0 = all) +.HP +\fB\-checklevel=\fR +.IP +How thorough the block verification of \fB\-checkblocks\fR is (0\-4, default: 3) +.HP +\fB\-conf=\fR +.IP +Specify configuration file (default: bitcoin.conf) +.HP +\fB\-daemon\fR +.IP +Run in the background as a daemon and accept commands +.HP +\fB\-datadir=\fR +.IP +Specify data directory +.HP +\fB\-dbcache=\fR +.IP +Set database cache size in megabytes (4 to 16384, default: 300) +.HP +\fB\-loadblock=\fR +.IP +Imports blocks from external blk000??.dat file on startup +.HP +\fB\-maxorphantx=\fR +.IP +Keep at most unconnectable transactions in memory (default: 100) +.HP +\fB\-maxmempool=\fR +.IP +Keep the transaction memory pool below megabytes (default: 300) +.HP +\fB\-mempoolexpiry=\fR +.IP +Do not keep transactions in the mempool longer than hours (default: +72) +.HP +\fB\-par=\fR +.IP +Set the number of script verification threads (\fB\-2\fR to 16, 0 = auto, <0 = +leave that many cores free, default: 0) +.HP +\fB\-pid=\fR +.IP +Specify pid file (default: bitcoind.pid) +.HP +\fB\-prune=\fR +.IP +Reduce storage requirements by pruning (deleting) old blocks. This mode +is incompatible with \fB\-txindex\fR and \fB\-rescan\fR. Warning: Reverting +this setting requires re\-downloading the entire blockchain. +(default: 0 = disable pruning blocks, >550 = target size in MiB +to use for block files) +.HP +\fB\-reindex\-chainstate\fR +.IP +Rebuild chain state from the currently indexed blocks +.HP +\fB\-reindex\fR +.IP +Rebuild chain state and block index from the blk*.dat files on disk +.HP +\fB\-sysperms\fR +.IP +Create new files with system default permissions, instead of umask 077 +(only effective with disabled wallet functionality) +.HP +\fB\-txindex\fR +.IP +Maintain a full transaction index, used by the getrawtransaction rpc +call (default: 0) +.PP +Connection options: +.HP +\fB\-addnode=\fR +.IP +Add a node to connect to and attempt to keep the connection open +.HP +\fB\-banscore=\fR +.IP +Threshold for disconnecting misbehaving peers (default: 100) +.HP +\fB\-bantime=\fR +.IP +Number of seconds to keep misbehaving peers from reconnecting (default: +86400) +.HP +\fB\-bind=\fR +.IP +Bind to given address and always listen on it. Use [host]:port notation +for IPv6 +.HP +\fB\-connect=\fR +.IP +Connect only to the specified node(s) +.HP +\fB\-discover\fR +.IP +Discover own IP addresses (default: 1 when listening and no \fB\-externalip\fR +or \fB\-proxy\fR) +.HP +\fB\-dns\fR +.IP +Allow DNS lookups for \fB\-addnode\fR, \fB\-seednode\fR and \fB\-connect\fR (default: 1) +.HP +\fB\-dnsseed\fR +.IP +Query for peer addresses via DNS lookup, if low on addresses (default: 1 +unless \fB\-connect\fR) +.HP +\fB\-externalip=\fR +.IP +Specify your own public address +.HP +\fB\-forcednsseed\fR +.IP +Always query for peer addresses via DNS lookup (default: 0) +.HP +\fB\-listen\fR +.IP +Accept connections from outside (default: 1 if no \fB\-proxy\fR or \fB\-connect\fR) +.HP +\fB\-listenonion\fR +.IP +Automatically create Tor hidden service (default: 1) +.HP +\fB\-maxconnections=\fR +.IP +Maintain at most connections to peers (default: 125) +.HP +\fB\-maxreceivebuffer=\fR +.IP +Maximum per\-connection receive buffer, *1000 bytes (default: 5000) +.HP +\fB\-maxsendbuffer=\fR +.IP +Maximum per\-connection send buffer, *1000 bytes (default: 1000) +.HP +\fB\-maxtimeadjustment\fR +.IP +Maximum allowed median peer time offset adjustment. Local perspective of +time may be influenced by peers forward or backward by this +amount. (default: 4200 seconds) +.HP +\fB\-onion=\fR +.IP +Use separate SOCKS5 proxy to reach peers via Tor hidden services +(default: \fB\-proxy\fR) +.HP +\fB\-onlynet=\fR +.IP +Only connect to nodes in network (ipv4, ipv6 or onion) +.HP +\fB\-permitbaremultisig\fR +.IP +Relay non\-P2SH multisig (default: 1) +.HP +\fB\-peerbloomfilters\fR +.IP +Support filtering of blocks and transaction with bloom filters (default: +1) +.HP +\fB\-port=\fR +.IP +Listen for connections on (default: 8333 or testnet: 18333) +.HP +\fB\-proxy=\fR +.IP +Connect through SOCKS5 proxy +.HP +\fB\-proxyrandomize\fR +.IP +Randomize credentials for every proxy connection. This enables Tor +stream isolation (default: 1) +.HP +\fB\-rpcserialversion\fR +.IP +Sets the serialization of raw transaction or block hex returned in +non\-verbose mode, non\-segwit(0) or segwit(1) (default: 1) +.HP +\fB\-seednode=\fR +.IP +Connect to a node to retrieve peer addresses, and disconnect +.HP +\fB\-timeout=\fR +.IP +Specify connection timeout in milliseconds (minimum: 1, default: 5000) +.HP +\fB\-torcontrol=\fR: +.IP +Tor control port to use if onion listening enabled (default: +127.0.0.1:9051) +.HP +\fB\-torpassword=\fR +.IP +Tor control port password (default: empty) +.HP +\fB\-whitebind=\fR +.IP +Bind to given address and whitelist peers connecting to it. Use +[host]:port notation for IPv6 +.HP +\fB\-whitelist=\fR +.IP +Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or +CIDR notated network (e.g. 1.2.3.0/24). 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 +.HP +\fB\-whitelistrelay\fR +.IP +Accept relayed transactions received from whitelisted peers even when +not relaying transactions (default: 1) +.HP +\fB\-whitelistforcerelay\fR +.IP +Force relay of transactions from whitelisted peers even if they violate +local relay policy (default: 1) +.HP +\fB\-maxuploadtarget=\fR +.IP +Tries to keep outbound traffic under the given target (in MiB per 24h), +0 = no limit (default: 0) +.PP +Wallet options: +.HP +\fB\-disablewallet\fR +.IP +Do not load the wallet and disable wallet RPC calls +.HP +\fB\-keypool=\fR +.IP +Set key pool size to (default: 100) +.HP +\fB\-fallbackfee=\fR +.IP +A fee rate (in BTC/kB) that will be used when fee estimation has +insufficient data (default: 0.0002) +.HP +\fB\-mintxfee=\fR +.IP +Fees (in BTC/kB) smaller than this are considered zero fee for +transaction creation (default: 0.00001) +.HP +\fB\-paytxfee=\fR +.IP +Fee (in BTC/kB) to add to transactions you send (default: 0.00) +.HP +\fB\-rescan\fR +.IP +Rescan the block chain for missing wallet transactions on startup +.HP +\fB\-salvagewallet\fR +.IP +Attempt to recover private keys from a corrupt wallet on startup +.HP +\fB\-spendzeroconfchange\fR +.IP +Spend unconfirmed change when sending transactions (default: 1) +.HP +\fB\-txconfirmtarget=\fR +.IP +If paytxfee is not set, include enough fee so transactions begin +confirmation on average within n blocks (default: 2) +.HP +\fB\-usehd\fR +.IP +Use hierarchical deterministic key generation (HD) after BIP32. Only has +effect during wallet creation/first start (default: 1) +.HP +\fB\-upgradewallet\fR +.IP +Upgrade wallet to latest format on startup +.HP +\fB\-wallet=\fR +.IP +Specify wallet file (within data directory) (default: wallet.dat) +.HP +\fB\-walletbroadcast\fR +.IP +Make the wallet broadcast transactions (default: 1) +.HP +\fB\-walletnotify=\fR +.IP +Execute command when a wallet transaction changes (%s in cmd is replaced +by TxID) +.HP +\fB\-zapwallettxes=\fR +.IP +Delete all wallet transactions and only recover those parts of the +blockchain through \fB\-rescan\fR on startup (1 = keep tx meta data e.g. +account owner and payment request information, 2 = drop tx meta +data) +.PP +Debugging/Testing options: +.HP +\fB\-uacomment=\fR +.IP +Append comment to the user agent string +.HP +\fB\-debug=\fR +.IP +Output debugging information (default: 0, supplying is +optional). If is not supplied or if = 1, +output all debugging information. can be: addrman, +alert, bench, cmpctblock, coindb, db, http, libevent, lock, +mempool, mempoolrej, net, proxy, prune, rand, reindex, rpc, +selectcoins, tor, zmq. +.HP +\fB\-help\-debug\fR +.IP +Show all debugging options (usage: \fB\-\-help\fR \fB\-help\-debug\fR) +.HP +\fB\-logips\fR +.IP +Include IP addresses in debug output (default: 0) +.HP +\fB\-logtimestamps\fR +.IP +Prepend debug output with timestamp (default: 1) +.HP +\fB\-minrelaytxfee=\fR +.IP +Fees (in BTC/kB) smaller than this are considered zero fee for relaying, +mining and transaction creation (default: 0.00001) +.HP +\fB\-maxtxfee=\fR +.IP +Maximum total fees (in BTC) to use in a single wallet transaction or raw +transaction; setting this too low may abort large transactions +(default: 0.10) +.HP +\fB\-printtoconsole\fR +.IP +Send trace/debug info to console instead of debug.log file +.HP +\fB\-shrinkdebugfile\fR +.IP +Shrink debug.log file on client startup (default: 1 when no \fB\-debug\fR) +.PP +Chain selection options: +.HP +\fB\-testnet\fR +.IP +Use the test chain +.PP +Node relay options: +.HP +\fB\-bytespersigop\fR +.IP +Equivalent bytes per sigop in transactions for relay and mining +(default: 20) +.HP +\fB\-datacarrier\fR +.IP +Relay and mine data carrier transactions (default: 1) +.HP +\fB\-datacarriersize\fR +.IP +Maximum size of data in data carrier transactions we relay and mine +(default: 83) +.HP +\fB\-mempoolreplacement\fR +.IP +Enable transaction replacement in the memory pool (default: 1) +.PP +Block creation options: +.HP +\fB\-blockmaxweight=\fR +.IP +Set maximum BIP141 block weight (default: 3000000) +.HP +\fB\-blockmaxsize=\fR +.IP +Set maximum block size in bytes (default: 750000) +.HP +\fB\-blockprioritysize=\fR +.IP +Set maximum size of high\-priority/low\-fee transactions in bytes +(default: 0) +.PP +RPC server options: +.HP +\fB\-server\fR +.IP +Accept command line and JSON\-RPC commands +.HP +\fB\-rest\fR +.IP +Accept public REST requests (default: 0) +.HP +\fB\-rpcbind=\fR +.IP +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) +.HP +\fB\-rpccookiefile=\fR +.IP +Location of the auth cookie (default: data dir) +.HP +\fB\-rpcuser=\fR +.IP +Username for JSON\-RPC connections +.HP +\fB\-rpcpassword=\fR +.IP +Password for JSON\-RPC connections +.HP +\fB\-rpcauth=\fR +.IP +Username and hashed password for JSON\-RPC connections. The field + comes in the format: :$. A +canonical python script is included in share/rpcuser. This option +can be specified multiple times +.HP +\fB\-rpcport=\fR +.IP +Listen for JSON\-RPC connections on (default: 8332 or testnet: +18332) +.HP +\fB\-rpcallowip=\fR +.IP +Allow JSON\-RPC connections from specified source. Valid for 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 +.HP +\fB\-rpcthreads=\fR +.IP +Set the number of threads to service RPC calls (default: 4) +.SH COPYRIGHT +Copyright (C) 2009-2016 The Bitcoin Core developers -.SH "SEE ALSO" -bitcoin.conf(5) -.SH AUTHOR -This manual page was written by Micah Anderson for the Debian system (but may be used by others). Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 3 or any later version published by the Free Software Foundation. +Please contribute if you find Bitcoin Core useful. Visit + for further information about the software. +The source code is available from . -On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL. +This is experimental software. +Distributed under the MIT software license, see the accompanying file COPYING +or . +This product includes software developed by the OpenSSL Project for use in the +OpenSSL Toolkit and cryptographic software written +by Eric Young and UPnP software written by Thomas Bernard. diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md index bb8b9246b87..af5c000b030 100644 --- a/contrib/devtools/README.md +++ b/contrib/devtools/README.md @@ -51,8 +51,9 @@ maintained: * for `src/secp256k1`: https://github.com/bitcoin-core/secp256k1.git (branch master) * for `src/leveldb`: https://github.com/bitcoin-core/leveldb.git (branch bitcoin-fork) * for `src/univalue`: https://github.com/bitcoin-core/univalue.git (branch master) +* for `src/crypto/ctaes`: https://github.com/bitcoin-core/ctaes.git (branch master) -Usage: `git-subtree-check.sh DIR COMMIT` +Usage: `git-subtree-check.sh DIR (COMMIT)` `COMMIT` may be omitted, in which case `HEAD` is used. diff --git a/contrib/devtools/fix-copyright-headers.py b/contrib/devtools/fix-copyright-headers.py index b6414a551f8..31a81ae4fad 100755 --- a/contrib/devtools/fix-copyright-headers.py +++ b/contrib/devtools/fix-copyright-headers.py @@ -16,7 +16,7 @@ import re year = time.gmtime()[0] -CMD_GIT_DATE = 'git log --format=@%%at -1 %s | date +"%%Y" -u -f -' +CMD_GIT_DATE = 'git log --format=%%ad --date=short -1 %s | cut -d"-" -f 1' CMD_REGEX= "perl -pi -e 's/(20\d\d)(?:-20\d\d)? The Bitcoin/$1-%s The Bitcoin/' %s" REGEX_CURRENT= re.compile("%s The Bitcoin" % year) CMD_LIST_FILES= "find %s | grep %s" diff --git a/contrib/devtools/git-subtree-check.sh b/contrib/devtools/git-subtree-check.sh index 1cb82fe6826..2384d66cad2 100755 --- a/contrib/devtools/git-subtree-check.sh +++ b/contrib/devtools/git-subtree-check.sh @@ -1,4 +1,7 @@ #!/bin/sh +# 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. DIR="$1" COMMIT="$2" diff --git a/contrib/devtools/optimize-pngs.py b/contrib/devtools/optimize-pngs.py index 799e0cc7d0f..b7b8dc00820 100755 --- a/contrib/devtools/optimize-pngs.py +++ b/contrib/devtools/optimize-pngs.py @@ -1,4 +1,7 @@ #!/usr/bin/env python +# 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. ''' Run this script 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 diff --git a/contrib/devtools/security-check.py b/contrib/devtools/security-check.py index 301fea85c1f..d774b7fea26 100755 --- a/contrib/devtools/security-check.py +++ b/contrib/devtools/security-check.py @@ -1,4 +1,7 @@ #!/usr/bin/python2 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' Perform basic ELF security checks on a series of executables. Exit status will be 0 if successful, and the program will be silent. diff --git a/contrib/devtools/test-security-check.py b/contrib/devtools/test-security-check.py index fed7626aaba..58817089c1c 100755 --- a/contrib/devtools/test-security-check.py +++ b/contrib/devtools/test-security-check.py @@ -1,4 +1,7 @@ #!/usr/bin/python2 +# Copyright (c) 2015-2016 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 script for security-check.py ''' diff --git a/contrib/gitian-keys/btcdrak-key.pgp b/contrib/gitian-keys/btcdrak-key.pgp index 60d76c0ec7a..f00dc729d57 100644 Binary files a/contrib/gitian-keys/btcdrak-key.pgp and b/contrib/gitian-keys/btcdrak-key.pgp differ diff --git a/contrib/gitian-keys/jl2012-key.pgp b/contrib/gitian-keys/jl2012-key.pgp index b8aad7fd88b..984f555cb72 100644 --- a/contrib/gitian-keys/jl2012-key.pgp +++ b/contrib/gitian-keys/jl2012-key.pgp @@ -1,105 +1,275 @@ -----BEGIN PGP PUBLIC KEY BLOCK----- -Comment: GPGTools - https://gpgtools.org +Version: SKS 1.1.5 +Comment: Hostname: pgp.mit.edu -mQINBFYhRd0BEAC+2VU+8+f9RTPLtl0C815oxaOCA9Tle13xNER8NjFrVwIuFQ64 -nO8Fbhd5KEEARuMS/lc5G6IV0QxBpDGE1sEjPQXrA6UnX8SDkNGhmoAsV07MP2Xl -glN9qqYUEoVD7ueh7Cp3A9rFjg7wcMJCPQDP6lZY4cPgYlE1C31TCrEdAsVVTQg+ -xIYWnhB92VxOJhk0N0h6xtCQ2MOtYDjYcBndQ5iK7L5jy5LI89YVRfbKtWqWZdwR -lgj2JCLeXKauXBI1qbedCJrz5e8nXcdqZt9TXSHo/XhNlqvsLiqBq4aXNU3xRkrv -fcweZ9jR9DjyQzefYFGaiCk37R4qLbaqQRm0luUizkCegIuTv44e/zig0im8yPAI -WtGnmBPSy4MpvvWiVVb+jHikdQG1T7g9kF6gEmj4kj9UseWnasiq+kkSNE67vLxb -uZDfA3QhavRMJbCNEY49/IX6urIsiCLFbe6C7JVWvJ7d5l3MAHE8Sut+ytjX7z7O -LFt7YD6loxGAdopEUZm50xs8PswKDajlzWGFXjDZdzQA1tb2CpHUtDkAInYDutR4 -qA29qtxaBswozzUYiDptGSkBqD1Nus7UAJYkwe2EjeszNPhmIAQXGWx2yWplPOJk -ZWDuhQtrDXZikl70q0ekIJ7bxkpMO8xUuhsBCS3Wn6GAtySy0XTttmItfQARAQAB -tBZqbDIwMTIgPGpsMjAxMkB4YnQuaGs+iQI3BBMBCgAhBQJWIUXdAhsBBQsJCAcD -BRUKCQgLBRYCAwEAAh4BAheAAAoJEMUkKhqzk2UXsbIQAJnXDjhEoKSILJRrKbg+ -MXP3Rhxc/ThXu5C8yhfYqKblqCaNNfEmrlercJKJVMvjY0tVTXYo8BEJmNN7nSNI -su8NheJ9vXacN3XrgkMPuFiUyKj9PGpSsM6Q8MjT0Bzd0pxodk+g0UEjyMktfu/3 -TqLsnoFPOtIjMOkr/uBzZn5d0AXIZQbAz4Xa2zBW+uR3OSXRRXCRJjCSWGIfDX0Y -i/Ea+3Be+y9bMqDa3nPULEkW7+RNuyjLr6QwPZ0/BpTTDcM6Vic2daFPO5B0+o3z -PMFmPcEd4nRHTPM9A5SaJtC8MjF/89mjhpxG3v8RqkqCdqdM2cezi/T4YD4jcynE -F36Ya3GuuewxEZci/N5ySG5gG8Y+80Wgc1e+sNtvIffHk3Wju2kOvNcBA2TBw36V -XCJXHROTA5+Cx4lUxOkQTJoYSVzx852WS6WHeLg1+XnDZvT7ciVIV0ExJQ9C1XOM -wjFMRsTWl+vflxmgCeHCIari57Jw3ij7ghRCgeqLp7FIXK5qSI4Tw2eajJpoTKPs -wlaO6kvOXtaCDH30FuVhKbPxII01Xi/A2ALtTkpA6mfnf19orQjv+HxX/iwUlpHM -UwsuhpZSQYIxIv/BOQnXDfw4TcjnHsqXZbqNzzFEjGurMTlOUX4KeTPscdOLUpnO -1FM4JIVybHHfhCH9Mpq+MIwCiQGBBBMBCABrBQJWpym9BYMJZgGAXhSAAAAAABUA -QGJsb2NraGFzaEBiaXRjb2luLm9yZzAwMDAwMDAwMDAwMDAwMDAwNWJiZWZkNGM3 -Mzk5OTE0OGRmZDQ1MjA5ZjA2MTUwMTljMTNjMGVjOWUwYmQ4MzUACgkQf6sRQmfk -+gQcZAgApPqnaIIE8Q5sruzua50RFRmmBtQys8sM95ciWYE4QaTXUnlhHl4QR4z/ -TQTRSBqXpdHQ9HBWrhFb6E0ykDEVx9zdEt0fvtlhHx1ItrZetfiA4PwidnyoDKs/ -/nt01RGreKSMDGInaQVEQxvEW+A0fwvcCdE8Mh3LcIydohfqUViB0c5zb7rUmize -+2Kt4Uth9T+ooo+UE87pHSJcxlcPOv6Dc7KeoUicD8DwWdsT7oxAMk9jj/ut4UNx -xOEp9Sa3sFN20tHMqyOZwnl22Py0y4ayJnceawpuka/bx7samg/2uUrO+dNKXObN -trebP83+8UFHOo7VGhesuawgwNjWW7kBjQRWIUbHAQwAy6re/3ur/fgNfE9yKivp -Bqmjq0eU5l3iT59hvKr7S+6GHUa+YvE9BBsawDSI4UILNQX0YGT1LRa20mC1okBX -5SIEpWzoZhybTMVMwS2ZHkUyO6VBAieUVojP3XQHFcDAiBvW7RRhJ2BU+v9DGo88 -HAYqKEB85P/i/E/a1xUfTWiiIhA8Dd/Hv6pzIG5QvN8XfrMIayLwpOV1G6KvBIJb -zyUVUvLyQySiZOyDczrAxzYq7b1qv8xwHDUzyUl6skPqbex1cFWIeiML9EY4DnZ9 -l3qb31Bhp+EHydv0esclM5XKQriSg/hsnJOLlCS45z/YhqGOCoD8QxXUJ71NhD/H -QR/AvGyTDcPr1/U1DJ0lG778wCOEe1Nad0G/8rcpHSY66RZR/Wf318S7uJt0mUw2 -JMt1BRxfbdgJaleUAqYjNQAMDb8LfPO6jhQnmf0nN99dpdzkwV/drVRcLDEnupDr -keBsokcuohzE0gbjUT4cNc0DuUsIELMTApG8KQCgzJy/ABEBAAGJA8QEGAEKAA8C -GwIFAlbi67wFCQGu8u4BqcDdIAQZAQoABgUCViFGxwAKCRDunlUgNL4k0qceC/91 -2ocEDwiu9kpBGCW0HD+VSyMVjLWMiClk+jPngvNEt63ZkYqRiy7fwnPuJrLFlaL0 -E0JLIweihC5AyPSJT1Q0LnOwbqCHn1s+9RfIodG/v6M48Ez4GffOtmYwW9KqogK7 -4FwdIx/wOIYDeh4rT7LRaWBNcIXO8J1+v/83u+Vx6TWKZTiZKQMEV8VOJWfSmTCE -6HVgUYvLCPB6DI+X4aVead1kayKOSuXlG/l94B5RHlJB/xQXZd1INyrZetTZxYzZ -CBhIWaZ/ji5vqFot0xVNYplRkbg1Mc96X+hwee8eiB/ySSWxUV/DDkA5ZzuE8n8R -EEjzqazjMNe50P7XKVg/eBE+TpgCDlqv69dqnOF326m6T3+FH/LDOHguQfB7pQKx -siviqjO3molBSyMHL39XFWyteVbgbbSaTRkpX//b7dQoFMiVhigcM78qoymBi6yX -qwpN13JoNuNJhEOwex5eEEUCVibFReUkBrYoGnWbwuOxiLORx/IbuNYOvsTGYEAJ -EMUkKhqzk2UXWScQAIvAgEpQpzuE1CWMBWcM/n4ruUrOVTeo6dYpUGN1LI0758xm -4VI47I8wPEy4pAbdPcqoaNnMcA/NpSYa3hV0svQDLqT96qKTrN71N1gNJa+5w+KN -rwev8MRpjuze9b4dn3avs4L9f0fkpzjSzezKwVb7loFSZqgKAaI0aSoOUTec9+OU -5ymgkYPEEF12ydkyMzLwyKrtEnIqgwQpjYTN/3P1x7Gkhv+E8Lz06TSga84yVy5I -5gO1Hklc3MW0J9jPJe3uALUtEh49KxCE2rdbIX7YbkxWaHHfK98Mu998IXr/4eUe -Zhf2CLC2cuuYbk1/rOcxPmeIJKa6S5PlWOf3Y2yLRO0VKcjD5pcGxiImoDVXC4VM -hztCVLddjU70c1ktSIBQBu9gkpPcECrzjYtpeAavOUgmpP/zQ8X2NGp6+5n9Wwii -tAgByNCg0s+PqcAZxup34b3ZY/t475tDlAmIOovH14Aa8g+0Ketj++9rPpmg9kGs -sGmn4mVItClaA7L9vZQQFnSxjyfICKsSxBhqded0lsinlzBfXDEh3N6fEXh81/Gg -zLUmTlkhcGaFXplYqrUIlkdO9PD4R2h5P6laLhK2dAf7oKavWHZQp02Yb5nVBiDc -KiVWKBP4nuTkWZCG5R966wpR1IOQQ3LykSd5SstcZX6iTpv4NZpCxI4CXpaCuQGN -BFYhSHABDADHaEJVygBdwU81c4YynyTOnWTZX+BR3EvRW51GcnfvjqkqgmlWNLET -JkswQ8+s0mjKGVnz4dkdr4cUbVegj/St7wzoO+m5mYIDMJf1j83Vo6lTo9FJFzbc -HrYC9RS7NkQmD7qzJz4KY/h0n5szFIC/JpYECBNzYrJQc8m2kZiSlyUQJve5/I5J -iI6QnM0x4kixNe32GITmKw9s3E2iRf6yXVlsrPouNS33lPXKtvmO1ae7R+G8Ve+D -JDv+TLxccy2iU9wuz4I3k20+rlmEwk17feDhfleh5Q+qjI4vkaNcXFa5coZE0HyW -SwAtLPSOv2vWkuFeYncXRyzg/CvKR57i9wnqMzNTMt3bHY2HezE13bHln5B/Jqr4 -ihhFQBqPG+UZlGYRfAI60PLh2yftX5xkm/POiLgEKF76/yIZI8wcPzzurAhFaZBp -8/MUv2ZJ/OUT4rdEVV+6XnrijNqVBU8mf8BML5CvjyhsU69yf1mvpiLQr34FNEcn -JekDGPIk97cAEQEAAYkCJQQYAQoADwIbDAUCVuLr0AUJAa7xWwAKCRDFJCoas5Nl -F8NMD/4hRoOKENEq940Z0iJg0TDvRvRnaIYsbneRQ3yg1DGVIQ+4RHmzQdpN9MW0 -5RTRLqJsW25ydWwh7y0O/oBRjaoDRAkMSIyOo/Fy+E9WWBmAwzeYCi91MyfetKIO -ocrXxpXXKnotAFDOgWGF8K+LlTDH/biOrd8ftgOVJWhz3X04ma7xvT2tQTqfFdbt -EivA+jFExq3No0Iq+Ctt/e0H2d9np62SeKBVdpbx9xAc2tPKKDSl+FyB7lj5CK5/ -FKhotl2bJhVXET48P6e+bFVwfRO7o48zuK5CJVbbdjhavQGhQoxfedW2dn9y7QoM -qayUuVIhULE/k+y3jsJBUT7p567nSdUGbc3uKt1sfPKYTdsFbHiTRltXmsIiv4bG -PslbXSvOQblFOXWrAE22CdKmGzhlEiFnbviZCCl0BFf4CwEVBJ3p9Lcoir1l9Aty -HIIFI3z1mmTz4F9BMbe6saNwBzO+Kh4+US5NV/hqvyz0aOLltb6KfI8WF8kOa1Cx -Djz/DTHnvMWO/dIOJuKsThfuxZZq3R1w3O36RB8XzDT/8NV86gfQwN07NWz1rdy4 -60fK36EjOJDqm/434/BDzWh8TqmnSamENxBTbICmWOj/25M26tA2S9zcPLJHTGMA -3yL3QlBtjWY2uNqr51cnZHgPKxBWzaRvcrZ+lUq5EG+F4J7q5rkBjQRWIUitAQwA -5A2AhW9DFxVsM105WEErD2NuM2rvtq7dTwArBEi2KdWkSGQvCE9xgyH8u5AEWxj8 -XXHE/rfunW0d9oF7Z9FbOuV+1HQOAj5hQQWLWHERwZ4gOAqG8ZKAbuwTlqitdiXE -PZiJYZSq0NXtngyeTx7XqzQSatfFOIQLzIiwPQXX0Tt+JB3B2SN/D2NP7rubzfS2 -Bg0ErhV20fPDl8YloEJFfj9lpF0ZJnJ5hXYP9Fl4MoPkyBkGPrJPooZ4FqUFHDiw -mttzP1BzFlwpAPGpI0NrkBdBlfFAtvhjreeB5Z4VYwt1xqoXgI+jYXAxoMl+rtkK -FdWaoT7wHwqDBeBWYXoyXA2dYIY8Ux1jeDBnREck7vaXhln6zXqMAQowE+F9OQnr -Wgf/LoOn5MYxsBDY9mPAO8urxUDE+Dq43JBXlS+jybMNZWdtkaBrIde7dw9IT8Fn -p8pG78DmgPxmRFH9QoypTqMfB+x7ZuB0fk1ud4ut33qLo78BWZoW0H++13CbSmrZ -ABEBAAGJAiUEGAEKAA8CGyAFAlbi690FCQGu8SoACgkQxSQqGrOTZRcNQBAAmeL1 -8Wr7vuvL5dySoYmWqHFvM8gRUwIGza5c3D29NYZJcPJRRkdGCV2IXEuUSOLtnjAN -kTM1TVMMnetqNR8Uryr7z3XjqYLnVwGqOPnFnlkE2zS3pG8AGG6OxxBhuEMvkwcd -1s3tWUlJYRWi1XhEjVZ5Km2pHsVxvoXeJCUVsa8nSXzqF8gOLm409NFMiKkp8QOG -heEV4yWrHkySi1fVfOdrHfBzu2lUmHGgSbmJIpLcK+cL3TjpJ+DkSNbniI13I/Eb -PO4Uai4a3QYz6sspZ7UzF/pjY5v6WpWXiVB5PP2Y5BrMUgWRlFxPYTc3KiIHUYVi -IjVtSOsVaRCHL/SYRq/qHs63XxlxKIhhilbR4OO+CvJ6N/vEpSbx69SqlxgDArZy -g3QQqerlLGpSFim9iWk3QBGWtQ96Ek6rjLLOn7b34I6bxXtfcOEo7gl0Y1TFkfOp -nsXAcRLrrXCpAhgC/vIQRTMKEcC18kj/vY144DwefzYCBhbI/rCSohAq8a/zhq2T -E+xlCYy931HWlUAGx/hms/0q+KQ712Zgk4XxXEx4RZiv3zl9Uph6c7SXxAMb8o2v -PzAxd3ShNOnng9hAl8zk5O1RZPa5u51ppkO1FsJ9zjb2Kvdg4ZEBtK8jETv9ckuq -yj9YmZZSRRQ2dujg81sLQ9CrO7WB3IGpwh+4lHQ= -=1irw +mQINBFYhRd0BEAC+2VU+8+f9RTPLtl0C815oxaOCA9Tle13xNER8NjFrVwIuFQ64nO8Fbhd5 +KEEARuMS/lc5G6IV0QxBpDGE1sEjPQXrA6UnX8SDkNGhmoAsV07MP2XlglN9qqYUEoVD7ueh +7Cp3A9rFjg7wcMJCPQDP6lZY4cPgYlE1C31TCrEdAsVVTQg+xIYWnhB92VxOJhk0N0h6xtCQ +2MOtYDjYcBndQ5iK7L5jy5LI89YVRfbKtWqWZdwRlgj2JCLeXKauXBI1qbedCJrz5e8nXcdq +Zt9TXSHo/XhNlqvsLiqBq4aXNU3xRkrvfcweZ9jR9DjyQzefYFGaiCk37R4qLbaqQRm0luUi +zkCegIuTv44e/zig0im8yPAIWtGnmBPSy4MpvvWiVVb+jHikdQG1T7g9kF6gEmj4kj9UseWn +asiq+kkSNE67vLxbuZDfA3QhavRMJbCNEY49/IX6urIsiCLFbe6C7JVWvJ7d5l3MAHE8Sut+ +ytjX7z7OLFt7YD6loxGAdopEUZm50xs8PswKDajlzWGFXjDZdzQA1tb2CpHUtDkAInYDutR4 +qA29qtxaBswozzUYiDptGSkBqD1Nus7UAJYkwe2EjeszNPhmIAQXGWx2yWplPOJkZWDuhQtr +DXZikl70q0ekIJ7bxkpMO8xUuhsBCS3Wn6GAtySy0XTttmItfQARAQABtBVKb2huc29uIExh +dSA8akBpai5oaz6JAjcEEwEKACECGwEFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AFAle9oRAA +CgkQxSQqGrOTZRck4Q//W/uBcS6LuvlZsoVYA3jmJInzkQx5DektEa0kSYysV+bJptyYrYV8 +RsQoNLJCkEh6Nk2rSvA6+dcHFwHhCQdYkTKJuUT8fQXhMF4C7G8iXPIjwSVnK0wa0c0eYtr3 +m6YPFsxfb+VTI/eQlu40HP3fWf4JN7zDXlz2IarC/GAsFlfZaXVpuSmCszr1uX+ywz4DYB6e +X0FuZk9fVYp0VERg+iAybV4+dqM4ZQ0Vu1cxLzrIPH2LdLHICxg79OMzAD1MHYnzkqajO0eI +blaZCc/QPaVv2bSi42WTeJJIISN+WrpeTlz3aoqhz7eGwKIckJAygnfVhYSCX7TWcaBTW6SB +wubLTfGJM2/T+OrXvVfeGAxLDPcFwpDDLkzv2u3cDbUbhf4i2+X8Xh/51yPRhi8EwIhJlaAR +CesE+iMHHvFV+ifdrqK81U9B9uiqN2xS9UBcXcJKmp9zYkPvYWfvT+D6QmvWmQ9p+EQLm9dg +zOZM6sZjWV6WtKsJWsaLQpqjC/iVnqbJoUb5g8S/vLJTT1KaTc0aTxs0v2jBFbld/kAu7Gfe +8cGz6ZWZfIBydjHFAYxCqPG0TYoQvy7eA01Djly0SPJH9PhYPBfznU91ZcaqWCCxXlp0PgCy +woMUiwP2kvK+HWTb4dCgbQwFNChNPkZ8QAsZuxGyZd7VxdbLPYkW1IiJAjcEEwEKACEFAldF +2iMCGwEFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQxSQqGrOTZRfnZRAAtR16Ns89cP8T +AzEvw55RtjeaeSmb0mw66KT/Bzzis7aWfvebP3Yki55MygHJNu+Bb/LDBNpYlJCjAoMCdLTc ++aDYCYZkrWOLQXWBTqa6XFLeexKX+gpKrNB505n00CWvVDVGsHJZ0Ha8CDZATIlj3e4owKVQ +jMLWY70MNwT/uc7YkSd38/EW5BkA76eE/AhHanqB4cWKGSNIiaq8OJYBiGNfb81Bz4Ly4kmW +VGgshYJPQpnMQDq713WZINT9Sn/NDfCrdNjFjHHxJjymZ7RoE5teqYOw7bnbA744VFxmYMrG +DrWfrTb1FORqltr4VHJnRpFIXv61DY4+eoTi1Zd5aH+ehpfDH1G/3UhPxbmM9wBsfsgy6dMy +N2XLmL9V/eHs4lzbTCyQwuiCCu99Vsn9VWcqsXGtv2xxsR3C9PYmvkm4Z1KqasKPTvRvZ7BD +0Bsdg2eyBq1m7HTK/gzSh4aCt8H6HbIz6MwO+POaAuHiZPOiESmLk5gG7wmE+/It/5vfEwDl +zL8+5PCCZtoRWaW7lyiezpAYjUq81SEsVsAqlrtIyvJnG+wATCdUHRN6GNtfZ1aMp0i3Jei5 +ST7LGAqVF6MiLskTbmIGW+P8at69orUmpA3vcvGUiSqW5JXXiPJUwUZxNAPxvpOh4B98tXfp +8kxmSyzcHR0a2Crouh+STPq0FmpsMjAxMiA8amwyMDEyQHhidC5oaz6JARwEEAECAAYFAldF +tGoACgkQmE8QzHcWn9Kybgf8DVmGhfIlQNvMH7YIg8hGrA/Q13C+FiHG4k2RQsd8vD25Sehj +GHNEsh26TxaF1XNC/yANipXyUkfYRkweVwRyJ/OTTivCtZQ/Ct0hJA+lDSfLEWm8pdiRGdio +McFq3Uy+KGBTbdlGaSsMbfCb6hunlGnnSC36X8yxnGwGPduZDlnKxrxey+eYgAN/ivC3bmRi +gVBAgDJXOBszmINGqg1T98MSe2ph7NxvWF9mF9JenJne/juThFMf0khnalQB7NeagX0UmS8F +/i5k5JgB/YVP4zTWhiAeetzBIfiQ4GadHyW52bNT9P6Rz9kKFA7xT7Olod+KaRr4+f8/6MCS +rgvpnokBHAQQAQoABgUCV0SRKQAKCRB0gQsBI0bJpko6CAC6g9o1t+/ZexSQVGqVGyU4w22Y ++OmLlx0XFYPi5ftZ8jjUkhnujis0i/KS1oreBzg0U92Cs3pWe05eDwVcwyTGJbGR2DPRM53/ +q2ETdzBbOPrSaOjaGRrMljPgu32kaeSRQbtPt+OIhvPuHATVEaHdDbsbyAQzCgpDnA2yvLIZ +wqFPIpX+zkn4tv4DRLOHa8+2loFMX9B0dKBDy8JrUDDt8sZ7dzoxEagUxLWgDzlQ3SkIyYZz +1Kk9RCx/TxQbDSQsGGpPyhEU3MeyCRQo8klDIxzBI8jfASnaxMdn5hdFdj0/CoEMTlHr2FVR +Z1ECKgDslJ0GwDhZ4HFbXnWcNx5aiQGBBBMBCABrBQJWpym9BYMJZgGAXhSAAAAAABUAQGJs +b2NraGFzaEBiaXRjb2luLm9yZzAwMDAwMDAwMDAwMDAwMDAwNWJiZWZkNGM3Mzk5OTE0OGRm +ZDQ1MjA5ZjA2MTUwMTljMTNjMGVjOWUwYmQ4MzUACgkQf6sRQmfk+gQcZAgApPqnaIIE8Q5s +ruzua50RFRmmBtQys8sM95ciWYE4QaTXUnlhHl4QR4z/TQTRSBqXpdHQ9HBWrhFb6E0ykDEV +x9zdEt0fvtlhHx1ItrZetfiA4PwidnyoDKs//nt01RGreKSMDGInaQVEQxvEW+A0fwvcCdE8 +Mh3LcIydohfqUViB0c5zb7rUmize+2Kt4Uth9T+ooo+UE87pHSJcxlcPOv6Dc7KeoUicD8Dw +WdsT7oxAMk9jj/ut4UNxxOEp9Sa3sFN20tHMqyOZwnl22Py0y4ayJnceawpuka/bx7samg/2 +uUrO+dNKXObNtrebP83+8UFHOo7VGhesuawgwNjWW4kCHAQQAQIABgUCV0HjEgAKCRCGD+uA +TmaTILHhD/9tumyLLIMuVH0hgBPk/S3BxvQXfzgMt8xYyKw3kmGkJpble9RGYWTcT+D9Dagp +ISzGlxo9hh+I8fArryQjDuiLN3OMxDmN5ctatbVTSQyXPHOLZj6y5X8mA5gKfZb1EvcZpwoS +3sUdpb31oCrmxtRVfYv7G1PaBYGf/XILu8mwu62VimhYlK/RrNZHNeFb4mJiLFviVFtAN98s +uT3lFT+BA/RsLUO+ogNcJEPQ/2Hhg93qUuKssdHKC8q5hLozTLOxepG5JjrKUS8PIXjicsnv +ui54VPkrh+8Lez7ezh1n3SXIWySN4H2Z3uFNTkgheLA7F0NhwVKPl9TDsEaaJROrbRFVc6aE +l6IQ8Z+8Uw6IifDKg9FrKlPoL9+vBrjjK9mE6E1CdLE9kttK7dHRbtCIx7TaiWIKwq6ihmOT +Eo1Ht2aq6Jg2KMCTJMQQN0vFtgUrAJMzE+hb0q2nl8VUWe44z+WuN4JX9f7sVXn4Vw6q4hfJ +7J4hgv5SRNlGRjHZzyaJfP95VnDIzKq0V3+fRGziIvA4r3TVcIVF2bvKK7H66zdOczhB141k +UGNuDsIqTaY84uk9L7lvC2jymeqV+VZu6tgxrn6OdyYd91Oya9bdduj1oycqX21pNUySkCMj +cXbDHl8EMtQVdctS+zF/Zu1dyK3Jhu2B7VyrdlMigkFBTIkCHAQQAQIABgUCV0b2MAAKCRBr +4s7RSpkXvBw+D/wLaBkcs9iXyVMGsFZgBhJODxz9BWSHfmNOsbvLSoPHCVJtmyshDBXJSruU +dOpPST3fo0T2TLdrL7DnP3nW8BqRkAoVAExZenCpT0p1oPaQj2rV82AxVjxc6syI0e83Lmp2 +USAqM3CPEvPBUL6yzmQdajJWfNaOM9XtePSsRXPGuT3gH8rZojFH7Ay+pBbZ48du+Pfm8fJD +M0heKIBQ4bOR4YTiV9t9LxOFzzt+MtEEixoyBfA56YQUaNfvjGr0NGeGXcwbGvtj7gt+14M0 +KJI0TTZWYvWbXDkhgmY4bhLbEcH6a8v3428F56n8TAYYzqD6XvdqiC0tFZgSeEAalaiNIohy +ZY/nKvZI/0lpfVBN2ozAFGF5SVUFkLUDgUzxJTnTacTDom5iifU2jcDWccNtPMNJCoufAYEk +dTQ9g3qtLypAEwW3PY58Cvfu7a6SiBFvMprwgOHBa7JVPPOkup0Dc8F1vtzxG8gASd8dK+8h ++yE0vGP0aCDGLrOT0IgT61LsIbg+9I13EPdTLaS4TflEncoC7TNy9kyuwmiQ+ObEl/IcMj1N +uEF3zp8HNlUUURN9GTI5Xx+zHXO7G1PO+wkKCKUoHLLJxMyqCw1TFIFCcF8PnJaGSfgNgNjq +GOZzar9AJY9djlNBgp73mYc0noRgxn8qYnmPEZPrZdbZIGTqCIkCHAQSAQoABgUCVz+PLwAK +CRDAwHYTL/p2lVR8EACqVrrQOqc+5512G2TzTHw1IKasdViMVi5iKeULU3POL2bHpmGcVWmT +slPB7TNXgGj+fr/ni6P5MceyQ8kgVKfHRfH6zF+VYIAD8qkKESCbT/Wlmv+6ACKV/knl9HXs +F/Pa/b7wOqrvdF7qo/NYwzgMghu3W/FMFET1KdQ4VwvysYUe66xmXARClT4M7+Awo0yqsWHw +Rk3uTJLE/GeRX7pmQQRqX2ZbKswXvWE4ECR1IlSphN0ul59o2Lq5ruNzvptnajSMJx7HHczI +oOv8QvfsCWaVE330C7096nZJrxECo5va8JYLZaeWrc/BMnp8ozQ9GsyAtidWi6upO8mzxYNV +5NAUuvCU9KBg3DRUxgAvoY6IRyiEV1XnNt5fzoHXHQJ4wmR49UWJ/Nz9+ZT6ZO7SzgYJCASM +/6XGfvuIPb6FpGZFhsleExacgepOiVGMsZ0FYXOEVhgOCBSJkAPCqe/igDXlFCDugHOvQgFc +RPFZOFxgAicrafyFKZ8HmZKM6wxtUDtgNJg6ANUTUA74TJjs8lU2H4BRvF1bfeTdjn7LI+Nt +qmwN1PU2TGCLvrLTMWfVjoIGELkaeLhLCPAN9XSOQASzksFHKQ5AWJ38dZVtdLu08IW/AKHo +e3lzLb67C/yJKmHoKioIacOdFkDQ8dTlJ6iSk8KlAGXb+6wZcyHlKokCNwQTAQoAIQUCViFF +3QIbAQULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAAKCRDFJCoas5NlF7GyEACZ1w44RKCkiCyU +aym4PjFz90YcXP04V7uQvMoX2Kim5agmjTXxJq5Xq3CSiVTL42NLVU12KPARCZjTe50jSLLv +DYXifb12nDd164JDD7hYlMio/TxqUrDOkPDI09Ac3dKcaHZPoNFBI8jJLX7v906i7J6BTzrS +IzDpK/7gc2Z+XdAFyGUGwM+F2tswVvrkdzkl0UVwkSYwklhiHw19GIvxGvtwXvsvWzKg2t5z +1CxJFu/kTbsoy6+kMD2dPwaU0w3DOlYnNnWhTzuQdPqN8zzBZj3BHeJ0R0zzPQOUmibQvDIx +f/PZo4acRt7/EapKgnanTNnHs4v0+GA+I3MpxBd+mGtxrrnsMRGXIvzeckhuYBvGPvNFoHNX +vrDbbyH3x5N1o7tpDrzXAQNkwcN+lVwiVx0TkwOfgseJVMTpEEyaGElc8fOdlkulh3i4Nfl5 +w2b0+3IlSFdBMSUPQtVzjMIxTEbE1pfr35cZoAnhwiGq4ueycN4o+4IUQoHqi6exSFyuakiO +E8NnmoyaaEyj7MJWjupLzl7Wggx99BblYSmz8SCNNV4vwNgC7U5KQOpn539faK0I7/h8V/4s +FJaRzFMLLoaWUkGCMSL/wTkJ1w38OE3I5x7Kl2W6jc8xRIxrqzE5TlF+Cnkz7HHTi1KZztRT +OCSFcmxx34Qh/TKavjCMAokCOgQTAQoAJAIbAQULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAIZ +AQUCV72hEAAKCRDFJCoas5NlF+DZEACN2sYVaoY752e6NhbKz4IeD56/zEP1x4yaUPvcbx3g +93i2oimghVnJWvwqxESFU2MgoXsMiLeuTADOSP4iP+DeBpB8qSuesHyAdyDRFq/w1qT3pKvT +mwPNXpTha9pHQoD4+/+pBwL2pR4l6MZ5+4iXJQFQQtVOhLfq2KuGuaPro4yBiyQX2eKCim1a +dNk6qtyRkFYlOrJRPqZastfNEb2Yc0DDUFLTzjyNsRxhwUd3DdOtqO//5XMvI9q/fc5wpDSP +zNzLoSkJM4V8TTg2sS23wCh3AZB2C7wnmWK6EHGNosFL5hJ6jtW96O5KwL2b/cvIv/+v214S +AhVblvhxgJ4zSQD2UpkORfKLbyp3wwRe4PFzlJWAPM8tjnLfGU4ACa+3tubDaembPM+Ft8Id +j85+HgE0W0s/eEOBTqxkWZr7blSKeiH4u3b193aGMIGGjF2SgGAORES76er8KPlPk19XsXzK +msO84zRT9JckcM5eCYTza2o3c3ycNZN6dkEAmhs8vzDWIBzB/L4galO8M00Vtck+EIScXNKV +SgZYbFb71zcKYT8yI53ZS04/1R8VAMEblwmxiTYscrjBoCcfEKEghYgsuICXjazFyXndI+m+ +Qx+XcLbZb4ubala+GlD4YwGaAHBVCIWHpBHHSH12Z0nermU0WRB4rb0uvewxqNNXoYkCOgQT +AQoAJAIbAQULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAUCV0XfoQIZAQAKCRDFJCoas5NlF3+p +EACzVNajdKSJAdCgKf36HCQ0TwkYeYuR1lWwwYzw8SPwjUGukSgo4P/recCm9HyT+AKO1vBc ++vgHTPECH3trDjWFg7bcL9P/zleKqvPuKGUIYihnXZmLLsavPBuSBmu7L9OR9jgSNY18s3Rl +/uQ6boOEKIP6gKREpBTJi3EUKWx/lp9K/nlCwTGOUP3sU0vhQTM+p0XYH2lP9ZeXBhKv75dj +qXn1fF65oZMzo/mKUCsXahJZPBrobwtcI4bdDzlDlcC5pC6SngrCJIzceCgsAkfutFG/H2MR +TyArvswpuZMpdniBbgnQDLWZ2bkP6qWBak9Z/80cXlSYhO4uP+rdvKMGxiobZj3YQ4u+8zqt +GhI1P7nsOtnmEp+tVWjriVrCCrSiSWE9vYmUbxw/So+FKfdQxVJ6ER1tDYcQQf+6itykJulU +Hml3jFaXYMVK6MnsKNTUvB1dlmYnSuuNUMzcwVQCrcxgpkDt7A9sJK0+PI+3HmViiLEN6fFX +0y25mmCi7aUQdgtntiaM/BroHgA+qceKJFDQrCYVJ2ecbrAfEWo6TimRcC31V/DRKnuZAb+Y +NvaSFFO0UQojsnCtSBBfUFY6zg7vZB+hGccduqdsMCuUvrBBOYcSjY8jWOuxZgSgkqc7YqZ2 +ILPj+9Q+9H1DIwpmb6titNlijrYNItB2C1KodokEHAQRAQgABgUCV0UdVgAKCRC9ApQkIfSI +n34PH/9coCxhWRgFd7S57bMX4OeG8drxazbrq/uByZVlkejqrZU4qVgwGWe1XVZXmsoI3ISp +hNBCE1ut94+9GdRmxtXVAWS7owFLoJhXWV71vq0AsJQJAF1qIZgQqVv4JfIcaT3lPw5aSSuS +bD+NU9xVnkx7ngARNxmrCSGuXWBJXSz+Yr5mugFROJJn4mn5+Zov3Tx9OYR7ekB0ojVQfdIz +yWJefZ+pF5Owc66TpQMd5qVdHAvcO16WQSOY5YeQc0AWPPPaUc8SKzqzBMCQ+XBASrxJDmWR +MN3NagcpZDQpkvXOmgZLJagsNGxF/VTQrfg2etGnDYBelvKtNJ0IgcPCDF97mApo8/Mis7G1 ++fVZFEMSLx9zH1rudfbN3dBxy5FIm/iL1iDCA9bhXd5LV3eOqyWse7PvEE9gjoim6CVSvtWS +6vSUBGGuIpRvaF2ZhROja+n582TkGu4/9Xwp20Y+xVxoxum1uJgvooJkt71K/lFOLa/GmcR+ +fsLX0wsutyRZFQvGpps0JAxso8u9RjmR3t4n3/dSMw916GLdxO9dI4uo07ComVjZyT9mx5Vw +SngFFUJCLaMEKNYpKYGsL5pvQkr/aEFsK+PwYoBik+dSI7KAHeIhy8n+OrOUKAts688eULpH +GyFgYGDOQTWfeko3KZMfqdHIjhGRtn1Lopr7sbhDmSfF55C9FBJUo8cobMc7RCgYAKUjm7pL +L3tq8ui4ENuRdsgm8b8f8/T6t/Q7OQAdc5Zg4kYkt5Bre9BSB4expcEfqLeIwqvRPBMOYJwL +2AVwU6S+gYsBUmy5DcKU3+Eh+67+D9ITH428CIn/9bzRkwY9XfskdENZyT8ciUvtoG5u+GY/ +tCR0kej74nlX8fMmXOTsURG9G829djbIEy+vKNH+qPFAOiEyauJOuMdc0Bnb73WlvYHPUHMM +QpRu+7dZqDmnUX4QQWAFCAvZRrEy+9ZLwNDzFRptAiDgwrCge0ROwWamhYFv5b6uA54vTjdl +PgakBXGVwPklcrjRipGw52rIr33x3BYzaEGX1/bQDsDMT/jMDLaRvLc2c5JmuP1qQ7M9vE6l +cb/YUeJQP/K5n52xEuo0eJ3MDfgZ+YCHYChjiMaQJ1MnTHFM85YKY4QJeLViZfsdPktW8Z5B +4YxKtZh4a887EAX+fx49GK976U/S4FhWp9d35yOg6gBvElxP6rW6lU5sJnppu+OA+jAWgjSJ +oO7PfwAn9pbg6Sy5PKpNtoRkucp515w9oaHbrJefGFEAaTXsAry0XQfqJGUkEV6wqCagZQhQ +r5dsdN4ONhVb88qY312bPDNsRKMQ8d9GiTb6tkzK+KB0Z9ROpTXQTrPuaM+YjtHJvPUoEVnI +J+60uQGNBFYhRscBDADLqt7/e6v9+A18T3IqK+kGqaOrR5TmXeJPn2G8qvtL7oYdRr5i8T0E +GxrANIjhQgs1BfRgZPUtFrbSYLWiQFflIgSlbOhmHJtMxUzBLZkeRTI7pUECJ5RWiM/ddAcV +wMCIG9btFGEnYFT6/0MajzwcBiooQHzk/+L8T9rXFR9NaKIiEDwN38e/qnMgblC83xd+swhr +IvCk5XUboq8EglvPJRVS8vJDJKJk7INzOsDHNirtvWq/zHAcNTPJSXqyQ+pt7HVwVYh6Iwv0 +RjgOdn2XepvfUGGn4QfJ2/R6xyUzlcpCuJKD+Gyck4uUJLjnP9iGoY4KgPxDFdQnvU2EP8dB +H8C8bJMNw+vX9TUMnSUbvvzAI4R7U1p3Qb/ytykdJjrpFlH9Z/fXxLu4m3SZTDYky3UFHF9t +2AlqV5QCpiM1AAwNvwt887qOFCeZ/Sc3312l3OTBX92tVFwsMSe6kOuR4GyiRy6iHMTSBuNR +Phw1zQO5SwgQsxMCkbwpAKDMnL8AEQEAAYkDxAQYAQoADwIbAgUCVuLrvAUJAa7y7gGpwN0g +BBkBCgAGBQJWIUbHAAoJEO6eVSA0viTSpx4L/3XahwQPCK72SkEYJbQcP5VLIxWMtYyIKWT6 +M+eC80S3rdmRipGLLt/Cc+4mssWVovQTQksjB6KELkDI9IlPVDQuc7BuoIefWz71F8ih0b+/ +ozjwTPgZ9862ZjBb0qqiArvgXB0jH/A4hgN6HitPstFpYE1whc7wnX6//ze75XHpNYplOJkp +AwRXxU4lZ9KZMITodWBRi8sI8HoMj5fhpV5p3WRrIo5K5eUb+X3gHlEeUkH/FBdl3Ug3Ktl6 +1NnFjNkIGEhZpn+OLm+oWi3TFU1imVGRuDUxz3pf6HB57x6IH/JJJbFRX8MOQDlnO4TyfxEQ +SPOprOMw17nQ/tcpWD94ET5OmAIOWq/r12qc4XfbqbpPf4Uf8sM4eC5B8HulArGyK+KqM7ea +iUFLIwcvf1cVbK15VuBttJpNGSlf/9vt1CgUyJWGKBwzvyqjKYGLrJerCk3Xcmg240mEQ7B7 +Hl4QRQJWJsVF5SQGtigadZvC47GIs5HH8hu41g6+xMZgQAkQxSQqGrOTZRdZJxAAi8CASlCn +O4TUJYwFZwz+fiu5Ss5VN6jp1ilQY3UsjTvnzGbhUjjsjzA8TLikBt09yqho2cxwD82lJhre +FXSy9AMupP3qopOs3vU3WA0lr7nD4o2vB6/wxGmO7N71vh2fdq+zgv1/R+SnONLN7MrBVvuW +gVJmqAoBojRpKg5RN5z345TnKaCRg8QQXXbJ2TIzMvDIqu0SciqDBCmNhM3/c/XHsaSG/4Tw +vPTpNKBrzjJXLkjmA7UeSVzcxbQn2M8l7e4AtS0SHj0rEITat1shfthuTFZocd8r3wy733wh +ev/h5R5mF/YIsLZy65huTX+s5zE+Z4gkprpLk+VY5/djbItE7RUpyMPmlwbGIiagNVcLhUyH +O0JUt12NTvRzWS1IgFAG72CSk9wQKvONi2l4Bq85SCak//NDxfY0anr7mf1bCKK0CAHI0KDS +z4+pwBnG6nfhvdlj+3jvm0OUCYg6i8fXgBryD7Qp62P772s+maD2QaywaafiZUi0KVoDsv29 +lBAWdLGPJ8gIqxLEGGp153SWyKeXMF9cMSHc3p8ReHzX8aDMtSZOWSFwZoVemViqtQiWR070 +8PhHaHk/qVouErZ0B/ugpq9YdlCnTZhvmdUGINwqJVYoE/ie5ORZkIblH3rrClHUg5BDcvKR +J3lKy1xlfqJOm/g1mkLEjgJeloKJA8QEGAEKAA8CGwIFAle9oT8FCQN9jeYBqcDdIAQZAQoA +BgUCViFGxwAKCRDunlUgNL4k0qceC/912ocEDwiu9kpBGCW0HD+VSyMVjLWMiClk+jPngvNE +t63ZkYqRiy7fwnPuJrLFlaL0E0JLIweihC5AyPSJT1Q0LnOwbqCHn1s+9RfIodG/v6M48Ez4 +GffOtmYwW9KqogK74FwdIx/wOIYDeh4rT7LRaWBNcIXO8J1+v/83u+Vx6TWKZTiZKQMEV8VO +JWfSmTCE6HVgUYvLCPB6DI+X4aVead1kayKOSuXlG/l94B5RHlJB/xQXZd1INyrZetTZxYzZ +CBhIWaZ/ji5vqFot0xVNYplRkbg1Mc96X+hwee8eiB/ySSWxUV/DDkA5ZzuE8n8REEjzqazj +MNe50P7XKVg/eBE+TpgCDlqv69dqnOF326m6T3+FH/LDOHguQfB7pQKxsiviqjO3molBSyMH +L39XFWyteVbgbbSaTRkpX//b7dQoFMiVhigcM78qoymBi6yXqwpN13JoNuNJhEOwex5eEEUC +VibFReUkBrYoGnWbwuOxiLORx/IbuNYOvsTGYEAJEMUkKhqzk2UXmJYQAJ4fOk1J7qOUuMZj +gidORGCfejuuzKWT/dPboHeUzhfvZ01yn6hM4lLO2/pVQTJ//JWcHd9pCs9YiCMdOHiAV9h4 ++drXCcwENpwZqzk56TvfRRcKkWs5h6w4EAIKpNA7dRJiEl3FVDvZ8RW7Woydrxlpe3uszqg5 +ullPREj7Rn6kPX634iyx0FWYOaVO/jSRmdM7A9U/o0/VhHoENZ3st2ophAuGvnDcBwVU2oal +o+UOMvgJxyCcqeX2yOz/Zdbcgl6yMDlmxAD4ujCqnZ0bM3ClX1BCFPj0miLg39fx4TvIpD4V +8+da8H1jGOJZ+bzn0kNeurZ7FsdvPh/QsYz1MgxI0Y6NW/WhSLtWeq5J0ik+8HhblOBVKNlQ +zoLpIay6cUicax23kQF9zjjwvadkUved4YUWG2ndmo/8iwSrjDkM2GO+YWbTm3Ciw3s0ZK3p +RyeEKmPBU+C6keMBxxy6J/6ft9b5/1ZCDfnr/9feb006snkApbuh9AH+5U03fMN6x267sxot +Pey/FYN4/LaZqJD7+24jGIZdW3XPmtETzAqncnTIiOhLu+K0KoDQ+OCXLypRMJfURQ2XT5uD +M5mregBIAWbfC+AqF+R7QTmEaa/cZxzmeiMjj6C2VqiKUtyt52VXwL2F6te+5FSxaeigCZRf +g02/go5YdwJAeU0jB4V4iQPEBBgBCgAPBQJWIUbHAhsCBQkA7U4AAakJEMUkKhqzk2UXwN0g +BBkBCgAGBQJWIUbHAAoJEO6eVSA0viTSpx4L/3XahwQPCK72SkEYJbQcP5VLIxWMtYyIKWT6 +M+eC80S3rdmRipGLLt/Cc+4mssWVovQTQksjB6KELkDI9IlPVDQuc7BuoIefWz71F8ih0b+/ +ozjwTPgZ9862ZjBb0qqiArvgXB0jH/A4hgN6HitPstFpYE1whc7wnX6//ze75XHpNYplOJkp +AwRXxU4lZ9KZMITodWBRi8sI8HoMj5fhpV5p3WRrIo5K5eUb+X3gHlEeUkH/FBdl3Ug3Ktl6 +1NnFjNkIGEhZpn+OLm+oWi3TFU1imVGRuDUxz3pf6HB57x6IH/JJJbFRX8MOQDlnO4TyfxEQ +SPOprOMw17nQ/tcpWD94ET5OmAIOWq/r12qc4XfbqbpPf4Uf8sM4eC5B8HulArGyK+KqM7ea +iUFLIwcvf1cVbK15VuBttJpNGSlf/9vt1CgUyJWGKBwzvyqjKYGLrJerCk3Xcmg240mEQ7B7 +Hl4QRQJWJsVF5SQGtigadZvC47GIs5HH8hu41g6+xMZgQGxeD/9ynUFUsAd8UnpvHN2tTzPF +eKb1MPBzVaW0IfA8IYZKhtm4S5yp/dNpt/eQfTs74LkXN57i8576m72I5g2jarVtJG2mB9bv +5RQBrOerWT1LxQA2Q8SMOsazUIMJUU63LH//mSPHOAkTVZPFew9y9voiMYA31TcJriRYDJbI +jH3GuMRAEJYA8GiY7/HdZHnmDK0SfdOMIprQJEn6G+I7MwI8qCvb2eGLfAM2Dwq/OQ7GtLIE +fbJqI/aMPhxQHc1GsberuWYnBJMuMpScWVUJufigzpO2qQgr9VjJAAdPwgh5YfURGXHoa0IE +Sy5BnbYBcdkgq9eY3SwJUx4XhlduzEu3Z6imR0tcgaM6wIIyqCwlup0jo8rNWZ+NQmdI3cqs +IPqrKn3vRXXVT50Y12EiaWbbrd34fmKWYBNHguoEj9BEW5jP1axM43MAXzsMfuLQhJsabrF0 +JWXsJRV5gZW3iNl2D0H0fTKNqBCXeLqGPsrCnmm1m2qlvKvpJClwURC56f+X5BDq5lMvL76e +2FxPDUJNjE3UxzMQjOacRztiTst7xKIhPZEHVIQyw17bkDhxspavwU6gOsFwXKEuuwjCUyA0 +pLAH+dQzVzCRCRP2ltg92gjf2PtwdbwtiMg8t15Q3Hd/hb0EV6d+xdzYLPI8KhOe/8znmK+x +4weSvG7GdRvb+rkBjQRWIUhwAQwAx2hCVcoAXcFPNXOGMp8kzp1k2V/gUdxL0VudRnJ3746p +KoJpVjSxEyZLMEPPrNJoyhlZ8+HZHa+HFG1XoI/0re8M6DvpuZmCAzCX9Y/N1aOpU6PRSRc2 +3B62AvUUuzZEJg+6syc+CmP4dJ+bMxSAvyaWBAgTc2KyUHPJtpGYkpclECb3ufyOSYiOkJzN +MeJIsTXt9hiE5isPbNxNokX+sl1ZbKz6LjUt95T1yrb5jtWnu0fhvFXvgyQ7/ky8XHMtolPc +Ls+CN5NtPq5ZhMJNe33g4X5XoeUPqoyOL5GjXFxWuXKGRNB8lksALSz0jr9r1pLhXmJ3F0cs +4Pwrykee4vcJ6jMzUzLd2x2Nh3sxNd2x5Z+Qfyaq+IoYRUAajxvlGZRmEXwCOtDy4dsn7V+c +ZJvzzoi4BChe+v8iGSPMHD887qwIRWmQafPzFL9mSfzlE+K3RFVful564ozalQVPJn/ATC+Q +r48obFOvcn9Zr6Yi0K9+BTRHJyXpAxjyJPe3ABEBAAGJAiUEGAEKAA8CGwwFAlbi69AFCQGu +8VsACgkQxSQqGrOTZRfDTA/+IUaDihDRKveNGdIiYNEw70b0Z2iGLG53kUN8oNQxlSEPuER5 +s0HaTfTFtOUU0S6ibFtucnVsIe8tDv6AUY2qA0QJDEiMjqPxcvhPVlgZgMM3mAovdTMn3rSi +DqHK18aV1yp6LQBQzoFhhfCvi5Uwx/24jq3fH7YDlSVoc919OJmu8b09rUE6nxXW7RIrwPox +RMatzaNCKvgrbf3tB9nfZ6etknigVXaW8fcQHNrTyig0pfhcge5Y+QiufxSoaLZdmyYVVxE+ +PD+nvmxVcH0Tu6OPM7iuQiVW23Y4Wr0BoUKMX3nVtnZ/cu0KDKmslLlSIVCxP5Pst47CQVE+ +6eeu50nVBm3N7irdbHzymE3bBWx4k0ZbV5rCIr+Gxj7JW10rzkG5RTl1qwBNtgnSphs4ZRIh +Z274mQgpdARX+AsBFQSd6fS3KIq9ZfQLchyCBSN89Zpk8+BfQTG3urGjcAczvioePlEuTVf4 +ar8s9Gji5bW+inyPFhfJDmtQsQ48/w0x57zFjv3SDibirE4X7sWWat0dcNzt+kQfF8w0//DV +fOoH0MDdOzVs9a3cuOtHyt+hIziQ6pv+N+PwQ81ofE6pp0mphDcQU2yApljo/9uTNurQNkvc +3DyyR0xjAN8i90JQbY1mNrjaq+dXJ2R4DysQVs2kb3K2fpVKuRBvheCe6uaJAiUEGAEKAA8C +GwwFAle9oUoFCQN9jFgACgkQxSQqGrOTZRc0yQ/9Hk0ADSWmmggcisR+ONFze/3UWww+hVdc +5qvLaTvVayeoTqsDpECoZT1gvrLMwUZ24cWxgc8Xx6QuNaFX0nql+1iaGpuyfo1sgg1q7e6y +z+d/3MvnsfB1i9g1tlRSWsbziljaqH5B5mq5hhYm5rmjJr4KbXCtyWu1XlaVOFRcUNsUipnG +jdqrmHfbY4mMDhBlCcMly8eKoWyX+hSZ2TsK5ryApK8thtvv3bANJnmaKXD+5kdrXkaW2u/s +duVlW1ad1oTDEM5y7m1LqUMtVZUHdLn+f+XGi0t8EKMW2PQ+owkkEEiQrIrArXXouhl/b4fD +kqozjE15eoBCghQBauo68/HodTGDwOBUTFgKc32g3rKkumljIzfYtsZVUk7XkvT/D9bsiHqP +R7M6m8FU+PDXRX75c3z/fp927AgZpdd6sfQygLX7JDoSZa5iY8nk2MOr8aN7vBIIiRm3k6dY +jOlpiaNVNfVYIl7XJ3k9F5Kdf6g8rNnYezphmO6+HvnEWnHYa5T7jPhFFeQwRWYK1gLSXzft +hrFrYKkLBtfUefPFOUp6/dMeRMLoXGW0TxN9pGem3Ovf2ixM9ti0BfKPjcW+GEtxgU9DloLW +oezXNdQPoD80xdYZuCV4NsTstrP5IeUkTPefnxOUWS1XiwfEDhpv1oydL0MnWDYK+jXacpVT +4mCJAiUEGAEKAA8FAlYhSHACGwwFCQDtTgAACgkQxSQqGrOTZRfcZRAAvGiCvggMlw339PE6 +coJxLV/PWIAiwj7QPtjWXm9aswHSMK5mmQ5/RgfC/11oV9QBK3t3eknEGcKhJDkw4xAB3aYd +kp35+mC6CXtRnIKXb9vyznGqd6DW0+FyDYj9/1ynuwmKnJnAzSDr7j3rpYbxGkmVBGwLfK85 +psidexuiK+1chvNHFrT4bwzSX6lB6808SQYO80vddRgjiZySs8JxziKSFv1DhsrgL/QCSlwq +QKcImQLRHvVqF8hBTUwSMbvGhmLVHCyekayh/rNtAgDf2163BYRMZfXZXxIOoNsD/bCsJzir +BmhwDY/9WhO8VDY1JcSD8V7zH4mLE6QDLllLVhyV330zsn14gaV6GC+q9NBqlEdYlofGXluj +HHAbg4V5SbWMzeJjsMUQDSLuSLMEN1GX4bHiY7amHRv4fyEtGLyDp9WaT6wn5CHoFC92GOsK +NAxTJw/kIa0J1O5cnIuS1fbymQtt9itbmSUHNhLcoE9Vg1V5yl9000bFLhKK5zv6cWQtEP8U +thTSJGHtnZ/zGC+oDvDbtyaTfa8Cj80IuGO4CBojG3HKzt/ZI4g2Gi8fnkYLgI/tx2u/c0/2 +WzAP5sEsGyiq7MvcPBV87JVnzzJvgxm4+lO1DVD/QKQd/NtrVJ8jXcuc21DE5o704rnBLawU +f4U6Tde+ZZx9WgxvAMi5AY0EViFIrQEMAOQNgIVvQxcVbDNdOVhBKw9jbjNq77au3U8AKwRI +tinVpEhkLwhPcYMh/LuQBFsY/F1xxP637p1tHfaBe2fRWzrlftR0DgI+YUEFi1hxEcGeIDgK +hvGSgG7sE5aorXYlxD2YiWGUqtDV7Z4Mnk8e16s0EmrXxTiEC8yIsD0F19E7fiQdwdkjfw9j +T+67m830tgYNBK4VdtHzw5fGJaBCRX4/ZaRdGSZyeYV2D/RZeDKD5MgZBj6yT6KGeBalBRw4 +sJrbcz9QcxZcKQDxqSNDa5AXQZXxQLb4Y63ngeWeFWMLdcaqF4CPo2FwMaDJfq7ZChXVmqE+ +8B8KgwXgVmF6MlwNnWCGPFMdY3gwZ0RHJO72l4ZZ+s16jAEKMBPhfTkJ61oH/y6Dp+TGMbAQ +2PZjwDvLq8VAxPg6uNyQV5Uvo8mzDWVnbZGgayHXu3cPSE/BZ6fKRu/A5oD8ZkRR/UKMqU6j +Hwfse2bgdH5NbneLrd96i6O/AVmaFtB/vtdwm0pq2QARAQABiQIlBBgBCgAPAhsgBQJW4uvd +BQkBrvEqAAoJEMUkKhqzk2UXDUAQAJni9fFq+77ry+XckqGJlqhxbzPIEVMCBs2uXNw9vTWG +SXDyUUZHRgldiFxLlEji7Z4wDZEzNU1TDJ3rajUfFK8q+89146mC51cBqjj5xZ5ZBNs0t6Rv +ABhujscQYbhDL5MHHdbN7VlJSWEVotV4RI1WeSptqR7Fcb6F3iQlFbGvJ0l86hfIDi5uNPTR +TIipKfEDhoXhFeMlqx5MkotX1Xznax3wc7tpVJhxoEm5iSKS3CvnC9046Sfg5EjW54iNdyPx +GzzuFGouGt0GM+rLKWe1Mxf6Y2Ob+lqVl4lQeTz9mOQazFIFkZRcT2E3NyoiB1GFYiI1bUjr +FWkQhy/0mEav6h7Ot18ZcSiIYYpW0eDjvgryejf7xKUm8evUqpcYAwK2coN0EKnq5SxqUhYp +vYlpN0ARlrUPehJOq4yyzp+29+COm8V7X3DhKO4JdGNUxZHzqZ7FwHES661wqQIYAv7yEEUz +ChHAtfJI/72NeOA8Hn82AgYWyP6wkqIQKvGv84atkxPsZQmMvd9R1pVABsf4ZrP9KvikO9dm +YJOF8VxMeEWYr985fVKYenO0l8QDG/KNrz8wMXd0oTTp54PYQJfM5OTtUWT2ubudaaZDtRbC +fc429ir3YOGRAbSvIxE7/XJLqso/WJmWUkUUNnbo4PNbC0PQqzu1gdyBqcIfuJR0iQIlBBgB +CgAPAhsgBQJXvaFaBQkDfYwqAAoJEMUkKhqzk2UXy2cP/R9HTn+6b1WuvpZ7fK4zyFSM5DF1 +86pyLe8XKEzxOs5zSaJRs3bziVdWlTTYC4f5D3TQH6NjlD9KThpOqIX2W90dfLYiRUDVzZtk +Qs0gM0U9RGYoqP08oUhdoy+Qe19y/f3yaEsUgpZ5WEj3IaOBnwvsFWQr00t8eQLRPZxc65cY +JLkHuB/S+PyQy+BATFg1JepM5Ov4oddcRAyk6eD/fnIhb5hxZGipVpSCZiCCQbrXEKbCiWP+ +LJg+N9cmRJ901tx0eEKDH4JxKxtQybhHtAV7IqrFWxHNJWDiW2gcsaSMVRi+I3f7Tq88GJdc +VGjxwzRAySVZ529ZEJydQKfa144P20NL0HrIdOiHVgJgXrL19+uyaF+7wTqV+B8z8HNl61zh +ZZpwYchKkq7X73yaOIt6o7JuUCdpYqei1a8pdNrhKyqOyqzvXlUevaRlNO0uDoUKdpLOOWm7 +cHuksxl1ZyMRr5v0e9qtfekR9st2+9RQYW+8ZbY82G9XG9ywpOpjKYcUYg9yZDxHmLaGPozU +4GCln7sIwAkG0iQfQDWF6PrzOvlAXaqEm19Z/LFsyALTHl5cAE8K0a/5qQc6hnLS9Dm/rZug +mbxazVhVszVkOzC2g6qmaJOzou2x3LFzT5PUg+VapVnFcmpFDx5mJMfJ7a1AyVDiv3zj/9zF +JuP1GY+6iQIlBBgBCgAPBQJWIUitAhsgBQkA7U4AAAoJEMUkKhqzk2UXirwP/1V1gt3j6mFK +Uzx3GE+Mb+W4crfTJY+r2yYhgUEK/Eqmp3qUgtJGv+sRJjgi5LMwTBhyHCQCSVujSBT3rKz6 +e6eVVezcPEmCSMyCV07GIQ0AlAWbYS7/ENGZx4EHlA7dJBDVYnEoLKbKmRu+v1pFcK9jPrkK +DwhRGthDm8qod4WxWay/yhiNlxcikeajI7+0ON7kfTPHeogxGD3wXMby4kosNn6QlvzKFHsu +srfr8YdBxQ5lIXPZyqNTs58oDX/1bM/SyernTZRNGauSVFy+sKiH/LSMWJsfnOT2sZ1AbpRS +khWEIPUZjEWFFjh7vxO1T5MHPq95HSPv6bj8whU+7KOrIkMuDBoceemrzcTXmBMYc181FqCx +8RAad4CX/oKDD23HKQ7bO/lJYdhIQb+QCKVWjdOS+BbjdDanS2EyGog1V6AMWcR+WhPdzO1W +mNhk8D5mrUQysjd5JrAzZ1w2iw1I3e9o02Zex/zPSAUmpa00hzN8pIZezX1I1h1mXHqpYKP1 +EvVdUEFsshVmjRNAYsKflXFWRxqQGlL0PSK6vHGlN6ZvkoS4qHRYV8zoPBivIyTcGLuRORHG +sRlAsdtxbwFYKeVqd/Yw5cocrw1C7ja1OpBFdL8kEt2kzOTAwdAebvntf0GY8TEPA4dYUFmv +Ww8nn+QC38ITGK9hVF+eVkuR +=j8C/ -----END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/macdeploy/detached-sig-apply.sh b/contrib/macdeploy/detached-sig-apply.sh index 781fe315eda..91674a92e6f 100755 --- a/contrib/macdeploy/detached-sig-apply.sh +++ b/contrib/macdeploy/detached-sig-apply.sh @@ -1,4 +1,8 @@ #!/bin/sh +# 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. + set -e UNSIGNED="$1" diff --git a/contrib/macdeploy/detached-sig-create.sh b/contrib/macdeploy/detached-sig-create.sh index 89a2da32f7a..5022ea88bc2 100755 --- a/contrib/macdeploy/detached-sig-create.sh +++ b/contrib/macdeploy/detached-sig-create.sh @@ -1,4 +1,8 @@ #!/bin/sh +# 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. + set -e ROOTDIR=dist diff --git a/contrib/qos/tc.sh b/contrib/qos/tc.sh index f6206042120..aaf5e1fa11e 100644 --- a/contrib/qos/tc.sh +++ b/contrib/qos/tc.sh @@ -1,3 +1,7 @@ +# Copyright (c) 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. + #network interface on which to limit traffic IF="eth0" #limit of the network interface in question diff --git a/contrib/qt_translations.py b/contrib/qt_translations.py index fd8a8b71298..cfdeed41aba 100755 --- a/contrib/qt_translations.py +++ b/contrib/qt_translations.py @@ -1,4 +1,7 @@ #!/usr/bin/env python +# Copyright (c) 2011 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. # Helpful little script that spits out a comma-separated list of # language codes for Qt icons that should be included diff --git a/contrib/seeds/makeseeds.py b/contrib/seeds/makeseeds.py index 4072405ef50..041f224f40e 100755 --- a/contrib/seeds/makeseeds.py +++ b/contrib/seeds/makeseeds.py @@ -1,4 +1,7 @@ #!/usr/bin/env python +# Copyright (c) 2013-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. # # Generate seeds.txt from Pieter's DNS seeder # diff --git a/contrib/spendfrom/setup.py b/contrib/spendfrom/setup.py index 01b9768a5b0..f80736752ae 100644 --- a/contrib/spendfrom/setup.py +++ b/contrib/spendfrom/setup.py @@ -1,3 +1,6 @@ +# Copyright (c) 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. from distutils.core import setup setup(name='btcspendfrom', version='1.0', diff --git a/contrib/spendfrom/spendfrom.py b/contrib/spendfrom/spendfrom.py index 72ee0425eb2..086b91b267e 100755 --- a/contrib/spendfrom/spendfrom.py +++ b/contrib/spendfrom/spendfrom.py @@ -1,4 +1,7 @@ #!/usr/bin/env python +# Copyright (c) 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. # # Use the raw transactions API to spend bitcoins received on particular addresses, # and send any change back to that same address. diff --git a/contrib/testgen/base58.py b/contrib/testgen/base58.py index b716495145f..72b288b2dc9 100644 --- a/contrib/testgen/base58.py +++ b/contrib/testgen/base58.py @@ -1,3 +1,6 @@ +# Copyright (c) 2012 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' Bitcoin base58 encoding and decoding. diff --git a/contrib/testgen/gen_base58_test_vectors.py b/contrib/testgen/gen_base58_test_vectors.py index 18134369536..8518774db3d 100755 --- a/contrib/testgen/gen_base58_test_vectors.py +++ b/contrib/testgen/gen_base58_test_vectors.py @@ -1,4 +1,7 @@ #!/usr/bin/env python +# Copyright (c) 2012 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' Generate valid and invalid base58 address and private key test vectors. diff --git a/contrib/tidy_datadir.sh b/contrib/tidy_datadir.sh index 5d6d8264442..8960f8811d8 100755 --- a/contrib/tidy_datadir.sh +++ b/contrib/tidy_datadir.sh @@ -1,4 +1,7 @@ #!/bin/bash +# Copyright (c) 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. if [ -d "$1" ]; then cd "$1" diff --git a/contrib/verify-commits/gpg.sh b/contrib/verify-commits/gpg.sh index 375d7117257..09ff2375447 100755 --- a/contrib/verify-commits/gpg.sh +++ b/contrib/verify-commits/gpg.sh @@ -1,4 +1,8 @@ #!/bin/sh +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + INPUT=$(cat /dev/stdin) VALID=false REVSIG=false diff --git a/contrib/verify-commits/pre-push-hook.sh b/contrib/verify-commits/pre-push-hook.sh index c57222818ab..c21febb9e92 100755 --- a/contrib/verify-commits/pre-push-hook.sh +++ b/contrib/verify-commits/pre-push-hook.sh @@ -1,4 +1,8 @@ #!/bin/bash +# 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. + if ! [[ "$2" =~ ^(git@)?(www.)?github.com(:|/)bitcoin/bitcoin(.git)?$ ]]; then exit 0 fi diff --git a/contrib/verify-commits/verify-commits.sh b/contrib/verify-commits/verify-commits.sh index 5219331e2e5..cfe4f11a0b7 100755 --- a/contrib/verify-commits/verify-commits.sh +++ b/contrib/verify-commits/verify-commits.sh @@ -1,4 +1,8 @@ #!/bin/sh +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + # Not technically POSIX-compliant due to use of "local", but almost every # shell anyone uses today supports it, so its probably fine diff --git a/contrib/verifybinaries/verify.sh b/contrib/verifybinaries/verify.sh index 657c3bd33c2..6b6b28184d4 100755 --- a/contrib/verifybinaries/verify.sh +++ b/contrib/verifybinaries/verify.sh @@ -1,4 +1,7 @@ #!/bin/bash +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. ### This script attempts to download the signature file SHA256SUMS.asc from bitcoin.org ### It first checks if the signature passes, and then downloads the files specified in diff --git a/contrib/zmq/zmq_sub.py b/contrib/zmq/zmq_sub.py index 6268123dd8e..3dea5e3c144 100755 --- a/contrib/zmq/zmq_sub.py +++ b/contrib/zmq/zmq_sub.py @@ -1,4 +1,7 @@ #!/usr/bin/env python2 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. import array import binascii diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index ef1307c241b..2bedbc6f18f 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -3,6 +3,7 @@ $(package)_version=1_59_0 $(package)_download_path=http://sourceforge.net/projects/boost/files/boost/1.59.0 $(package)_file_name=$(package)_$($(package)_version).tar.bz2 $(package)_sha256_hash=727a932322d94287b62abb1bd2d41723eec4356a7728909e38adb65ca25241ca +$(package)_patches=fix-win-wake-from-sleep.patch define $(package)_set_vars $(package)_config_opts_release=variant=release @@ -25,6 +26,7 @@ $(package)_cxxflags_linux=-fPIC endef define $(package)_preprocess_cmds + patch -p1 < $($(package)_patch_dir)/fix-win-wake-from-sleep.patch && \ echo "using $(boost_toolset_$(host_os)) : : $($(package)_cxx) : \"$($(package)_cxxflags) $($(package)_cppflags)\" \"$($(package)_ldflags)\" \"$(boost_archiver_$(host_os))\" \"$(host_STRIP)\" \"$(host_RANLIB)\" \"$(host_WINDRES)\" : ;" > user-config.jam endef diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk index e34cf7be2f1..1bb8cb5d266 100644 --- a/depends/packages/miniupnpc.mk +++ b/depends/packages/miniupnpc.mk @@ -1,8 +1,8 @@ package=miniupnpc -$(package)_version=2.0 +$(package)_version=2.0.20170509 $(package)_download_path=http://miniupnp.free.fr/files $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=d434ceb8986efbe199c5ca53f90ed53eab290b1e6d0530b717eb6fa49d61f93b +$(package)_sha256_hash=d3c368627f5cdfb66d3ebd64ca39ba54d6ff14a61966dbecb8dd296b7039f16a define $(package)_set_vars $(package)_build_opts=CC="$($(package)_cc)" diff --git a/depends/packages/native_biplist.mk b/depends/packages/native_biplist.mk index eb8672d556a..3c6e8900f66 100644 --- a/depends/packages/native_biplist.mk +++ b/depends/packages/native_biplist.mk @@ -4,6 +4,11 @@ $(package)_download_path=https://pypi.python.org/packages/source/b/biplist $(package)_file_name=biplist-$($(package)_version).tar.gz $(package)_sha256_hash=b57cadfd26e4754efdf89e9e37de87885f9b5c847b2615688ca04adfaf6ca604 $(package)_install_libdir=$(build_prefix)/lib/python/dist-packages +$(package)_patches=sorted_list.patch + +define $(package)_preprocess_cmds + patch -p1 < $($(package)_patch_dir)/sorted_list.patch +endef define $(package)_build_cmds python setup.py build diff --git a/depends/patches/boost/fix-win-wake-from-sleep.patch b/depends/patches/boost/fix-win-wake-from-sleep.patch new file mode 100644 index 00000000000..8fb4d3028bf --- /dev/null +++ b/depends/patches/boost/fix-win-wake-from-sleep.patch @@ -0,0 +1,31 @@ +--- old/libs/thread/src/win32/thread.cpp ++++ new/libs/thread/src/win32/thread.cpp +@@ -645,7 +645,7 @@ + } Detailed; + } Reason; + } REASON_CONTEXT, *PREASON_CONTEXT; +- static REASON_CONTEXT default_reason_context={0/*POWER_REQUEST_CONTEXT_VERSION*/, 0x00000001/*POWER_REQUEST_CONTEXT_SIMPLE_STRING*/, (LPWSTR)L"generic"}; ++ //static REASON_CONTEXT default_reason_context={0/*POWER_REQUEST_CONTEXT_VERSION*/, 0x00000001/*POWER_REQUEST_CONTEXT_SIMPLE_STRING*/, (LPWSTR)L"generic"}; + typedef BOOL (WINAPI *setwaitabletimerex_t)(HANDLE, const LARGE_INTEGER *, LONG, PTIMERAPCROUTINE, LPVOID, PREASON_CONTEXT, ULONG); + static inline BOOL WINAPI SetWaitableTimerEx_emulation(HANDLE hTimer, const LARGE_INTEGER *lpDueTime, LONG lPeriod, PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, PREASON_CONTEXT WakeContext, ULONG TolerableDelay) + { +@@ -715,7 +715,8 @@ + if(time_left.milliseconds/20>tolerable) // 5% + tolerable=time_left.milliseconds/20; + LARGE_INTEGER due_time=get_due_time(target_time); +- bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,&detail_::default_reason_context,tolerable)!=0; ++ //bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,&detail_::default_reason_context,tolerable)!=0; ++ bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,NULL,tolerable)!=0; + if(set_time_succeeded) + { + timeout_index=handle_count; +@@ -799,7 +800,8 @@ + if(time_left.milliseconds/20>tolerable) // 5% + tolerable=time_left.milliseconds/20; + LARGE_INTEGER due_time=get_due_time(target_time); +- bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,&detail_::default_reason_context,tolerable)!=0; ++ //bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,&detail_::default_reason_context,tolerable)!=0; ++ bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,NULL,tolerable)!=0; + if(set_time_succeeded) + { + timeout_index=handle_count; diff --git a/depends/patches/native_biplist/sorted_list.patch b/depends/patches/native_biplist/sorted_list.patch new file mode 100644 index 00000000000..89abdb1b71f --- /dev/null +++ b/depends/patches/native_biplist/sorted_list.patch @@ -0,0 +1,29 @@ +--- a/biplist/__init__.py 2014-10-26 19:03:11.000000000 +0000 ++++ b/biplist/__init__.py 2016-07-19 19:30:17.663521999 +0000 +@@ -541,7 +541,7 @@ + return HashableWrapper(n) + elif isinstance(root, dict): + n = {} +- for key, value in iteritems(root): ++ for key, value in sorted(iteritems(root)): + n[self.wrapRoot(key)] = self.wrapRoot(value) + return HashableWrapper(n) + elif isinstance(root, list): +@@ -616,7 +616,7 @@ + elif isinstance(obj, dict): + size = proc_size(len(obj)) + self.incrementByteCount('dictBytes', incr=1+size) +- for key, value in iteritems(obj): ++ for key, value in sorted(iteritems(obj)): + check_key(key) + self.computeOffsets(key, asReference=True) + self.computeOffsets(value, asReference=True) +@@ -714,7 +714,7 @@ + keys = [] + values = [] + objectsToWrite = [] +- for key, value in iteritems(obj): ++ for key, value in sorted(iteritems(obj)): + keys.append(key) + values.append(value) + for key in keys: diff --git a/doc/Doxyfile b/doc/Doxyfile index 428fba98e1b..c2af687eca1 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -28,13 +28,13 @@ DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. -PROJECT_NAME = Bitcoin +PROJECT_NAME = "Bitcoin Core" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 0.12.99 +PROJECT_NUMBER = 0.13.2 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer diff --git a/doc/README.md b/doc/README.md index c30f29452b7..be2ab7283ab 100644 --- a/doc/README.md +++ b/doc/README.md @@ -1,4 +1,4 @@ -Bitcoin Core 0.12.99 +Bitcoin Core 0.13.2 ===================== Setup diff --git a/doc/README_osx.md b/doc/README_osx.md index aed3cd97e1e..6a5c672277c 100644 --- a/doc/README_osx.md +++ b/doc/README_osx.md @@ -22,7 +22,7 @@ These tools inject timestamps by default, which produce non-deterministic binaries. The ZERO_AR_DATE environment variable is used to disable that. This version of cctools has been patched to use the current version of clang's -headers and and its libLTO.so rather than those from llvmgcc, as it was +headers and its libLTO.so rather than those from llvmgcc, as it was originally done in toolchain4. To complicate things further, all builds must target an Apple SDK. These SDKs diff --git a/doc/README_windows.txt b/doc/README_windows.txt index 2d1c4503c91..0623049da02 100644 --- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -1,4 +1,4 @@ -Bitcoin Core 0.12.99 +Bitcoin Core 0.13.2 ===================== Intro diff --git a/doc/bips.md b/doc/bips.md index 039d5114fd9..4f416100891 100644 --- a/doc/bips.md +++ b/doc/bips.md @@ -26,4 +26,9 @@ BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.13.0**): * [`BIP 125`](https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki): Opt-in full replace-by-fee signaling honoured in mempool and mining as of **v0.12.0** ([PR 6871](https://github.com/bitcoin/bitcoin/pull/6871)). * [`BIP 130`](https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki): direct headers announcement is negotiated with peer versions `>=70012` as of **v0.12.0** ([PR 6494](https://github.com/bitcoin/bitcoin/pull/6494)). * [`BIP 133`](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki): feefilter messages are respected and sent for peer versions `>=70013` as of **v0.13.0** ([PR 7542](https://github.com/bitcoin/bitcoin/pull/7542)). +* [`BIP 141`](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki): Segregated Witness (Consensus Layer) as of **v0.13.0** ([PR 8149](https://github.com/bitcoin/bitcoin/pull/8149)), and defined for mainnet as of **v0.13.1** ([PR 8937](https://github.com/bitcoin/bitcoin/pull/8937)). +* [`BIP 143`](https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki): Transaction Signature Verification for Version 0 Witness Program as of **v0.13.0** ([PR 8149](https://github.com/bitcoin/bitcoin/pull/8149)) and defined for mainnet as of **v0.13.1** ([PR 8937](https://github.com/bitcoin/bitcoin/pull/8937)). +* [`BIP 144`](https://github.com/bitcoin/bips/blob/master/bip-0144.mediawiki): Segregated Witness as of **0.13.0** ([PR 8149](https://github.com/bitcoin/bitcoin/pull/8149)). +* [`BIP 145`](https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki): getblocktemplate updates for Segregated Witness as of **v0.13.0** ([PR 8149](https://github.com/bitcoin/bitcoin/pull/8149)). +* [`BIP 147`](https://github.com/bitcoin/bips/blob/master/bip-0147.mediawiki): NULLDUMMY softfork as of **v0.13.1** ([PR 8636](https://github.com/bitcoin/bitcoin/pull/8636) and [PR 8937](https://github.com/bitcoin/bitcoin/pull/8937)). * [`BIP 152`](https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki): Compact block transfer and related optimizations are used as of **v0.13.0** ([PR 8068](https://github.com/bitcoin/bitcoin/pull/8068)). diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md index d923301467a..55283d6dcea 100644 --- a/doc/build-openbsd.md +++ b/doc/build-openbsd.md @@ -1,6 +1,6 @@ OpenBSD build guide ====================== -(updated for OpenBSD 5.7) +(updated for OpenBSD 5.9) This guide describes how to build bitcoind and command-line utilities on OpenBSD. @@ -15,11 +15,10 @@ Run the following as root to install the base dependencies for building: 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 +pkg_add python # (select highest version, e.g. 3.5) ``` -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. +The default C++ compiler that comes with OpenBSD 5.9 is g++ 4.2. This version is old (from 2007), and is not able to compile the current version of Bitcoin Core, primarily as it has no C++11 support, but even before there were issues. So here we will be installing a newer compiler. GCC ------- @@ -27,7 +26,7 @@ GCC You can install a newer version of gcc with: ```bash -pkg_add g++ # (select newest 4.x version, e.g. 4.9.2) +pkg_add g++ # (select newest 4.x version, e.g. 4.9.3) ``` This compiler will not overwrite the system compiler, it will be installed as `egcc` and `eg++` in `/usr/local/bin`. @@ -49,18 +48,15 @@ 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 +curl -o boost_1_61_0.tar.bz2 http://heanet.dl.sourceforge.net/project/boost/boost/1.61.0/boost_1_61_0.tar.bz2 +echo 'a547bd06c2fd9a71ba1d169d9cf0339da7ebf4753849a8f7d6fdb8feee99b640 boost_1_61_0.tar.bz2' | sha256 -c +# MUST output: (SHA256) boost_1_61_0.tar.bz2: OK +tar -xjf boost_1_61_0.tar.bz2 -# Boost 1.59 needs two small patches for OpenBSD -cd boost_1_59_0 +# Boost 1.61 needs one small patch for OpenBSD +cd boost_1_61_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++ : "-fvisibility=hidden -fPIC" "" "ar" "strip" "ranlib" "" : ;' > user-config.jam @@ -84,7 +80,7 @@ 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' +curl -o db-4.8.30.NC.tar.gz '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 @@ -93,9 +89,25 @@ tar -xzf db-4.8.30.NC.tar.gz 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 +make install # do NOT use -jX, this is broken ``` +### Resource limits + +The standard ulimit restrictions in OpenBSD are very strict: + + data(kbytes) 1572864 + +This is, unfortunately, no longer enough to compile some `.cpp` files in the project, +at least with gcc 4.9.3 (see issue https://github.com/bitcoin/bitcoin/issues/6658). +If your user is in the `staff` group the limit can be raised with: + + ulimit -d 3000000 + +The change will only affect the current shell and processes spawned by it. To +make the change system-wide, change `datasize-cur` and `datasize-max` in +`/etc/login.conf`, and reboot. + ### Building Bitcoin Core **Important**: use `gmake`, not `make`. The non-GNU `make` will exit with a horrible error. @@ -123,7 +135,7 @@ To configure without wallet: Build and run the tests: ```bash -gmake +gmake # can use -jX here for parallelism gmake check ``` diff --git a/doc/build-osx.md b/doc/build-osx.md index c9eb4225abb..63a7ee28ca9 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -16,7 +16,7 @@ Then install [Homebrew](http://brew.sh). Dependencies ---------------------- - brew install automake berkeley-db4 libtool boost --c++11 miniupnpc openssl pkg-config protobuf --c++11 qt5 libevent + brew install automake berkeley-db4 libtool boost --c++11 miniupnpc openssl pkg-config homebrew/versions/protobuf260 --c++11 qt5 libevent NOTE: Building with Qt4 is still supported, however, could result in a broken UI. Building with Qt5 is recommended. @@ -90,6 +90,6 @@ Uncheck everything except Qt Creator during the installation process. Notes ----- -* Tested on OS X 10.7 through 10.11 on 64-bit Intel processors only. +* Tested on OS X 10.8 through 10.12 on 64-bit Intel processors only. * Building with downloaded Qt binaries is not officially supported. See the notes in [#7714](https://github.com/bitcoin/bitcoin/issues/7714) diff --git a/doc/build-unix.md b/doc/build-unix.md index bd89978cc2a..d607d2a5942 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -82,6 +82,7 @@ install necessary parts of boost: BerkeleyDB is required for the wallet. db4.8 packages are available [here](https://launchpad.net/~bitcoin/+archive/bitcoin). You can add the repository and install using the following commands: + sudo apt-get install software-properties-common sudo add-apt-repository ppa:bitcoin/bitcoin sudo apt-get update sudo apt-get install libdb4.8-dev libdb4.8++-dev @@ -293,9 +294,10 @@ These steps can be performed on, for example, an Ubuntu VM. The depends system will also work on other Linux distributions, however the commands for installing the toolchain will be different. -First install the toolchain: +Make sure you install the build requirements mentioned above. +Then, install the toolchain and curl: - sudo apt-get install g++-arm-linux-gnueabihf + sudo apt-get install g++-arm-linux-gnueabihf curl To build executables for ARM: diff --git a/doc/build-windows.md b/doc/build-windows.md index 2b9233d1e14..129774491b2 100644 --- a/doc/build-windows.md +++ b/doc/build-windows.md @@ -16,9 +16,11 @@ These steps can be performed on, for example, an Ubuntu VM. The depends system will also work on other Linux distributions, however the commands for installing the toolchain will be different. -First install the toolchains: +Make sure you install the build requirements mentioned in +[build-unix.md](/doc/build-unix.md). +Then, install the toolchains and curl: - sudo apt-get install g++-mingw-w64-i686 mingw-w64-i686-dev g++-mingw-w64-x86-64 mingw-w64-x86-64-dev + sudo apt-get install g++-mingw-w64-i686 mingw-w64-i686-dev g++-mingw-w64-x86-64 mingw-w64-x86-64-dev curl To build executables for Windows 32-bit: diff --git a/doc/gitian-building.md b/doc/gitian-building.md index 7796a5fc9c1..84dce3f082f 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -55,7 +55,7 @@ In the VirtualBox GUI click "New" and choose the following parameters in the wiz ![](gitian-building/create_vm_memsize.png) -- Memory Size: at least 1024MB, anything less will really slow down the build. +- Memory Size: at least 3000MB, anything less and the build might not complete. ![](gitian-building/create_vm_hard_disk.png) @@ -337,7 +337,7 @@ Getting and building the inputs -------------------------------- 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 +in the bitcoin repository under 'Fetch and create 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. diff --git a/doc/gitian-building/create_vm_memsize.png b/doc/gitian-building/create_vm_memsize.png index 5abfee53370..6f42cda73f3 100644 Binary files a/doc/gitian-building/create_vm_memsize.png and b/doc/gitian-building/create_vm_memsize.png differ diff --git a/doc/reduce-traffic.md b/doc/reduce-traffic.md index 2d86588eb2a..697099beabe 100644 --- a/doc/reduce-traffic.md +++ b/doc/reduce-traffic.md @@ -19,8 +19,7 @@ This is *not* a hard limit; only a threshold to minimize the outbound traffic. When the limit is about to be reached, the uploaded data is cut by no longer serving historic blocks (blocks older than one week). Keep in mind that new nodes require other nodes that are willing to serve -historic blocks. **The recommended minimum is 144 blocks per day (max. 144MB -per day)** +historic blocks. Whitelisted peers will never be disconnected, although their traffic counts for calculating the target. diff --git a/doc/release-notes.md b/doc/release-notes.md index 3d2baaaaeaa..955a45a409a 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,12 +1,9 @@ -(note: this is a temporary file, to be added-to by anybody, and moved to -release-notes at release time) +Bitcoin Core version 0.13.x is now available from: -Bitcoin Core version *version* is now available from: + - - -This is a new major version release, including new features, various bugfixes -and performance improvements, as well as updated translations. +This is a new minor version release, including various bugfixes and +performance improvements, as well as updated translations. Please report bugs using the issue tracker at github: @@ -31,91 +28,24 @@ libraries such as Qt are no longer being tested on XP. We do not have time nor resources to provide support for an OS that is end-of-life. From 0.13.0 on, Windows XP is no longer supported. Users are -suggested to upgrade to a newer verion of Windows, or install an alternative OS +suggested to upgrade to a newer version of Windows, or install an alternative OS that is supported. No attempt is made to prevent installing or running the software on Windows XP, you can still do so at your own risk, but do not expect it to work: do not report issues about Windows XP to the issue tracker. +From 0.13.1 onwards OS X 10.7 is no longer supported. 0.13.0 was intended to work on 10.7+, +but severe issues with the libc++ version on 10.7.x keep it from running reliably. +0.13.1 now requires 10.8+, and will communicate that to 10.7 users, rather than crashing unexpectedly. + Notable changes =============== -Database cache memory increased --------------------------------- - -As a result of growth of the UTXO set, performance with the prior default -database cache of 100 MiB has suffered. -For this reason the default was changed to 300 MiB in this release. - -For nodes on low-memory systems, the database cache can be changed back to -100 MiB (or to another value) by either: - -- Adding `dbcache=100` in bitcoin.conf -- Changing it in the GUI under `Options → Size of database cache` - -Note that the database cache setting has the most performance impact -during initial sync of a node, and when catching up after downtime. - -bitcoin-cli: arguments privacy --------------------------------- - -The RPC command line client gained a new argument, `-stdin` -to read extra arguments from standard input, one per line until EOF/Ctrl-D. -For example: - - $ echo -e "mysecretcode\n120" | src/bitcoin-cli -stdin walletpassphrase - -It is recommended to use this for sensitive information such as wallet -passphrases, as command-line arguments can usually be read from the process -table by any user on the system. - -RPC low-level changes ----------------------- - -- `gettxoutsetinfo` UTXO hash (`hash_serialized`) has changed. There was a divergence between - 32-bit and 64-bit platforms, and the txids were missing in the hashed data. This has been - fixed, but this means that the output will be different than from previous versions. - -- Full UTF-8 support in the RPC API. Non-ASCII characters in, for example, - wallet labels have always been malformed because they weren't taken into account - properly in JSON RPC processing. This is no longer the case. This also affects - the GUI debug console. - -C++11 and Python 3 -------------------- - -Various code modernizations have been done. The Bitcoin Core code base has -started using C++11. This means that a C++11-capable compiler is now needed for -building. Effectively this means GCC 4.7 or higher, or Clang 3.3 or higher. - -When cross-compiling for a target that doesn't have C++11 libraries, configure with -`./configure --enable-glibc-back-compat ... LDFLAGS=-static-libstdc++`. - -For running the functional tests in `qa/rpc-tests`, Python3.4 or higher is now -required. - -Linux ARM builds ------------------- - -Due to popular request, Linux ARM builds have been added to the uploaded -executables. - -The following extra files can be found in the download directory or torrent: - -- `bitcoin-${VERSION}-arm-linux-gnueabihf.tar.gz`: Linux binaries for the most - common 32-bit ARM architecture. -- `bitcoin-${VERSION}-aarch64-linux-gnu.tar.gz`: Linux binaries for the most - common 64-bit ARM architecture. - -ARM builds are still experimental. If you have problems on a certain device or -Linux distribution combination please report them on the bug tracker, it may be -possible to resolve them. - -Note that Android is not considered ARM Linux in this context. The executables -are not expected to work out of the box on Android. +Example item +----------------------------------------------- -0.13.0 Change log +0.13.x Change log ================= Detailed release notes follow. This overview includes changes that affect @@ -123,85 +53,13 @@ behavior, not code moves, refactors and string updates. For convenience in locat the code changes and accompanying discussion, both the pull request and git merge commit are mentioned. -### RPC and REST - -Asm script outputs replacements for OP_NOP2 and OP_NOP3 -------------------------------------------------------- - -OP_NOP2 has been renamed to OP_CHECKLOCKTIMEVERIFY by [BIP -65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) - -OP_NOP3 has been renamed to OP_CHECKSEQUENCEVERIFY by [BIP -112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki) - -The following outputs are affected by this change: -- RPC `getrawtransaction` (in verbose mode) -- RPC `decoderawtransaction` -- RPC `decodescript` -- REST `/rest/tx/` (JSON format) -- REST `/rest/block/` (JSON format when including extended tx details) -- `bitcoin-tx -json` - -New mempool information RPC calls ---------------------------------- - -RPC calls have been added to output detailed statistics for individual mempool -entries, as well as to calculate the in-mempool ancestors or descendants of a -transaction: see `getmempoolentry`, `getmempoolancestors`, `getmempooldescendants`. - -### ZMQ - -Each ZMQ notification now contains an up-counting sequence number that allows -listeners to detect lost notifications. -The sequence number is always the last element in a multi-part ZMQ notification and -therefore backward compatible. -Each message type has its own counter. -(https://github.com/bitcoin/bitcoin/pull/7762) - -### Configuration and command-line options - -### Block and transaction handling - -### P2P protocol and network code - -The p2p alert system has been removed in #7692 and the 'alert' message is no longer supported. - - -Fee filtering of invs (BIP 133) ------------------------------------- - -The optional new p2p message "feefilter" is implemented and the protocol -version is bumped to 70013. Upon receiving a feefilter message from a peer, -a node will not send invs for any transactions which do not meet the filter -feerate. [BIP 133](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki) - -### Validation - -### Build system - -### Wallet - -Hierarchical Deterministic Key Generation ------------------------------------------ -Newly created wallets will use hierarchical deterministic key generation -according to BIP32 (keypath m/0'/0'/k'). -Existing wallets will still use traditional key generation. - -Backups of HD wallets, regardless of when they have been created, can -therefore be used to re-generate all possible private keys, even the -ones which haven't already been generated during the time of the backup. - -HD key generation for new wallets can be disabled by `-usehd=0`. Keep in -mind that this flag only has affect on newly created wallets. -You can't disable HD key generation once you have created a HD wallet. - -There is no distinction between internal (change) and external keys. - -[Pull request](https://github.com/bitcoin/bitcoin/pull/8035/files), [BIP 32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) +[to be filled in at release] -### GUI +Credits +======= -### Tests +Thanks to everyone who directly contributed to this release: -### Miscellaneous +[to be filled in at release] +As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). diff --git a/doc/release-notes/release-notes-0.13.0.md b/doc/release-notes/release-notes-0.13.0.md new file mode 100644 index 00000000000..f9bf3d75de0 --- /dev/null +++ b/doc/release-notes/release-notes-0.13.0.md @@ -0,0 +1,863 @@ +Bitcoin Core version 0.13.0 is now available from: + + + +This is a new major version release, including new features, various bugfixes +and performance improvements, as well as updated translations. + +Please report bugs using the issue tracker at github: + + + +To receive security and update notifications, please subscribe to: + + + +Compatibility +============== + +Microsoft ended support for Windows XP on [April 8th, 2014](https://www.microsoft.com/en-us/WindowsForBusiness/end-of-xp-support), +an OS initially released in 2001. This means that not even critical security +updates will be released anymore. Without security updates, using a bitcoin +wallet on a XP machine is irresponsible at least. + +In addition to that, with 0.12.x there have been varied reports of Bitcoin Core +randomly crashing on Windows XP. It is [not clear](https://github.com/bitcoin/bitcoin/issues/7681#issuecomment-217439891) +what the source of these crashes is, but it is likely that upstream +libraries such as Qt are no longer being tested on XP. + +We do not have time nor resources to provide support for an OS that is +end-of-life. From 0.13.0 on, Windows XP is no longer supported. Users are +suggested to upgrade to a newer verion of Windows, or install an alternative OS +that is supported. + +No attempt is made to prevent installing or running the software on Windows XP, +you can still do so at your own risk, but do not expect it to work: do not +report issues about Windows XP to the issue tracker. + +Notable changes +=============== + +Database cache memory increased +-------------------------------- + +As a result of growth of the UTXO set, performance with the prior default +database cache of 100 MiB has suffered. +For this reason the default was changed to 300 MiB in this release. + +For nodes on low-memory systems, the database cache can be changed back to +100 MiB (or to another value) by either: + +- Adding `dbcache=100` in bitcoin.conf +- Changing it in the GUI under `Options → Size of database cache` + +Note that the database cache setting has the most performance impact +during initial sync of a node, and when catching up after downtime. + + +bitcoin-cli: arguments privacy +------------------------------ + +The RPC command line client gained a new argument, `-stdin` +to read extra arguments from standard input, one per line until EOF/Ctrl-D. +For example: + + $ src/bitcoin-cli -stdin walletpassphrase + mysecretcode + 120 + ..... press Ctrl-D here to end input + $ + +It is recommended to use this for sensitive information such as wallet +passphrases, as command-line arguments can usually be read from the process +table by any user on the system. + + +C++11 and Python 3 +------------------ + +Various code modernizations have been done. The Bitcoin Core code base has +started using C++11. This means that a C++11-capable compiler is now needed for +building. Effectively this means GCC 4.7 or higher, or Clang 3.3 or higher. + +When cross-compiling for a target that doesn't have C++11 libraries, configure with +`./configure --enable-glibc-back-compat ... LDFLAGS=-static-libstdc++`. + +For running the functional tests in `qa/rpc-tests`, Python3.4 or higher is now +required. + + +Linux ARM builds +---------------- + +Due to popular request, Linux ARM builds have been added to the uploaded +executables. + +The following extra files can be found in the download directory or torrent: + +- `bitcoin-${VERSION}-arm-linux-gnueabihf.tar.gz`: Linux binaries for the most + common 32-bit ARM architecture. +- `bitcoin-${VERSION}-aarch64-linux-gnu.tar.gz`: Linux binaries for the most + common 64-bit ARM architecture. + +ARM builds are still experimental. If you have problems on a certain device or +Linux distribution combination please report them on the bug tracker, it may be +possible to resolve them. + +Note that Android is not considered ARM Linux in this context. The executables +are not expected to work out of the box on Android. + + +Compact Block support (BIP 152) +------------------------------- + +Support for block relay using the Compact Blocks protocol has been implemented +in PR 8068. + +The primary goal is reducing the bandwidth spikes at relay time, though in many +cases it also reduces propagation delay. It is automatically enabled between +compatible peers. +[BIP 152](https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki) + +As a side-effect, ordinary non-mining nodes will download and upload blocks +faster if those blocks were produced by miners using similar transaction +filtering policies. This means that a miner who produces a block with many +transactions discouraged by your node will be relayed slower than one with +only transactions already in your memory pool. The overall effect of such +relay differences on the network may result in blocks which include widely- +discouraged transactions losing a stale block race, and therefore miners may +wish to configure their node to take common relay policies into consideration. + + +Hierarchical Deterministic Key Generation +----------------------------------------- +Newly created wallets will use hierarchical deterministic key generation +according to BIP32 (keypath m/0'/0'/k'). +Existing wallets will still use traditional key generation. + +Backups of HD wallets, regardless of when they have been created, can +therefore be used to re-generate all possible private keys, even the +ones which haven't already been generated during the time of the backup. +**Attention:** Encrypting the wallet will create a new seed which requires +a new backup! + +Wallet dumps (created using the `dumpwallet` RPC) will contain the deterministic +seed. This is expected to allow future versions to import the seed and all +associated funds, but this is not yet implemented. + +HD key generation for new wallets can be disabled by `-usehd=0`. Keep in +mind that this flag only has affect on newly created wallets. +You can't disable HD key generation once you have created a HD wallet. + +There is no distinction between internal (change) and external keys. + +HD wallets are incompatible with older versions of Bitcoin Core. + +[Pull request](https://github.com/bitcoin/bitcoin/pull/8035/files), [BIP 32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) + + +Segregated Witness +------------------ + +The code preparations for Segregated Witness ("segwit"), as described in [BIP +141](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki), [BIP +143](https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki), [BIP +144](https://github.com/bitcoin/bips/blob/master/bip-0144.mediawiki), and [BIP +145](https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki) are +finished and included in this release. However, BIP 141 does not yet specify +activation parameters on mainnet, and so this release does not support segwit +use on mainnet. Testnet use is supported, and after BIP 141 is updated with +proposed parameters, a future release of Bitcoin Core is expected that +implements those parameters for mainnet. + +Furthermore, because segwit activation is not yet specified for mainnet, +version 0.13.0 will behave similarly as other pre-segwit releases even after a +future activation of BIP 141 on the network. Upgrading from 0.13.0 will be +required in order to utilize segwit-related features on mainnet (such as signal +BIP 141 activation, mine segwit blocks, fully validate segwit blocks, relay +segwit blocks to other segwit nodes, and use segwit transactions in the +wallet, etc). + + +Mining transaction selection ("Child Pays For Parent") +------------------------------------------------------ + +The mining transaction selection algorithm has been replaced with an algorithm +that selects transactions based on their feerate inclusive of unconfirmed +ancestor transactions. This means that a low-fee transaction can become more +likely to be selected if a high-fee transaction that spends its outputs is +relayed. + +With this change, the `-blockminsize` command line option has been removed. + +The command line option `-blockmaxsize` remains an option to specify the +maximum number of serialized bytes in a generated block. In addition, the new +command line option `-blockmaxweight` has been added, which specifies the +maximum "block weight" of a generated block, as defined by [BIP 141 (Segregated +Witness)] (https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki). + +In preparation for Segregated Witness, the mining algorithm has been modified +to optimize transaction selection for a given block weight, rather than a given +number of serialized bytes in a block. In this release, transaction selection +is unaffected by this distinction (as BIP 141 activation is not supported on +mainnet in this release, see above), but in future releases and after BIP 141 +activation, these calculations would be expected to differ. + +For optimal runtime performance, miners using this release should specify +`-blockmaxweight` on the command line, and not specify `-blockmaxsize`. +Additionally (or only) specifying `-blockmaxsize`, or relying on default +settings for both, may result in performance degradation, as the logic to +support `-blockmaxsize` performs additional computation to ensure that +constraint is met. (Note that for mainnet, in this release, the equivalent +parameter for `-blockmaxweight` would be four times the desired +`-blockmaxsize`. See [BIP 141] +(https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki) for additional +details.) + +In the future, the `-blockmaxsize` option may be removed, as block creation is +no longer optimized for this metric. Feedback is requested on whether to +deprecate or keep this command line option in future releases. + + +Reindexing changes +------------------ + +In earlier versions, reindexing did validation while reading through the block +files on disk. These two have now been split up, so that all blocks are known +before validation starts. This was necessary to make certain optimizations that +are available during normal synchronizations also available during reindexing. + +The two phases are distinct in the Bitcoin-Qt GUI. During the first one, +"Reindexing blocks on disk" is shown. During the second (slower) one, +"Processing blocks on disk" is shown. + +It is possible to only redo validation now, without rebuilding the block index, +using the command line option `-reindex-chainstate` (in addition to +`-reindex` which does both). This new option is useful when the blocks on disk +are assumed to be fine, but the chainstate is still corrupted. It is also +useful for benchmarks. + + +Removal of internal miner +-------------------------- + +As CPU mining has been useless for a long time, the internal miner has been +removed in this release, and replaced with a simpler implementation for the +test framework. + +The overall result of this is that `setgenerate` RPC call has been removed, as +well as the `-gen` and `-genproclimit` command-line options. + +For testing, the `generate` call can still be used to mine a block, and a new +RPC call `generatetoaddress` has been added to mine to a specific address. This +works with wallet disabled. + + +New bytespersigop implementation +-------------------------------- + +The former implementation of the bytespersigop filter accidentally broke bare +multisig (which is meant to be controlled by the `permitbaremultisig` option), +since the consensus protocol always counts these older transaction forms as 20 +sigops for backwards compatibility. Simply fixing this bug by counting more +accurately would have reintroduced a vulnerability. It has therefore been +replaced with a new implementation that rather than filter such transactions, +instead treats them (for fee purposes only) as if they were in fact the size +of a transaction actually using all 20 sigops. + + +Low-level P2P changes +---------------------- + +- The optional new p2p message "feefilter" is implemented and the protocol + version is bumped to 70013. Upon receiving a feefilter message from a peer, + a node will not send invs for any transactions which do not meet the filter + feerate. [BIP 133](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki) + +- The P2P alert system has been removed in PR #7692 and the `alert` P2P message + is no longer supported. + +- The transaction relay mechanism used to relay one quarter of all transactions + instantly, while queueing up the rest and sending them out in batch. As + this resulted in chains of dependent transactions being reordered, it + systematically hurt transaction relay. The relay code was redesigned in PRs + \#7840 and #8082, and now always batches transactions announcements while also + sorting them according to dependency order. This significantly reduces orphan + transactions. To compensate for the removal of instant relay, the frequency of + batch sending was doubled for outgoing peers. + +- Since PR #7840 the BIP35 `mempool` command is also subject to batch processing. + Also the `mempool` message is no longer handled for non-whitelisted peers when + `NODE_BLOOM` is disabled through `-peerbloomfilters=0`. + +- The maximum size of orphan transactions that are kept in memory until their + ancestors arrive has been raised in PR #8179 from 5000 to 99999 bytes. They + are now also removed from memory when they are included in a block, conflict + with a block, and time out after 20 minutes. + +- We respond at most once to a getaddr request during the lifetime of a + connection since PR #7856. + +- Connections to peers who have recently been the first one to give us a valid + new block or transaction are protected from disconnections since PR #8084. + + +Low-level RPC changes +---------------------- + +- RPC calls have been added to output detailed statistics for individual mempool + entries, as well as to calculate the in-mempool ancestors or descendants of a + transaction: see `getmempoolentry`, `getmempoolancestors`, `getmempooldescendants`. + +- `gettxoutsetinfo` UTXO hash (`hash_serialized`) has changed. There was a divergence between + 32-bit and 64-bit platforms, and the txids were missing in the hashed data. This has been + fixed, but this means that the output will be different than from previous versions. + +- Full UTF-8 support in the RPC API. Non-ASCII characters in, for example, + wallet labels have always been malformed because they weren't taken into account + properly in JSON RPC processing. This is no longer the case. This also affects + the GUI debug console. + +- Asm script outputs replacements for OP_NOP2 and OP_NOP3 + + - OP_NOP2 has been renamed to OP_CHECKLOCKTIMEVERIFY by [BIP +65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) + + - OP_NOP3 has been renamed to OP_CHECKSEQUENCEVERIFY by [BIP +112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki) + + - The following outputs are affected by this change: + + - RPC `getrawtransaction` (in verbose mode) + - RPC `decoderawtransaction` + - RPC `decodescript` + - REST `/rest/tx/` (JSON format) + - REST `/rest/block/` (JSON format when including extended tx details) + - `bitcoin-tx -json` + +- The sorting of the output of the `getrawmempool` output has changed. + +- New RPC commands: `generatetoaddress`, `importprunedfunds`, `removeprunedfunds`, `signmessagewithprivkey`, + `getmempoolancestors`, `getmempooldescendants`, `getmempoolentry`, + `createwitnessaddress`, `addwitnessaddress`. + +- Removed RPC commands: `setgenerate`, `getgenerate`. + +- New options were added to `fundrawtransaction`: `includeWatching`, `changeAddress`, `changePosition` and `feeRate`. + + +Low-level ZMQ changes +---------------------- + +- Each ZMQ notification now contains an up-counting sequence number that allows + listeners to detect lost notifications. + The sequence number is always the last element in a multi-part ZMQ notification and + therefore backward compatible. Each message type has its own counter. + PR [#7762](https://github.com/bitcoin/bitcoin/pull/7762). + + +0.13.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 other APIs + +- #7156 `9ee02cf` Remove cs_main lock from `createrawtransaction` (laanwj) +- #7326 `2cd004b` Fix typo, wrong information in gettxout help text (paveljanik) +- #7222 `82429d0` Indicate which transactions are signaling opt-in RBF (sdaftuar) +- #7480 `b49a623` Changed getnetworkhps value to double to avoid overflow (instagibbs) +- #7550 `8b958ab` Input-from-stdin mode for bitcoin-cli (laanwj) +- #7670 `c9a1265` Use cached block hash in blockToJSON() (rat4) +- #7726 `9af69fa` Correct importaddress help reference to importpubkey (CypherGrue) +- #7766 `16555b6` Register calls where they are defined (laanwj) +- #7797 `e662a76` Fix generatetoaddress failing to parse address (mruddy) +- #7774 `916b15a` Add versionHex in getblock and getblockheader JSON results (mruddy) +- #7863 `72c54e3` Getblockchaininfo: make bip9_softforks an object, not an array (rustyrussell) +- #7842 `d97101e` Do not print minping time in getpeerinfo when no ping received yet (paveljanik) +- #7518 `be14ca5` Add multiple options to fundrawtransaction (promag) +- #7756 `9e47fce` Add cursor to iterate over utxo set, use this in `gettxoutsetinfo` (laanwj) +- #7848 `88616d2` Divergence between 32- and 64-bit when hashing >4GB affects `gettxoutsetinfo` (laanwj) +- #7827 `4205ad7` Speed up `getchaintips` (mrbandrews) +- #7762 `a1eb344` Append a message sequence number to every ZMQ notification (jonasschnelli) +- #7688 `46880ed` List solvability in listunspent output and improve help (sipa) +- #7926 `5725807` Push back `getaddednodeinfo` dead value (instagibbs) +- #7953 `0630353` Create `signmessagewithprivkey` rpc (achow101) +- #8049 `c028c7b` Expose information on whether transaction relay is enabled in `getnetworkinfo` (laanwj) +- #7967 `8c1e49b` Add feerate option to `fundrawtransaction` (jonasschnelli) +- #8118 `9b6a48c` Reduce unnecessary hashing in `signrawtransaction` (jonasnick) +- #7957 `79004d4` Add support for transaction sequence number (jonasschnelli) +- #8153 `75ec320` `fundrawtransaction` feeRate: Use BTC/kB (MarcoFalke) +- #7292 `7ce9ac5` Expose ancestor/descendant information over RPC (sdaftuar) +- #8171 `62fcf27` Fix createrawtx sequence number unsigned int parsing (jonasschnelli) +- #7892 `9c3d0fa` Add full UTF-8 support to RPC (laanwj) +- #8317 `304eff3` Don't use floating point in rpcwallet (MarcoFalke) +- #8258 `5a06ebb` Hide softfork in `getblockchaininfo` if timeout is 0 (jl2012) +- #8244 `1922e5a` Remove unnecessary LOCK(cs_main) in getrawmempool (dcousens) + +### Block and transaction handling + +- #7056 `6a07208` Save last db read (morcos) +- #6842 `0192806` Limitfreerelay edge case bugfix (ptschip) +- #7084 `11d74f6` Replace maxFeeRate of 10000*minRelayTxFee with maxTxFee in mempool (MarcoFalke) +- #7539 `9f33dba` Add tags to mempool's mapTx indices (sdaftuar) +- #7592 `26a2a72` Re-remove ERROR logging for mempool rejects (laanwj) +- #7187 `14d6324` Keep reorgs fast for SequenceLocks checks (morcos) +- #7594 `01f4267` Mempool: Add tracking of ancestor packages (sdaftuar) +- #7904 `fc9e334` Txdb: Fix assert crash in new UTXO set cursor (laanwj) +- #7927 `f9c2ac7` Minor changes to dbwrapper to simplify support for other databases (laanwj) +- #7933 `e26b620` Fix OOM when deserializing UTXO entries with invalid length (sipa) +- #8020 `5e374f7` Use SipHash-2-4 for various non-cryptographic hashes (sipa) +- #8076 `d720980` VerifyDB: don't check blocks that have been pruned (sdaftuar) +- #8080 `862fd24` Do not use mempool for GETDATA for tx accepted after the last mempool req (gmaxwell) +- #7997 `a82f033` Replace mapNextTx with slimmer setSpends (kazcw) +- #8220 `1f86d64` Stop trimming when mapTx is empty (sipa) +- #8273 `396f9d6` Bump `-dbcache` default to 300MiB (laanwj) +- #7225 `eb33179` Eliminate unnecessary call to CheckBlock (sdaftuar) +- #7907 `006cdf6` Optimize and Cleanup CScript::FindAndDelete (pstratem) +- #7917 `239d419` Optimize reindex (sipa) +- #7763 `3081fb9` Put hex-encoded version in UpdateTip (sipa) +- #8149 `d612837` Testnet-only segregated witness (sipa) +- #8305 `3730393` Improve handling of unconnecting headers (sdaftuar) +- #8363 `fca1a41` Rename "block cost" to "block weight" (sdaftuar) +- #8381 `f84ee3d` Make witness v0 outputs non-standard (jl2012) +- #8364 `3f65ba2` Treat high-sigop transactions as larger rather than rejecting them (sipa) + +### P2P protocol and network code + +- #6589 `dc0305d` Log bytes recv/sent per command (jonasschnelli) +- #7164 `3b43cad` Do not download transactions during initial blockchain sync (ptschip) +- #7458 `898fedf` peers.dat, banlist.dat recreated when missing (kirkalx) +- #7637 `3da5d1b` Fix memleak in TorController (laanwj, jonasschnelli) +- #7553 `9f14e5a` Remove vfReachable and modify IsReachable to only use vfLimited (pstratem) +- #7708 `9426632` De-neuter NODE_BLOOM (pstratem) +- #7692 `29b2be6` Remove P2P alert system (btcdrak) +- #7542 `c946a15` Implement "feefilter" P2P message (morcos) +- #7573 `352fd57` Add `-maxtimeadjustment` command line option (mruddy) +- #7570 `232592a` Add IPv6 Link-Local Address Support (mruddy) +- #7874 `e6a4d48` Improve AlreadyHave (morcos) +- #7856 `64e71b3` Only send one GetAddr response per connection (gmaxwell) +- #7868 `7daa3ad` Split DNS resolving functionality out of net structures (theuni) +- #7919 `7617682` Fix headers announcements edge case (sdaftuar) +- #7514 `d9594bf` Fix IsInitialBlockDownload for testnet (jmacwhyte) +- #7959 `03cf6e8` fix race that could fail to persist a ban (kazcw) +- #7840 `3b9a0bf` Several performance and privacy improvements to inv/mempool handling (sipa) +- #8011 `65aecda` Don't run ThreadMessageHandler at lowered priority (kazcw) +- #7696 `5c3f8dd` Fix de-serialization bug where AddrMan is left corrupted (EthanHeilman) +- #7932 `ed749bd` CAddrMan::Deserialize handle corrupt serializations better (pstratem) +- #7906 `83121cc` Prerequisites for p2p encapsulation changes (theuni) +- #8033 `18436d8` Fix Socks5() connect failures to be less noisy and less unnecessarily scary (wtogami) +- #8082 `01d8359` Defer inserting into maprelay until just before relaying (gmaxwell) +- #7960 `6a22373` Only use AddInventoryKnown for transactions (sdaftuar) +- #8078 `2156fa2` Disable the mempool P2P command when bloom filters disabled (petertodd) +- #8065 `67c91f8` Addrman offline attempts (gmaxwell) +- #7703 `761cddb` Tor: Change auth order to only use password auth if -torpassword (laanwj) +- #8083 `cd0c513` Add support for dnsseeds with option to filter by servicebits (jonasschnelli) +- #8173 `4286f43` Use SipHash for node eviction (sipa) +- #8154 `1445835` Drop vAddrToSend after sending big addr message (kazcw) +- #7749 `be9711e` Enforce expected outbound services (sipa) +- #8208 `0a64777` Do not set extra flags for unfiltered DNS seed results (sipa) +- #8084 `e4bb4a8` Add recently accepted blocks and txn to AttemptToEvictConnection (gmaxwell) +- #8113 `3f89a53` Rework addnode behaviour (sipa) +- #8179 `94ab58b` Evict orphans which are included or precluded by accepted blocks (gmaxwell) +- #8068 `e9d76a1` Compact Blocks (TheBlueMatt) +- #8204 `0833894` Update petertodd's testnet seed (petertodd) +- #8247 `5cd35d3` Mark my dnsseed as supporting filtering (sipa) +- #8275 `042c323` Remove bad chain alert partition check (btcdrak) +- #8271 `1bc9c80` Do not send witnesses in cmpctblock (sipa) +- #8312 `ca40ef6` Fix mempool DoS vulnerability from malleated transactions (sdaftuar) +- #7180 `16ccb74` Account for `sendheaders` `verack` messages (laanwj) +- #8102 `425278d` Bugfix: use global ::fRelayTxes instead of CNode in version send (sipa) +- #8408 `b7e2011` Prevent fingerprinting, disk-DoS with compact blocks (sdaftuar) + +### Build system + +- #7302 `41f1a3e` C++11 build/runtime fixes (theuni) +- #7322 `fd9356b` c++11: add scoped enum fallbacks to CPPFLAGS rather than defining them locally (theuni) +- #7441 `a6771fc` Use Debian 8.3 in gitian build guide (fanquake) +- #7349 `152a821` Build against system UniValue when available (luke-jr) +- #7520 `621940e` LibreSSL doesn't define OPENSSL_VERSION, use LIBRESSL_VERSION_TEXT instead (paveljanik) +- #7528 `9b9bfce` autogen.sh: warn about needing autoconf if autoreconf is not found (knocte) +- #7504 `19324cf` Crystal clean make clean (paveljanik) +- #7619 `18b3f1b` Add missing sudo entry in gitian VM setup (btcdrak) +- #7616 `639ec58` [depends] Delete unused patches (MarcoFalke) +- #7658 `c15eb28` Add curl to Gitian setup instructions (btcdrak) +- #7710 `909b72b` [Depends] Bump miniupnpc and config.guess+sub (fanquake) +- #7723 `5131005` build: python 3 compatibility (laanwj) +- #7477 `28ad4d9` Fix quoting of copyright holders in configure.ac (domob1812) +- #7711 `a67bc5e` [build-aux] Update Boost & check macros to latest serials (fanquake) +- #7788 `4dc1b3a` Use relative paths instead of absolute paths in protoc calls (paveljanik) +- #7809 `bbd210d` depends: some base fixes/changes (theuni) +- #7603 `73fc922` Build System: Use PACKAGE_TARNAME in NSIS script (JeremyRand) +- #7905 `187186b` test: move accounting_tests and rpc_wallet_tests to wallet/test (laanwj) +- #7911 `351abf9` leveldb: integrate leveldb into our buildsystem (theuni) +- #7944 `a407807` Re-instate TARGET_OS=linux in configure.ac. Removed by 351abf9e035 (randy-waterhouse) +- #7920 `c3e3cfb` Switch Travis to Trusty (theuni) +- #7954 `08b37c5` build: quiet annoying warnings without adding new ones (theuni) +- #7165 `06162f1` build: Enable C++11 in build, require C++11 compiler (laanwj) +- #7982 `559fbae` build: No need to check for leveldb atomics (theuni) +- #8002 `f9b4582` [depends] Add -stdlib=libc++ to darwin CXX flags (fanquake) +- #7993 `6a034ed` [depends] Bump Freetype, ccache, ZeroMQ, miniupnpc, expat (fanquake) +- #8167 `19ea173` Ship debug tarballs/zips with debug symbols (theuni) +- #8175 `f0299d8` Add --disable-bench to config flags for windows (laanwj) +- #7283 `fd9881a` [gitian] Default reference_datetime to commit author date (MarcoFalke) +- #8181 `9201ce8` Get rid of `CLIENT_DATE` (laanwj) +- #8133 `fde0ac4` Finish up out-of-tree changes (theuni) +- #8188 `65a9d7d` Add armhf/aarch64 gitian builds (theuni) +- #8194 `cca1c8c` [gitian] set correct PATH for wrappers (MarcoFalke) +- #8198 `5201614` Sync ax_pthread with upstream draft4 (fanquake) +- #8210 `12a541e` [Qt] Bump to Qt5.6.1 (jonasschnelli) +- #8285 `da50997` windows: Add testnet link to installer (laanwj) +- #8304 `0cca2fe` [travis] Update SDK_URL (MarcoFalke) +- #8310 `6ae20df` Require boost for bench (theuni) +- #8315 `2e51590` Don't require sudo for Linux (theuni) +- #8314 `67caef6` Fix pkg-config issues for 0.13 (theuni) +- #8373 `1fe7f40` Fix OSX non-deterministic dmg (theuni) +- #8358 `cfd1280` Gbuild: Set memory explicitly (default is too low) (MarcoFalke) + +### GUI + +- #7154 `00b4b8d` Add InMempool() info to transaction details (jonasschnelli) +- #7068 `5f3c670` [RPC-Tests] add simple way to run rpc test over QT clients (jonasschnelli) +- #7218 `a1c185b` Fix misleading translation (MarcoFalke) +- #7214 `be9a9a3` qt5: Use the fixed font the system recommends (MarcoFalke) +- #7256 `08ab906` Add note to coin control dialog QT5 workaround (fanquake) +- #7255 `e289807` Replace some instances of formatWithUnit with formatHtmlWithUnit (fanquake) +- #7317 `3b57e9c` Fix RPCTimerInterface ordering issue (jonasschnelli) +- #7327 `c079d79` Transaction View: LastMonth calculation fixed (crowning-) +- #7334 `e1060c5` coincontrol workaround is still needed in qt5.4 (fixed in qt5.5) (MarcoFalke) +- #7383 `ae2db67` Rename "amount" to "requested amount" in receive coins table (jonasschnelli) +- #7396 `cdcbc59` Add option to increase/decrease font size in the console window (jonasschnelli) +- #7437 `9645218` Disable tab navigation for peers tables (Kefkius) +- #7604 `354b03d` build: Remove spurious dollar sign. Fixes #7189 (dooglus) +- #7605 `7f001bd` Remove openssl info from init/log and from Qt debug window (jonasschnelli) +- #7628 `87d6562` Add 'copy full transaction details' option (ericshawlinux) +- #7613 `3798e5d` Add autocomplete to bitcoin-qt's console window (GamerSg) +- #7668 `b24266c` Fix history deletion bug after font size change (achow101) +- #7680 `41d2dfa` Remove reflection from `about` icon (laanwj) +- #7686 `f034bce` Remove 0-fee from send dialog (MarcoFalke) +- #7506 `b88e0b0` Use CCoinControl selection in CWallet::FundTransaction (promag) +- #7732 `0b98dd7` Debug window: replace "Build date" with "Datadir" (jonasschnelli) +- #7761 `60db51d` remove trailing output-index from transaction-id (jonasschnelli) +- #7772 `6383268` Clear the input line after activating autocomplete (paveljanik) +- #7925 `f604bf6` Fix out-of-tree GUI builds (laanwj) +- #7939 `574ddc6` Make it possible to show details for multiple transactions (laanwj) +- #8012 `b33824b` Delay user confirmation of send (Tyler-Hardin) +- #8006 `7c8558d` Add option to disable the system tray icon (Tyler-Hardin) +- #8046 `169d379` Fix Cmd-Q / Menu Quit shutdown on OSX (jonasschnelli) +- #8042 `6929711` Don't allow to open the debug window during splashscreen & verification state (jonasschnelli) +- #8014 `77b49ac` Sort transactions by date (Tyler-Hardin) +- #8073 `eb2f6f7` askpassphrasedialog: Clear pass fields on accept (rat4) +- #8129 `ee1533e` Fix RPC console auto completer (UdjinM6) +- #7636 `fb0ac48` Add bitcoin address label to request payment QR code (makevoid) +- #8231 `760a6c7` Fix a bug where the SplashScreen will not be hidden during startup (jonasschnelli) +- #8256 `af2421c` BUG: bitcoin-qt crash (fsb4000) +- #8257 `ff03c50` Do not ask a UI question from bitcoind (sipa) +- #8288 `91abb77` Network-specific example address (laanwj) +- #7707 `a914968` UI support for abandoned transactions (jonasschnelli) +- #8207 `f7a403b` Add a link to the Bitcoin-Core repository and website to the About Dialog (MarcoFalke) +- #8281 `6a87eb0` Remove client name from debug window (laanwj) +- #8407 `45eba4b` Add dbcache migration path (jonasschnelli) + +### Wallet + +- #7262 `fc08994` Reduce inefficiency of GetAccountAddress() (dooglus) +- #7537 `78e81b0` Warn on unexpected EOF while salvaging wallet (laanwj) +- #7521 `3368895` Don't resend wallet txs that aren't in our own mempool (morcos) +- #7576 `86a1ec5` Move wallet help string creation to CWallet (jonasschnelli) +- #7577 `5b3b5a7` Move "load wallet phase" to CWallet (jonasschnelli) +- #7608 `0735c0c` Move hardcoded file name out of log messages (MarcoFalke) +- #7649 `4900641` Prevent multiple calls to CWallet::AvailableCoins (promag) +- #7646 `e5c3511` Fix lockunspent help message (promag) +- #7558 `b35a591` Add import/removeprunedfunds rpc call (instagibbs) +- #6215 `48c5adf` add bip32 pub key serialization (jonasschnelli) +- #7913 `bafd075` Fix for incorrect locking in GetPubKey() (keystore.cpp) (yurizhykin) +- #8036 `41138f9` init: Move berkeleydb version reporting to wallet (laanwj) +- #8028 `373b50d` Fix insanity of CWalletDB::WriteTx and CWalletTx::WriteToDisk (pstratem) +- #8061 `f6b7df3` Improve Wallet encapsulation (pstratem) +- #7891 `950be19` Always require OS randomness when generating secret keys (sipa) +- #7689 `b89ef13` Replace OpenSSL AES with ctaes-based version (sipa) +- #7825 `f972b04` Prevent multiple calls to ExtractDestination (pedrobranco) +- #8137 `243ac0c` Improve CWallet API with new AccountMove function (pstratem) +- #8142 `52c3f34` Improve CWallet API with new GetAccountPubkey function (pstratem) +- #8035 `b67a472` Add simplest BIP32/deterministic key generation implementation (jonasschnelli) +- #7687 `a6ddb19` Stop treating importaddress'ed scripts as change (sipa) +- #8298 `aef3811` wallet: Revert input selection post-pruning (laanwj) +- #8324 `bc94b87` Keep HD seed during salvagewallet (jonasschnelli) +- #8323 `238300b` Add HD keypath to CKeyMetadata, report metadata in validateaddress (jonasschnelli) +- #8367 `3b38a6a` Ensure <0.13 clients can't open HD wallets (jonasschnelli) +- #8378 `ebea651` Move SetMinVersion for FEATURE_HD to SetHDMasterKey (pstratem) +- #8390 `73adfe3` Correct hdmasterkeyid/masterkeyid name confusion (jonasschnelli) +- #8206 `18b8ee1` Add HD xpriv to dumpwallet (jonasschnelli) +- #8389 `c3c82c4` Create a new HD seed after encrypting the wallet (jonasschnelli) + +### Tests and QA + +- #7320 `d3dfc6d` Test walletpassphrase timeout (MarcoFalke) +- #7208 `47c5ed1` Make max tip age an option instead of chainparam (laanwj) +- #7372 `21376af` Trivial: [qa] wallet: Print maintenance (MarcoFalke) +- #7280 `668906f` [travis] Fail when documentation is outdated (MarcoFalke) +- #7177 `93b0576` [qa] Change default block priority size to 0 (MarcoFalke) +- #7236 `02676c5` Use createrawtx locktime parm in txn_clone (dgenr8) +- #7212 `326ffed` Adds unittests for CAddrMan and CAddrinfo, removes source of non-determinism (EthanHeilman) +- #7490 `d007511` tests: Remove May15 test (laanwj) +- #7531 `18cb2d5` Add bip68-sequence.py to extended rpc tests (btcdrak) +- #7536 `ce5fc02` test: test leading spaces for ParseHex (laanwj) +- #7620 `1b68de3` [travis] Only run check-doc.py once (MarcoFalke) +- #7455 `7f96671` [travis] Exit early when check-doc.py fails (MarcoFalke) +- #7667 `56d2c4e` Move GetTempPath() to testutil (musalbas) +- #7517 `f1ca891` test: script_error checking in script_invalid tests (laanwj) +- #7684 `3d0dfdb` Extend tests (MarcoFalke) +- #7697 `622fe6c` Tests: make prioritise_transaction.py more robust (sdaftuar) +- #7709 `efde86b` Tests: fix missing import in mempool_packages (sdaftuar) +- #7702 `29e1131` Add tests verifychain, lockunspent, getbalance, listsinceblock (MarcoFalke) +- #7720 `3b4324b` rpc-test: Normalize assert() (MarcoFalke) +- #7757 `26794d4` wallet: Wait for reindex to catch up (MarcoFalke) +- #7764 `a65b36c` Don't run pruning.py twice (MarcoFalke) +- #7773 `7c80e72` Fix comments in tests (btcdrak) +- #7489 `e9723cb` tests: Make proxy_test work on travis servers without IPv6 (laanwj) +- #7801 `70ac71b` Remove misleading "errorString syntax" (MarcoFalke) +- #7803 `401c65c` maxblocksinflight: Actually enable test (MarcoFalke) +- #7802 `3bc71e1` httpbasics: Actually test second connection (MarcoFalke) +- #7849 `ab8586e` tests: add varints_bitpatterns test (laanwj) +- #7846 `491171f` Clean up lockorder data of destroyed mutexes (sipa) +- #7853 `6ef5e00` py2: Unfiddle strings into bytes explicitly (MarcoFalke) +- #7878 `53adc83` [test] bctest.py: Revert faa41ee (MarcoFalke) +- #7798 `cabba24` [travis] Print the commit which was evaluated (MarcoFalke) +- #7833 `b1bf511` tests: Check Content-Type header returned from RPC server (laanwj) +- #7851 `fa9d86f` pull-tester: Don't mute zmq ImportError (MarcoFalke) +- #7822 `0e6fd5e` Add listunspent() test for spendable/unspendable UTXO (jpdffonseca) +- #7912 `59ad568` Tests: Fix deserialization of reject messages (sdaftuar) +- #7941 `0ea3941` Fixing comment in script_test.json test case (Christewart) +- #7807 `0ad1041` Fixed miner test values, gave constants for less error-prone values (instagibbs) +- #7980 `88b77c7` Smartfees: Properly use ordered dict (MarcoFalke) +- #7814 `77b637f` Switch to py3 (MarcoFalke) +- #8030 `409a8a1` Revert fatal-ness of missing python-zmq (laanwj) +- #8018 `3e90fe6` Autofind rpc tests --srcdir (jonasschnelli) +- #8016 `5767e80` Fix multithread CScheduler and reenable test (paveljanik) +- #7972 `423ca30` pull-tester: Run rpc test in parallel (MarcoFalke) +- #8039 `69b3a6d` Bench: Add crypto hash benchmarks (laanwj) +- #8041 `5b736dd` Fix bip9-softforks blockstore issue (MarcoFalke) +- #7994 `1f01443` Add op csv tests to script_tests.json (Christewart) +- #8038 `e2bf830` Various minor fixes (MarcoFalke) +- #8072 `1b87e5b` Travis: 'make check' in parallel and verbose (theuni) +- #8056 `8844ef1` Remove hardcoded "4 nodes" from test_framework (MarcoFalke) +- #8047 `37f9a1f` Test_framework: Set wait-timeout for bitcoind procs (MarcoFalke) +- #8095 `6700cc9` Test framework: only cleanup on successful test runs (sdaftuar) +- #8098 `06bd4f6` Test_framework: Append portseed to tmpdir (MarcoFalke) +- #8104 `6ff2c8d` Add timeout to sync_blocks() and sync_mempools() (sdaftuar) +- #8111 `61b8684` Benchmark SipHash (sipa) +- #8107 `52b803e` Bench: Added base58 encoding/decoding benchmarks (yurizhykin) +- #8115 `0026e0e` Avoid integer division in the benchmark inner-most loop (gmaxwell) +- #8090 `a2df115` Adding P2SH(p2pkh) script test case (Christewart) +- #7992 `ec45cc5` Extend #7956 with one more test (TheBlueMatt) +- #8139 `ae5575b` Fix interrupted HTTP RPC connection workaround for Python 3.5+ (sipa) +- #8164 `0f24eaf` [Bitcoin-Tx] fix missing test fixtures, fix 32bit atoi issue (jonasschnelli) +- #8166 `0b5279f` Src/test: Do not shadow local variables (paveljanik) +- #8141 `44c1b1c` Continuing port of java comparison tool (mrbandrews) +- #8201 `36b7400` fundrawtransaction: Fix race, assert amounts (MarcoFalke) +- #8214 `ed2cd59` Mininode: fail on send_message instead of silent return (MarcoFalke) +- #8215 `a072d1a` Don't use floating point in wallet tests (MarcoFalke) +- #8066 `65c2058` Test_framework: Use different rpc_auth_pair for each node (MarcoFalke) +- #8216 `0d41d70` Assert 'changePosition out of bounds' (MarcoFalke) +- #8222 `961893f` Enable mempool consistency checks in unit tests (sipa) +- #7751 `84370d5` test_framework: python3.4 authproxy compat (laanwj) +- #7744 `d8e862a` test_framework: detect failure of bitcoind startup (laanwj) +- #8280 `115735d` Increase sync_blocks() timeouts in pruning.py (MarcoFalke) +- #8340 `af9b7a9` Solve trivial merge conflict in p2p-segwit.py (MarcoFalke) +- #8067 `3e4cf8f` Travis: use slim generic image, and some fixups (theuni) +- #7951 `5c7df70` Test_framework: Properly print exception (MarcoFalke) +- #8070 `7771aa5` Remove non-determinism which is breaking net_tests #8069 (EthanHeilman) +- #8309 `bb2646a` Add wallet-hd test (MarcoFalke) +- #8444 `cd0910b` Fix p2p-feefilter.py for changed tx relay behavior (sdaftuar) + +### Mining + +- #7507 `11c7699` Remove internal miner (Leviathn) +- #7663 `c87f51e` Make the generate RPC call function for non-regtest (sipa) +- #7671 `e2ebd25` Add generatetoaddress RPC to mine to an address (achow101) +- #7935 `66ed450` Versionbits: GBT support (luke-jr) +- #7600 `66db2d6` Select transactions using feerate-with-ancestors (sdaftuar) +- #8295 `f5660d3` Mining-related fixups for 0.13.0 (sdaftuar) +- #7796 `536b75e` Add support for negative fee rates, fixes `prioritizetransaction` (MarcoFalke) +- #8362 `86edc20` Scale legacy sigop count in CreateNewBlock (sdaftuar) +- #8489 `8b0eee6` Bugfix: Use pre-BIP141 sigops until segwit activates (GBT) (luke-jr) + +### Documentation and miscellaneous + +- #7423 `69e2a40` Add example for building with constrained resources (jarret) +- #8254 `c2c69ed` Add OSX ZMQ requirement to QA readme (fanquake) +- #8203 `377d131` Clarify documentation for running a tor node (nathaniel-mahieu) +- #7428 `4b12266` Add example for listing ./configure flags (nathaniel-mahieu) +- #7847 `3eae681` Add arch linux build example (mruddy) +- #7968 `ff69aaf` Fedora build requirements (wtogami) +- #8013 `fbedc09` Fedora build requirements, add gcc-c++ and fix typo (wtogami) +- #8009 `fbd8478` Fixed invalid example paths in gitian-building.md (JeremyRand) +- #8240 `63fbdbc` Mention Windows XP end of support in release notes (laanwj) +- #8303 `5077d2c` Update bips.md for CSV softfork (fanquake) +- #7789 `e0b3e19` Add note about using the Qt official binary installer (paveljanik) +- #7791 `e30a5b0` Change Precise to Trusty in gitian-building.md (JeremyRand) +- #7838 `8bb5d3d` Update gitian build guide to debian 8.4.0 (fanquake) +- #7855 `b778e59` Replace precise with trusty (MarcoFalke) +- #7975 `fc23fee` Update bitcoin-core GitHub links (MarcoFalke) +- #8034 `e3a8207` Add basic git squash workflow (fanquake) +- #7813 `214ec0b` Update port in tor.md (MarcoFalke) +- #8193 `37c9830` Use Debian 8.5 in the gitian-build guide (fanquake) +- #8261 `3685e0c` Clarify help for `getblockchaininfo` (paveljanik) +- #7185 `ea0f5a2` Note that reviewers should mention the id of the commits they reviewed (pstratem) +- #7290 `c851d8d` [init] Add missing help for args (MarcoFalke) +- #7281 `f9fd4c2` Improve CheckInputs() comment about sig verification (petertodd) +- #7417 `1e06bab` Minor improvements to the release process (PRabahy) +- #7444 `4cdbd42` Improve block validity/ConnectBlock() comments (petertodd) +- #7527 `db2e1c0` Fix and cleanup listreceivedbyX documentation (instagibbs) +- #7541 `b6e00af` Clarify description of blockindex (pinheadmz) +- #7590 `f06af57` Improving wording related to Boost library requirements [updated] (jonathancross) +- #7635 `0fa88ef` Add dependency info to test docs (elliotolds) +- #7609 `3ba07bd` RPM spec file project (AliceWonderMiscreations) +- #7850 `229a17c` Removed call to `TryCreateDirectory` from `GetDefaultDataDir` in `src/util.cpp` (alexreg) +- #7888 `ec870e1` Prevector: fix 2 bugs in currently unreached code paths (kazcw) +- #7922 `90653bc` CBase58Data::SetString: cleanse the full vector (kazcw) +- #7881 `c4e8390` Update release process (laanwj) +- #7952 `a9c8b74` Log invalid block hash to make debugging easier (paveljanik) +- #7974 `8206835` More comments on the design of AttemptToEvictConnection (gmaxwell) +- #7795 `47a7cfb` UpdateTip: log only one line at most per block (laanwj) +- #8110 `e7e25ea` Add benchmarking notes (fanquake) +- #8121 `58f0c92` Update implemented BIPs list (fanquake) +- #8029 `58725ba` Simplify OS X build notes (fanquake) +- #8143 `d46b8b5` comment nit: miners don't vote (instagibbs) +- #8136 `22e0b35` Log/report in 10% steps during VerifyDB (jonasschnelli) +- #8168 `d366185` util: Add ParseUInt32 and ParseUInt64 (laanwj) +- #8178 `f7b1bfc` Add git and github tips and tricks to developer notes (sipa) +- #8177 `67db011` developer notes: updates for C++11 (kazcw) +- #8229 `8ccdac1` [Doc] Update OS X build notes for 10.11 SDK (fanquake) +- #8233 `9f1807a` Mention Linux ARM executables in release process and notes (laanwj) +- #7540 `ff46dd4` Rename OP_NOP3 to OP_CHECKSEQUENCEVERIFY (btcdrak) +- #8289 `26316ff` bash-completion: Adapt for 0.12 and 0.13 (roques) +- #7453 `3dc3149` Missing patches from 0.12 (MarcoFalke) +- #7113 `54a550b` Switch to a more efficient rolling Bloom filter (sipa) +- #7257 `de9e5ea` Combine common error strings for different options so translations can be shared and reused (luke-jr) +- #7304 `b8f485c` [contrib] Add clang-format-diff.py (MarcoFalke) +- #7378 `e6f97ef` devtools: replace github-merge with python version (laanwj) +- #7395 `0893705` devtools: show pull and commit information in github-merge (laanwj) +- #7402 `6a5932b` devtools: github-merge get toplevel dir without extra whitespace (achow101) +- #7425 `20a408c` devtools: Fix utf-8 support in messages for github-merge (laanwj) +- #7632 `409f843` Delete outdated test-patches reference (Lewuathe) +- #7662 `386f438` remove unused NOBLKS_VERSION_{START,END} constants (rat4) +- #7737 `aa0d2b2` devtools: make github-merge.py use py3 (laanwj) +- #7781 `55db5f0` devtools: Auto-set branch to merge to in github-merge (laanwj) +- #7934 `f17032f` Improve rolling bloom filter performance and benchmark (sipa) +- #8004 `2efe38b` signal handling: fReopenDebugLog and fRequestShutdown should be type sig_atomic_t (catilac) +- #7713 `f6598df` Fixes for verify-commits script (petertodd) +- #8412 `8360d5b` libconsensus: Expose a flag for BIP112 (jtimon) + +Credits +======= + +Thanks to everyone who directly contributed to this release: + +- 21E14 +- accraze +- Adam Brown +- Alexander Regueiro +- Alex Morcos +- Alfie John +- Alice Wonder +- AlSzacrel +- Andrew Chow +- Andrés G. Aragoneses +- Bob McElrath +- BtcDrak +- calebogden +- Cédric Félizard +- Chirag Davé +- Chris Moore +- Chris Stewart +- Christian von Roques +- Chris Wheeler +- Cory Fields +- crowning- +- Daniel Cousens +- Daniel Kraft +- Denis Lukianov +- Elias Rohrer +- Elliot Olds +- Eric Shaw +- error10 +- Ethan Heilman +- face +- fanquake +- Francesco 'makevoid' Canessa +- fsb4000 +- Gavin Andresen +- gladoscc +- Gregory Maxwell +- Gregory Sanders +- instagibbs +- James O'Beirne +- Jannes Faber +- Jarret Dyrbye +- Jeremy Rand +- jloughry +- jmacwhyte +- Joao Fonseca +- Johnson Lau +- Jonas Nick +- Jonas Schnelli +- Jonathan Cross +- João Barbosa +- Jorge Timón +- Kaz Wesley +- Kefkius +- kirkalx +- Krzysztof Jurewicz +- Leviathn +- lewuathe +- Luke Dashjr +- Luv Khemani +- Marcel Krüger +- Marco Falke +- Mark Friedenbach +- Matt +- Matt Bogosian +- Matt Corallo +- Matthew English +- Matthew Zipkin +- mb300sd +- Mitchell Cash +- mrbandrews +- mruddy +- Murch +- Mustafa +- Nathaniel Mahieu +- Nicolas Dorier +- Patrick Strateman +- Paul Rabahy +- paveljanik +- Pavel Janík +- Pavel Vasin +- Pedro Branco +- Peter Todd +- Philip Kaufmann +- Pieter Wuille +- Prayag Verma +- ptschip +- Puru +- randy-waterhouse +- R E Broadley +- Rusty Russell +- Suhas Daftuar +- Suriyaa Kudo +- TheLazieR Yip +- Thomas Kerin +- Tom Harding +- Tyler Hardin +- UdjinM6 +- Warren Togami +- Will Binns +- Wladimir J. van der Laan +- Yuri Zhykin + +As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). diff --git a/doc/release-notes/release-notes-0.13.1.md b/doc/release-notes/release-notes-0.13.1.md new file mode 100644 index 00000000000..75c2d61be8d --- /dev/null +++ b/doc/release-notes/release-notes-0.13.1.md @@ -0,0 +1,410 @@ +Bitcoin Core version 0.13.1 is now available from: + + + +This is a new minor version release, including activation parameters for the +segwit softfork, various bugfixes and performance improvements, as well as +updated translations. + +Please report bugs using the issue tracker at github: + + + +To receive security and update notifications, please subscribe to: + + + +Compatibility +============== + +Microsoft ended support for Windows XP on [April 8th, 2014](https://www.microsoft.com/en-us/WindowsForBusiness/end-of-xp-support), +an OS initially released in 2001. This means that not even critical security +updates will be released anymore. Without security updates, using a bitcoin +wallet on a XP machine is irresponsible at least. + +In addition to that, with 0.12.x there have been varied reports of Bitcoin Core +randomly crashing on Windows XP. It is [not clear](https://github.com/bitcoin/bitcoin/issues/7681#issuecomment-217439891) +what the source of these crashes is, but it is likely that upstream +libraries such as Qt are no longer being tested on XP. + +We do not have time nor resources to provide support for an OS that is +end-of-life. From 0.13.0 on, Windows XP is no longer supported. Users are +suggested to upgrade to a newer version of Windows, or install an alternative OS +that is supported. + +No attempt is made to prevent installing or running the software on Windows XP, +you can still do so at your own risk, but do not expect it to work: do not +report issues about Windows XP to the issue tracker. + +From 0.13.1 onwards OS X 10.7 is no longer supported. 0.13.0 was intended to work on 10.7+, +but severe issues with the libc++ version on 10.7.x keep it from running reliably. +0.13.1 now requires 10.8+, and will communicate that to 10.7 users, rather than crashing unexpectedly. + +Notable changes +=============== + +Segregated witness soft fork +---------------------------- + +Segregated witness (segwit) is a soft fork that, if activated, will +allow transaction-producing software to separate (segregate) transaction +signatures (witnesses) from the part of the data in a transaction that is +covered by the txid. This provides several immediate benefits: + +- **Elimination of unwanted transaction malleability:** Segregating the witness + allows both existing and upgraded software to calculate the transaction + identifier (txid) of transactions without referencing the witness, which can + sometimes be changed by third-parties (such as miners) or by co-signers in a + multisig spend. This solves all known cases of unwanted transaction + malleability, which is a problem that makes programming Bitcoin wallet + software more difficult and which seriously complicates the design of smart + contracts for Bitcoin. + +- **Capacity increase:** Segwit transactions contain new fields that are not + part of the data currently used to calculate the size of a block, which + allows a block containing segwit transactions to hold more data than allowed + by the current maximum block size. Estimates based on the transactions + currently found in blocks indicate that if all wallets switch to using + segwit, the network will be able to support about 70% more transactions. The + network will also be able to support more of the advanced-style payments + (such as multisig) than it can support now because of the different weighting + given to different parts of a transaction after segwit activates (see the + following section for details). + +- **Weighting data based on how it affects node performance:** Some parts of + each Bitcoin block need to be stored by nodes in order to validate future + blocks; other parts of a block can be immediately forgotten (pruned) or used + only for helping other nodes sync their copy of the block chain. One large + part of the immediately prunable data are transaction signatures (witnesses), + and segwit makes it possible to give a different "weight" to segregated + witnesses to correspond with the lower demands they place on node resources. + Specifically, each byte of a segregated witness is given a weight of 1, each + other byte in a block is given a weight of 4, and the maximum allowed weight + of a block is 4 million. Weighting the data this way better aligns the most + profitable strategy for creating blocks with the long-term costs of block + validation. + +- **Signature covers value:** A simple improvement in the way signatures are + generated in segwit simplifies the design of secure signature generators + (such as hardware wallets), reduces the amount of data the signature + generator needs to download, and allows the signature generator to operate + more quickly. This is made possible by having the generator sign the amount + of bitcoins they think they are spending, and by having full nodes refuse to + accept those signatures unless the amount of bitcoins being spent is exactly + the same as was signed. For non-segwit transactions, wallets instead had to + download the complete previous transactions being spent for every payment + they made, which could be a slow operation on hardware wallets and in other + situations where bandwidth or computation speed was constrained. + +- **Linear scaling of sighash operations:** In 2015 a block was produced that + required about 25 seconds to validate on modern hardware because of the way + transaction signature hashes are performed. Other similar blocks, or blocks + that could take even longer to validate, can still be produced today. The + problem that caused this can't be fixed in a soft fork without unwanted + side-effects, but transactions that opt-in to using segwit will now use a + different signature method that doesn't suffer from this problem and doesn't + have any unwanted side-effects. + +- **Increased security for multisig:** Bitcoin addresses (both P2PKH addresses + that start with a '1' and P2SH addresses that start with a '3') use a hash + function known as RIPEMD-160. For P2PKH addresses, this provides about 160 + bits of security---which is beyond what cryptographers believe can be broken + today. But because P2SH is more flexible, only about 80 bits of security is + provided per address. Although 80 bits is very strong security, it is within + the realm of possibility that it can be broken by a powerful adversary. + Segwit allows advanced transactions to use the SHA256 hash function instead, + which provides about 128 bits of security (that is 281 trillion times as + much security as 80 bits and is equivalent to the maximum bits of security + believed to be provided by Bitcoin's choice of parameters for its Elliptic + Curve Digital Security Algorithm [ECDSA].) + +- **More efficient almost-full-node security** Satoshi Nakamoto's original + Bitcoin paper describes a method for allowing newly-started full nodes to + skip downloading and validating some data from historic blocks that are + protected by large amounts of proof of work. Unfortunately, Nakamoto's + method can't guarantee that a newly-started node using this method will + produce an accurate copy of Bitcoin's current ledger (called the UTXO set), + making the node vulnerable to falling out of consensus with other nodes. + Although the problems with Nakamoto's method can't be fixed in a soft fork, + Segwit accomplishes something similar to his original proposal: it makes it + possible for a node to optionally skip downloading some blockchain data + (specifically, the segregated witnesses) while still ensuring that the node + can build an accurate copy of the UTXO set for the block chain with the most + proof of work. Segwit enables this capability at the consensus layer, but + note that Bitcoin Core does not provide an option to use this capability as + of this 0.13.1 release. + +- **Script versioning:** Segwit makes it easy for future soft forks to allow + Bitcoin users to individually opt-in to almost any change in the Bitcoin + Script language when those users receive new transactions. Features + currently being researched by Bitcoin Core contributors that may use this + capability include support for Schnorr signatures, which can improve the + privacy and efficiency of multisig transactions (or transactions with + multiple inputs), and Merklized Abstract Syntax Trees (MAST), which can + improve the privacy and efficiency of scripts with two or more conditions. + Other Bitcoin community members are studying several other improvements + that can be made using script versioning. + +Activation for the segwit soft fork is being managed using BIP9 +versionbits. Segwit's version bit is bit 1, and nodes will begin +tracking which blocks signal support for segwit at the beginning of the +first retarget period after segwit's start date of 15 November 2016. If +95% of blocks within a 2,016-block retarget period (about two weeks) +signal support for segwit, the soft fork will be locked in. After +another 2,016 blocks, segwit will activate. + +For more information about segwit, please see the [segwit FAQ][], the +[segwit wallet developers guide][] or BIPs [141][BIP141], [143][BIP143], +[144][BIP144], and [145][BIP145]. If you're a miner or mining pool +operator, please see the [versionbits FAQ][] for information about +signaling support for a soft fork. + +[Segwit FAQ]: https://bitcoincore.org/en/2016/01/26/segwit-benefits/ +[segwit wallet developers guide]: https://bitcoincore.org/en/segwit_wallet_dev/ +[BIP141]: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki +[BIP143]: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki +[BIP144]: https://github.com/bitcoin/bips/blob/master/bip-0144.mediawiki +[BIP145]: https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki +[versionbits FAQ]: https://bitcoincore.org/en/2016/06/08/version-bits-miners-faq/ + + +Null dummy soft fork +------------------- + +Combined with the segwit soft fork is an additional change that turns a +long-existing network relay policy into a consensus rule. The +`OP_CHECKMULTISIG` and `OP_CHECKMULTISIGVERIFY` opcodes consume an extra +stack element ("dummy element") after signature validation. The dummy +element is not inspected in any manner, and could be replaced by any +value without invalidating the script. + +Because any value can be used for this dummy element, it's possible for +a third-party to insert data into other people's transactions, changing +the transaction's txid (called transaction malleability) and possibly +causing other problems. + +Since Bitcoin Core 0.10.0, nodes have defaulted to only relaying and +mining transactions whose dummy element was a null value (0x00, also +called OP_0). The null dummy soft fork turns this relay rule into a +consensus rule both for non-segwit transactions and segwit transactions, +so that this method of mutating transactions is permanently eliminated +from the network. + +Signaling for the null dummy soft fork is done by signaling support +for segwit, and the null dummy soft fork will activate at the same time +as segwit. + +For more information, please see [BIP147][]. + +[BIP147]: https://github.com/bitcoin/bips/blob/master/bip-0147.mediawiki + +Low-level RPC changes +--------------------- + +- `importprunedfunds` only accepts two required arguments. Some versions accept + an optional third arg, which was always ignored. Make sure to never pass more + than two arguments. + + +Linux ARM builds +---------------- + +With the 0.13.0 release, pre-built Linux ARM binaries were added to the set of +uploaded executables. Additional detail on the ARM architecture targeted by each +is provided below. + +The following extra files can be found in the download directory or torrent: + +- `bitcoin-${VERSION}-arm-linux-gnueabihf.tar.gz`: Linux binaries targeting + the 32-bit ARMv7-A architecture. +- `bitcoin-${VERSION}-aarch64-linux-gnu.tar.gz`: Linux binaries targeting + the 64-bit ARMv8-A architecture. + +ARM builds are still experimental. If you have problems on a certain device or +Linux distribution combination please report them on the bug tracker, it may be +possible to resolve them. Note that the device you use must be (backward) +compatible with the architecture targeted by the binary that you use. +For example, a Raspberry Pi 2 Model B or Raspberry Pi 3 Model B (in its 32-bit +execution state) device, can run the 32-bit ARMv7-A targeted binary. However, +no model of Raspberry Pi 1 device can run either binary because they are all +ARMv6 architecture devices that are not compatible with ARMv7-A or ARMv8-A. + +Note that Android is not considered ARM Linux in this context. The executables +are not expected to work out of the box on Android. + + +0.13.1 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. + +### Consensus +- #8636 `9dfa0c8` Implement NULLDUMMY softfork (BIP147) (jl2012) +- #8848 `7a34a46` Add NULLDUMMY verify flag in bitcoinconsensus.h (jl2012) +- #8937 `8b66659` Define start and end time for segwit deployment (sipa) + +### RPC and other APIs +- #8581 `526d2b0` Drop misleading option in importprunedfunds (MarcoFalke) +- #8699 `a5ec248` Remove createwitnessaddress RPC command (jl2012) +- #8780 `794b007` Deprecate getinfo (MarcoFalke) +- #8832 `83ad563` Throw JSONRPCError when utxo set can not be read (MarcoFalke) +- #8884 `b987348` getblockchaininfo help: pruneheight is the lowest, not highest, block (luke-jr) +- #8858 `3f508ed` rpc: Generate auth cookie in hex instead of base64 (laanwj) +- #8951 `7c2bf4b` RPC/Mining: getblocktemplate: Update and fix formatting of help (luke-jr) + +### Block and transaction handling +- #8611 `a9429ca` Reduce default number of blocks to check at startup (sipa) +- #8634 `3e80ab7` Add policy: null signature for failed CHECK(MULTI)SIG (jl2012) +- #8525 `1672225` Do not store witness txn in rejection cache (sipa) +- #8499 `9777fe1` Add several policy limits and disable uncompressed keys for segwit scripts (jl2012) +- #8526 `0027672` Make non-minimal OP_IF/NOTIF argument non-standard for P2WSH (jl2012) +- #8524 `b8c79a0` Precompute sighashes (sipa) +- #8651 `b8c79a0` Predeclare PrecomputedTransactionData as struct (sipa) + +### P2P protocol and network code +- #8740 `42ea51a` No longer send local address in addrMe (laanwj) +- #8427 `69d1cd2` Ignore `notfound` P2P messages (laanwj) +- #8573 `4f84082` Set jonasschnellis dns-seeder filter flag (jonasschnelli) +- #8712 `23feab1` Remove maxuploadtargets recommended minimum (jonasschnelli) +- #8862 `7ae6242` Fix a few cases where messages were sent after requested disconnect (theuni) +- #8393 `fe1975a` Support for compact blocks together with segwit (sipa) +- #8282 `2611ad7` Feeler connections to increase online addrs in the tried table (EthanHeilman) +- #8612 `2215c22` Check for compatibility with download in FindNextBlocksToDownload (sipa) +- #8606 `bbf379b` Fix some locks (sipa) +- #8594 `ab295bb` Do not add random inbound peers to addrman (gmaxwell) +- #8940 `5b4192b` Add x9 service bit support to dnsseed.bluematt.me, seed.bitcoinstats.com (TheBlueMatt, cdecker) +- #8944 `685e4c7` Remove bogus assert on number of oubound connections. (TheBlueMatt) +- #8949 `0dbc48a` Be more agressive in getting connections to peers with relevant services (gmaxwell) + +### Build system +- #8293 `fa5b249` Allow building libbitcoinconsensus without any univalue (luke-jr) +- #8492 `8b0bdd3` Allow building bench_bitcoin by itself (luke-jr) +- #8563 `147003c` Add configure check for -latomic (ajtowns) +- #8626 `ea51b0f` Berkeley DB v6 compatibility fix (netsafe) +- #8520 `75f2065` Remove check for `openssl/ec.h` (laanwj) + +### GUI +- #8481 `d9f0d4e` Fix minimize and close bugs (adlawren) +- #8487 `a37cec5` Persist the datadir after option reset (achow101) +- #8697 `41fd852` Fix op order to append first alert (rodasmith) +- #8678 `8e03382` Fix UI bug that could result in paying unexpected fee (jonasschnelli) +- #8911 `7634d8e` Translate all files, even if wallet disabled (laanwj) +- #8540 `1db3352` Fix random segfault when closing "Choose data directory" dialog (laanwj) +- #7579 `f1c0d78` Show network/chain errors in the GUI (jonasschnelli) + +### Wallet +- #8443 `464dedd` Trivial cleanup of HD wallet changes (jonasschnelli) +- #8539 `cb07f19` CDB: fix debug output (crowning-) +- #8664 `091cdeb` Fix segwit-related wallet bug (sdaftuar) +- #8693 `c6a6291` Add witness address to address book (instagibbs) +- #8765 `6288659` Remove "unused" ThreadFlushWalletDB from removeprunedfunds (jonasschnelli) + +### Tests and QA +- #8713 `ae8c7df` create_cache: Delete temp dir when done (MarcoFalke) +- #8716 `e34374e` Check legacy wallet as well (MarcoFalke) +- #8750 `d6ebe13` Refactor RPCTestHandler to prevent TimeoutExpired (MarcoFalke) +- #8652 `63462c2` remove root test directory for RPC tests (yurizhykin) +- #8724 `da94272` walletbackup: Sync blocks inside the loop (MarcoFalke) +- #8400 `bea02dc` enable rpcbind_test (yurizhykin) +- #8417 `f70be14` Add walletdump RPC test (including HD- & encryption-tests) (jonasschnelli) +- #8419 `a7aa3cc` Enable size accounting in mining unit tests (sdaftuar) +- #8442 `8bb1efd` Rework hd wallet dump test (MarcoFalke) +- #8528 `3606b6b` Update p2p-segwit.py to reflect correct behavior (instagibbs) +- #8531 `a27cdd8` abandonconflict: Use assert_equal (MarcoFalke) +- #8667 `6b07362` Fix SIGHASH_SINGLE bug in test_framework SignatureHash (jl2012) +- #8673 `03b0196` Fix obvious assignment/equality error in test (JeremyRubin) +- #8739 `cef633c` Fix broken sendcmpct test in p2p-compactblocks.py (sdaftuar) +- #8418 `ff893aa` Add tests for compact blocks (sdaftuar) +- #8803 `375437c` Ping regularly in p2p-segwit.py to keep connection alive (jl2012) +- #8827 `9bbe66e` Split up slow RPC calls to avoid pruning test timeouts (sdaftuar) +- #8829 `2a8bca4` Add bitcoin-tx JSON tests (jnewbery) +- #8834 `1dd1783` blockstore: Switch to dumb dbm (MarcoFalke) +- #8835 `d87227d` nulldummy.py: Don't run unused code (MarcoFalke) +- #8836 `eb18cc1` bitcoin-util-test.py should fail if the output file is empty (jnewbery) +- #8839 `31ab2f8` Avoid ConnectionResetErrors during RPC tests (laanwj) +- #8840 `cbc3fe5` Explicitly set encoding to utf8 when opening text files (laanwj) +- #8841 `3e4abb5` Fix nulldummy test (jl2012) +- #8854 `624a007` Fix race condition in p2p-compactblocks test (sdaftuar) +- #8857 `1f60d45` mininode: Only allow named args in wait_until (MarcoFalke) +- #8860 `0bee740` util: Move wait_bitcoinds() into stop_nodes() (MarcoFalke) +- #8882 `b73f065` Fix race conditions in p2p-compactblocks.py and sendheaders.py (sdaftuar) +- #8904 `cc6f551` Fix compact block shortids for a test case (dagurval) + +### Documentation +- #8754 `0e2c6bd` Target protobuf 2.6 in OS X build notes. (fanquake) +- #8461 `b17a3f9` Document return value of networkhashps for getmininginfo RPC endpoint (jlopp) +- #8512 `156e305` Corrected JSON typo on setban of net.cpp (sevastos) +- #8683 `8a7d7ff` Fix incorrect file name bitcoin.qrc (bitcoinsSG) +- #8891 `5e0dd9e` Update bips.md for Segregated Witness (fanquake) +- #8545 `863ae74` Update git-subtree-check.sh README (MarcoFalke) +- #8607 `486650a` Fix doxygen off-by-one comments, fix typos (MarcoFalke) +- #8560 `c493f43` Fix two VarInt examples in serialize.h (cbarcenas) +- #8737 `084cae9` UndoReadFromDisk works on undo files (rev), not on block files (paveljanik) +- #8625 `0a35573` Clarify statement about parallel jobs in rpc-tests.py (isle2983) +- #8624 `0e6d753` build: Mention curl (MarcoFalke) +- #8604 `b09e13c` build,doc: Update for 0.13.0+ and OpenBSD 5.9 (laanwj) +- #8939 `06d15fb` Update implemented bips for 0.13.1 (sipa) + +### Miscellaneous +- #8742 `d31ac72` Specify Protobuf version 2 in paymentrequest.proto (fanquake) +- #8414,#8558,#8676,#8700,#8701,#8702 Add missing copyright headers (isle2983, kazcw) +- #8899 `4ed2627` Fix wake from sleep issue with Boost 1.59.0 (fanquake) +- #8817 `bcf3806` update bitcoin-tx to output witness data (jnewbery) +- #8513 `4e5fc31` Fix a type error that would not compile on OSX. (JeremyRubin) +- #8392 `30eac2d` Fix several node initialization issues (sipa) +- #8548 `305d8ac` Use `__func__` to get function name for output printing (MarcoFalke) +- #8291 `a987431` [util] CopyrightHolders: Check for untranslated substitution (MarcoFalke) + +Credits +======= + +Thanks to everyone who directly contributed to this release: + +- adlawren +- Alexey Vesnin +- Anders Øyvind Urke-Sætre +- Andrew Chow +- Anthony Towns +- BtcDrak +- Chris Stewart +- Christian Barcenas +- Christian Decker +- Cory Fields +- crowning- +- Dagur Valberg Johannsson +- David A. Harding +- Eric Lombrozo +- Ethan Heilman +- fanquake +- Gaurav Rana +- Gregory Maxwell +- instagibbs +- isle2983 +- Jameson Lopp +- Jeremy Rubin +- jnewbery +- Johnson Lau +- Jonas Schnelli +- jonnynewbs +- Justin Camarena +- Kaz Wesley +- leijurv +- Luke Dashjr +- MarcoFalke +- Marty Jones +- Matt Corallo +- Micha +- Michael Ford +- mruddy +- Pavel Janík +- Pieter Wuille +- rodasmith +- Sev +- Suhas Daftuar +- whythat +- Wladimir J. van der Laan + +As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/). diff --git a/doc/release-notes/release-notes-0.13.2.md b/doc/release-notes/release-notes-0.13.2.md new file mode 100644 index 00000000000..45fff5c8bbd --- /dev/null +++ b/doc/release-notes/release-notes-0.13.2.md @@ -0,0 +1,178 @@ +Bitcoin Core version 0.13.2 is now available from: + + + +This is a new minor version release, including various bugfixes and +performance improvements, as well as updated translations. + +Please report bugs using the issue tracker at github: + + + +To receive security and update notifications, please subscribe to: + + + +Compatibility +============== + +Microsoft ended support for Windows XP on [April 8th, 2014](https://www.microsoft.com/en-us/WindowsForBusiness/end-of-xp-support), +an OS initially released in 2001. This means that not even critical security +updates will be released anymore. Without security updates, using a bitcoin +wallet on a XP machine is irresponsible at least. + +In addition to that, with 0.12.x there have been varied reports of Bitcoin Core +randomly crashing on Windows XP. It is [not clear](https://github.com/bitcoin/bitcoin/issues/7681#issuecomment-217439891) +what the source of these crashes is, but it is likely that upstream +libraries such as Qt are no longer being tested on XP. + +We do not have time nor resources to provide support for an OS that is +end-of-life. From 0.13.0 on, Windows XP is no longer supported. Users are +suggested to upgrade to a newer version of Windows, or install an alternative OS +that is supported. + +No attempt is made to prevent installing or running the software on Windows XP, +you can still do so at your own risk, but do not expect it to work: do not +report issues about Windows XP to the issue tracker. + +From 0.13.1 onwards OS X 10.7 is no longer supported. 0.13.0 was intended to work on 10.7+, +but severe issues with the libc++ version on 10.7.x keep it from running reliably. +0.13.1 now requires 10.8+, and will communicate that to 10.7 users, rather than crashing unexpectedly. + +Notable changes +=============== + +Change to wallet handling of mempool rejection +----------------------------------------------- + +When a newly created transaction failed to enter the mempool due to +the limits on chains of unconfirmed transactions the sending RPC +calls would return an error. The transaction would still be queued +in the wallet and, once some of the parent transactions were +confirmed, broadcast after the software was restarted. + +This behavior has been changed to return success and to reattempt +mempool insertion at the same time transaction rebroadcast is +attempted, avoiding a need for a restart. + +Transactions in the wallet which cannot be accepted into the mempool +can be abandoned with the previously existing abandontransaction RPC +(or in the GUI via a context menu on the transaction). + + +0.13.2 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. + +### Consensus +- #9293 `e591c10` [0.13 Backport #9053] IBD using chainwork instead of height and not using header timestamp (gmaxwell) +- #9053 `5b93eee` IBD using chainwork instead of height and not using header timestamps (gmaxwell) + +### RPC and other APIs +- #8845 `1d048b9` Don't return the address of a P2SH of a P2SH (jnewbery) +- #9041 `87fbced` keypoololdest denote Unix epoch, not GMT (s-matthew-english) +- #9122 `f82c81b` fix getnettotals RPC description about timemillis (visvirial) +- #9042 `5bcb05d` [rpc] ParseHash: Fail when length is not 64 (MarcoFalke) +- #9194 `f26dab7` Add option to return non-segwit serialization via rpc (instagibbs) +- #9347 `b711390` [0.13.2] wallet/rpc backports (MarcoFalke) +- #9292 `c365556` Complain when unknown rpcserialversion is specified (sipa) +- #9322 `49a612f` [qa] Don't set unknown rpcserialversion (MarcoFalke) + +### Block and transaction handling +- #8357 `ce0d817` [mempool] Fix relaypriority calculation error (maiiz) +- #9267 `0a4aa87` [0.13 backport #9239] Disable fee estimates for a confirm target of 1 block (morcos) +- #9196 `0c09d9f` Send tip change notification from invalidateblock (ryanofsky) + +### P2P protocol and network code +- #8995 `9ef3875` Add missing cs_main lock to ::GETBLOCKTXN processing (TheBlueMatt) +- #9234 `94531b5` torcontrol: Explicitly request RSA1024 private key (laanwj) +- #8637 `2cad5db` Compact Block Tweaks (rebase of #8235) (sipa) +- #9058 `286e548` Fixes for p2p-compactblocks.py test timeouts on travis (#8842) (ryanofsky) +- #8865 `4c71fc4` Decouple peer-processing-logic from block-connection-logic (TheBlueMatt) +- #9117 `6fe3981` net: don't send feefilter messages before the version handshake is complete (theuni) +- #9188 `ca1fd75` Make orphan parent fetching ask for witnesses (gmaxwell) +- #9052 `3a3bcbf` Use RelevantServices instead of node_network in AttemptToEvict (gmaxwell) +- #9048 `9460771` [0.13 backport #9026] Fix handling of invalid compact blocks (sdaftuar) +- #9357 `03b6f62` [0.13 backport #9352] Attempt reconstruction from all compact block announcements (sdaftuar) +- #9189 `b96a8f7` Always add default_witness_commitment with GBT client support (sipa) +- #9253 `28d0f22` Fix calculation of number of bound sockets to use (TheBlueMatt) +- #9199 `da5a16b` Always drop the least preferred HB peer when adding a new one (gmaxwell) + +### Build system +- #9169 `d1b4da9` build: fix qt5.7 build under macOS (theuni) +- #9326 `a0f7ece` Update for OpenSSL 1.1 API (gmaxwell) +- #9224 `396c405` Prevent FD_SETSIZE error building on OpenBSD (ivdsangen) + +### GUI +- #8972 `6f86b53` Make warnings label selectable (jonasschnelli) (MarcoFalke) +- #9185 `6d70a73` Fix coincontrol sort issue (jonasschnelli) +- #9094 `5f3a12c` Use correct conversion function for boost::path datadir (laanwj) +- #8908 `4a974b2` Update bitcoin-qt.desktop (s-matthew-english) +- #9190 `dc46b10` Plug many memory leaks (laanwj) + +### Wallet +- #9290 `35174a0` Make RelayWalletTransaction attempt to AcceptToMemoryPool (gmaxwell) +- #9295 `43bcfca` Bugfix: Fundrawtransaction: don't terminate when keypool is empty (jonasschnelli) +- #9302 `f5d606e` Return txid even if ATMP fails for new transaction (sipa) +- #9262 `fe39f26` Prefer coins that have fewer ancestors, sanity check txn before ATMP (instagibbs) + +### Tests and QA +- #9159 `eca9b46` Wait for specific block announcement in p2p-compactblocks (ryanofsky) +- #9186 `dccdc3a` Fix use-after-free in scheduler tests (laanwj) +- #9168 `3107280` Add assert_raises_message to check specific error message (mrbandrews) +- #9191 `29435db` 0.13.2 Backports (MarcoFalke) +- #9077 `1d4c884` Increase wallet-dump RPC timeout (ryanofsky) +- #9098 `ecd7db5` Handle zombies and cluttered tmpdirs (MarcoFalke) +- #8927 `387ec9d` Add script tests for FindAndDelete in pre-segwit and segwit scripts (jl2012) +- #9200 `eebc699` bench: Fix subtle counting issue when rescaling iteration count (laanwj) + +### Miscellaneous +- #8838 `094848b` Calculate size and weight of block correctly in CreateNewBlock() (jnewbery) +- #8920 `40169dc` Set minimum required Boost to 1.47.0 (fanquake) +- #9251 `a710a43` Improvement of documentation of command line parameter 'whitelist' (wodry) +- #8932 `106da69` Allow bitcoin-tx to create v2 transactions (btcdrak) +- #8929 `12428b4` add software-properties-common (sigwo) +- #9120 `08d1c90` bug: Missed one "return false" in recent refactoring in #9067 (UdjinM6) +- #9067 `f85ee01` Fix exit codes (UdjinM6) +- #9340 `fb987b3` [0.13] Update secp256k1 subtree (MarcoFalke) +- #9229 `b172377` Remove calls to getaddrinfo_a (TheBlueMatt) + +Credits +======= + +Thanks to everyone who directly contributed to this release: + +- Alex Morcos +- BtcDrak +- Cory Fields +- fanquake +- Gregory Maxwell +- Gregory Sanders +- instagibbs +- Ivo van der Sangen +- jnewbery +- Johnson Lau +- Jonas Schnelli +- Luke Dashjr +- maiiz +- MarcoFalke +- Masahiko Hyuga +- Matt Corallo +- matthias +- mrbandrews +- Pavel Janík +- Pieter Wuille +- randy-waterhouse +- Russell Yanofsky +- S. Matthew English +- Steven +- Suhas Daftuar +- UdjinM6 +- Wladimir J. van der Laan +- wodry + +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 35ee1edae11..ccc4bcd2308 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -10,6 +10,7 @@ Before every minor and major release: * Update [bips.md](bips.md) to account for changes since the last release. * Update version in sources (see below) * Write release notes (see below) +* Update `src/chainparams.cpp` nMinimumChainWork with information from the getblockchaininfo rpc. Before every major release: @@ -112,16 +113,16 @@ The gbuild invocations below DO NOT DO THIS by default. ### Build and sign Bitcoin Core for Linux, Windows, and OS X: pushd ./gitian-builder - ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml + ./bin/gbuild --memory 3000 --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 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/gbuild --memory 3000 --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 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/gbuild --memory 3000 --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 mv build/out/bitcoin-*-osx-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../ diff --git a/doc/shared-libraries.md b/doc/shared-libraries.md index ec6f16c8aaf..dc363582cc8 100644 --- a/doc/shared-libraries.md +++ b/doc/shared-libraries.md @@ -30,12 +30,17 @@ The interface is defined in the C header `bitcoinconsensus.h` located in `src/s - `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NONE` - `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH` - Evaluate P2SH ([BIP16](https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki)) subscripts - `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG` - Enforce strict DER ([BIP66](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki)) compliance +- `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NULLDUMMY` - Enforce NULLDUMMY ([BIP147](https://github.com/bitcoin/bips/blob/master/bip-0147.mediawiki)) +- `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY` - Enable CHECKLOCKTIMEVERIFY ([BIP65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki)) +- `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKSEQUENCEVERIFY` - Enable CHECKSEQUENCEVERIFY ([BIP112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki)) +- `bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS` - Enable WITNESS ([BIP141](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki)) ##### Errors - `bitcoinconsensus_ERR_OK` - No errors with input parameters *(see the return value of `bitcoinconsensus_verify_script` for the verification status)* - `bitcoinconsensus_ERR_TX_INDEX` - An invalid index for `txTo` - `bitcoinconsensus_ERR_TX_SIZE_MISMATCH` - `txToLen` did not match with the size of `txTo` - `bitcoinconsensus_ERR_DESERIALIZE` - An error deserializing `txTo` +- `bitcoinconsensus_ERR_AMOUNT_REQUIRED` - Input amount is required if WITNESS is used ### Example Implementations - [NBitcoin](https://github.com/NicolasDorier/NBitcoin/blob/master/NBitcoin/Script.cs#L814) (.NET Bindings) diff --git a/doc/translation_process.md b/doc/translation_process.md index 310d560b364..9e9ced24572 100644 --- a/doc/translation_process.md +++ b/doc/translation_process.md @@ -6,7 +6,7 @@ The Bitcoin-Core project has been designed to support multiple localisations. Th ### Helping to translate (using Transifex) Transifex is setup to monitor the Github repo for updates, and when code containing new translations is found, Transifex will process any changes. It may take several hours after a pull-request has been merged, to appear in the Transifex web interface. -Multiple language support is critical in assisting Bitcoin’s global adoption, and growth. One of Bitcoin’s greatest strengths is cross-boarder money transfers, any help making that easier is greatly appreciated. +Multiple language support is critical in assisting Bitcoin’s global adoption, and growth. One of Bitcoin’s greatest strengths is cross-border money transfers, any help making that easier is greatly appreciated. See the [Transifex Bitcoin project](https://www.transifex.com/projects/p/bitcoin/) to assist in translations. You should also join the translation mailing list for announcements - see details below. @@ -94,7 +94,7 @@ When new plurals are added to the source file, it's important to do the followin 7. Save the source file ### Translating a new language -To create a new language template, you will need to edit the languages manifest file `src/qt/bitcoin.qrc` and add a new entry. Below is an example of the english language entry. +To create a new language template, you will need to edit the languages manifest file `src/qt/bitcoin_locale.qrc` and add a new entry. Below is an example of the English language entry. ```xml diff --git a/qa/README.md b/qa/README.md index 723660c6c85..225207cc1ce 100644 --- a/qa/README.md +++ b/qa/README.md @@ -41,8 +41,8 @@ Run all possible tests with qa/pull-tester/rpc-tests.py -extended -By default, tests will be run in parallel if you want to specify how many -tests should be run in parallel, append `-parallel=n` (default n=4). +By default, tests will be run in parallel. To specify how many jobs to run, +append `-parallel=n` (default n=4). If you want to create a basic coverage report for the rpc test suite, append `--coverage`. diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 11b83bac146..887644c51b9 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -94,12 +94,12 @@ if ENABLE_ZMQ: try: import zmq - except ImportError as e: - print("WARNING: \"import zmq\" failed. Set ENABLE_ZMQ=0 or " \ - "to run zmq tests, see dependency info in /qa/README.md.") - ENABLE_ZMQ=0 + except ImportError: + print("ERROR: \"import zmq\" failed. Set ENABLE_ZMQ=0 or " + "to run zmq tests, see dependency info in /qa/README.md.") + # ENABLE_ZMQ=0 + raise -#Tests testScripts = [ # longest test should go first, to favor running tests in parallel 'p2p-fullblocktest.py', @@ -107,6 +107,7 @@ 'bip68-112-113-p2p.py', 'wallet.py', 'wallet-hd.py', + 'wallet-dump.py', 'listtransactions.py', 'receivedby.py', 'mempool_resurrect_test.py', @@ -141,6 +142,8 @@ 'segwit.py', 'importprunedfunds.py', 'signmessages.py', + 'p2p-compactblocks.py', + 'nulldummy.py', ] if ENABLE_ZMQ: testScripts.append('zmq_test.py') @@ -158,7 +161,7 @@ 'txn_clone.py --mineblock', 'forknotify.py', 'invalidateblock.py', -# 'rpcbind_test.py', #temporary, bug in libevent, see #6655 + 'rpcbind_test.py', 'smartfees.py', 'maxblocksinflight.py', 'p2p-acceptblock.py', @@ -240,6 +243,10 @@ def __init__(self, num_tests_parallel, test_list=None, flags=None): self.test_list = test_list self.flags = flags self.num_running = 0 + # In case there is a graveyard of zombie bitcoinds, we can apply a + # pseudorandom offset to hopefully jump over them. + # (625 is PORT_RANGE/MAX_NODES) + self.portseed_offset = int(time.time() * 1000) % 625 self.jobs = [] def get_next(self): @@ -247,22 +254,28 @@ def get_next(self): # Add tests self.num_running += 1 t = self.test_list.pop(0) - port_seed = ["--portseed=%s" % len(self.test_list)] + port_seed = ["--portseed={}".format(len(self.test_list) + self.portseed_offset)] + log_stdout = tempfile.SpooledTemporaryFile(max_size=2**16) + log_stderr = tempfile.SpooledTemporaryFile(max_size=2**16) self.jobs.append((t, time.time(), subprocess.Popen((RPC_TESTS_DIR + t).split() + self.flags + port_seed, universal_newlines=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE))) + stdout=log_stdout, + stderr=log_stderr), + log_stdout, + log_stderr)) if not self.jobs: raise IndexError('pop from empty list') while True: # Return first proc that finishes time.sleep(.5) for j in self.jobs: - (name, time0, proc) = j + (name, time0, proc, log_out, log_err) = j if proc.poll() is not None: - (stdout, stderr) = proc.communicate(timeout=3) + log_out.seek(0), log_err.seek(0) + [stdout, stderr] = [l.read().decode('utf-8') for l in (log_out, log_err)] + log_out.close(), log_err.close() passed = stderr == "" and proc.returncode == 0 self.num_running -= 1 self.jobs.remove(j) diff --git a/qa/rpc-tests/abandonconflict.py b/qa/rpc-tests/abandonconflict.py index c50c3cc562e..874df487777 100755 --- a/qa/rpc-tests/abandonconflict.py +++ b/qa/rpc-tests/abandonconflict.py @@ -68,7 +68,7 @@ def run_test(self): # In mempool txs from self should increase balance from change newbalance = self.nodes[0].getbalance() - assert(newbalance == balance - Decimal("30") + Decimal("24.9996")) + assert_equal(newbalance, balance - Decimal("30") + Decimal("24.9996")) balance = newbalance # Restart the node with a higher min relay fee so the parent tx is no longer in mempool @@ -78,16 +78,16 @@ def run_test(self): self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.0001"]) # Verify txs no longer in mempool - assert(len(self.nodes[0].getrawmempool()) == 0) + assert_equal(len(self.nodes[0].getrawmempool()), 0) # Not in mempool txs from self should only reduce balance # inputs are still spent, but change not received newbalance = self.nodes[0].getbalance() - assert(newbalance == balance - Decimal("24.9996")) + assert_equal(newbalance, balance - Decimal("24.9996")) # Unconfirmed received funds that are not in mempool, also shouldn't show # up in unconfirmed balance unconfbalance = self.nodes[0].getunconfirmedbalance() + self.nodes[0].getbalance() - assert(unconfbalance == newbalance) + assert_equal(unconfbalance, newbalance) # Also shouldn't show up in listunspent assert(not txABC2 in [utxo["txid"] for utxo in self.nodes[0].listunspent(0)]) balance = newbalance @@ -96,35 +96,35 @@ def run_test(self): # including that the child tx was also abandoned self.nodes[0].abandontransaction(txAB1) newbalance = self.nodes[0].getbalance() - assert(newbalance == balance + Decimal("30")) + assert_equal(newbalance, balance + Decimal("30")) balance = newbalance # Verify that even with a low min relay fee, the tx is not reaccepted from wallet on startup once abandoned stop_node(self.nodes[0],0) self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.00001"]) - assert(len(self.nodes[0].getrawmempool()) == 0) - assert(self.nodes[0].getbalance() == balance) + assert_equal(len(self.nodes[0].getrawmempool()), 0) + assert_equal(self.nodes[0].getbalance(), balance) # But if its received again then it is unabandoned # And since now in mempool, the change is available # But its child tx remains abandoned self.nodes[0].sendrawtransaction(signed["hex"]) newbalance = self.nodes[0].getbalance() - assert(newbalance == balance - Decimal("20") + Decimal("14.99998")) + assert_equal(newbalance, balance - Decimal("20") + Decimal("14.99998")) balance = newbalance # Send child tx again so its unabandoned self.nodes[0].sendrawtransaction(signed2["hex"]) newbalance = self.nodes[0].getbalance() - assert(newbalance == balance - Decimal("10") - Decimal("14.99998") + Decimal("24.9996")) + assert_equal(newbalance, balance - Decimal("10") - Decimal("14.99998") + Decimal("24.9996")) balance = newbalance # Remove using high relay fee again stop_node(self.nodes[0],0) self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.0001"]) - assert(len(self.nodes[0].getrawmempool()) == 0) + assert_equal(len(self.nodes[0].getrawmempool()), 0) newbalance = self.nodes[0].getbalance() - assert(newbalance == balance - Decimal("24.9996")) + assert_equal(newbalance, balance - Decimal("24.9996")) balance = newbalance # Create a double spend of AB1 by spending again from only A's 10 output @@ -143,7 +143,7 @@ def run_test(self): # Verify that B and C's 10 BTC outputs are available for spending again because AB1 is now conflicted newbalance = self.nodes[0].getbalance() - assert(newbalance == balance + Decimal("20")) + assert_equal(newbalance, balance + Decimal("20")) balance = newbalance # There is currently a minor bug around this and so this test doesn't work. See Issue #7315 @@ -151,7 +151,7 @@ def run_test(self): # Don't think C's should either self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) newbalance = self.nodes[0].getbalance() - #assert(newbalance == balance - Decimal("10")) + #assert_equal(newbalance, balance - Decimal("10")) print("If balance has not declined after invalidateblock then out of mempool wallet tx which is no longer") print("conflicted has not resumed causing its inputs to be seen as spent. See Issue #7315") print(str(balance) + " -> " + str(newbalance) + " ?") diff --git a/qa/rpc-tests/bip9-softforks.py b/qa/rpc-tests/bip9-softforks.py index 979d1410c26..be6ddde112e 100755 --- a/qa/rpc-tests/bip9-softforks.py +++ b/qa/rpc-tests/bip9-softforks.py @@ -195,7 +195,6 @@ def test_BIP(self, bipName, activated_version, invalidate, invalidatePostSignatu # Restart all self.test.block_store.close() stop_nodes(self.nodes) - wait_bitcoinds() shutil.rmtree(self.options.tmpdir) self.setup_chain() self.setup_network() diff --git a/qa/rpc-tests/create_cache.py b/qa/rpc-tests/create_cache.py index b6161e0917d..1ace6310d0d 100755 --- a/qa/rpc-tests/create_cache.py +++ b/qa/rpc-tests/create_cache.py @@ -12,9 +12,15 @@ class CreateCache(BitcoinTestFramework): + def __init__(self): + super().__init__() + + # Test network and test nodes are not required: + self.num_nodes = 0 + self.nodes = [] + def setup_network(self): - # Don't setup any test nodes - self.options.noshutdown = True + pass def run_test(self): pass diff --git a/qa/rpc-tests/forknotify.py b/qa/rpc-tests/forknotify.py index 5a3f75c8087..a1901aedab8 100755 --- a/qa/rpc-tests/forknotify.py +++ b/qa/rpc-tests/forknotify.py @@ -22,7 +22,7 @@ def __init__(self): def setup_network(self): self.nodes = [] self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt") - with open(self.alert_filename, 'w') as f: + with open(self.alert_filename, 'w', encoding='utf8') as f: pass # Just open then close to create zero-length file self.nodes.append(start_node(0, self.options.tmpdir, ["-blockversion=2", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""])) @@ -44,7 +44,7 @@ def run_test(self): self.nodes[1].generate(1) self.sync_all() - with open(self.alert_filename, 'r') as f: + with open(self.alert_filename, 'r', encoding='utf8') as f: alert_text = f.read() if len(alert_text) == 0: @@ -56,7 +56,7 @@ def run_test(self): self.nodes[1].generate(1) self.sync_all() - with open(self.alert_filename, 'r') as f: + with open(self.alert_filename, 'r', encoding='utf8') as f: alert_text2 = f.read() if alert_text != alert_text2: diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index eeb8476634f..0dcca4cb570 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -470,7 +470,6 @@ def run_test(self): self.nodes[1].encryptwallet("test") self.nodes.pop(1) stop_nodes(self.nodes) - wait_bitcoinds() self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) # This test is not meant to test fee estimation and we'd like @@ -485,6 +484,23 @@ def run_test(self): self.is_network_split=False self.sync_all() + # drain the keypool + self.nodes[1].getnewaddress() + inputs = [] + outputs = {self.nodes[0].getnewaddress():1.1} + rawTx = self.nodes[1].createrawtransaction(inputs, outputs) + # fund a transaction that requires a new key for the change output + # creating the key must be impossible because the wallet is locked + try: + fundedTx = self.nodes[1].fundrawtransaction(rawTx) + raise AssertionError("Wallet unlocked without passphrase") + except JSONRPCException as e: + assert('Keypool ran out' in e.error['message']) + + #refill the keypool + self.nodes[1].walletpassphrase("test", 100) + self.nodes[1].walletlock() + try: self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.2) raise AssertionError("Wallet unlocked without passphrase") diff --git a/qa/rpc-tests/importprunedfunds.py b/qa/rpc-tests/importprunedfunds.py index d86f51b7f3a..3287470c55c 100755 --- a/qa/rpc-tests/importprunedfunds.py +++ b/qa/rpc-tests/importprunedfunds.py @@ -20,14 +20,10 @@ def setup_network(self, split=False): self.is_network_split=False self.sync_all() - def run_test (self): - import time - begintime = int(time.time()) - + def run_test(self): print("Mining blocks...") self.nodes[0].generate(101) - # sync self.sync_all() # address @@ -72,7 +68,6 @@ def run_test (self): rawtxn2 = self.nodes[0].gettransaction(txnid2)['hex'] proof2 = self.nodes[0].gettxoutproof([txnid2]) - txnid3 = self.nodes[0].sendtoaddress(address3, 0.025) self.nodes[0].generate(1) rawtxn3 = self.nodes[0].gettransaction(txnid3)['hex'] @@ -82,28 +77,27 @@ def run_test (self): #Import with no affiliated address try: - result1 = self.nodes[1].importprunedfunds(rawtxn1, proof1, "") + self.nodes[1].importprunedfunds(rawtxn1, proof1) except JSONRPCException as e: assert('No addresses' in e.error['message']) else: assert(False) - balance1 = self.nodes[1].getbalance("", 0, True) assert_equal(balance1, Decimal(0)) #Import with affiliated address with no rescan - self.nodes[1].importaddress(address2, "", False) - result2 = self.nodes[1].importprunedfunds(rawtxn2, proof2, "") - balance2 = Decimal(self.nodes[1].getbalance("", 0, True)) + self.nodes[1].importaddress(address2, "add2", False) + result2 = self.nodes[1].importprunedfunds(rawtxn2, proof2) + balance2 = self.nodes[1].getbalance("add2", 0, True) assert_equal(balance2, Decimal('0.05')) #Import with private key with no rescan - self.nodes[1].importprivkey(address3_privkey, "", False) - result3 = self.nodes[1].importprunedfunds(rawtxn3, proof3, "") - balance3 = Decimal(self.nodes[1].getbalance("", 0, False)) + self.nodes[1].importprivkey(address3_privkey, "add3", False) + result3 = self.nodes[1].importprunedfunds(rawtxn3, proof3) + balance3 = self.nodes[1].getbalance("add3", 0, False) assert_equal(balance3, Decimal('0.025')) - balance3 = Decimal(self.nodes[1].getbalance("", 0, True)) + balance3 = self.nodes[1].getbalance("*", 0, True) assert_equal(balance3, Decimal('0.075')) #Addresses Test - after import @@ -118,7 +112,6 @@ def run_test (self): assert_equal(address_info['ismine'], True) #Remove transactions - try: self.nodes[1].removeprunedfunds(txnid1) except JSONRPCException as e: @@ -126,18 +119,16 @@ def run_test (self): else: assert(False) - - balance1 = Decimal(self.nodes[1].getbalance("", 0, True)) + balance1 = self.nodes[1].getbalance("*", 0, True) assert_equal(balance1, Decimal('0.075')) - self.nodes[1].removeprunedfunds(txnid2) - balance2 = Decimal(self.nodes[1].getbalance("", 0, True)) + balance2 = self.nodes[1].getbalance("*", 0, True) assert_equal(balance2, Decimal('0.025')) self.nodes[1].removeprunedfunds(txnid3) - balance3 = Decimal(self.nodes[1].getbalance("", 0, True)) + balance3 = self.nodes[1].getbalance("*", 0, True) assert_equal(balance3, Decimal('0.0')) if __name__ == '__main__': - ImportPrunedFundsTest ().main () + ImportPrunedFundsTest().main() diff --git a/qa/rpc-tests/keypool.py b/qa/rpc-tests/keypool.py index c75303ecbfc..fa394765680 100755 --- a/qa/rpc-tests/keypool.py +++ b/qa/rpc-tests/keypool.py @@ -12,6 +12,11 @@ class KeyPoolTest(BitcoinTestFramework): def run_test(self): nodes = self.nodes + addr_before_encrypting = nodes[0].getnewaddress() + addr_before_encrypting_data = nodes[0].validateaddress(addr_before_encrypting) + wallet_info_old = nodes[0].getwalletinfo() + assert(addr_before_encrypting_data['hdmasterkeyid'] == wallet_info_old['hdmasterkeyid']) + # Encrypt wallet and wait to terminate nodes[0].encryptwallet('test') bitcoind_processes[0].wait() @@ -19,6 +24,11 @@ def run_test(self): nodes[0] = start_node(0, self.options.tmpdir) # Keep creating keys addr = nodes[0].getnewaddress() + addr_data = nodes[0].validateaddress(addr) + wallet_info = nodes[0].getwalletinfo() + assert(addr_before_encrypting_data['hdmasterkeyid'] != wallet_info['hdmasterkeyid']) + assert(addr_data['hdmasterkeyid'] == wallet_info['hdmasterkeyid']) + try: addr = nodes[0].getnewaddress() raise AssertionError('Keypool should be exhausted after one address') diff --git a/qa/rpc-tests/maxuploadtarget.py b/qa/rpc-tests/maxuploadtarget.py index 125d4eb2751..d0e9fe9a3f5 100755 --- a/qa/rpc-tests/maxuploadtarget.py +++ b/qa/rpc-tests/maxuploadtarget.py @@ -75,7 +75,7 @@ def sync_with_ping(self, timeout=30): def received_pong(): return (self.last_pong.nonce == self.ping_counter) self.connection.send_message(msg_ping(nonce=self.ping_counter)) - success = wait_until(received_pong, timeout) + success = wait_until(received_pong, timeout=timeout) self.ping_counter += 1 return success diff --git a/qa/rpc-tests/multi_rpc.py b/qa/rpc-tests/multi_rpc.py index 24373b257d7..cdeb94caa09 100755 --- a/qa/rpc-tests/multi_rpc.py +++ b/qa/rpc-tests/multi_rpc.py @@ -26,7 +26,7 @@ def setup_chain(self): #Append rpcauth to bitcoin.conf before initialization rpcauth = "rpcauth=rt:93648e835a54c573682c2eb19f882535$7681e9c5b74bdd85e78166031d2058e1069b3ed7ed967c93fc63abba06f31144" rpcauth2 = "rpcauth=rt2:f8607b1a88861fac29dfccf9b52ff9f$ff36a0c23c8c62b4846112e50fa888416e94c17bfd4c42f88fd8f55ec6a3137e" - with open(os.path.join(self.options.tmpdir+"/node0", "bitcoin.conf"), 'a') as f: + with open(os.path.join(self.options.tmpdir+"/node0", "bitcoin.conf"), 'a', encoding='utf8') as f: f.write(rpcauth+"\n") f.write(rpcauth2+"\n") diff --git a/qa/rpc-tests/nulldummy.py b/qa/rpc-tests/nulldummy.py new file mode 100755 index 00000000000..54b7eac3765 --- /dev/null +++ b/qa/rpc-tests/nulldummy.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +from test_framework.mininode import CTransaction, NetworkThread +from test_framework.blocktools import create_coinbase, create_block, add_witness_commitment +from test_framework.script import CScript +from io import BytesIO +import time + +NULLDUMMY_ERROR = "64: non-mandatory-script-verify-flag (Dummy CHECKMULTISIG argument must be zero)" + +def trueDummy(tx): + scriptSig = CScript(tx.vin[0].scriptSig) + newscript = [] + for i in scriptSig: + if (len(newscript) == 0): + assert(len(i) == 0) + newscript.append(b'\x51') + else: + newscript.append(i) + tx.vin[0].scriptSig = CScript(newscript) + tx.rehash() + +''' +This test is meant to exercise NULLDUMMY softfork. +Connect to a single node. +Generate 2 blocks (save the coinbases for later). +Generate 427 more blocks. +[Policy/Consensus] Check that NULLDUMMY compliant transactions are accepted in the 430th block. +[Policy] Check that non-NULLDUMMY transactions are rejected before activation. +[Consensus] Check that the new NULLDUMMY rules are not enforced on the 431st block. +[Policy/Consensus] Check that the new NULLDUMMY rules are enforced on the 432nd block. +''' + +class NULLDUMMYTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 1 + self.setup_clean_chain = True + + def setup_network(self): + # Must set the blockversion for this test + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, + extra_args=[['-debug', '-whitelist=127.0.0.1', '-walletprematurewitness']]) + + def run_test(self): + self.address = self.nodes[0].getnewaddress() + self.ms_address = self.nodes[0].addmultisigaddress(1,[self.address]) + self.wit_address = self.nodes[0].addwitnessaddress(self.address) + self.wit_ms_address = self.nodes[0].addwitnessaddress(self.ms_address) + + NetworkThread().start() # Start up network handling in another thread + self.coinbase_blocks = self.nodes[0].generate(2) # Block 2 + coinbase_txid = [] + for i in self.coinbase_blocks: + coinbase_txid.append(self.nodes[0].getblock(i)['tx'][0]) + self.nodes[0].generate(427) # Block 429 + self.lastblockhash = self.nodes[0].getbestblockhash() + self.tip = int("0x" + self.lastblockhash, 0) + self.lastblockheight = 429 + self.lastblocktime = int(time.time()) + 429 + + print ("Test 1: NULLDUMMY compliant base transactions should be accepted to mempool and mined before activation [430]") + test1txs = [self.create_transaction(self.nodes[0], coinbase_txid[0], self.ms_address, 49)] + txid1 = self.tx_submit(self.nodes[0], test1txs[0]) + test1txs.append(self.create_transaction(self.nodes[0], txid1, self.ms_address, 48)) + txid2 = self.tx_submit(self.nodes[0], test1txs[1]) + test1txs.append(self.create_transaction(self.nodes[0], coinbase_txid[1], self.wit_ms_address, 49)) + txid3 = self.tx_submit(self.nodes[0], test1txs[2]) + self.block_submit(self.nodes[0], test1txs, False, True) + + print ("Test 2: Non-NULLDUMMY base multisig transaction should not be accepted to mempool before activation") + test2tx = self.create_transaction(self.nodes[0], txid2, self.ms_address, 48) + trueDummy(test2tx) + txid4 = self.tx_submit(self.nodes[0], test2tx, NULLDUMMY_ERROR) + + print ("Test 3: Non-NULLDUMMY base transactions should be accepted in a block before activation [431]") + self.block_submit(self.nodes[0], [test2tx], False, True) + + print ("Test 4: Non-NULLDUMMY base multisig transaction is invalid after activation") + test4tx = self.create_transaction(self.nodes[0], txid4, self.address, 47) + test6txs=[CTransaction(test4tx)] + trueDummy(test4tx) + self.tx_submit(self.nodes[0], test4tx, NULLDUMMY_ERROR) + self.block_submit(self.nodes[0], [test4tx]) + + print ("Test 5: Non-NULLDUMMY P2WSH multisig transaction invalid after activation") + test5tx = self.create_transaction(self.nodes[0], txid3, self.wit_address, 48) + test6txs.append(CTransaction(test5tx)) + test5tx.wit.vtxinwit[0].scriptWitness.stack[0] = b'\x01' + self.tx_submit(self.nodes[0], test5tx, NULLDUMMY_ERROR) + self.block_submit(self.nodes[0], [test5tx], True) + + print ("Test 6: NULLDUMMY compliant base/witness transactions should be accepted to mempool and in block after activation [432]") + for i in test6txs: + self.tx_submit(self.nodes[0], i) + self.block_submit(self.nodes[0], test6txs, True, True) + + + def create_transaction(self, node, txid, to_address, amount): + inputs = [{ "txid" : txid, "vout" : 0}] + outputs = { to_address : amount } + rawtx = node.createrawtransaction(inputs, outputs) + signresult = node.signrawtransaction(rawtx) + tx = CTransaction() + f = BytesIO(hex_str_to_bytes(signresult['hex'])) + tx.deserialize(f) + return tx + + + def tx_submit(self, node, tx, msg = ""): + tx.rehash() + try: + node.sendrawtransaction(bytes_to_hex_str(tx.serialize_with_witness()), True) + except JSONRPCException as exp: + assert_equal(exp.error["message"], msg) + else: + assert_equal('', msg) + return tx.hash + + + def block_submit(self, node, txs, witness = False, accept = False): + block = create_block(self.tip, create_coinbase(self.lastblockheight + 1), self.lastblocktime + 1) + block.nVersion = 4 + for tx in txs: + tx.rehash() + block.vtx.append(tx) + block.hashMerkleRoot = block.calc_merkle_root() + witness and add_witness_commitment(block) + block.rehash() + block.solve() + node.submitblock(bytes_to_hex_str(block.serialize(True))) + if (accept): + assert_equal(node.getbestblockhash(), block.hash) + self.tip = block.sha256 + self.lastblockhash = block.hash + self.lastblocktime += 1 + self.lastblockheight += 1 + else: + assert_equal(node.getbestblockhash(), self.lastblockhash) + +if __name__ == '__main__': + NULLDUMMYTest().main() diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py new file mode 100755 index 00000000000..156a559b10a --- /dev/null +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -0,0 +1,952 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.mininode import * +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +from test_framework.blocktools import create_block, create_coinbase, add_witness_commitment +from test_framework.siphash import siphash256 +from test_framework.script import CScript, OP_TRUE + +''' +CompactBlocksTest -- test compact blocks (BIP 152) + +Version 1 compact blocks are pre-segwit (txids) +Version 2 compact blocks are post-segwit (wtxids) +''' + +# TestNode: A peer we use to send messages to bitcoind, and store responses. +class TestNode(SingleNodeConnCB): + def __init__(self): + SingleNodeConnCB.__init__(self) + self.last_sendcmpct = [] + self.last_headers = None + self.last_inv = None + self.last_cmpctblock = None + self.block_announced = False + self.last_getdata = None + self.last_getblocktxn = None + self.last_block = None + self.last_blocktxn = None + # Store the hashes of blocks we've seen announced. + # This is for synchronizing the p2p message traffic, + # so we can eg wait until a particular block is announced. + self.set_announced_blockhashes = set() + + def on_sendcmpct(self, conn, message): + self.last_sendcmpct.append(message) + + def on_block(self, conn, message): + self.last_block = message + + def on_cmpctblock(self, conn, message): + self.last_cmpctblock = message + self.block_announced = True + self.last_cmpctblock.header_and_shortids.header.calc_sha256() + self.set_announced_blockhashes.add(self.last_cmpctblock.header_and_shortids.header.sha256) + + def on_headers(self, conn, message): + self.last_headers = message + self.block_announced = True + for x in self.last_headers.headers: + x.calc_sha256() + self.set_announced_blockhashes.add(x.sha256) + + def on_inv(self, conn, message): + self.last_inv = message + for x in self.last_inv.inv: + if x.type == 2: + self.block_announced = True + self.set_announced_blockhashes.add(x.hash) + + def on_getdata(self, conn, message): + self.last_getdata = message + + def on_getblocktxn(self, conn, message): + self.last_getblocktxn = message + + def on_blocktxn(self, conn, message): + self.last_blocktxn = message + + # Requires caller to hold mininode_lock + def received_block_announcement(self): + return self.block_announced + + def clear_block_announcement(self): + with mininode_lock: + self.block_announced = False + self.last_inv = None + self.last_headers = None + self.last_cmpctblock = None + + def get_headers(self, locator, hashstop): + msg = msg_getheaders() + msg.locator.vHave = locator + msg.hashstop = hashstop + self.connection.send_message(msg) + + def send_header_for_blocks(self, new_blocks): + headers_message = msg_headers() + headers_message.headers = [CBlockHeader(b) for b in new_blocks] + self.send_message(headers_message) + + def request_headers_and_sync(self, locator, hashstop=0): + self.clear_block_announcement() + self.get_headers(locator, hashstop) + assert(wait_until(self.received_block_announcement, timeout=30)) + assert(self.received_block_announcement()) + self.clear_block_announcement() + + # Block until a block announcement for a particular block hash is + # received. + def wait_for_block_announcement(self, block_hash, timeout=30): + def received_hash(): + return (block_hash in self.set_announced_blockhashes) + return wait_until(received_hash, timeout=timeout) + +class CompactBlocksTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.setup_clean_chain = True + # Node0 = pre-segwit, node1 = segwit-aware + self.num_nodes = 2 + self.utxos = [] + + def setup_network(self): + self.nodes = [] + + # Start up node0 to be a version 1, pre-segwit node. + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, + [["-debug", "-logtimemicros=1", "-bip9params=segwit:0:0"], + ["-debug", "-logtimemicros", "-txindex"]]) + connect_nodes(self.nodes[0], 1) + + def build_block_on_tip(self, node, segwit=False): + height = node.getblockcount() + tip = node.getbestblockhash() + mtp = node.getblockheader(tip)['mediantime'] + block = create_block(int(tip, 16), create_coinbase(height + 1), mtp + 1) + block.nVersion = 4 + if segwit: + add_witness_commitment(block) + block.solve() + return block + + # Create 10 more anyone-can-spend utxo's for testing. + def make_utxos(self): + # Doesn't matter which node we use, just use node0. + block = self.build_block_on_tip(self.nodes[0]) + self.test_node.send_and_ping(msg_block(block)) + assert(int(self.nodes[0].getbestblockhash(), 16) == block.sha256) + self.nodes[0].generate(100) + + total_value = block.vtx[0].vout[0].nValue + out_value = total_value // 10 + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(block.vtx[0].sha256, 0), b'')) + for i in range(10): + tx.vout.append(CTxOut(out_value, CScript([OP_TRUE]))) + tx.rehash() + + block2 = self.build_block_on_tip(self.nodes[0]) + block2.vtx.append(tx) + block2.hashMerkleRoot = block2.calc_merkle_root() + block2.solve() + self.test_node.send_and_ping(msg_block(block2)) + assert_equal(int(self.nodes[0].getbestblockhash(), 16), block2.sha256) + self.utxos.extend([[tx.sha256, i, out_value] for i in range(10)]) + return + + # Test "sendcmpct" (between peers preferring the same version): + # - No compact block announcements unless sendcmpct is sent. + # - If sendcmpct is sent with version > preferred_version, the message is ignored. + # - If sendcmpct is sent with boolean 0, then block announcements are not + # made with compact blocks. + # - If sendcmpct is then sent with boolean 1, then new block announcements + # are made with compact blocks. + # If old_node is passed in, request compact blocks with version=preferred-1 + # and verify that it receives block announcements via compact block. + def test_sendcmpct(self, node, test_node, preferred_version, old_node=None): + # Make sure we get a SENDCMPCT message from our peer + def received_sendcmpct(): + return (len(test_node.last_sendcmpct) > 0) + got_message = wait_until(received_sendcmpct, timeout=30) + assert(received_sendcmpct()) + assert(got_message) + with mininode_lock: + # Check that the first version received is the preferred one + assert_equal(test_node.last_sendcmpct[0].version, preferred_version) + # And that we receive versions down to 1. + assert_equal(test_node.last_sendcmpct[-1].version, 1) + test_node.last_sendcmpct = [] + + tip = int(node.getbestblockhash(), 16) + + def check_announcement_of_new_block(node, peer, predicate): + peer.clear_block_announcement() + block_hash = int(node.generate(1)[0], 16) + peer.wait_for_block_announcement(block_hash, timeout=30) + assert(peer.block_announced) + assert(got_message) + + with mininode_lock: + assert predicate(peer), ( + "block_hash={!r}, cmpctblock={!r}, inv={!r}".format( + block_hash, peer.last_cmpctblock, peer.last_inv)) + + # We shouldn't get any block announcements via cmpctblock yet. + check_announcement_of_new_block(node, test_node, lambda p: p.last_cmpctblock is None) + + # Try one more time, this time after requesting headers. + test_node.request_headers_and_sync(locator=[tip]) + check_announcement_of_new_block(node, test_node, lambda p: p.last_cmpctblock is None and p.last_inv is not None) + + # Test a few ways of using sendcmpct that should NOT + # result in compact block announcements. + # Before each test, sync the headers chain. + test_node.request_headers_and_sync(locator=[tip]) + + # Now try a SENDCMPCT message with too-high version + sendcmpct = msg_sendcmpct() + sendcmpct.version = preferred_version+1 + sendcmpct.announce = True + test_node.send_and_ping(sendcmpct) + check_announcement_of_new_block(node, test_node, lambda p: p.last_cmpctblock is None) + + # Headers sync before next test. + test_node.request_headers_and_sync(locator=[tip]) + + # Now try a SENDCMPCT message with valid version, but announce=False + sendcmpct.version = preferred_version + sendcmpct.announce = False + test_node.send_and_ping(sendcmpct) + check_announcement_of_new_block(node, test_node, lambda p: p.last_cmpctblock is None) + + # Headers sync before next test. + test_node.request_headers_and_sync(locator=[tip]) + + # Finally, try a SENDCMPCT message with announce=True + sendcmpct.version = preferred_version + sendcmpct.announce = True + test_node.send_and_ping(sendcmpct) + check_announcement_of_new_block(node, test_node, lambda p: p.last_cmpctblock is not None) + + # Try one more time (no headers sync should be needed!) + check_announcement_of_new_block(node, test_node, lambda p: p.last_cmpctblock is not None) + + # Try one more time, after turning on sendheaders + test_node.send_and_ping(msg_sendheaders()) + check_announcement_of_new_block(node, test_node, lambda p: p.last_cmpctblock is not None) + + # Try one more time, after sending a version-1, announce=false message. + sendcmpct.version = preferred_version-1 + sendcmpct.announce = False + test_node.send_and_ping(sendcmpct) + check_announcement_of_new_block(node, test_node, lambda p: p.last_cmpctblock is not None) + + # Now turn off announcements + sendcmpct.version = preferred_version + sendcmpct.announce = False + test_node.send_and_ping(sendcmpct) + check_announcement_of_new_block(node, test_node, lambda p: p.last_cmpctblock is None and p.last_headers is not None) + + if old_node is not None: + # Verify that a peer using an older protocol version can receive + # announcements from this node. + sendcmpct.version = preferred_version-1 + sendcmpct.announce = True + old_node.send_and_ping(sendcmpct) + # Header sync + old_node.request_headers_and_sync(locator=[tip]) + check_announcement_of_new_block(node, old_node, lambda p: p.last_cmpctblock is not None) + + # This test actually causes bitcoind to (reasonably!) disconnect us, so do this last. + def test_invalid_cmpctblock_message(self): + self.nodes[0].generate(101) + block = self.build_block_on_tip(self.nodes[0]) + + cmpct_block = P2PHeaderAndShortIDs() + cmpct_block.header = CBlockHeader(block) + cmpct_block.prefilled_txn_length = 1 + # This index will be too high + prefilled_txn = PrefilledTransaction(1, block.vtx[0]) + cmpct_block.prefilled_txn = [prefilled_txn] + self.test_node.send_and_ping(msg_cmpctblock(cmpct_block)) + assert(int(self.nodes[0].getbestblockhash(), 16) == block.hashPrevBlock) + + # Compare the generated shortids to what we expect based on BIP 152, given + # bitcoind's choice of nonce. + def test_compactblock_construction(self, node, test_node, version, use_witness_address): + # Generate a bunch of transactions. + node.generate(101) + num_transactions = 25 + address = node.getnewaddress() + if use_witness_address: + # Want at least one segwit spend, so move all funds to + # a witness address. + address = node.addwitnessaddress(address) + value_to_send = node.getbalance() + node.sendtoaddress(address, satoshi_round(value_to_send-Decimal(0.1))) + node.generate(1) + + segwit_tx_generated = False + for i in range(num_transactions): + txid = node.sendtoaddress(address, 0.1) + hex_tx = node.gettransaction(txid)["hex"] + tx = FromHex(CTransaction(), hex_tx) + if not tx.wit.is_null(): + segwit_tx_generated = True + + if use_witness_address: + assert(segwit_tx_generated) # check that our test is not broken + + # Wait until we've seen the block announcement for the resulting tip + tip = int(node.getbestblockhash(), 16) + assert(test_node.wait_for_block_announcement(tip)) + + # Now mine a block, and look at the resulting compact block. + test_node.clear_block_announcement() + block_hash = int(node.generate(1)[0], 16) + + # Store the raw block in our internal format. + block = FromHex(CBlock(), node.getblock("%02x" % block_hash, False)) + [tx.calc_sha256() for tx in block.vtx] + block.rehash() + + # Don't care which type of announcement came back for this test; just + # request the compact block if we didn't get one yet. + wait_until(test_node.received_block_announcement, timeout=30) + assert(test_node.received_block_announcement()) + + with mininode_lock: + if test_node.last_cmpctblock is None: + test_node.clear_block_announcement() + inv = CInv(4, block_hash) # 4 == "CompactBlock" + test_node.send_message(msg_getdata([inv])) + + wait_until(test_node.received_block_announcement, timeout=30) + assert(test_node.received_block_announcement()) + + # Now we should have the compactblock + header_and_shortids = None + with mininode_lock: + assert(test_node.last_cmpctblock is not None) + # Convert the on-the-wire representation to absolute indexes + header_and_shortids = HeaderAndShortIDs(test_node.last_cmpctblock.header_and_shortids) + + # Check that we got the right block! + header_and_shortids.header.calc_sha256() + assert_equal(header_and_shortids.header.sha256, block_hash) + + # Make sure the prefilled_txn appears to have included the coinbase + assert(len(header_and_shortids.prefilled_txn) >= 1) + assert_equal(header_and_shortids.prefilled_txn[0].index, 0) + + # Check that all prefilled_txn entries match what's in the block. + for entry in header_and_shortids.prefilled_txn: + entry.tx.calc_sha256() + # This checks the non-witness parts of the tx agree + assert_equal(entry.tx.sha256, block.vtx[entry.index].sha256) + + # And this checks the witness + wtxid = entry.tx.calc_sha256(True) + if version == 2: + assert_equal(wtxid, block.vtx[entry.index].calc_sha256(True)) + else: + # Shouldn't have received a witness + assert(entry.tx.wit.is_null()) + + # Check that the cmpctblock message announced all the transactions. + assert_equal(len(header_and_shortids.prefilled_txn) + len(header_and_shortids.shortids), len(block.vtx)) + + # And now check that all the shortids are as expected as well. + # Determine the siphash keys to use. + [k0, k1] = header_and_shortids.get_siphash_keys() + + index = 0 + while index < len(block.vtx): + if (len(header_and_shortids.prefilled_txn) > 0 and + header_and_shortids.prefilled_txn[0].index == index): + # Already checked prefilled transactions above + header_and_shortids.prefilled_txn.pop(0) + else: + tx_hash = block.vtx[index].sha256 + if version == 2: + tx_hash = block.vtx[index].calc_sha256(True) + shortid = calculate_shortid(k0, k1, tx_hash) + assert_equal(shortid, header_and_shortids.shortids[0]) + header_and_shortids.shortids.pop(0) + index += 1 + + # Test that bitcoind requests compact blocks when we announce new blocks + # via header or inv, and that responding to getblocktxn causes the block + # to be successfully reconstructed. + # Post-segwit: upgraded nodes would only make this request of cb-version-2, + # NODE_WITNESS peers. Unupgraded nodes would still make this request of + # any cb-version-1-supporting peer. + def test_compactblock_requests(self, node, test_node, version, segwit): + # Try announcing a block with an inv or header, expect a compactblock + # request + for announce in ["inv", "header"]: + block = self.build_block_on_tip(node, segwit=segwit) + with mininode_lock: + test_node.last_getdata = None + + if announce == "inv": + test_node.send_message(msg_inv([CInv(2, block.sha256)])) + else: + test_node.send_header_for_blocks([block]) + success = wait_until(lambda: test_node.last_getdata is not None, timeout=30) + assert(success) + assert_equal(len(test_node.last_getdata.inv), 1) + assert_equal(test_node.last_getdata.inv[0].type, 4) + assert_equal(test_node.last_getdata.inv[0].hash, block.sha256) + + # Send back a compactblock message that omits the coinbase + comp_block = HeaderAndShortIDs() + comp_block.header = CBlockHeader(block) + comp_block.nonce = 0 + [k0, k1] = comp_block.get_siphash_keys() + coinbase_hash = block.vtx[0].sha256 + if version == 2: + coinbase_hash = block.vtx[0].calc_sha256(True) + comp_block.shortids = [ + calculate_shortid(k0, k1, coinbase_hash) ] + test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) + assert_equal(int(node.getbestblockhash(), 16), block.hashPrevBlock) + # Expect a getblocktxn message. + with mininode_lock: + assert(test_node.last_getblocktxn is not None) + absolute_indexes = test_node.last_getblocktxn.block_txn_request.to_absolute() + assert_equal(absolute_indexes, [0]) # should be a coinbase request + + # Send the coinbase, and verify that the tip advances. + if version == 2: + msg = msg_witness_blocktxn() + else: + msg = msg_blocktxn() + msg.block_transactions.blockhash = block.sha256 + msg.block_transactions.transactions = [block.vtx[0]] + test_node.send_and_ping(msg) + assert_equal(int(node.getbestblockhash(), 16), block.sha256) + + # Create a chain of transactions from given utxo, and add to a new block. + def build_block_with_transactions(self, node, utxo, num_transactions): + block = self.build_block_on_tip(node) + + for i in range(num_transactions): + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(utxo[0], utxo[1]), b'')) + tx.vout.append(CTxOut(utxo[2] - 1000, CScript([OP_TRUE]))) + tx.rehash() + utxo = [tx.sha256, 0, tx.vout[0].nValue] + block.vtx.append(tx) + + block.hashMerkleRoot = block.calc_merkle_root() + block.solve() + return block + + # Test that we only receive getblocktxn requests for transactions that the + # node needs, and that responding to them causes the block to be + # reconstructed. + def test_getblocktxn_requests(self, node, test_node, version): + with_witness = (version==2) + + def test_getblocktxn_response(compact_block, peer, expected_result): + msg = msg_cmpctblock(compact_block.to_p2p()) + peer.send_and_ping(msg) + with mininode_lock: + assert(peer.last_getblocktxn is not None) + absolute_indexes = peer.last_getblocktxn.block_txn_request.to_absolute() + assert_equal(absolute_indexes, expected_result) + + def test_tip_after_message(node, peer, msg, tip): + peer.send_and_ping(msg) + assert_equal(int(node.getbestblockhash(), 16), tip) + + # First try announcing compactblocks that won't reconstruct, and verify + # that we receive getblocktxn messages back. + utxo = self.utxos.pop(0) + + block = self.build_block_with_transactions(node, utxo, 5) + self.utxos.append([block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue]) + comp_block = HeaderAndShortIDs() + comp_block.initialize_from_block(block, use_witness=with_witness) + + test_getblocktxn_response(comp_block, test_node, [1, 2, 3, 4, 5]) + + msg_bt = msg_blocktxn() + if with_witness: + msg_bt = msg_witness_blocktxn() # serialize with witnesses + msg_bt.block_transactions = BlockTransactions(block.sha256, block.vtx[1:]) + test_tip_after_message(node, test_node, msg_bt, block.sha256) + + utxo = self.utxos.pop(0) + block = self.build_block_with_transactions(node, utxo, 5) + self.utxos.append([block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue]) + + # Now try interspersing the prefilled transactions + comp_block.initialize_from_block(block, prefill_list=[0, 1, 5], use_witness=with_witness) + test_getblocktxn_response(comp_block, test_node, [2, 3, 4]) + msg_bt.block_transactions = BlockTransactions(block.sha256, block.vtx[2:5]) + test_tip_after_message(node, test_node, msg_bt, block.sha256) + + # Now try giving one transaction ahead of time. + utxo = self.utxos.pop(0) + block = self.build_block_with_transactions(node, utxo, 5) + self.utxos.append([block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue]) + test_node.send_and_ping(msg_tx(block.vtx[1])) + assert(block.vtx[1].hash in node.getrawmempool()) + + # Prefill 4 out of the 6 transactions, and verify that only the one + # that was not in the mempool is requested. + comp_block.initialize_from_block(block, prefill_list=[0, 2, 3, 4], use_witness=with_witness) + test_getblocktxn_response(comp_block, test_node, [5]) + + msg_bt.block_transactions = BlockTransactions(block.sha256, [block.vtx[5]]) + test_tip_after_message(node, test_node, msg_bt, block.sha256) + + # Now provide all transactions to the node before the block is + # announced and verify reconstruction happens immediately. + utxo = self.utxos.pop(0) + block = self.build_block_with_transactions(node, utxo, 10) + self.utxos.append([block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue]) + for tx in block.vtx[1:]: + test_node.send_message(msg_tx(tx)) + test_node.sync_with_ping() + # Make sure all transactions were accepted. + mempool = node.getrawmempool() + for tx in block.vtx[1:]: + assert(tx.hash in mempool) + + # Clear out last request. + with mininode_lock: + test_node.last_getblocktxn = None + + # Send compact block + comp_block.initialize_from_block(block, prefill_list=[0], use_witness=with_witness) + test_tip_after_message(node, test_node, msg_cmpctblock(comp_block.to_p2p()), block.sha256) + with mininode_lock: + # Shouldn't have gotten a request for any transaction + assert(test_node.last_getblocktxn is None) + + # Incorrectly responding to a getblocktxn shouldn't cause the block to be + # permanently failed. + def test_incorrect_blocktxn_response(self, node, test_node, version): + if (len(self.utxos) == 0): + self.make_utxos() + utxo = self.utxos.pop(0) + + block = self.build_block_with_transactions(node, utxo, 10) + self.utxos.append([block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue]) + # Relay the first 5 transactions from the block in advance + for tx in block.vtx[1:6]: + test_node.send_message(msg_tx(tx)) + test_node.sync_with_ping() + # Make sure all transactions were accepted. + mempool = node.getrawmempool() + for tx in block.vtx[1:6]: + assert(tx.hash in mempool) + + # Send compact block + comp_block = HeaderAndShortIDs() + comp_block.initialize_from_block(block, prefill_list=[0], use_witness=(version == 2)) + test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) + absolute_indexes = [] + with mininode_lock: + assert(test_node.last_getblocktxn is not None) + absolute_indexes = test_node.last_getblocktxn.block_txn_request.to_absolute() + assert_equal(absolute_indexes, [6, 7, 8, 9, 10]) + + # Now give an incorrect response. + # Note that it's possible for bitcoind to be smart enough to know we're + # lying, since it could check to see if the shortid matches what we're + # sending, and eg disconnect us for misbehavior. If that behavior + # change were made, we could just modify this test by having a + # different peer provide the block further down, so that we're still + # verifying that the block isn't marked bad permanently. This is good + # enough for now. + msg = msg_blocktxn() + if version==2: + msg = msg_witness_blocktxn() + msg.block_transactions = BlockTransactions(block.sha256, [block.vtx[5]] + block.vtx[7:]) + test_node.send_and_ping(msg) + + # Tip should not have updated + assert_equal(int(node.getbestblockhash(), 16), block.hashPrevBlock) + + # We should receive a getdata request + success = wait_until(lambda: test_node.last_getdata is not None, timeout=10) + assert(success) + assert_equal(len(test_node.last_getdata.inv), 1) + assert(test_node.last_getdata.inv[0].type == 2 or test_node.last_getdata.inv[0].type == 2|MSG_WITNESS_FLAG) + assert_equal(test_node.last_getdata.inv[0].hash, block.sha256) + + # Deliver the block + if version==2: + test_node.send_and_ping(msg_witness_block(block)) + else: + test_node.send_and_ping(msg_block(block)) + assert_equal(int(node.getbestblockhash(), 16), block.sha256) + + def test_getblocktxn_handler(self, node, test_node, version): + # bitcoind will not send blocktxn responses for blocks whose height is + # more than 10 blocks deep. + MAX_GETBLOCKTXN_DEPTH = 10 + chain_height = node.getblockcount() + current_height = chain_height + while (current_height >= chain_height - MAX_GETBLOCKTXN_DEPTH): + block_hash = node.getblockhash(current_height) + block = FromHex(CBlock(), node.getblock(block_hash, False)) + + msg = msg_getblocktxn() + msg.block_txn_request = BlockTransactionsRequest(int(block_hash, 16), []) + num_to_request = random.randint(1, len(block.vtx)) + msg.block_txn_request.from_absolute(sorted(random.sample(range(len(block.vtx)), num_to_request))) + test_node.send_message(msg) + success = wait_until(lambda: test_node.last_blocktxn is not None, timeout=10) + assert(success) + + [tx.calc_sha256() for tx in block.vtx] + with mininode_lock: + assert_equal(test_node.last_blocktxn.block_transactions.blockhash, int(block_hash, 16)) + all_indices = msg.block_txn_request.to_absolute() + for index in all_indices: + tx = test_node.last_blocktxn.block_transactions.transactions.pop(0) + tx.calc_sha256() + assert_equal(tx.sha256, block.vtx[index].sha256) + if version == 1: + # Witnesses should have been stripped + assert(tx.wit.is_null()) + else: + # Check that the witness matches + assert_equal(tx.calc_sha256(True), block.vtx[index].calc_sha256(True)) + test_node.last_blocktxn = None + current_height -= 1 + + # Next request should send a full block response, as we're past the + # allowed depth for a blocktxn response. + block_hash = node.getblockhash(current_height) + msg.block_txn_request = BlockTransactionsRequest(int(block_hash, 16), [0]) + with mininode_lock: + test_node.last_block = None + test_node.last_blocktxn = None + test_node.send_and_ping(msg) + with mininode_lock: + test_node.last_block.block.calc_sha256() + assert_equal(test_node.last_block.block.sha256, int(block_hash, 16)) + assert_equal(test_node.last_blocktxn, None) + + def test_compactblocks_not_at_tip(self, node, test_node): + # Test that requesting old compactblocks doesn't work. + MAX_CMPCTBLOCK_DEPTH = 5 + new_blocks = [] + for i in range(MAX_CMPCTBLOCK_DEPTH + 1): + test_node.clear_block_announcement() + new_blocks.append(node.generate(1)[0]) + wait_until(test_node.received_block_announcement, timeout=30) + + test_node.clear_block_announcement() + test_node.send_message(msg_getdata([CInv(4, int(new_blocks[0], 16))])) + success = wait_until(lambda: test_node.last_cmpctblock is not None, timeout=30) + assert(success) + + test_node.clear_block_announcement() + node.generate(1) + wait_until(test_node.received_block_announcement, timeout=30) + test_node.clear_block_announcement() + with mininode_lock: + test_node.last_block = None + test_node.send_message(msg_getdata([CInv(4, int(new_blocks[0], 16))])) + success = wait_until(lambda: test_node.last_block is not None, timeout=30) + assert(success) + with mininode_lock: + test_node.last_block.block.calc_sha256() + assert_equal(test_node.last_block.block.sha256, int(new_blocks[0], 16)) + + # Generate an old compactblock, and verify that it's not accepted. + cur_height = node.getblockcount() + hashPrevBlock = int(node.getblockhash(cur_height-5), 16) + block = self.build_block_on_tip(node) + block.hashPrevBlock = hashPrevBlock + block.solve() + + comp_block = HeaderAndShortIDs() + comp_block.initialize_from_block(block) + test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) + + tips = node.getchaintips() + found = False + for x in tips: + if x["hash"] == block.hash: + assert_equal(x["status"], "headers-only") + found = True + break + assert(found) + + # Requesting this block via getblocktxn should silently fail + # (to avoid fingerprinting attacks). + msg = msg_getblocktxn() + msg.block_txn_request = BlockTransactionsRequest(block.sha256, [0]) + with mininode_lock: + test_node.last_blocktxn = None + test_node.send_and_ping(msg) + with mininode_lock: + assert(test_node.last_blocktxn is None) + + def activate_segwit(self, node): + node.generate(144*3) + assert_equal(get_bip9_status(node, "segwit")["status"], 'active') + + def test_end_to_end_block_relay(self, node, listeners): + utxo = self.utxos.pop(0) + + block = self.build_block_with_transactions(node, utxo, 10) + + [l.clear_block_announcement() for l in listeners] + + # ToHex() won't serialize with witness, but this block has no witnesses + # anyway. TODO: repeat this test with witness tx's to a segwit node. + node.submitblock(ToHex(block)) + + for l in listeners: + wait_until(lambda: l.received_block_announcement(), timeout=30) + with mininode_lock: + for l in listeners: + assert(l.last_cmpctblock is not None) + l.last_cmpctblock.header_and_shortids.header.calc_sha256() + assert_equal(l.last_cmpctblock.header_and_shortids.header.sha256, block.sha256) + + # Test that we don't get disconnected if we relay a compact block with valid header, + # but invalid transactions. + def test_invalid_tx_in_compactblock(self, node, test_node, use_segwit): + assert(len(self.utxos)) + utxo = self.utxos[0] + + block = self.build_block_with_transactions(node, utxo, 5) + del block.vtx[3] + block.hashMerkleRoot = block.calc_merkle_root() + if use_segwit: + # If we're testing with segwit, also drop the coinbase witness, + # but include the witness commitment. + add_witness_commitment(block) + block.vtx[0].wit.vtxinwit = [] + block.solve() + + # Now send the compact block with all transactions prefilled, and + # verify that we don't get disconnected. + comp_block = HeaderAndShortIDs() + comp_block.initialize_from_block(block, prefill_list=[0, 1, 2, 3, 4], use_witness=use_segwit) + msg = msg_cmpctblock(comp_block.to_p2p()) + test_node.send_and_ping(msg) + + # Check that the tip didn't advance + assert(int(node.getbestblockhash(), 16) is not block.sha256) + test_node.sync_with_ping() + + # Helper for enabling cb announcements + # Send the sendcmpct request and sync headers + def request_cb_announcements(self, peer, node, version): + tip = node.getbestblockhash() + peer.get_headers(locator=[int(tip, 16)], hashstop=0) + + msg = msg_sendcmpct() + msg.version = version + msg.announce = True + peer.send_and_ping(msg) + + def test_compactblock_reconstruction_multiple_peers(self, node, stalling_peer, delivery_peer): + assert(len(self.utxos)) + + def announce_cmpct_block(node, peer): + utxo = self.utxos.pop(0) + block = self.build_block_with_transactions(node, utxo, 5) + + cmpct_block = HeaderAndShortIDs() + cmpct_block.initialize_from_block(block) + msg = msg_cmpctblock(cmpct_block.to_p2p()) + peer.send_and_ping(msg) + with mininode_lock: + assert(peer.last_getblocktxn is not None) + return block, cmpct_block + + block, cmpct_block = announce_cmpct_block(node, stalling_peer) + + for tx in block.vtx[1:]: + delivery_peer.send_message(msg_tx(tx)) + delivery_peer.sync_with_ping() + mempool = node.getrawmempool() + for tx in block.vtx[1:]: + assert(tx.hash in mempool) + + delivery_peer.send_and_ping(msg_cmpctblock(cmpct_block.to_p2p())) + assert_equal(int(node.getbestblockhash(), 16), block.sha256) + + self.utxos.append([block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue]) + + # Now test that delivering an invalid compact block won't break relay + + block, cmpct_block = announce_cmpct_block(node, stalling_peer) + for tx in block.vtx[1:]: + delivery_peer.send_message(msg_tx(tx)) + delivery_peer.sync_with_ping() + + cmpct_block.prefilled_txn[0].tx.wit.vtxinwit = [ CTxInWitness() ] + cmpct_block.prefilled_txn[0].tx.wit.vtxinwit[0].scriptWitness.stack = [ser_uint256(0)] + + cmpct_block.use_witness = True + delivery_peer.send_and_ping(msg_cmpctblock(cmpct_block.to_p2p())) + assert(int(node.getbestblockhash(), 16) != block.sha256) + + msg = msg_blocktxn() + msg.block_transactions.blockhash = block.sha256 + msg.block_transactions.transactions = block.vtx[1:] + stalling_peer.send_and_ping(msg) + assert_equal(int(node.getbestblockhash(), 16), block.sha256) + + def run_test(self): + # Setup the p2p connections and start up the network thread. + self.test_node = TestNode() + self.segwit_node = TestNode() + self.old_node = TestNode() # version 1 peer <--> segwit node + + connections = [] + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], self.test_node)) + connections.append(NodeConn('127.0.0.1', p2p_port(1), self.nodes[1], + self.segwit_node, services=NODE_NETWORK|NODE_WITNESS)) + connections.append(NodeConn('127.0.0.1', p2p_port(1), self.nodes[1], + self.old_node, services=NODE_NETWORK)) + self.test_node.add_connection(connections[0]) + self.segwit_node.add_connection(connections[1]) + self.old_node.add_connection(connections[2]) + + NetworkThread().start() # Start up network handling in another thread + + # Test logic begins here + self.test_node.wait_for_verack() + + # We will need UTXOs to construct transactions in later tests. + self.make_utxos() + + print("Running tests, pre-segwit activation:") + + print("\tTesting SENDCMPCT p2p message... ") + self.test_sendcmpct(self.nodes[0], self.test_node, 1) + sync_blocks(self.nodes) + self.test_sendcmpct(self.nodes[1], self.segwit_node, 2, old_node=self.old_node) + sync_blocks(self.nodes) + + print("\tTesting compactblock construction...") + self.test_compactblock_construction(self.nodes[0], self.test_node, 1, False) + sync_blocks(self.nodes) + self.test_compactblock_construction(self.nodes[1], self.segwit_node, 2, False) + sync_blocks(self.nodes) + + print("\tTesting compactblock requests... ") + self.test_compactblock_requests(self.nodes[0], self.test_node, 1, False) + sync_blocks(self.nodes) + self.test_compactblock_requests(self.nodes[1], self.segwit_node, 2, False) + sync_blocks(self.nodes) + + print("\tTesting getblocktxn requests...") + self.test_getblocktxn_requests(self.nodes[0], self.test_node, 1) + sync_blocks(self.nodes) + self.test_getblocktxn_requests(self.nodes[1], self.segwit_node, 2) + sync_blocks(self.nodes) + + print("\tTesting getblocktxn handler...") + self.test_getblocktxn_handler(self.nodes[0], self.test_node, 1) + sync_blocks(self.nodes) + self.test_getblocktxn_handler(self.nodes[1], self.segwit_node, 2) + self.test_getblocktxn_handler(self.nodes[1], self.old_node, 1) + sync_blocks(self.nodes) + + print("\tTesting compactblock requests/announcements not at chain tip...") + self.test_compactblocks_not_at_tip(self.nodes[0], self.test_node) + sync_blocks(self.nodes) + self.test_compactblocks_not_at_tip(self.nodes[1], self.segwit_node) + self.test_compactblocks_not_at_tip(self.nodes[1], self.old_node) + sync_blocks(self.nodes) + + print("\tTesting handling of incorrect blocktxn responses...") + self.test_incorrect_blocktxn_response(self.nodes[0], self.test_node, 1) + sync_blocks(self.nodes) + self.test_incorrect_blocktxn_response(self.nodes[1], self.segwit_node, 2) + sync_blocks(self.nodes) + + # End-to-end block relay tests + print("\tTesting end-to-end block relay...") + self.request_cb_announcements(self.test_node, self.nodes[0], 1) + self.request_cb_announcements(self.old_node, self.nodes[1], 1) + self.request_cb_announcements(self.segwit_node, self.nodes[1], 2) + self.test_end_to_end_block_relay(self.nodes[0], [self.segwit_node, self.test_node, self.old_node]) + self.test_end_to_end_block_relay(self.nodes[1], [self.segwit_node, self.test_node, self.old_node]) + + print("\tTesting handling of invalid compact blocks...") + self.test_invalid_tx_in_compactblock(self.nodes[0], self.test_node, False) + self.test_invalid_tx_in_compactblock(self.nodes[1], self.segwit_node, False) + self.test_invalid_tx_in_compactblock(self.nodes[1], self.old_node, False) + + print("\tTesting reconstructing compact blocks from all peers...") + self.test_compactblock_reconstruction_multiple_peers(self.nodes[1], self.segwit_node, self.old_node) + sync_blocks(self.nodes) + + # Advance to segwit activation + print ("\nAdvancing to segwit activation\n") + self.activate_segwit(self.nodes[1]) + print ("Running tests, post-segwit activation...") + + print("\tTesting compactblock construction...") + self.test_compactblock_construction(self.nodes[1], self.old_node, 1, True) + self.test_compactblock_construction(self.nodes[1], self.segwit_node, 2, True) + sync_blocks(self.nodes) + + print("\tTesting compactblock requests (unupgraded node)... ") + self.test_compactblock_requests(self.nodes[0], self.test_node, 1, True) + + print("\tTesting getblocktxn requests (unupgraded node)...") + self.test_getblocktxn_requests(self.nodes[0], self.test_node, 1) + + # Need to manually sync node0 and node1, because post-segwit activation, + # node1 will not download blocks from node0. + print("\tSyncing nodes...") + assert(self.nodes[0].getbestblockhash() != self.nodes[1].getbestblockhash()) + while (self.nodes[0].getblockcount() > self.nodes[1].getblockcount()): + block_hash = self.nodes[0].getblockhash(self.nodes[1].getblockcount()+1) + self.nodes[1].submitblock(self.nodes[0].getblock(block_hash, False)) + assert_equal(self.nodes[0].getbestblockhash(), self.nodes[1].getbestblockhash()) + + print("\tTesting compactblock requests (segwit node)... ") + self.test_compactblock_requests(self.nodes[1], self.segwit_node, 2, True) + + print("\tTesting getblocktxn requests (segwit node)...") + self.test_getblocktxn_requests(self.nodes[1], self.segwit_node, 2) + sync_blocks(self.nodes) + + print("\tTesting getblocktxn handler (segwit node should return witnesses)...") + self.test_getblocktxn_handler(self.nodes[1], self.segwit_node, 2) + self.test_getblocktxn_handler(self.nodes[1], self.old_node, 1) + + # Test that if we submitblock to node1, we'll get a compact block + # announcement to all peers. + # (Post-segwit activation, blocks won't propagate from node0 to node1 + # automatically, so don't bother testing a block announced to node0.) + print("\tTesting end-to-end block relay...") + self.request_cb_announcements(self.test_node, self.nodes[0], 1) + self.request_cb_announcements(self.old_node, self.nodes[1], 1) + self.request_cb_announcements(self.segwit_node, self.nodes[1], 2) + self.test_end_to_end_block_relay(self.nodes[1], [self.segwit_node, self.test_node, self.old_node]) + + print("\tTesting handling of invalid compact blocks...") + self.test_invalid_tx_in_compactblock(self.nodes[0], self.test_node, False) + self.test_invalid_tx_in_compactblock(self.nodes[1], self.segwit_node, True) + self.test_invalid_tx_in_compactblock(self.nodes[1], self.old_node, True) + + print("\tTesting invalid index in cmpctblock message...") + self.test_invalid_cmpctblock_message() + + +if __name__ == '__main__': + CompactBlocksTest().main() diff --git a/qa/rpc-tests/p2p-feefilter.py b/qa/rpc-tests/p2p-feefilter.py index cd0501a3140..96d99d38a73 100755 --- a/qa/rpc-tests/p2p-feefilter.py +++ b/qa/rpc-tests/p2p-feefilter.py @@ -62,6 +62,7 @@ def setup_network(self): def run_test(self): node1 = self.nodes[1] + node0 = self.nodes[0] # Get out of IBD node1.generate(1) sync_blocks(self.nodes) @@ -91,8 +92,17 @@ def run_test(self): node1.settxfee(Decimal("0.00010000")) [node1.sendtoaddress(node1.getnewaddress(), 1) for x in range(3)] sync_mempools(self.nodes) # must be sure node 0 has received all txs - time.sleep(10) # wait 10 secs to be sure its doesn't relay any - assert(allInvsMatch([], test_node)) + + # Send one transaction from node0 that should be received, so that we + # we can sync the test on receipt (if node1's txs were relayed, they'd + # be received by the time this node0 tx is received). This is + # unfortunately reliant on the current relay behavior where we batch up + # to 35 entries in an inv, which means that when this next transaction + # is eligible for relay, the prior transactions from node1 are eligible + # as well. + node0.settxfee(Decimal("0.00020000")) + txids = [node0.sendtoaddress(node0.getnewaddress(), 1)] + assert(allInvsMatch(txids, test_node)) test_node.clear_invs() # Remove fee filter and check that txs are received again diff --git a/qa/rpc-tests/p2p-mempool.py b/qa/rpc-tests/p2p-mempool.py index 5d2daf39f82..80948426d9e 100755 --- a/qa/rpc-tests/p2p-mempool.py +++ b/qa/rpc-tests/p2p-mempool.py @@ -63,7 +63,7 @@ def sync_with_ping(self, timeout=30): def received_pong(): return (self.last_pong.nonce == self.ping_counter) self.connection.send_message(msg_ping(nonce=self.ping_counter)) - success = wait_until(received_pong, timeout) + success = wait_until(received_pong, timeout=timeout) self.ping_counter += 1 return success diff --git a/qa/rpc-tests/p2p-segwit.py b/qa/rpc-tests/p2p-segwit.py index b30d41af929..fddd2627be3 100755 --- a/qa/rpc-tests/p2p-segwit.py +++ b/qa/rpc-tests/p2p-segwit.py @@ -166,16 +166,22 @@ def __init__(self, sha256, n, nValue): self.n = n self.nValue = nValue +# Helper for getting the script associated with a P2PKH +def GetP2PKHScript(pubkeyhash): + return CScript([CScriptOp(OP_DUP), CScriptOp(OP_HASH160), pubkeyhash, CScriptOp(OP_EQUALVERIFY), CScriptOp(OP_CHECKSIG)]) + +# Add signature for a P2PK witness program. +def sign_P2PK_witness_input(script, txTo, inIdx, hashtype, value, key): + tx_hash = SegwitVersion1SignatureHash(script, txTo, inIdx, hashtype, value) + signature = key.sign(tx_hash) + chr(hashtype).encode('latin-1') + txTo.wit.vtxinwit[inIdx].scriptWitness.stack = [signature, script] + txTo.rehash() + class SegWitTest(BitcoinTestFramework): def setup_chain(self): initialize_chain_clean(self.options.tmpdir, 3) - def add_options(self, parser): - parser.add_option("--oldbinary", dest="oldbinary", - default=None, - help="pre-segwit bitcoind binary for upgrade testing") - def setup_network(self): self.nodes = [] self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-logtimemicros=1", "-whitelist=127.0.0.1"])) @@ -183,12 +189,9 @@ def setup_network(self): self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-logtimemicros=1", "-whitelist=127.0.0.1", "-acceptnonstdtxn=0"])) connect_nodes(self.nodes[0], 1) - # If an old bitcoind is given, do the upgrade-after-activation test. - self.test_upgrade = False - if (self.options.oldbinary != None): - self.nodes.append(start_node(2, self.options.tmpdir, ["-debug", "-whitelist=127.0.0.1"], binary=self.options.oldbinary)) - connect_nodes(self.nodes[0], 2) - self.test_upgrade = True + # Disable segwit's bip9 parameter to simulate upgrading after activation. + self.nodes.append(start_node(2, self.options.tmpdir, ["-debug", "-whitelist=127.0.0.1", "-bip9params=segwit:0:0"])) + connect_nodes(self.nodes[0], 2) ''' Helpers ''' # Build a block on top of node0's tip. @@ -302,13 +305,18 @@ def test_unnecessary_witness_before_segwit_activation(self): sync_blocks(self.nodes) # We'll add an unnecessary witness to this transaction that would cause - # it to be too large according to IsStandard. + # it to be non-standard, to test that violating policy with a witness before + # segwit activation doesn't blind a node to a transaction. Transactions + # rejected for having a witness before segwit activation shouldn't be added + # to the rejection cache. tx3 = CTransaction() tx3.vin.append(CTxIn(COutPoint(tx2.sha256, 0), CScript([p2sh_program]))) tx3.vout.append(CTxOut(tx2.vout[0].nValue-1000, scriptPubKey)) tx3.wit.vtxinwit.append(CTxInWitness()) tx3.wit.vtxinwit[0].scriptWitness.stack = [b'a'*400000] tx3.rehash() + # Note that this should be rejected for the premature witness reason, + # rather than a policy check, since segwit hasn't activated yet. self.std_node.test_transaction_acceptance(tx3, True, False, b'no-witness-yet') # If we send without witness, it should be accepted. @@ -904,14 +912,6 @@ def test_witness_tx_relay_before_segwit_activation(self): # But eliminating the witness should fix it self.test_node.test_transaction_acceptance(tx, with_witness=False, accepted=True) - # Verify that inv's to test_node come with getdata's for non-witness tx's - # Just tweak the transaction, announce it, and verify we get a getdata - # for a normal tx - tx.vout[0].scriptPubKey = CScript([OP_TRUE, OP_TRUE]) - tx.rehash() - self.test_node.announce_tx_and_wait_for_getdata(tx) - assert(self.test_node.last_getdata.inv[0].type == 1) - # Cleanup: mine the first transaction and update utxo self.nodes[0].generate(1) assert_equal(len(self.nodes[0].getrawmempool()), 0) @@ -946,8 +946,7 @@ def test_tx_relay_after_segwit_activation(self): self.test_node.test_transaction_acceptance(tx, with_witness=True, accepted=False) # Verify that removing the witness succeeds. - # Re-announcing won't result in a getdata for ~2.5 minutes, so just - # deliver the modified transaction. + self.test_node.announce_tx_and_wait_for_getdata(tx) self.test_node.test_transaction_acceptance(tx, with_witness=False, accepted=True) # Now try to add extra witness data to a valid witness tx. @@ -961,8 +960,24 @@ def test_tx_relay_after_segwit_activation(self): tx3 = CTransaction() tx3.vin.append(CTxIn(COutPoint(tx2.sha256, 0), b"")) - tx3.vout.append(CTxOut(tx2.vout[0].nValue-1000, CScript([OP_TRUE]))) tx3.wit.vtxinwit.append(CTxInWitness()) + + # Add too-large for IsStandard witness and check that it does not enter reject filter + p2sh_program = CScript([OP_TRUE]) + p2sh_pubkey = hash160(p2sh_program) + witness_program2 = CScript([b'a'*400000]) + tx3.vout.append(CTxOut(tx2.vout[0].nValue-1000, CScript([OP_HASH160, p2sh_pubkey, OP_EQUAL]))) + tx3.wit.vtxinwit[0].scriptWitness.stack = [witness_program2] + tx3.rehash() + + # Node will not be blinded to the transaction + self.std_node.announce_tx_and_wait_for_getdata(tx3) + self.std_node.test_transaction_acceptance(tx3, True, False, b'tx-size') + self.std_node.announce_tx_and_wait_for_getdata(tx3) + self.std_node.test_transaction_acceptance(tx3, True, False, b'tx-size') + + # Remove witness stuffing, instead add extra witness push on stack + tx3.vout[0] = CTxOut(tx2.vout[0].nValue-1000, CScript([OP_TRUE])) tx3.wit.vtxinwit[0].scriptWitness.stack = [CScript([CScriptNum(1)]), witness_program ] tx3.rehash() @@ -1002,7 +1017,7 @@ def test_tx_relay_after_segwit_activation(self): def test_block_relay(self, segwit_activated): print("\tTesting block relay") - blocktype = 2|MSG_WITNESS_FLAG if segwit_activated else 2 + blocktype = 2|MSG_WITNESS_FLAG # test_node has set NODE_WITNESS, so all getdata requests should be for # witness blocks. @@ -1065,12 +1080,12 @@ def test_block_relay(self, segwit_activated): assert_equal(wit_block.serialize(False), non_wit_block.serialize()) assert_equal(wit_block.serialize(True), block.serialize(True)) - # Test size, vsize, cost + # Test size, vsize, weight rpc_details = self.nodes[0].getblock(block.hash, True) assert_equal(rpc_details["size"], len(block.serialize(True))) assert_equal(rpc_details["strippedsize"], len(block.serialize(False))) - cost = 3*len(block.serialize(False)) + len(block.serialize(True)) - assert_equal(rpc_details["cost"], cost) + weight = 3*len(block.serialize(False)) + len(block.serialize(True)) + assert_equal(rpc_details["weight"], weight) # Upgraded node should not ask for blocks from unupgraded block4 = self.build_next_block(nVersion=4) @@ -1086,6 +1101,82 @@ def test_block_relay(self, segwit_activated): self.old_node.announce_tx_and_wait_for_getdata(block4.vtx[0]) assert(block4.sha256 not in self.old_node.getdataset) + # V0 segwit outputs should be standard after activation, but not before. + def test_standardness_v0(self, segwit_activated): + print("\tTesting standardness of v0 outputs (%s activation)" % ("after" if segwit_activated else "before")) + assert(len(self.utxo)) + + witness_program = CScript([OP_TRUE]) + witness_hash = sha256(witness_program) + scriptPubKey = CScript([OP_0, witness_hash]) + + p2sh_pubkey = hash160(witness_program) + p2sh_scriptPubKey = CScript([OP_HASH160, p2sh_pubkey, OP_EQUAL]) + + # First prepare a p2sh output (so that spending it will pass standardness) + p2sh_tx = CTransaction() + p2sh_tx.vin = [CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")] + p2sh_tx.vout = [CTxOut(self.utxo[0].nValue-1000, p2sh_scriptPubKey)] + p2sh_tx.rehash() + + # Mine it on test_node to create the confirmed output. + self.test_node.test_transaction_acceptance(p2sh_tx, with_witness=True, accepted=True) + self.nodes[0].generate(1) + sync_blocks(self.nodes) + + # Now test standardness of v0 P2WSH outputs. + # Start by creating a transaction with two outputs. + tx = CTransaction() + tx.vin = [CTxIn(COutPoint(p2sh_tx.sha256, 0), CScript([witness_program]))] + tx.vout = [CTxOut(p2sh_tx.vout[0].nValue-10000, scriptPubKey)] + tx.vout.append(CTxOut(8000, scriptPubKey)) # Might burn this later + tx.rehash() + + self.std_node.test_transaction_acceptance(tx, with_witness=True, accepted=segwit_activated) + + # Now create something that looks like a P2PKH output. This won't be spendable. + scriptPubKey = CScript([OP_0, hash160(witness_hash)]) + tx2 = CTransaction() + if segwit_activated: + # if tx was accepted, then we spend the second output. + tx2.vin = [CTxIn(COutPoint(tx.sha256, 1), b"")] + tx2.vout = [CTxOut(7000, scriptPubKey)] + tx2.wit.vtxinwit.append(CTxInWitness()) + tx2.wit.vtxinwit[0].scriptWitness.stack = [witness_program] + else: + # if tx wasn't accepted, we just re-spend the p2sh output we started with. + tx2.vin = [CTxIn(COutPoint(p2sh_tx.sha256, 0), CScript([witness_program]))] + tx2.vout = [CTxOut(p2sh_tx.vout[0].nValue-1000, scriptPubKey)] + tx2.rehash() + + self.std_node.test_transaction_acceptance(tx2, with_witness=True, accepted=segwit_activated) + + # Now update self.utxo for later tests. + tx3 = CTransaction() + if segwit_activated: + # tx and tx2 were both accepted. Don't bother trying to reclaim the + # P2PKH output; just send tx's first output back to an anyone-can-spend. + sync_mempools([self.nodes[0], self.nodes[1]]) + tx3.vin = [CTxIn(COutPoint(tx.sha256, 0), b"")] + tx3.vout = [CTxOut(tx.vout[0].nValue-1000, CScript([OP_TRUE]))] + tx3.wit.vtxinwit.append(CTxInWitness()) + tx3.wit.vtxinwit[0].scriptWitness.stack = [witness_program] + tx3.rehash() + self.test_node.test_transaction_acceptance(tx3, with_witness=True, accepted=True) + else: + # tx and tx2 didn't go anywhere; just clean up the p2sh_tx output. + tx3.vin = [CTxIn(COutPoint(p2sh_tx.sha256, 0), CScript([witness_program]))] + tx3.vout = [CTxOut(p2sh_tx.vout[0].nValue-1000, witness_program)] + tx3.rehash() + self.test_node.test_transaction_acceptance(tx3, with_witness=True, accepted=True) + + self.nodes[0].generate(1) + sync_blocks(self.nodes) + self.utxo.pop(0) + self.utxo.append(UTXO(tx3.sha256, 0, tx3.vout[0].nValue)) + assert_equal(len(self.nodes[1].getrawmempool()), 0) + + # Verify that future segwit upgraded transactions are non-standard, # but valid in blocks. Can run this before and after segwit activation. def test_segwit_versions(self): @@ -1232,13 +1323,6 @@ def test_signature_version_1(self): sync_blocks(self.nodes) self.utxo.pop(0) - # Add signature for a P2PK witness program. - def sign_P2PK_witness_input(script, txTo, inIdx, hashtype, value, key): - tx_hash = SegwitVersion1SignatureHash(script, txTo, inIdx, hashtype, value) - signature = key.sign(tx_hash) + chr(hashtype).encode('latin-1') - txTo.wit.vtxinwit[inIdx].scriptWitness.stack = [signature, script] - txTo.rehash() - # Test each hashtype prev_utxo = UTXO(tx.sha256, 0, tx.vout[0].nValue) for sigflag in [ 0, SIGHASH_ANYONECANPAY ]: @@ -1293,6 +1377,9 @@ def sign_P2PK_witness_input(script, txTo, inIdx, hashtype, value, key): block = self.build_next_block() used_sighash_single_out_of_bounds = False for i in range(NUM_TESTS): + # Ping regularly to keep the connection alive + if (not i % 100): + self.test_node.sync_with_ping() # Choose random number of inputs to use. num_inputs = random.randint(1, 10) # Create a slight bias for producing more utxos @@ -1349,7 +1436,7 @@ def sign_P2PK_witness_input(script, txTo, inIdx, hashtype, value, key): tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) tx2.vout.append(CTxOut(tx.vout[0].nValue, CScript([OP_TRUE]))) - script = CScript([CScriptOp(OP_DUP), CScriptOp(OP_HASH160), pubkeyhash, CScriptOp(OP_EQUALVERIFY), CScriptOp(OP_CHECKSIG)]) + script = GetP2PKHScript(pubkeyhash) sig_hash = SegwitVersion1SignatureHash(script, tx2, 0, SIGHASH_ALL, tx.vout[0].nValue) signature = key.sign(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL @@ -1598,19 +1685,258 @@ def test_witness_sigops(self): def test_getblocktemplate_before_lockin(self): print("\tTesting getblocktemplate setting of segwit versionbit (before lockin)") - block_version = (self.nodes[0].getblocktemplate())['version'] - assert_equal(block_version & (1 << VB_WITNESS_BIT), 0) + # Node0 is segwit aware, node2 is not. + for node in [self.nodes[0], self.nodes[2]]: + gbt_results = node.getblocktemplate() + block_version = gbt_results['version'] + # If we're not indicating segwit support, we should not be signalling + # for segwit activation, nor should we get a witness commitment. + assert_equal(block_version & (1 << VB_WITNESS_BIT), 0) + assert('default_witness_commitment' not in gbt_results) # Workaround: # Can either change the tip, or change the mempool and wait 5 seconds # to trigger a recomputation of getblocktemplate. - self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1) + txid = int(self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1), 16) # Using mocktime lets us avoid sleep() + sync_mempools(self.nodes) self.nodes[0].setmocktime(int(time.time())+10) + self.nodes[2].setmocktime(int(time.time())+10) + + for node in [self.nodes[0], self.nodes[2]]: + gbt_results = node.getblocktemplate({"rules" : ["segwit"]}) + block_version = gbt_results['version'] + if node == self.nodes[2]: + # If this is a non-segwit node, we should still not get a witness + # commitment, nor a version bit signalling segwit. + assert_equal(block_version & (1 << VB_WITNESS_BIT), 0) + assert('default_witness_commitment' not in gbt_results) + else: + # For segwit-aware nodes, check the version bit and the witness + # commitment are correct. + assert(block_version & (1 << VB_WITNESS_BIT) != 0) + assert('default_witness_commitment' in gbt_results) + witness_commitment = gbt_results['default_witness_commitment'] + + # TODO: this duplicates some code from blocktools.py, would be nice + # to refactor. + # Check that default_witness_commitment is present. + block = CBlock() + witness_root = block.get_merkle_root([ser_uint256(0), ser_uint256(txid)]) + check_commitment = uint256_from_str(hash256(ser_uint256(witness_root)+ser_uint256(0))) + from test_framework.blocktools import WITNESS_COMMITMENT_HEADER + output_data = WITNESS_COMMITMENT_HEADER + ser_uint256(check_commitment) + script = CScript([OP_RETURN, output_data]) + assert_equal(witness_commitment, bytes_to_hex_str(script)) + + # undo mocktime + self.nodes[0].setmocktime(0) + self.nodes[2].setmocktime(0) + + # Uncompressed pubkeys are no longer supported in default relay policy, + # but (for now) are still valid in blocks. + def test_uncompressed_pubkey(self): + print("\tTesting uncompressed pubkeys") + # Segwit transactions using uncompressed pubkeys are not accepted + # under default policy, but should still pass consensus. + key = CECKey() + key.set_secretbytes(b"9") + key.set_compressed(False) + pubkey = CPubKey(key.get_pubkey()) + assert_equal(len(pubkey), 65) # This should be an uncompressed pubkey + + assert(len(self.utxo) > 0) + utxo = self.utxo.pop(0) + + # Test 1: P2WPKH + # First create a P2WPKH output that uses an uncompressed pubkey + pubkeyhash = hash160(pubkey) + scriptPKH = CScript([OP_0, pubkeyhash]) + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(utxo.sha256, utxo.n), b"")) + tx.vout.append(CTxOut(utxo.nValue-1000, scriptPKH)) + tx.rehash() + + # Confirm it in a block. + block = self.build_next_block() + self.update_witness_block_with_transactions(block, [tx]) + self.test_node.test_witness_block(block, accepted=True) + + # Now try to spend it. Send it to a P2WSH output, which we'll + # use in the next test. + witness_program = CScript([pubkey, CScriptOp(OP_CHECKSIG)]) + witness_hash = sha256(witness_program) + scriptWSH = CScript([OP_0, witness_hash]) + + tx2 = CTransaction() + tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b"")) + tx2.vout.append(CTxOut(tx.vout[0].nValue-1000, scriptWSH)) + script = GetP2PKHScript(pubkeyhash) + sig_hash = SegwitVersion1SignatureHash(script, tx2, 0, SIGHASH_ALL, tx.vout[0].nValue) + signature = key.sign(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL + tx2.wit.vtxinwit.append(CTxInWitness()) + tx2.wit.vtxinwit[0].scriptWitness.stack = [ signature, pubkey ] + tx2.rehash() + + # Should fail policy test. + self.test_node.test_transaction_acceptance(tx2, True, False, b'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)') + # But passes consensus. + block = self.build_next_block() + self.update_witness_block_with_transactions(block, [tx2]) + self.test_node.test_witness_block(block, accepted=True) + + # Test 2: P2WSH + # Try to spend the P2WSH output created in last test. + # Send it to a P2SH(P2WSH) output, which we'll use in the next test. + p2sh_witness_hash = hash160(scriptWSH) + scriptP2SH = CScript([OP_HASH160, p2sh_witness_hash, OP_EQUAL]) + scriptSig = CScript([scriptWSH]) + + tx3 = CTransaction() + tx3.vin.append(CTxIn(COutPoint(tx2.sha256, 0), b"")) + tx3.vout.append(CTxOut(tx2.vout[0].nValue-1000, scriptP2SH)) + tx3.wit.vtxinwit.append(CTxInWitness()) + sign_P2PK_witness_input(witness_program, tx3, 0, SIGHASH_ALL, tx2.vout[0].nValue, key) + + # Should fail policy test. + self.test_node.test_transaction_acceptance(tx3, True, False, b'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)') + # But passes consensus. + block = self.build_next_block() + self.update_witness_block_with_transactions(block, [tx3]) + self.test_node.test_witness_block(block, accepted=True) + + # Test 3: P2SH(P2WSH) + # Try to spend the P2SH output created in the last test. + # Send it to a P2PKH output, which we'll use in the next test. + scriptPubKey = GetP2PKHScript(pubkeyhash) + tx4 = CTransaction() + tx4.vin.append(CTxIn(COutPoint(tx3.sha256, 0), scriptSig)) + tx4.vout.append(CTxOut(tx3.vout[0].nValue-1000, scriptPubKey)) + tx4.wit.vtxinwit.append(CTxInWitness()) + sign_P2PK_witness_input(witness_program, tx4, 0, SIGHASH_ALL, tx3.vout[0].nValue, key) + + # Should fail policy test. + self.test_node.test_transaction_acceptance(tx4, True, False, b'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)') + block = self.build_next_block() + self.update_witness_block_with_transactions(block, [tx4]) + self.test_node.test_witness_block(block, accepted=True) + + # Test 4: Uncompressed pubkeys should still be valid in non-segwit + # transactions. + tx5 = CTransaction() + tx5.vin.append(CTxIn(COutPoint(tx4.sha256, 0), b"")) + tx5.vout.append(CTxOut(tx4.vout[0].nValue-1000, CScript([OP_TRUE]))) + (sig_hash, err) = SignatureHash(scriptPubKey, tx5, 0, SIGHASH_ALL) + signature = key.sign(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL + tx5.vin[0].scriptSig = CScript([signature, pubkey]) + tx5.rehash() + # Should pass policy and consensus. + self.test_node.test_transaction_acceptance(tx5, True, True) + block = self.build_next_block() + self.update_witness_block_with_transactions(block, [tx5]) + self.test_node.test_witness_block(block, accepted=True) + self.utxo.append(UTXO(tx5.sha256, 0, tx5.vout[0].nValue)) + + def test_non_standard_witness(self): + print("\tTesting detection of non-standard P2WSH witness") + pad = chr(1).encode('latin-1') + + # Create scripts for tests + scripts = [] + scripts.append(CScript([OP_DROP] * 100)) + scripts.append(CScript([OP_DROP] * 99)) + scripts.append(CScript([pad * 59] * 59 + [OP_DROP] * 60)) + scripts.append(CScript([pad * 59] * 59 + [OP_DROP] * 61)) + + p2wsh_scripts = [] + + assert(len(self.utxo)) + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b"")) + + # For each script, generate a pair of P2WSH and P2SH-P2WSH output. + outputvalue = (self.utxo[0].nValue - 1000) // (len(scripts) * 2) + for i in scripts: + p2wsh = CScript([OP_0, sha256(i)]) + p2sh = hash160(p2wsh) + p2wsh_scripts.append(p2wsh) + tx.vout.append(CTxOut(outputvalue, p2wsh)) + tx.vout.append(CTxOut(outputvalue, CScript([OP_HASH160, p2sh, OP_EQUAL]))) + tx.rehash() + txid = tx.sha256 + self.test_node.test_transaction_acceptance(tx, with_witness=False, accepted=True) + + self.nodes[0].generate(1) + sync_blocks(self.nodes) + + # Creating transactions for tests + p2wsh_txs = [] + p2sh_txs = [] + for i in range(len(scripts)): + p2wsh_tx = CTransaction() + p2wsh_tx.vin.append(CTxIn(COutPoint(txid,i*2))) + p2wsh_tx.vout.append(CTxOut(outputvalue - 5000, CScript([OP_0, hash160(hex_str_to_bytes(""))]))) + p2wsh_tx.wit.vtxinwit.append(CTxInWitness()) + p2wsh_tx.rehash() + p2wsh_txs.append(p2wsh_tx) + p2sh_tx = CTransaction() + p2sh_tx.vin.append(CTxIn(COutPoint(txid,i*2+1), CScript([p2wsh_scripts[i]]))) + p2sh_tx.vout.append(CTxOut(outputvalue - 5000, CScript([OP_0, hash160(hex_str_to_bytes(""))]))) + p2sh_tx.wit.vtxinwit.append(CTxInWitness()) + p2sh_tx.rehash() + p2sh_txs.append(p2sh_tx) + + # Testing native P2WSH + # Witness stack size, excluding witnessScript, over 100 is non-standard + p2wsh_txs[0].wit.vtxinwit[0].scriptWitness.stack = [pad] * 101 + [scripts[0]] + self.std_node.test_transaction_acceptance(p2wsh_txs[0], True, False, b'bad-witness-nonstandard') + # Non-standard nodes should accept + self.test_node.test_transaction_acceptance(p2wsh_txs[0], True, True) + + # Stack element size over 80 bytes is non-standard + p2wsh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 81] * 100 + [scripts[1]] + self.std_node.test_transaction_acceptance(p2wsh_txs[1], True, False, b'bad-witness-nonstandard') + # Non-standard nodes should accept + self.test_node.test_transaction_acceptance(p2wsh_txs[1], True, True) + # Standard nodes should accept if element size is not over 80 bytes + p2wsh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 80] * 100 + [scripts[1]] + self.std_node.test_transaction_acceptance(p2wsh_txs[1], True, True) + + # witnessScript size at 3600 bytes is standard + p2wsh_txs[2].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, scripts[2]] + self.test_node.test_transaction_acceptance(p2wsh_txs[2], True, True) + self.std_node.test_transaction_acceptance(p2wsh_txs[2], True, True) + + # witnessScript size at 3601 bytes is non-standard + p2wsh_txs[3].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, pad, scripts[3]] + self.std_node.test_transaction_acceptance(p2wsh_txs[3], True, False, b'bad-witness-nonstandard') + # Non-standard nodes should accept + self.test_node.test_transaction_acceptance(p2wsh_txs[3], True, True) + + # Repeating the same tests with P2SH-P2WSH + p2sh_txs[0].wit.vtxinwit[0].scriptWitness.stack = [pad] * 101 + [scripts[0]] + self.std_node.test_transaction_acceptance(p2sh_txs[0], True, False, b'bad-witness-nonstandard') + self.test_node.test_transaction_acceptance(p2sh_txs[0], True, True) + p2sh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 81] * 100 + [scripts[1]] + self.std_node.test_transaction_acceptance(p2sh_txs[1], True, False, b'bad-witness-nonstandard') + self.test_node.test_transaction_acceptance(p2sh_txs[1], True, True) + p2sh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 80] * 100 + [scripts[1]] + self.std_node.test_transaction_acceptance(p2sh_txs[1], True, True) + p2sh_txs[2].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, scripts[2]] + self.test_node.test_transaction_acceptance(p2sh_txs[2], True, True) + self.std_node.test_transaction_acceptance(p2sh_txs[2], True, True) + p2sh_txs[3].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, pad, scripts[3]] + self.std_node.test_transaction_acceptance(p2sh_txs[3], True, False, b'bad-witness-nonstandard') + self.test_node.test_transaction_acceptance(p2sh_txs[3], True, True) + + self.nodes[0].generate(1) # Mine and clean up the mempool of non-standard node + # Valid but non-standard transactions in a block should be accepted by standard node + sync_blocks(self.nodes) + assert_equal(len(self.nodes[0].getrawmempool()), 0) + assert_equal(len(self.nodes[1].getrawmempool()), 0) + + self.utxo.pop(0) - block_version = self.nodes[0].getblocktemplate({"rules" : ["segwit"]})['version'] - assert(block_version & (1 << VB_WITNESS_BIT) != 0) - self.nodes[0].setmocktime(0) # undo mocktime def run_test(self): # Setup the p2p connections and start up the network thread. @@ -1645,6 +1971,7 @@ def run_test(self): # Advance to segwit being 'started' self.advance_to_segwit_started() + sync_blocks(self.nodes) self.test_getblocktemplate_before_lockin() sync_blocks(self.nodes) @@ -1658,6 +1985,7 @@ def run_test(self): self.test_witness_tx_relay_before_segwit_activation() self.test_block_relay(segwit_activated=False) self.test_p2sh_witness(segwit_activated=False) + self.test_standardness_v0(segwit_activated=False) sync_blocks(self.nodes) @@ -1679,14 +2007,14 @@ def run_test(self): self.test_witness_input_length() self.test_block_relay(segwit_activated=True) self.test_tx_relay_after_segwit_activation() + self.test_standardness_v0(segwit_activated=True) self.test_segwit_versions() self.test_premature_coinbase_witness_spend() + self.test_uncompressed_pubkey() self.test_signature_version_1() + self.test_non_standard_witness() sync_blocks(self.nodes) - if self.test_upgrade: - self.test_upgrade_after_activation(self.nodes[2], 2) - else: - print("\tSkipping upgrade-after-activation test (use --oldbinary to enable)") + self.test_upgrade_after_activation(self.nodes[2], 2) self.test_witness_sigops() diff --git a/qa/rpc-tests/p2p-versionbits-warning.py b/qa/rpc-tests/p2p-versionbits-warning.py index 962cafef0b1..fc3eddddee1 100755 --- a/qa/rpc-tests/p2p-versionbits-warning.py +++ b/qa/rpc-tests/p2p-versionbits-warning.py @@ -6,6 +6,7 @@ from test_framework.mininode import * from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * +import re import time from test_framework.blocktools import create_block, create_coinbase @@ -21,6 +22,10 @@ VB_TOP_BITS = 0x20000000 VB_UNKNOWN_BIT = 27 # Choose a bit unassigned to any deployment +WARN_UNKNOWN_RULES_MINED = "Unknown block versions being mined! It's possible unknown rules are in effect" +WARN_UNKNOWN_RULES_ACTIVE = "unknown new rules activated (versionbit {})".format(VB_UNKNOWN_BIT) +VB_PATTERN = re.compile("^Warning.*versionbit") + # TestNode: bare-bones "peer". Used mostly as a conduit for a test to sending # p2p messages to a node, generating the messages in the main testing logic. class TestNode(NodeConnCB): @@ -65,16 +70,12 @@ def __init__(self): self.num_nodes = 1 def setup_network(self): - self.nodes = [] self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt") # Open and close to create zero-length file - with open(self.alert_filename, 'w') as f: + with open(self.alert_filename, 'w', encoding='utf8') as _: pass - self.node_options = ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""] - self.nodes.append(start_node(0, self.options.tmpdir, self.node_options)) - - import re - self.vb_pattern = re.compile("^Warning.*versionbit") + self.extra_args = [["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]] + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args) # Send numblocks blocks via peer with nVersionToUse set. def send_blocks_with_version(self, peer, numblocks, nVersionToUse): @@ -83,7 +84,7 @@ def send_blocks_with_version(self, peer, numblocks, nVersionToUse): block_time = self.nodes[0].getblockheader(tip)["time"]+1 tip = int(tip, 16) - for i in range(numblocks): + for _ in range(numblocks): block = create_block(tip, create_coinbase(height+1), block_time) block.nVersion = nVersionToUse block.solve() @@ -94,9 +95,9 @@ def send_blocks_with_version(self, peer, numblocks, nVersionToUse): peer.sync_with_ping() def test_versionbits_in_alert_file(self): - with open(self.alert_filename, 'r') as f: + with open(self.alert_filename, 'r', encoding='utf8') as f: alert_text = f.read() - assert(self.vb_pattern.match(alert_text)) + assert(VB_PATTERN.match(alert_text)) def run_test(self): # Setup the p2p connection and start up the network thread. @@ -122,8 +123,10 @@ def run_test(self): # Fill rest of period with regular version blocks self.nodes[0].generate(VB_PERIOD - VB_THRESHOLD + 1) # Check that we're not getting any versionbit-related errors in - # getinfo() - assert(not self.vb_pattern.match(self.nodes[0].getinfo()["errors"])) + # get*info() + assert(not VB_PATTERN.match(self.nodes[0].getinfo()["errors"])) + assert(not VB_PATTERN.match(self.nodes[0].getmininginfo()["errors"])) + assert(not VB_PATTERN.match(self.nodes[0].getnetworkinfo()["warnings"])) # 3. Now build one period of blocks with >= VB_THRESHOLD blocks signaling # some unknown bit @@ -132,30 +135,31 @@ def run_test(self): # Might not get a versionbits-related alert yet, as we should # have gotten a different alert due to more than 51/100 blocks # being of unexpected version. - # Check that getinfo() shows some kind of error. - assert(len(self.nodes[0].getinfo()["errors"]) != 0) + # Check that get*info() shows some kind of error. + assert(WARN_UNKNOWN_RULES_MINED in self.nodes[0].getinfo()["errors"]) + assert(WARN_UNKNOWN_RULES_MINED in self.nodes[0].getmininginfo()["errors"]) + assert(WARN_UNKNOWN_RULES_MINED in self.nodes[0].getnetworkinfo()["warnings"]) # Mine a period worth of expected blocks so the generic block-version warning # is cleared, and restart the node. This should move the versionbit state # to ACTIVE. self.nodes[0].generate(VB_PERIOD) - stop_node(self.nodes[0], 0) - wait_bitcoinds() + stop_nodes(self.nodes) # Empty out the alert file - with open(self.alert_filename, 'w') as f: + with open(self.alert_filename, 'w', encoding='utf8') as _: pass - self.nodes[0] = start_node(0, self.options.tmpdir, ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args) # Connecting one block should be enough to generate an error. self.nodes[0].generate(1) - assert(len(self.nodes[0].getinfo()["errors"]) != 0) - stop_node(self.nodes[0], 0) - wait_bitcoinds() + assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getinfo()["errors"]) + assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getmininginfo()["errors"]) + assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getnetworkinfo()["warnings"]) + stop_nodes(self.nodes) self.test_versionbits_in_alert_file() # Test framework expects the node to still be running... - self.nodes[0] = start_node(0, self.options.tmpdir, ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]) - + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args) if __name__ == '__main__': VersionBitsWarningTest().main() diff --git a/qa/rpc-tests/pruning.py b/qa/rpc-tests/pruning.py index 7cbe69c29b2..287dbc776e1 100755 --- a/qa/rpc-tests/pruning.py +++ b/qa/rpc-tests/pruning.py @@ -157,7 +157,10 @@ def reorg_test(self): print("Usage possibly still high bc of stale blocks in block files:", calc_usage(self.prunedir)) print("Mine 220 more blocks so we have requisite history (some blocks will be big and cause pruning of previous chain)") - self.nodes[0].generate(220) #node 0 has many large tx's in its mempool from the disconnects + for i in range(22): + # This can be slow, so do this in multiple RPC calls to avoid + # RPC timeouts. + self.nodes[0].generate(10) #node 0 has many large tx's in its mempool from the disconnects sync_blocks(self.nodes[0:3], timeout=300) usage = calc_usage(self.prunedir) diff --git a/qa/rpc-tests/reindex.py b/qa/rpc-tests/reindex.py index abbbb103369..25cf4c1679b 100755 --- a/qa/rpc-tests/reindex.py +++ b/qa/rpc-tests/reindex.py @@ -7,7 +7,11 @@ # Test -reindex and -reindex-chainstate with CheckBlockIndex # from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from test_framework.util import ( + start_nodes, + stop_nodes, + assert_equal, +) import time class ReindexTest(BitcoinTestFramework): @@ -18,16 +22,14 @@ def __init__(self): self.num_nodes = 1 def setup_network(self): - self.nodes = [] - self.is_network_split = False - self.nodes.append(start_node(0, self.options.tmpdir)) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) def reindex(self, justchainstate=False): self.nodes[0].generate(3) blockcount = self.nodes[0].getblockcount() - stop_node(self.nodes[0], 0) - wait_bitcoinds() - self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug", "-reindex-chainstate" if justchainstate else "-reindex", "-checkblockindex=1"]) + stop_nodes(self.nodes) + extra_args = [["-debug", "-reindex-chainstate" if justchainstate else "-reindex", "-checkblockindex=1"]] + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args) while self.nodes[0].getblockcount() < blockcount: time.sleep(0.1) assert_equal(self.nodes[0].getblockcount(), blockcount) diff --git a/qa/rpc-tests/rpcbind_test.py b/qa/rpc-tests/rpcbind_test.py index 572273566b6..3089455537e 100755 --- a/qa/rpc-tests/rpcbind_test.py +++ b/qa/rpc-tests/rpcbind_test.py @@ -5,143 +5,106 @@ # Test for -rpcbind, as well as -rpcallowip and -rpcconnect -# TODO extend this test from the test framework (like all other tests) - import tempfile import traceback +from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * from test_framework.netutil import * -def run_bind_test(tmpdir, allow_ips, connect_to, addresses, expected): - ''' - Start a node with requested rpcallowip and rpcbind parameters, - then try to connect, and check if the set of bound addresses - matches the expected set. - ''' - expected = [(addr_to_hex(addr), port) for (addr, port) in expected] - base_args = ['-disablewallet', '-nolisten'] - if allow_ips: - base_args += ['-rpcallowip=' + x for x in allow_ips] - binds = ['-rpcbind='+addr for addr in addresses] - nodes = start_nodes(self.num_nodes, tmpdir, [base_args + binds], connect_to) - try: - pid = bitcoind_processes[0].pid - assert_equal(set(get_bind_addrs(pid)), set(expected)) - finally: - stop_nodes(nodes) - wait_bitcoinds() - -def run_allowip_test(tmpdir, allow_ips, rpchost, rpcport): - ''' - Start a node with rpcwallow IP, and request getinfo - at a non-localhost IP. - ''' - base_args = ['-disablewallet', '-nolisten'] + ['-rpcallowip='+x for x in allow_ips] - nodes = start_nodes(self.num_nodes, tmpdir, [base_args]) - try: - # connect to node through non-loopback interface - url = "http://rt:rt@%s:%d" % (rpchost, rpcport,) - node = get_rpc_proxy(url, 1) - node.getinfo() - finally: - node = None # make sure connection will be garbage collected and closed - stop_nodes(nodes) - wait_bitcoinds() - - -def run_test(tmpdir): - assert(sys.platform.startswith('linux')) # due to OS-specific network stats queries, this test works only on Linux - # find the first non-loopback interface for testing - non_loopback_ip = None - for name,ip in all_interfaces(): - if ip != '127.0.0.1': - non_loopback_ip = ip - break - if non_loopback_ip is None: - assert(not 'This test requires at least one non-loopback IPv4 interface') - print("Using interface %s for testing" % non_loopback_ip) +class RPCBindTest(BitcoinTestFramework): - defaultport = rpc_port(0) + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 1 - # check default without rpcallowip (IPv4 and IPv6 localhost) - run_bind_test(tmpdir, None, '127.0.0.1', [], - [('127.0.0.1', defaultport), ('::1', defaultport)]) - # check default with rpcallowip (IPv6 any) - run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1', [], - [('::0', defaultport)]) - # check only IPv4 localhost (explicit) - run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1', ['127.0.0.1'], - [('127.0.0.1', defaultport)]) - # check only IPv4 localhost (explicit) with alternative port - run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1:32171', ['127.0.0.1:32171'], - [('127.0.0.1', 32171)]) - # check only IPv4 localhost (explicit) with multiple alternative ports on same host - run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1:32171', ['127.0.0.1:32171', '127.0.0.1:32172'], - [('127.0.0.1', 32171), ('127.0.0.1', 32172)]) - # check only IPv6 localhost (explicit) - run_bind_test(tmpdir, ['[::1]'], '[::1]', ['[::1]'], - [('::1', defaultport)]) - # check both IPv4 and IPv6 localhost (explicit) - run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1', ['127.0.0.1', '[::1]'], - [('127.0.0.1', defaultport), ('::1', defaultport)]) - # check only non-loopback interface - run_bind_test(tmpdir, [non_loopback_ip], non_loopback_ip, [non_loopback_ip], - [(non_loopback_ip, defaultport)]) - - # Check that with invalid rpcallowip, we are denied - run_allowip_test(tmpdir, [non_loopback_ip], non_loopback_ip, defaultport) - try: - run_allowip_test(tmpdir, ['1.1.1.1'], non_loopback_ip, defaultport) - assert(not 'Connection not denied by rpcallowip as expected') - except ValueError: + def setup_network(self): pass -def main(): - import optparse - - parser = optparse.OptionParser(usage="%prog [options]") - parser.add_option("--nocleanup", dest="nocleanup", default=False, action="store_true", - help="Leave bitcoinds and test.* datadir on exit or error") - parser.add_option("--srcdir", dest="srcdir", default="../../src", - help="Source directory containing bitcoind/bitcoin-cli (default: %default%)") - parser.add_option("--tmpdir", dest="tmpdir", default=tempfile.mkdtemp(prefix="test"), - help="Root directory for datadirs") - (options, args) = parser.parse_args() - - os.environ['PATH'] = options.srcdir+":"+os.environ['PATH'] - - check_json_precision() - - success = False - nodes = [] - try: - print("Initializing test directory "+options.tmpdir) - if not os.path.isdir(options.tmpdir): - os.makedirs(options.tmpdir) - initialize_chain(options.tmpdir) - - run_test(options.tmpdir) - - success = True - - except AssertionError as e: - print("Assertion failed: "+e.message) - except Exception as e: - print("Unexpected exception caught during testing: "+str(e)) - traceback.print_tb(sys.exc_info()[2]) - - if not options.nocleanup: - print("Cleaning up") - wait_bitcoinds() - shutil.rmtree(options.tmpdir) + def setup_nodes(self): + pass - if success: - print("Tests successful") - sys.exit(0) - else: - print("Failed") - sys.exit(1) + def run_bind_test(self, allow_ips, connect_to, addresses, expected): + ''' + Start a node with requested rpcallowip and rpcbind parameters, + then try to connect, and check if the set of bound addresses + matches the expected set. + ''' + expected = [(addr_to_hex(addr), port) for (addr, port) in expected] + base_args = ['-disablewallet', '-nolisten'] + if allow_ips: + base_args += ['-rpcallowip=' + x for x in allow_ips] + binds = ['-rpcbind='+addr for addr in addresses] + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [base_args + binds], connect_to) + try: + pid = bitcoind_processes[0].pid + assert_equal(set(get_bind_addrs(pid)), set(expected)) + finally: + stop_nodes(self.nodes) + + def run_allowip_test(self, allow_ips, rpchost, rpcport): + ''' + Start a node with rpcallow IP, and request getinfo + at a non-localhost IP. + ''' + base_args = ['-disablewallet', '-nolisten'] + ['-rpcallowip='+x for x in allow_ips] + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [base_args]) + try: + # connect to node through non-loopback interface + node = get_rpc_proxy(rpc_url(0, "%s:%d" % (rpchost, rpcport)), 0) + node.getinfo() + finally: + node = None # make sure connection will be garbage collected and closed + stop_nodes(self.nodes) + + def run_test(self): + # due to OS-specific network stats queries, this test works only on Linux + assert(sys.platform.startswith('linux')) + # find the first non-loopback interface for testing + non_loopback_ip = None + for name,ip in all_interfaces(): + if ip != '127.0.0.1': + non_loopback_ip = ip + break + if non_loopback_ip is None: + assert(not 'This test requires at least one non-loopback IPv4 interface') + print("Using interface %s for testing" % non_loopback_ip) + + defaultport = rpc_port(0) + + # check default without rpcallowip (IPv4 and IPv6 localhost) + self.run_bind_test(None, '127.0.0.1', [], + [('127.0.0.1', defaultport), ('::1', defaultport)]) + # check default with rpcallowip (IPv6 any) + self.run_bind_test(['127.0.0.1'], '127.0.0.1', [], + [('::0', defaultport)]) + # check only IPv4 localhost (explicit) + self.run_bind_test(['127.0.0.1'], '127.0.0.1', ['127.0.0.1'], + [('127.0.0.1', defaultport)]) + # check only IPv4 localhost (explicit) with alternative port + self.run_bind_test(['127.0.0.1'], '127.0.0.1:32171', ['127.0.0.1:32171'], + [('127.0.0.1', 32171)]) + # check only IPv4 localhost (explicit) with multiple alternative ports on same host + self.run_bind_test(['127.0.0.1'], '127.0.0.1:32171', ['127.0.0.1:32171', '127.0.0.1:32172'], + [('127.0.0.1', 32171), ('127.0.0.1', 32172)]) + # check only IPv6 localhost (explicit) + self.run_bind_test(['[::1]'], '[::1]', ['[::1]'], + [('::1', defaultport)]) + # check both IPv4 and IPv6 localhost (explicit) + self.run_bind_test(['127.0.0.1'], '127.0.0.1', ['127.0.0.1', '[::1]'], + [('127.0.0.1', defaultport), ('::1', defaultport)]) + # check only non-loopback interface + self.run_bind_test([non_loopback_ip], non_loopback_ip, [non_loopback_ip], + [(non_loopback_ip, defaultport)]) + + # Check that with invalid rpcallowip, we are denied + self.run_allowip_test([non_loopback_ip], non_loopback_ip, defaultport) + try: + self.run_allowip_test(['1.1.1.1'], non_loopback_ip, defaultport) + assert(not 'Connection not denied by rpcallowip as expected') + except JSONRPCException: + pass if __name__ == '__main__': - main() + RPCBindTest ().main () diff --git a/qa/rpc-tests/segwit.py b/qa/rpc-tests/segwit.py index d4c9a8afed3..31a48955e5c 100755 --- a/qa/rpc-tests/segwit.py +++ b/qa/rpc-tests/segwit.py @@ -9,9 +9,11 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -from test_framework.mininode import sha256, ripemd160 -import os -import shutil +from test_framework.mininode import sha256, ripemd160, CTransaction, CTxIn, COutPoint, CTxOut +from test_framework.address import script_to_p2sh, key_to_p2pkh +from test_framework.script import CScript, OP_HASH160, OP_CHECKSIG, OP_0, hash160, OP_EQUAL, OP_DUP, OP_EQUALVERIFY, OP_1, OP_2, OP_CHECKMULTISIG +from io import BytesIO +from test_framework.mininode import FromHex NODE_0 = 0 NODE_1 = 1 @@ -69,6 +71,11 @@ def getutxo(txid): utxo["txid"] = txid return utxo +def find_unspent(node, min_value): + for utxo in node.listunspent(): + if utxo['amount'] >= min_value: + return utxo + class SegWitTest(BitcoinTestFramework): def setup_chain(self): @@ -77,8 +84,8 @@ def setup_chain(self): def setup_network(self): self.nodes = [] - self.nodes.append(start_node(0, self.options.tmpdir, ["-logtimemicros", "-debug", "-walletprematurewitness"])) - self.nodes.append(start_node(1, self.options.tmpdir, ["-logtimemicros", "-debug", "-blockversion=4", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness"])) + self.nodes.append(start_node(0, self.options.tmpdir, ["-logtimemicros", "-debug", "-walletprematurewitness", "-rpcserialversion=0"])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-logtimemicros", "-debug", "-blockversion=4", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness", "-rpcserialversion=1"])) self.nodes.append(start_node(2, self.options.tmpdir, ["-logtimemicros", "-debug", "-blockversion=536870915", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness"])) connect_nodes(self.nodes[1], 0) connect_nodes(self.nodes[2], 1) @@ -117,8 +124,21 @@ def fail_mine(self, node, txid, sign, redeem_script=""): sync_blocks(self.nodes) def run_test(self): - self.nodes[0].generate(160) #block 160 - + self.nodes[0].generate(161) #block 161 + + print("Verify sigops are counted in GBT with pre-BIP141 rules before the fork") + txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1) + tmpl = self.nodes[0].getblocktemplate({}) + assert(tmpl['sigoplimit'] == 20000) + assert(tmpl['transactions'][0]['hash'] == txid) + assert(tmpl['transactions'][0]['sigops'] == 2) + tmpl = self.nodes[0].getblocktemplate({'rules':['segwit']}) + assert(tmpl['sigoplimit'] == 20000) + assert(tmpl['transactions'][0]['hash'] == txid) + assert(tmpl['transactions'][0]['sigops'] == 2) + self.nodes[0].generate(1) #block 162 + + balance_presetup = self.nodes[0].getbalance() self.pubkey = [] p2sh_ids = [] # p2sh_ids[NODE][VER] is an array of txids that spend to a witness version VER pkscript to an address for NODE embedded in p2sh wit_ids = [] # wit_ids[NODE][VER] is an array of txids that spend to a witness version VER pkscript to an address for NODE via bare witness @@ -137,18 +157,18 @@ def run_test(self): for i in range(5): for n in range(3): for v in range(2): - wit_ids[n][v].append(send_to_witness(v, self.nodes[0], self.nodes[0].listunspent()[0], self.pubkey[n], False, Decimal("49.999"))) - p2sh_ids[n][v].append(send_to_witness(v, self.nodes[0], self.nodes[0].listunspent()[0], self.pubkey[n], True, Decimal("49.999"))) + wit_ids[n][v].append(send_to_witness(v, self.nodes[0], find_unspent(self.nodes[0], 50), self.pubkey[n], False, Decimal("49.999"))) + p2sh_ids[n][v].append(send_to_witness(v, self.nodes[0], find_unspent(self.nodes[0], 50), self.pubkey[n], True, Decimal("49.999"))) - self.nodes[0].generate(1) #block 161 + self.nodes[0].generate(1) #block 163 sync_blocks(self.nodes) # Make sure all nodes recognize the transactions as theirs - assert_equal(self.nodes[0].getbalance(), 60*50 - 60*50 + 20*Decimal("49.999") + 50) + assert_equal(self.nodes[0].getbalance(), balance_presetup - 60*50 + 20*Decimal("49.999") + 50) assert_equal(self.nodes[1].getbalance(), 20*Decimal("49.999")) assert_equal(self.nodes[2].getbalance(), 20*Decimal("49.999")) - self.nodes[0].generate(262) #block 423 + self.nodes[0].generate(260) #block 423 sync_blocks(self.nodes) print("Verify default node can't accept any witness format txs before fork") @@ -191,7 +211,19 @@ def run_test(self): block = self.nodes[2].generate(1) #block 432 (first block with new rules; 432 = 144 * 3) sync_blocks(self.nodes) assert_equal(len(self.nodes[2].getrawmempool()), 0) - assert_equal(len(self.nodes[2].getblock(block[0])["tx"]), 5) + segwit_tx_list = self.nodes[2].getblock(block[0])["tx"] + assert_equal(len(segwit_tx_list), 5) + + print("Verify block and transaction serialization rpcs return differing serializations depending on rpc serialization flag") + assert(self.nodes[2].getblock(block[0], False) != self.nodes[0].getblock(block[0], False)) + assert(self.nodes[1].getblock(block[0], False) == self.nodes[2].getblock(block[0], False)) + for i in range(len(segwit_tx_list)): + tx = FromHex(CTransaction(), self.nodes[2].gettransaction(segwit_tx_list[i])["hex"]) + assert(self.nodes[2].getrawtransaction(segwit_tx_list[i]) != self.nodes[0].getrawtransaction(segwit_tx_list[i])) + assert(self.nodes[1].getrawtransaction(segwit_tx_list[i], 0) == self.nodes[2].getrawtransaction(segwit_tx_list[i])) + assert(self.nodes[0].getrawtransaction(segwit_tx_list[i]) != self.nodes[2].gettransaction(segwit_tx_list[i])["hex"]) + assert(self.nodes[1].getrawtransaction(segwit_tx_list[i]) == self.nodes[2].gettransaction(segwit_tx_list[i])["hex"]) + assert(self.nodes[0].getrawtransaction(segwit_tx_list[i]) == bytes_to_hex_str(tx.serialize_without_witness())) print("Verify witness txs without witness data are invalid after the fork") self.fail_mine(self.nodes[2], wit_ids[NODE_2][WIT_V0][2], False) @@ -205,5 +237,380 @@ def run_test(self): self.success_mine(self.nodes[0], p2sh_ids[NODE_0][WIT_V0][0], True) #block 434 self.success_mine(self.nodes[0], p2sh_ids[NODE_0][WIT_V1][0], True) #block 435 + print("Verify sigops are counted in GBT with BIP141 rules after the fork") + txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1) + tmpl = self.nodes[0].getblocktemplate({'rules':['segwit']}) + assert(tmpl['sigoplimit'] == 80000) + assert(tmpl['transactions'][0]['txid'] == txid) + assert(tmpl['transactions'][0]['sigops'] == 8) + + print("Verify non-segwit miners get a valid GBT response after the fork") + send_to_witness(1, self.nodes[0], find_unspent(self.nodes[0], 50), self.pubkey[0], False, Decimal("49.998")) + try: + tmpl = self.nodes[0].getblocktemplate({}) + assert(len(tmpl['transactions']) == 1) # Doesn't include witness tx + assert(tmpl['sigoplimit'] == 20000) + assert(tmpl['transactions'][0]['hash'] == txid) + assert(tmpl['transactions'][0]['sigops'] == 2) + assert(('!segwit' in tmpl['rules']) or ('segwit' not in tmpl['rules'])) + except JSONRPCException: + # This is an acceptable outcome + pass + + print("Verify behaviour of importaddress, addwitnessaddress and listunspent") + + # Some public keys to be used later + pubkeys = [ + "0363D44AABD0F1699138239DF2F042C3282C0671CC7A76826A55C8203D90E39242", # cPiM8Ub4heR9NBYmgVzJQiUH1if44GSBGiqaeJySuL2BKxubvgwb + "02D3E626B3E616FC8662B489C123349FECBFC611E778E5BE739B257EAE4721E5BF", # cPpAdHaD6VoYbW78kveN2bsvb45Q7G5PhaPApVUGwvF8VQ9brD97 + "04A47F2CBCEFFA7B9BCDA184E7D5668D3DA6F9079AD41E422FA5FD7B2D458F2538A62F5BD8EC85C2477F39650BD391EA6250207065B2A81DA8B009FC891E898F0E", # 91zqCU5B9sdWxzMt1ca3VzbtVm2YM6Hi5Rxn4UDtxEaN9C9nzXV + "02A47F2CBCEFFA7B9BCDA184E7D5668D3DA6F9079AD41E422FA5FD7B2D458F2538", # cPQFjcVRpAUBG8BA9hzr2yEzHwKoMgLkJZBBtK9vJnvGJgMjzTbd + "036722F784214129FEB9E8129D626324F3F6716555B603FFE8300BBCB882151228", # cQGtcm34xiLjB1v7bkRa4V3aAc9tS2UTuBZ1UnZGeSeNy627fN66 + "0266A8396EE936BF6D99D17920DB21C6C7B1AB14C639D5CD72B300297E416FD2EC", # cTW5mR5M45vHxXkeChZdtSPozrFwFgmEvTNnanCW6wrqwaCZ1X7K + "0450A38BD7F0AC212FEBA77354A9B036A32E0F7C81FC4E0C5ADCA7C549C4505D2522458C2D9AE3CEFD684E039194B72C8A10F9CB9D4764AB26FCC2718D421D3B84", # 92h2XPssjBpsJN5CqSP7v9a7cf2kgDunBC6PDFwJHMACM1rrVBJ + ] + + # Import a compressed key and an uncompressed key, generate some multisig addresses + self.nodes[0].importprivkey("92e6XLo5jVAVwrQKPNTs93oQco8f8sDNBcpv73Dsrs397fQtFQn") + uncompressed_spendable_address = ["mvozP4UwyGD2mGZU4D2eMvMLPB9WkMmMQu"] + self.nodes[0].importprivkey("cNC8eQ5dg3mFAVePDX4ddmPYpPbw41r9bm2jd1nLJT77e6RrzTRR") + compressed_spendable_address = ["mmWQubrDomqpgSYekvsU7HWEVjLFHAakLe"] + assert ((self.nodes[0].validateaddress(uncompressed_spendable_address[0])['iscompressed'] == False)) + assert ((self.nodes[0].validateaddress(compressed_spendable_address[0])['iscompressed'] == True)) + + self.nodes[0].importpubkey(pubkeys[0]) + compressed_solvable_address = [key_to_p2pkh(pubkeys[0])] + self.nodes[0].importpubkey(pubkeys[1]) + compressed_solvable_address.append(key_to_p2pkh(pubkeys[1])) + self.nodes[0].importpubkey(pubkeys[2]) + uncompressed_solvable_address = [key_to_p2pkh(pubkeys[2])] + + spendable_anytime = [] # These outputs should be seen anytime after importprivkey and addmultisigaddress + spendable_after_importaddress = [] # These outputs should be seen after importaddress + solvable_after_importaddress = [] # These outputs should be seen after importaddress but not spendable + unsolvable_after_importaddress = [] # These outputs should be unsolvable after importaddress + solvable_anytime = [] # These outputs should be solvable after importpubkey + unseen_anytime = [] # These outputs should never be seen + + uncompressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [uncompressed_spendable_address[0], compressed_spendable_address[0]])) + uncompressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [uncompressed_spendable_address[0], uncompressed_spendable_address[0]])) + compressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_spendable_address[0], compressed_spendable_address[0]])) + uncompressed_solvable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_spendable_address[0], uncompressed_solvable_address[0]])) + compressed_solvable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_spendable_address[0], compressed_solvable_address[0]])) + compressed_solvable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_solvable_address[0], compressed_solvable_address[1]])) + unknown_address = ["mtKKyoHabkk6e4ppT7NaM7THqPUt7AzPrT", "2NDP3jLWAFT8NDAiUa9qiE6oBt2awmMq7Dx"] + + # Test multisig_without_privkey + # We have 2 public keys without private keys, use addmultisigaddress to add to wallet. + # Money sent to P2SH of multisig of this should only be seen after importaddress with the BASE58 P2SH address. + + multisig_without_privkey_address = self.nodes[0].addmultisigaddress(2, [pubkeys[3], pubkeys[4]]) + script = CScript([OP_2, hex_str_to_bytes(pubkeys[3]), hex_str_to_bytes(pubkeys[4]), OP_2, OP_CHECKMULTISIG]) + solvable_after_importaddress.append(CScript([OP_HASH160, hash160(script), OP_EQUAL])) + + for i in compressed_spendable_address: + v = self.nodes[0].validateaddress(i) + if (v['isscript']): + [bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v) + # bare and p2sh multisig with compressed keys should always be spendable + spendable_anytime.extend([bare, p2sh]) + # P2WSH and P2SH(P2WSH) multisig with compressed keys are spendable after direct importaddress + spendable_after_importaddress.extend([p2wsh, p2sh_p2wsh]) + else: + [p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh] = self.p2pkh_address_to_script(v) + # normal P2PKH and P2PK with compressed keys should always be spendable + spendable_anytime.extend([p2pkh, p2pk]) + # P2SH_P2PK, P2SH_P2PKH, and witness with compressed keys are spendable after direct importaddress + spendable_after_importaddress.extend([p2wpkh, p2sh_p2wpkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh]) + + for i in uncompressed_spendable_address: + v = self.nodes[0].validateaddress(i) + if (v['isscript']): + [bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v) + # bare and p2sh multisig with uncompressed keys should always be spendable + spendable_anytime.extend([bare, p2sh]) + # P2WSH and P2SH(P2WSH) multisig with uncompressed keys are never seen + unseen_anytime.extend([p2wsh, p2sh_p2wsh]) + else: + [p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh] = self.p2pkh_address_to_script(v) + # normal P2PKH and P2PK with uncompressed keys should always be spendable + spendable_anytime.extend([p2pkh, p2pk]) + # P2SH_P2PK and P2SH_P2PKH are spendable after direct importaddress + spendable_after_importaddress.extend([p2sh_p2pk, p2sh_p2pkh]) + # witness with uncompressed keys are never seen + unseen_anytime.extend([p2wpkh, p2sh_p2wpkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh]) + + for i in compressed_solvable_address: + v = self.nodes[0].validateaddress(i) + if (v['isscript']): + # Multisig without private is not seen after addmultisigaddress, but seen after importaddress + [bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v) + solvable_after_importaddress.extend([bare, p2sh, p2wsh, p2sh_p2wsh]) + else: + [p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh] = self.p2pkh_address_to_script(v) + # normal P2PKH and P2PK with compressed keys should always be seen + solvable_anytime.extend([p2pkh, p2pk]) + # P2SH_P2PK, P2SH_P2PKH, and witness with compressed keys are seen after direct importaddress + solvable_after_importaddress.extend([p2wpkh, p2sh_p2wpkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh]) + + for i in uncompressed_solvable_address: + v = self.nodes[0].validateaddress(i) + if (v['isscript']): + [bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v) + # Base uncompressed multisig without private is not seen after addmultisigaddress, but seen after importaddress + solvable_after_importaddress.extend([bare, p2sh]) + # P2WSH and P2SH(P2WSH) multisig with uncompressed keys are never seen + unseen_anytime.extend([p2wsh, p2sh_p2wsh]) + else: + [p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh] = self.p2pkh_address_to_script(v) + # normal P2PKH and P2PK with uncompressed keys should always be seen + solvable_anytime.extend([p2pkh, p2pk]) + # P2SH_P2PK, P2SH_P2PKH with uncompressed keys are seen after direct importaddress + solvable_after_importaddress.extend([p2sh_p2pk, p2sh_p2pkh]) + # witness with uncompressed keys are never seen + unseen_anytime.extend([p2wpkh, p2sh_p2wpkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh]) + + op1 = CScript([OP_1]) + op0 = CScript([OP_0]) + # 2N7MGY19ti4KDMSzRfPAssP6Pxyuxoi6jLe is the P2SH(P2PKH) version of mjoE3sSrb8ByYEvgnC3Aox86u1CHnfJA4V + unsolvable_address = ["mjoE3sSrb8ByYEvgnC3Aox86u1CHnfJA4V", "2N7MGY19ti4KDMSzRfPAssP6Pxyuxoi6jLe", script_to_p2sh(op1), script_to_p2sh(op0)] + unsolvable_address_key = hex_str_to_bytes("02341AEC7587A51CDE5279E0630A531AEA2615A9F80B17E8D9376327BAEAA59E3D") + unsolvablep2pkh = CScript([OP_DUP, OP_HASH160, hash160(unsolvable_address_key), OP_EQUALVERIFY, OP_CHECKSIG]) + unsolvablep2wshp2pkh = CScript([OP_0, sha256(unsolvablep2pkh)]) + p2shop0 = CScript([OP_HASH160, hash160(op0), OP_EQUAL]) + p2wshop1 = CScript([OP_0, sha256(op1)]) + unsolvable_after_importaddress.append(unsolvablep2pkh) + unsolvable_after_importaddress.append(unsolvablep2wshp2pkh) + unsolvable_after_importaddress.append(op1) # OP_1 will be imported as script + unsolvable_after_importaddress.append(p2wshop1) + unseen_anytime.append(op0) # OP_0 will be imported as P2SH address with no script provided + unsolvable_after_importaddress.append(p2shop0) + + spendable_txid = [] + solvable_txid = [] + spendable_txid.append(self.mine_and_test_listunspent(spendable_anytime, 2)) + solvable_txid.append(self.mine_and_test_listunspent(solvable_anytime, 1)) + self.mine_and_test_listunspent(spendable_after_importaddress + solvable_after_importaddress + unseen_anytime + unsolvable_after_importaddress, 0) + + importlist = [] + for i in compressed_spendable_address + uncompressed_spendable_address + compressed_solvable_address + uncompressed_solvable_address: + v = self.nodes[0].validateaddress(i) + if (v['isscript']): + bare = hex_str_to_bytes(v['hex']) + importlist.append(bytes_to_hex_str(bare)) + importlist.append(bytes_to_hex_str(CScript([OP_0, sha256(bare)]))) + else: + pubkey = hex_str_to_bytes(v['pubkey']) + p2pk = CScript([pubkey, OP_CHECKSIG]) + p2pkh = CScript([OP_DUP, OP_HASH160, hash160(pubkey), OP_EQUALVERIFY, OP_CHECKSIG]) + importlist.append(bytes_to_hex_str(p2pk)) + importlist.append(bytes_to_hex_str(p2pkh)) + importlist.append(bytes_to_hex_str(CScript([OP_0, hash160(pubkey)]))) + importlist.append(bytes_to_hex_str(CScript([OP_0, sha256(p2pk)]))) + importlist.append(bytes_to_hex_str(CScript([OP_0, sha256(p2pkh)]))) + + importlist.append(bytes_to_hex_str(unsolvablep2pkh)) + importlist.append(bytes_to_hex_str(unsolvablep2wshp2pkh)) + importlist.append(bytes_to_hex_str(op1)) + importlist.append(bytes_to_hex_str(p2wshop1)) + + for i in importlist: + try: + self.nodes[0].importaddress(i,"",False,True) + except JSONRPCException as exp: + assert_equal(exp.error["message"], "The wallet already contains the private key for this address or script") + + self.nodes[0].importaddress(script_to_p2sh(op0)) # import OP_0 as address only + self.nodes[0].importaddress(multisig_without_privkey_address) # Test multisig_without_privkey + + spendable_txid.append(self.mine_and_test_listunspent(spendable_anytime + spendable_after_importaddress, 2)) + solvable_txid.append(self.mine_and_test_listunspent(solvable_anytime + solvable_after_importaddress, 1)) + self.mine_and_test_listunspent(unsolvable_after_importaddress, 1) + self.mine_and_test_listunspent(unseen_anytime, 0) + + # addwitnessaddress should refuse to return a witness address if an uncompressed key is used or the address is + # not in the wallet + # note that no witness address should be returned by unsolvable addresses + # the multisig_without_privkey_address will fail because its keys were not added with importpubkey + for i in uncompressed_spendable_address + uncompressed_solvable_address + unknown_address + unsolvable_address + [multisig_without_privkey_address]: + try: + self.nodes[0].addwitnessaddress(i) + except JSONRPCException as exp: + assert_equal(exp.error["message"], "Public key or redeemscript not known to wallet, or the key is uncompressed") + else: + assert(False) + + for i in compressed_spendable_address + compressed_solvable_address: + witaddress = self.nodes[0].addwitnessaddress(i) + # addwitnessaddress should return the same address if it is a known P2SH-witness address + assert_equal(witaddress, self.nodes[0].addwitnessaddress(witaddress)) + + spendable_txid.append(self.mine_and_test_listunspent(spendable_anytime + spendable_after_importaddress, 2)) + solvable_txid.append(self.mine_and_test_listunspent(solvable_anytime + solvable_after_importaddress, 1)) + self.mine_and_test_listunspent(unsolvable_after_importaddress, 1) + self.mine_and_test_listunspent(unseen_anytime, 0) + + # Repeat some tests. This time we don't add witness scripts with importaddress + # Import a compressed key and an uncompressed key, generate some multisig addresses + self.nodes[0].importprivkey("927pw6RW8ZekycnXqBQ2JS5nPyo1yRfGNN8oq74HeddWSpafDJH") + uncompressed_spendable_address = ["mguN2vNSCEUh6rJaXoAVwY3YZwZvEmf5xi"] + self.nodes[0].importprivkey("cMcrXaaUC48ZKpcyydfFo8PxHAjpsYLhdsp6nmtB3E2ER9UUHWnw") + compressed_spendable_address = ["n1UNmpmbVUJ9ytXYXiurmGPQ3TRrXqPWKL"] + + self.nodes[0].importpubkey(pubkeys[5]) + compressed_solvable_address = [key_to_p2pkh(pubkeys[5])] + self.nodes[0].importpubkey(pubkeys[6]) + uncompressed_solvable_address = [key_to_p2pkh(pubkeys[6])] + + spendable_after_addwitnessaddress = [] # These outputs should be seen after importaddress + solvable_after_addwitnessaddress=[] # These outputs should be seen after importaddress but not spendable + unseen_anytime = [] # These outputs should never be seen + + uncompressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [uncompressed_spendable_address[0], compressed_spendable_address[0]])) + uncompressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [uncompressed_spendable_address[0], uncompressed_spendable_address[0]])) + compressed_spendable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_spendable_address[0], compressed_spendable_address[0]])) + uncompressed_solvable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_solvable_address[0], uncompressed_solvable_address[0]])) + compressed_solvable_address.append(self.nodes[0].addmultisigaddress(2, [compressed_spendable_address[0], compressed_solvable_address[0]])) + + premature_witaddress = [] + + for i in compressed_spendable_address: + v = self.nodes[0].validateaddress(i) + if (v['isscript']): + [bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v) + # P2WSH and P2SH(P2WSH) multisig with compressed keys are spendable after addwitnessaddress + spendable_after_addwitnessaddress.extend([p2wsh, p2sh_p2wsh]) + premature_witaddress.append(script_to_p2sh(p2wsh)) + else: + [p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh] = self.p2pkh_address_to_script(v) + # P2WPKH, P2SH_P2WPKH are spendable after addwitnessaddress + spendable_after_addwitnessaddress.extend([p2wpkh, p2sh_p2wpkh]) + premature_witaddress.append(script_to_p2sh(p2wpkh)) + + for i in uncompressed_spendable_address + uncompressed_solvable_address: + v = self.nodes[0].validateaddress(i) + if (v['isscript']): + [bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v) + # P2WSH and P2SH(P2WSH) multisig with uncompressed keys are never seen + unseen_anytime.extend([p2wsh, p2sh_p2wsh]) + else: + [p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh] = self.p2pkh_address_to_script(v) + # P2WPKH, P2SH_P2WPKH with uncompressed keys are never seen + unseen_anytime.extend([p2wpkh, p2sh_p2wpkh]) + + for i in compressed_solvable_address: + v = self.nodes[0].validateaddress(i) + if (v['isscript']): + # P2WSH multisig without private key are seen after addwitnessaddress + [bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v) + solvable_after_addwitnessaddress.extend([p2wsh, p2sh_p2wsh]) + premature_witaddress.append(script_to_p2sh(p2wsh)) + else: + [p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh] = self.p2pkh_address_to_script(v) + # P2SH_P2PK, P2SH_P2PKH with compressed keys are seen after addwitnessaddress + solvable_after_addwitnessaddress.extend([p2wpkh, p2sh_p2wpkh]) + premature_witaddress.append(script_to_p2sh(p2wpkh)) + + self.mine_and_test_listunspent(spendable_after_addwitnessaddress + solvable_after_addwitnessaddress + unseen_anytime, 0) + + # addwitnessaddress should refuse to return a witness address if an uncompressed key is used + # note that a multisig address returned by addmultisigaddress is not solvable until it is added with importaddress + # premature_witaddress are not accepted until the script is added with addwitnessaddress first + for i in uncompressed_spendable_address + uncompressed_solvable_address + premature_witaddress + [compressed_solvable_address[1]]: + try: + self.nodes[0].addwitnessaddress(i) + except JSONRPCException as exp: + assert_equal(exp.error["message"], "Public key or redeemscript not known to wallet, or the key is uncompressed") + else: + assert(False) + + # after importaddress it should pass addwitnessaddress + v = self.nodes[0].validateaddress(compressed_solvable_address[1]) + self.nodes[0].importaddress(v['hex'],"",False,True) + for i in compressed_spendable_address + compressed_solvable_address + premature_witaddress: + witaddress = self.nodes[0].addwitnessaddress(i) + assert_equal(witaddress, self.nodes[0].addwitnessaddress(witaddress)) + + spendable_txid.append(self.mine_and_test_listunspent(spendable_after_addwitnessaddress, 2)) + solvable_txid.append(self.mine_and_test_listunspent(solvable_after_addwitnessaddress, 1)) + self.mine_and_test_listunspent(unseen_anytime, 0) + + # Check that spendable outputs are really spendable + self.create_and_mine_tx_from_txids(spendable_txid) + + # import all the private keys so solvable addresses become spendable + self.nodes[0].importprivkey("cPiM8Ub4heR9NBYmgVzJQiUH1if44GSBGiqaeJySuL2BKxubvgwb") + self.nodes[0].importprivkey("cPpAdHaD6VoYbW78kveN2bsvb45Q7G5PhaPApVUGwvF8VQ9brD97") + self.nodes[0].importprivkey("91zqCU5B9sdWxzMt1ca3VzbtVm2YM6Hi5Rxn4UDtxEaN9C9nzXV") + self.nodes[0].importprivkey("cPQFjcVRpAUBG8BA9hzr2yEzHwKoMgLkJZBBtK9vJnvGJgMjzTbd") + self.nodes[0].importprivkey("cQGtcm34xiLjB1v7bkRa4V3aAc9tS2UTuBZ1UnZGeSeNy627fN66") + self.nodes[0].importprivkey("cTW5mR5M45vHxXkeChZdtSPozrFwFgmEvTNnanCW6wrqwaCZ1X7K") + self.create_and_mine_tx_from_txids(solvable_txid) + + def mine_and_test_listunspent(self, script_list, ismine): + utxo = find_unspent(self.nodes[0], 50) + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(int('0x'+utxo['txid'],0), utxo['vout']))) + for i in script_list: + tx.vout.append(CTxOut(10000000, i)) + tx.rehash() + signresults = self.nodes[0].signrawtransaction(bytes_to_hex_str(tx.serialize_without_witness()))['hex'] + txid = self.nodes[0].sendrawtransaction(signresults, True) + self.nodes[0].generate(1) + sync_blocks(self.nodes) + watchcount = 0 + spendcount = 0 + for i in self.nodes[0].listunspent(): + if (i['txid'] == txid): + watchcount += 1 + if (i['spendable'] == True): + spendcount += 1 + if (ismine == 2): + assert_equal(spendcount, len(script_list)) + elif (ismine == 1): + assert_equal(watchcount, len(script_list)) + assert_equal(spendcount, 0) + else: + assert_equal(watchcount, 0) + return txid + + def p2sh_address_to_script(self,v): + bare = CScript(hex_str_to_bytes(v['hex'])) + p2sh = CScript(hex_str_to_bytes(v['scriptPubKey'])) + p2wsh = CScript([OP_0, sha256(bare)]) + p2sh_p2wsh = CScript([OP_HASH160, hash160(p2wsh), OP_EQUAL]) + return([bare, p2sh, p2wsh, p2sh_p2wsh]) + + def p2pkh_address_to_script(self,v): + pubkey = hex_str_to_bytes(v['pubkey']) + p2wpkh = CScript([OP_0, hash160(pubkey)]) + p2sh_p2wpkh = CScript([OP_HASH160, hash160(p2wpkh), OP_EQUAL]) + p2pk = CScript([pubkey, OP_CHECKSIG]) + p2pkh = CScript(hex_str_to_bytes(v['scriptPubKey'])) + p2sh_p2pk = CScript([OP_HASH160, hash160(p2pk), OP_EQUAL]) + p2sh_p2pkh = CScript([OP_HASH160, hash160(p2pkh), OP_EQUAL]) + p2wsh_p2pk = CScript([OP_0, sha256(p2pk)]) + p2wsh_p2pkh = CScript([OP_0, sha256(p2pkh)]) + p2sh_p2wsh_p2pk = CScript([OP_HASH160, hash160(p2wsh_p2pk), OP_EQUAL]) + p2sh_p2wsh_p2pkh = CScript([OP_HASH160, hash160(p2wsh_p2pkh), OP_EQUAL]) + return [p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh] + + def create_and_mine_tx_from_txids(self, txids, success = True): + tx = CTransaction() + for i in txids: + txtmp = CTransaction() + txraw = self.nodes[0].getrawtransaction(i) + f = BytesIO(hex_str_to_bytes(txraw)) + txtmp.deserialize(f) + for j in range(len(txtmp.vout)): + tx.vin.append(CTxIn(COutPoint(int('0x'+i,0), j))) + tx.vout.append(CTxOut(0, CScript())) + tx.rehash() + signresults = self.nodes[0].signrawtransaction(bytes_to_hex_str(tx.serialize_without_witness()))['hex'] + self.nodes[0].sendrawtransaction(signresults, True) + self.nodes[0].generate(1) + sync_blocks(self.nodes) + + if __name__ == '__main__': SegWitTest().main() diff --git a/qa/rpc-tests/sendheaders.py b/qa/rpc-tests/sendheaders.py index c3f3180b6bc..81b2442e6ae 100755 --- a/qa/rpc-tests/sendheaders.py +++ b/qa/rpc-tests/sendheaders.py @@ -80,20 +80,19 @@ Expect: disconnect. ''' -class BaseNode(NodeConnCB): +direct_fetch_response_time = 0.05 + +class BaseNode(SingleNodeConnCB): def __init__(self): - NodeConnCB.__init__(self) - self.connection = None + SingleNodeConnCB.__init__(self) self.last_inv = None self.last_headers = None self.last_block = None - self.ping_counter = 1 - self.last_pong = msg_pong(0) self.last_getdata = None - self.sleep_time = 0.05 self.block_announced = False self.last_getheaders = None self.disconnected = False + self.last_blockhash_announced = None def clear_last_announcement(self): with mininode_lock: @@ -101,9 +100,6 @@ def clear_last_announcement(self): self.last_inv = None self.last_headers = None - def add_connection(self, conn): - self.connection = conn - # Request data for a list of block hashes def get_data(self, block_hashes): msg = msg_getdata() @@ -122,17 +118,17 @@ def send_block_inv(self, blockhash): msg.inv = [CInv(2, blockhash)] self.connection.send_message(msg) - # Wrapper for the NodeConn's send_message function - def send_message(self, message): - self.connection.send_message(message) - def on_inv(self, conn, message): self.last_inv = message self.block_announced = True + self.last_blockhash_announced = message.inv[-1].hash def on_headers(self, conn, message): self.last_headers = message - self.block_announced = True + if len(message.headers): + self.block_announced = True + message.headers[-1].calc_sha256() + self.last_blockhash_announced = message.headers[-1].sha256 def on_block(self, conn, message): self.last_block = message.block @@ -141,9 +137,6 @@ def on_block(self, conn, message): def on_getdata(self, conn, message): self.last_getdata = message - def on_pong(self, conn, message): - self.last_pong = message - def on_getheaders(self, conn, message): self.last_getheaders = message @@ -157,7 +150,7 @@ def check_last_announcement(self, headers=None, inv=None): expect_headers = headers if headers != None else [] expect_inv = inv if inv != None else [] test_function = lambda: self.block_announced - self.sync(test_function) + assert(wait_until(test_function, timeout=60)) with mininode_lock: self.block_announced = False @@ -180,30 +173,14 @@ def check_last_announcement(self, headers=None, inv=None): return success # Syncing helpers - def sync(self, test_function, timeout=60): - while timeout > 0: - with mininode_lock: - if test_function(): - return - time.sleep(self.sleep_time) - timeout -= self.sleep_time - raise AssertionError("Sync failed to complete") - - def sync_with_ping(self, timeout=60): - self.send_message(msg_ping(nonce=self.ping_counter)) - test_function = lambda: self.last_pong.nonce == self.ping_counter - self.sync(test_function, timeout) - self.ping_counter += 1 - return - def wait_for_block(self, blockhash, timeout=60): test_function = lambda: self.last_block != None and self.last_block.sha256 == blockhash - self.sync(test_function, timeout) + assert(wait_until(test_function, timeout=timeout)) return def wait_for_getheaders(self, timeout=60): test_function = lambda: self.last_getheaders != None - self.sync(test_function, timeout) + assert(wait_until(test_function, timeout=timeout)) return def wait_for_getdata(self, hash_list, timeout=60): @@ -211,12 +188,17 @@ def wait_for_getdata(self, hash_list, timeout=60): return test_function = lambda: self.last_getdata != None and [x.hash for x in self.last_getdata.inv] == hash_list - self.sync(test_function, timeout) + assert(wait_until(test_function, timeout=timeout)) return def wait_for_disconnect(self, timeout=60): test_function = lambda: self.disconnected - self.sync(test_function, timeout) + assert(wait_until(test_function, timeout=timeout)) + return + + def wait_for_block_announcement(self, block_hash, timeout=60): + test_function = lambda: self.last_blockhash_announced == block_hash + assert(wait_until(test_function, timeout=timeout)) return def send_header_for_blocks(self, new_blocks): @@ -266,7 +248,9 @@ def mine_blocks(self, count): def mine_reorg(self, length): self.nodes[0].generate(length) # make sure all invalidated blocks are node0's sync_blocks(self.nodes, wait=0.1) - [x.clear_last_announcement() for x in self.p2p_connections] + for x in self.p2p_connections: + x.wait_for_block_announcement(int(self.nodes[0].getbestblockhash(), 16)) + x.clear_last_announcement() tip_height = self.nodes[1].getblockcount() hash_to_invalidate = self.nodes[1].getblockhash(tip_height-(length-1)) @@ -495,7 +479,7 @@ def run_test(self): test_node.send_header_for_blocks(blocks) test_node.sync_with_ping() - test_node.wait_for_getdata([x.sha256 for x in blocks], timeout=test_node.sleep_time) + test_node.wait_for_getdata([x.sha256 for x in blocks], timeout=direct_fetch_response_time) [ test_node.send_message(msg_block(x)) for x in blocks ] @@ -526,13 +510,13 @@ def run_test(self): # both blocks (same work as tip) test_node.send_header_for_blocks(blocks[1:2]) test_node.sync_with_ping() - test_node.wait_for_getdata([x.sha256 for x in blocks[0:2]], timeout=test_node.sleep_time) + test_node.wait_for_getdata([x.sha256 for x in blocks[0:2]], timeout=direct_fetch_response_time) # Announcing 16 more headers should trigger direct fetch for 14 more # blocks test_node.send_header_for_blocks(blocks[2:18]) test_node.sync_with_ping() - test_node.wait_for_getdata([x.sha256 for x in blocks[2:16]], timeout=test_node.sleep_time) + test_node.wait_for_getdata([x.sha256 for x in blocks[2:16]], timeout=direct_fetch_response_time) # Announcing 1 more header should not trigger any response test_node.last_getdata = None diff --git a/qa/rpc-tests/test_framework/address.py b/qa/rpc-tests/test_framework/address.py new file mode 100644 index 00000000000..50b999be611 --- /dev/null +++ b/qa/rpc-tests/test_framework/address.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# address.py +# +# This file encodes and decodes BASE58 P2PKH and P2SH addresses +# + +from .script import hash256, hash160, sha256, CScript, OP_0 +from .util import bytes_to_hex_str, hex_str_to_bytes + +chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' + +def byte_to_base58(b, version): + result = '' + str = bytes_to_hex_str(b) + str = bytes_to_hex_str(chr(version).encode('latin-1')) + str + checksum = bytes_to_hex_str(hash256(hex_str_to_bytes(str))) + str += checksum[:8] + value = int('0x'+str,0) + while value > 0: + result = chars[value % 58] + result + value //= 58 + while (str[:2] == '00'): + result = chars[0] + result + str = str[2:] + return result + +# TODO: def base58_decode + +def keyhash_to_p2pkh(hash, main = False): + assert (len(hash) == 20) + version = 0 if main else 111 + return byte_to_base58(hash, version) + +def scripthash_to_p2sh(hash, main = False): + assert (len(hash) == 20) + version = 5 if main else 196 + return byte_to_base58(hash, version) + +def key_to_p2pkh(key, main = False): + key = check_key(key) + return keyhash_to_p2pkh(hash160(key), main) + +def script_to_p2sh(script, main = False): + script = check_script(script) + return scripthash_to_p2sh(hash160(script), main) + +def key_to_p2sh_p2wpkh(key, main = False): + key = check_key(key) + p2shscript = CScript([OP_0, hash160(key)]) + return script_to_p2sh(p2shscript, main) + +def script_to_p2sh_p2wsh(script, main = False): + script = check_script(script) + p2shscript = CScript([OP_0, sha256(script)]) + return script_to_p2sh(p2shscript, main) + +def check_key(key): + if (type(key) is str): + key = hex_str_to_bytes(key) # Assuming this is hex string + if (type(key) is bytes and (len(key) == 33 or len(key) == 65)): + return key + assert(False) + +def check_script(script): + if (type(script) is str): + script = hex_str_to_bytes(script) # Assuming this is hex string + if (type(script) is bytes or type(script) is CScript): + return script + assert(False) diff --git a/qa/rpc-tests/test_framework/authproxy.py b/qa/rpc-tests/test_framework/authproxy.py index d095a56ce75..7b051545c85 100644 --- a/qa/rpc-tests/test_framework/authproxy.py +++ b/qa/rpc-tests/test_framework/authproxy.py @@ -42,6 +42,7 @@ import decimal import json import logging +import socket try: import urllib.parse as urlparse except ImportError: @@ -126,8 +127,9 @@ def _request(self, method, path, postdata): return self._get_response() else: raise - except BrokenPipeError: - # Python 3.5+ raises this instead of BadStatusLine when the connection was reset + except (BrokenPipeError,ConnectionResetError): + # Python 3.5+ raises BrokenPipeError instead of BadStatusLine when the connection was reset + # ConnectionResetError happens on FreeBSD with Python 3.4 self.__conn.close() self.__conn.request(method, path, postdata, headers) return self._get_response() @@ -156,7 +158,15 @@ def _batch(self, rpc_call_list): return self._request('POST', self.__url.path, postdata.encode('utf-8')) def _get_response(self): - http_response = self.__conn.getresponse() + try: + http_response = self.__conn.getresponse() + except socket.timeout as e: + raise JSONRPCException({ + 'code': -344, + 'message': '%r RPC took longer than %f seconds. Consider ' + 'using larger timeout for calls that take ' + 'longer to return.' % (self._service_name, + self.__conn.timeout)}) if http_response is None: raise JSONRPCException({ 'code': -342, 'message': 'missing HTTP response from server'}) diff --git a/qa/rpc-tests/test_framework/blockstore.py b/qa/rpc-tests/test_framework/blockstore.py index 6120dd574b5..28a6b92b819 100644 --- a/qa/rpc-tests/test_framework/blockstore.py +++ b/qa/rpc-tests/test_framework/blockstore.py @@ -1,4 +1,7 @@ #!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. # BlockStore: a helper class that keeps a map of blocks and implements # helper functions for responding to getheaders and getdata, # and for constructing a getheaders message @@ -6,11 +9,11 @@ from .mininode import * from io import BytesIO -import dbm.ndbm +import dbm.dumb as dbmd class BlockStore(object): def __init__(self, datadir): - self.blockDB = dbm.ndbm.open(datadir + "/blocks", 'c') + self.blockDB = dbmd.open(datadir + "/blocks", 'c') self.currentBlock = 0 self.headers_map = dict() @@ -120,7 +123,7 @@ def get_locator(self, current_tip=None): class TxStore(object): def __init__(self, datadir): - self.txDB = dbm.ndbm.open(datadir + "/transactions", 'c') + self.txDB = dbmd.open(datadir + "/transactions", 'c') def close(self): self.txDB.close() diff --git a/qa/rpc-tests/test_framework/coverage.py b/qa/rpc-tests/test_framework/coverage.py index 23fce610140..13b33869f54 100644 --- a/qa/rpc-tests/test_framework/coverage.py +++ b/qa/rpc-tests/test_framework/coverage.py @@ -50,7 +50,7 @@ def __call__(self, *args, **kwargs): rpc_method = self.auth_service_proxy_instance._service_name if self.coverage_logfile: - with open(self.coverage_logfile, 'a+') as f: + with open(self.coverage_logfile, 'a+', encoding='utf8') as f: f.write("%s\n" % rpc_method) return return_val @@ -100,7 +100,7 @@ def write_all_rpc_commands(dirname, node): if line and not line.startswith('='): commands.add("%s\n" % line.split()[0]) - with open(filename, 'w') as f: + with open(filename, 'w', encoding='utf8') as f: f.writelines(list(commands)) return True diff --git a/qa/rpc-tests/test_framework/key.py b/qa/rpc-tests/test_framework/key.py index ba3038fe044..c63a15c1e0c 100644 --- a/qa/rpc-tests/test_framework/key.py +++ b/qa/rpc-tests/test_framework/key.py @@ -75,6 +75,9 @@ # this specifies the curve used with ECDSA. NID_secp256k1 = 714 # from openssl/obj_mac.h +SECP256K1_ORDER = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 +SECP256K1_ORDER_HALF = SECP256K1_ORDER // 2 + # Thx to Sam Devlin for the ctypes magic 64-bit fix. def _check_result(val, func, args): if val == 0: @@ -147,7 +150,7 @@ def get_ecdh_key(self, other_pubkey, kdf=lambda k: hashlib.sha256(k).digest()): r = self.get_raw_ecdh_key(other_pubkey) return kdf(r) - def sign(self, hash): + def sign(self, hash, low_s = True): # FIXME: need unit tests for below cases if not isinstance(hash, bytes): raise TypeError('Hash must be bytes instance; got %r' % hash.__class__) @@ -159,7 +162,25 @@ def sign(self, hash): 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] + assert mb_sig.raw[0] == 0x30 + assert mb_sig.raw[1] == sig_size0.value - 2 + total_size = mb_sig.raw[1] + assert mb_sig.raw[2] == 2 + r_size = mb_sig.raw[3] + assert mb_sig.raw[4 + r_size] == 2 + s_size = mb_sig.raw[5 + r_size] + s_value = int.from_bytes(mb_sig.raw[6+r_size:6+r_size+s_size], byteorder='big') + if (not low_s) or s_value <= SECP256K1_ORDER_HALF: + return mb_sig.raw[:sig_size0.value] + else: + low_s_value = SECP256K1_ORDER - s_value + low_s_bytes = (low_s_value).to_bytes(33, byteorder='big') + while len(low_s_bytes) > 1 and low_s_bytes[0] == 0 and low_s_bytes[1] < 0x80: + low_s_bytes = low_s_bytes[1:] + new_s_size = len(low_s_bytes) + new_total_size_byte = (total_size + new_s_size - s_size).to_bytes(1,byteorder='big') + new_s_size_byte = (new_s_size).to_bytes(1,byteorder='big') + return b'\x30' + new_total_size_byte + mb_sig.raw[2:5+r_size] + new_s_size_byte + low_s_bytes def verify(self, hash, sig): """Verify a DER signature""" diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index cdd5292cd67..4d238c08d9c 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -36,9 +36,10 @@ from threading import Thread import logging import copy +from test_framework.siphash import siphash256 BIP0031_VERSION = 60000 -MY_VERSION = 60001 # past bip-31 for ping/pong +MY_VERSION = 70014 # past bip-31 for ping/pong MY_SUBVERSION = b"/python-mininode-tester:0.0.3/" MAX_INV_SZ = 50000 @@ -52,7 +53,7 @@ NODE_WITNESS = (1 << 3) # Keep our own socket map for asyncore, so that we can track disconnects -# ourselves (to workaround an issue with closing an asyncore socket when +# ourselves (to workaround an issue with closing an asyncore socket when # using select) mininode_socket_map = dict() @@ -74,8 +75,19 @@ def ripemd160(s): def hash256(s): return sha256(sha256(s)) +def ser_compact_size(l): + r = b"" + if l < 253: + r = struct.pack("B", l) + elif l < 0x10000: + r = struct.pack("> (64 - b) | (n & ((1 << (64 - b)) - 1)) << b + +def siphash_round(v0, v1, v2, v3): + v0 = (v0 + v1) & ((1 << 64) - 1) + v1 = rotl64(v1, 13) + v1 ^= v0 + v0 = rotl64(v0, 32) + v2 = (v2 + v3) & ((1 << 64) - 1) + v3 = rotl64(v3, 16) + v3 ^= v2 + v0 = (v0 + v3) & ((1 << 64) - 1) + v3 = rotl64(v3, 21) + v3 ^= v0 + v2 = (v2 + v1) & ((1 << 64) - 1) + v1 = rotl64(v1, 17) + v1 ^= v2 + v2 = rotl64(v2, 32) + return (v0, v1, v2, v3) + +def siphash256(k0, k1, h): + n0 = h & ((1 << 64) - 1) + n1 = (h >> 64) & ((1 << 64) - 1) + n2 = (h >> 128) & ((1 << 64) - 1) + n3 = (h >> 192) & ((1 << 64) - 1) + v0 = 0x736f6d6570736575 ^ k0 + v1 = 0x646f72616e646f6d ^ k1 + v2 = 0x6c7967656e657261 ^ k0 + v3 = 0x7465646279746573 ^ k1 ^ n0 + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0 ^= n0 + v3 ^= n1 + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0 ^= n1 + v3 ^= n2 + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0 ^= n2 + v3 ^= n3 + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0 ^= n3 + v3 ^= 0x2000000000000000 + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0 ^= 0x2000000000000000 + v2 ^= 0xFF + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3) + return v0 ^ v1 ^ v2 ^ v3 diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index 0dfece6b277..bb624301cfb 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -21,7 +21,6 @@ sync_mempools, stop_nodes, stop_node, - wait_bitcoinds, enable_coverage, check_json_precision, initialize_chain_clean, @@ -81,7 +80,6 @@ def split_network(self): """ assert not self.is_network_split stop_nodes(self.nodes) - wait_bitcoinds() self.setup_network(True) def sync_all(self): @@ -100,7 +98,6 @@ def join_network(self): """ assert self.is_network_split stop_nodes(self.nodes) - wait_bitcoinds() self.setup_network(False) def main(self): @@ -123,7 +120,8 @@ def main(self): self.add_options(parser) (self.options, self.args) = parser.parse_args() - self.options.tmpdir += '/' + str(self.options.port_seed) + # backup dir variable for removal at cleanup + self.options.root, self.options.tmpdir = self.options.tmpdir, self.options.tmpdir + '/' + str(self.options.port_seed) if self.options.trace_rpc: logging.basicConfig(level=logging.DEBUG, stream=sys.stdout) @@ -139,16 +137,11 @@ def main(self): success = False try: - if not os.path.isdir(self.options.tmpdir): - os.makedirs(self.options.tmpdir) + os.makedirs(self.options.tmpdir, exist_ok=False) self.setup_chain() - self.setup_network() - self.run_test() - success = True - except JSONRPCException as e: print("JSONRPC error: "+e.error['message']) traceback.print_tb(sys.exc_info()[2]) @@ -167,13 +160,14 @@ def main(self): if not self.options.noshutdown: print("Stopping nodes") stop_nodes(self.nodes) - wait_bitcoinds() else: print("Note: bitcoinds were not stopped and may still be running") if not self.options.nocleanup and not self.options.noshutdown and success: print("Cleaning up") shutil.rmtree(self.options.tmpdir) + if not os.listdir(self.options.root): + os.rmdir(self.options.root) else: print("Not cleaning up dir %s" % self.options.tmpdir) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 32fe79efc38..bf3f2b2db16 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -157,7 +157,7 @@ def initialize_datadir(dirname, n): if not os.path.isdir(datadir): os.makedirs(datadir) rpc_u, rpc_p = rpc_auth_pair(n) - with open(os.path.join(datadir, "bitcoin.conf"), 'w') as f: + with open(os.path.join(datadir, "bitcoin.conf"), 'w', encoding='utf8') as f: f.write("regtest=1\n") f.write("rpcuser=" + rpc_u + "\n") f.write("rpcpassword=" + rpc_p + "\n") @@ -171,7 +171,15 @@ def rpc_auth_pair(n): def rpc_url(i, rpchost=None): rpc_u, rpc_p = rpc_auth_pair(i) - return "http://%s:%s@%s:%d" % (rpc_u, rpc_p, rpchost or '127.0.0.1', rpc_port(i)) + host = '127.0.0.1' + port = rpc_port(i) + if rpchost: + parts = rpchost.split(':') + if len(parts) == 2: + host, port = parts + else: + host = rpchost + return "http://%s:%s@%s:%d" % (rpc_u, rpc_p, host, int(port)) def wait_for_bitcoind_start(process, url, i): ''' @@ -254,7 +262,6 @@ def initialize_chain(test_dir, num_nodes): # Shut them down, and clean up cache directories: stop_nodes(rpcs) - wait_bitcoinds() disable_mocktime() for i in range(MAX_NODES): os.remove(log_filename("cache", i, "debug.log")) @@ -320,7 +327,7 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary= return proxy -def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, binary=None): +def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, timewait=None, binary=None): """ Start multiple bitcoinds, return RPC connections to them """ @@ -329,7 +336,7 @@ def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, binary=None): rpcs = [] try: for i in range(num_nodes): - rpcs.append(start_node(i, dirname, extra_args[i], rpchost, binary=binary[i])) + rpcs.append(start_node(i, dirname, extra_args[i], rpchost, timewait=timewait, binary=binary[i])) except: # If one node failed to start, stop the others stop_nodes(rpcs) raise @@ -353,6 +360,7 @@ def stop_nodes(nodes): except http.client.CannotSendRequest as e: print("WARN: Unable to stop node: " + repr(e)) del nodes[:] # Emptying array closes connections as a side effect + wait_bitcoinds() def set_node_times(nodes, t): for node in nodes: @@ -500,10 +508,14 @@ def assert_greater_than(thing1, thing2): raise AssertionError("%s <= %s"%(str(thing1),str(thing2))) def assert_raises(exc, fun, *args, **kwds): + assert_raises_message(exc, None, fun, *args, **kwds) + +def assert_raises_message(exc, message, fun, *args, **kwds): try: fun(*args, **kwds) - except exc: - pass + except exc as e: + if message is not None and message not in e.error['message']: + raise AssertionError("Expected substring not found:"+e.error['message']) except Exception as e: raise AssertionError("Unexpected exception raised: "+type(e).__name__) else: diff --git a/qa/rpc-tests/wallet-dump.py b/qa/rpc-tests/wallet-dump.py new file mode 100755 index 00000000000..c6dc2e3d107 --- /dev/null +++ b/qa/rpc-tests/wallet-dump.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import (start_nodes, start_node, assert_equal, bitcoind_processes) + + +def read_dump(file_name, addrs, hd_master_addr_old): + """ + Read the given dump, count the addrs that match, count change and reserve. + Also check that the old hd_master is inactive + """ + with open(file_name, encoding='utf8') as inputfile: + found_addr = 0 + found_addr_chg = 0 + found_addr_rsv = 0 + hd_master_addr_ret = None + for line in inputfile: + # only read non comment lines + if line[0] != "#" and len(line) > 10: + # split out some data + key_label, comment = line.split("#") + # key = key_label.split(" ")[0] + keytype = key_label.split(" ")[2] + if len(comment) > 1: + addr_keypath = comment.split(" addr=")[1] + addr = addr_keypath.split(" ")[0] + keypath = None + if keytype == "inactivehdmaster=1": + # ensure the old master is still available + assert(hd_master_addr_old == addr) + elif keytype == "hdmaster=1": + # ensure we have generated a new hd master key + assert(hd_master_addr_old != addr) + hd_master_addr_ret = addr + else: + keypath = addr_keypath.rstrip().split("hdkeypath=")[1] + + # count key types + for addrObj in addrs: + if addrObj['address'] == addr and addrObj['hdkeypath'] == keypath and keytype == "label=": + found_addr += 1 + break + elif keytype == "change=1": + found_addr_chg += 1 + break + elif keytype == "reserve=1": + found_addr_rsv += 1 + break + return found_addr, found_addr_chg, found_addr_rsv, hd_master_addr_ret + + +class WalletDumpTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.setup_clean_chain = False + self.num_nodes = 1 + self.extra_args = [["-keypool=90"]] + + def setup_network(self, split=False): + # Use 1 minute timeout because the initial getnewaddress RPC can take + # longer than the default 30 seconds due to an expensive + # CWallet::TopUpKeyPool call, and the encryptwallet RPC made later in + # the test often takes even longer. + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args, timewait=60) + + def run_test (self): + tmpdir = self.options.tmpdir + + # generate 20 addresses to compare against the dump + test_addr_count = 20 + addrs = [] + for i in range(0,test_addr_count): + addr = self.nodes[0].getnewaddress() + vaddr= self.nodes[0].validateaddress(addr) #required to get hd keypath + addrs.append(vaddr) + # Should be a no-op: + self.nodes[0].keypoolrefill() + + # dump unencrypted wallet + self.nodes[0].dumpwallet(tmpdir + "/node0/wallet.unencrypted.dump") + + found_addr, found_addr_chg, found_addr_rsv, hd_master_addr_unenc = \ + read_dump(tmpdir + "/node0/wallet.unencrypted.dump", addrs, None) + assert_equal(found_addr, test_addr_count) # all keys must be in the dump + assert_equal(found_addr_chg, 50) # 50 blocks where mined + assert_equal(found_addr_rsv, 90 + 1) # keypool size (TODO: fix off-by-one) + + #encrypt wallet, restart, unlock and dump + self.nodes[0].encryptwallet('test') + bitcoind_processes[0].wait() + self.nodes[0] = start_node(0, self.options.tmpdir, self.extra_args[0]) + self.nodes[0].walletpassphrase('test', 10) + # Should be a no-op: + self.nodes[0].keypoolrefill() + self.nodes[0].dumpwallet(tmpdir + "/node0/wallet.encrypted.dump") + + found_addr, found_addr_chg, found_addr_rsv, hd_master_addr_enc = \ + read_dump(tmpdir + "/node0/wallet.encrypted.dump", addrs, hd_master_addr_unenc) + assert_equal(found_addr, test_addr_count) + assert_equal(found_addr_chg, 90 + 1 + 50) # old reserve keys are marked as change now + assert_equal(found_addr_rsv, 90 + 1) # keypool size (TODO: fix off-by-one) + +if __name__ == '__main__': + WalletDumpTest().main () diff --git a/qa/rpc-tests/wallet-hd.py b/qa/rpc-tests/wallet-hd.py index c738ee2207e..a49d91f6f4f 100755 --- a/qa/rpc-tests/wallet-hd.py +++ b/qa/rpc-tests/wallet-hd.py @@ -31,7 +31,7 @@ def run_test (self): tmpdir = self.options.tmpdir # Make sure we use hd, keep masterkeyid - masterkeyid = self.nodes[1].getwalletinfo()['masterkeyid'] + masterkeyid = self.nodes[1].getwalletinfo()['hdmasterkeyid'] assert_equal(len(masterkeyid), 40) # Import a non-HD private key in the HD wallet @@ -39,8 +39,8 @@ def run_test (self): self.nodes[1].importprivkey(self.nodes[0].dumpprivkey(non_hd_add)) # This should be enough to keep the master key and the non-HD key - self.nodes[1].backupwallet(tmpdir + "hd.bak") - #self.nodes[1].dumpwallet(tmpdir + "hd.dump") + self.nodes[1].backupwallet(tmpdir + "/hd.bak") + #self.nodes[1].dumpwallet(tmpdir + "/hd.dump") # Derive some HD addresses and remember the last # Also send funds to each add @@ -63,7 +63,7 @@ def run_test (self): print("Restore backup ...") self.stop_node(1) os.remove(self.options.tmpdir + "/node1/regtest/wallet.dat") - shutil.copyfile(tmpdir + "hd.bak", tmpdir + "/node1/regtest/wallet.dat") + shutil.copyfile(tmpdir + "/hd.bak", tmpdir + "/node1/regtest/wallet.dat") self.nodes[1] = start_node(1, self.options.tmpdir, self.node_args[1]) #connect_nodes_bi(self.nodes, 0, 1) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 5d96e7a6e5b..992fb8a2d64 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -18,9 +18,10 @@ def __init__(self): super().__init__() self.setup_clean_chain = True self.num_nodes = 4 + self.extra_args = [['-usehd={:d}'.format(i%2==0)] for i in range(4)] def setup_network(self, split=False): - self.nodes = start_nodes(3, self.options.tmpdir) + self.nodes = start_nodes(3, self.options.tmpdir, self.extra_args[:3]) connect_nodes_bi(self.nodes,0,1) connect_nodes_bi(self.nodes,1,2) connect_nodes_bi(self.nodes,0,2) @@ -70,7 +71,7 @@ def run_test (self): unspent_0 = self.nodes[2].listunspent()[0] unspent_0 = {"txid": unspent_0["txid"], "vout": unspent_0["vout"]} self.nodes[2].lockunspent(False, [unspent_0]) - assert_raises(JSONRPCException, self.nodes[2].sendtoaddress, self.nodes[2].getnewaddress(), 20) + assert_raises_message(JSONRPCException, "Insufficient funds", self.nodes[2].sendtoaddress, self.nodes[2].getnewaddress(), 20) assert_equal([unspent_0], self.nodes[2].listlockunspent()) self.nodes[2].lockunspent(True, [unspent_0]) assert_equal(len(self.nodes[2].listlockunspent()), 0) @@ -154,7 +155,7 @@ def run_test (self): txid2 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1) sync_mempools(self.nodes) - self.nodes.append(start_node(3, self.options.tmpdir)) + self.nodes.append(start_node(3, self.options.tmpdir, self.extra_args[3])) connect_nodes_bi(self.nodes, 0, 3) sync_blocks(self.nodes) @@ -198,7 +199,6 @@ def run_test (self): #do some -walletbroadcast tests stop_nodes(self.nodes) - wait_bitcoinds() self.nodes = start_nodes(3, self.options.tmpdir, [["-walletbroadcast=0"],["-walletbroadcast=0"],["-walletbroadcast=0"]]) connect_nodes_bi(self.nodes,0,1) connect_nodes_bi(self.nodes,1,2) @@ -224,7 +224,6 @@ def run_test (self): #restart the nodes with -walletbroadcast=1 stop_nodes(self.nodes) - wait_bitcoinds() self.nodes = start_nodes(3, self.options.tmpdir) connect_nodes_bi(self.nodes,0,1) connect_nodes_bi(self.nodes,1,2) @@ -331,11 +330,12 @@ def run_test (self): # disabled until issue is fixed: https://github.com/bitcoin/bitcoin/issues/7463 # '-salvagewallet', ] + chainlimit = 6 for m in maintenance: print("check " + m) stop_nodes(self.nodes) - wait_bitcoinds() - self.nodes = start_nodes(3, self.options.tmpdir, [[m]] * 3) + # set lower ancestor limit for later + self.nodes = start_nodes(3, self.options.tmpdir, [[m, "-limitancestorcount="+str(chainlimit)]] * 3) while m == '-reindex' and [block_count] * 3 != [self.nodes[i].getblockcount() for i in range(3)]: # reindex will leave rpc warm up "early"; Wait for it to finish time.sleep(0.1) @@ -348,5 +348,26 @@ def run_test (self): assert_equal(coinbase_tx_1["transactions"][0]["blockhash"], blocks[1]) assert_equal(len(self.nodes[0].listsinceblock(blocks[1])["transactions"]), 0) + # ==Check that wallet prefers to use coins that don't exceed mempool limits ===== + + # Get all non-zero utxos together + chain_addrs = [self.nodes[0].getnewaddress(), self.nodes[0].getnewaddress()] + singletxid = self.nodes[0].sendtoaddress(chain_addrs[0], self.nodes[0].getbalance(), "", "", True) + self.nodes[0].generate(1) + node0_balance = self.nodes[0].getbalance() + # Split into two chains + rawtx = self.nodes[0].createrawtransaction([{"txid":singletxid, "vout":0}], {chain_addrs[0]:node0_balance/2-Decimal('0.01'), chain_addrs[1]:node0_balance/2-Decimal('0.01')}) + signedtx = self.nodes[0].signrawtransaction(rawtx) + singletxid = self.nodes[0].sendrawtransaction(signedtx["hex"]) + txids = [singletxid, singletxid] + self.nodes[0].generate(1) + + # Make a long chain of unconfirmed payments without hitting mempool limit + txid_list = [] + for i in range(chainlimit*2): + txid_list.append(self.nodes[0].sendtoaddress(chain_addrs[0], Decimal('0.0001'))) + assert_equal(self.nodes[0].getmempoolinfo()['size'], chainlimit*2) + assert_equal(len(txid_list), chainlimit*2) + if __name__ == '__main__': WalletTest().main() diff --git a/qa/rpc-tests/walletbackup.py b/qa/rpc-tests/walletbackup.py index b991d5c7618..e12cb10a50a 100755 --- a/qa/rpc-tests/walletbackup.py +++ b/qa/rpc-tests/walletbackup.py @@ -45,12 +45,12 @@ def __init__(self): super().__init__() self.setup_clean_chain = True self.num_nodes = 4 + # nodes 1, 2,3 are spenders, let's give them a keypool=100 + self.extra_args = [["-keypool=100"], ["-keypool=100"], ["-keypool=100"], []] # This mirrors how the network was setup in the bash test def setup_network(self, split=False): - # nodes 1, 2,3 are spenders, let's give them a keypool=100 - extra_args = [["-keypool=100"], ["-keypool=100"], ["-keypool=100"], []] - self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args) + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args) connect_nodes(self.nodes[0], 3) connect_nodes(self.nodes[1], 3) connect_nodes(self.nodes[2], 3) @@ -79,6 +79,7 @@ def do_one_round(self): # Must sync mempools before mining. sync_mempools(self.nodes) self.nodes[3].generate(1) + sync_blocks(self.nodes) # As above, this mirrors the original bash test. def start_three(self): diff --git a/share/genbuild.sh b/share/genbuild.sh index 1ef77d706f7..eecac4bd00b 100755 --- a/share/genbuild.sh +++ b/share/genbuild.sh @@ -1,4 +1,8 @@ #!/bin/sh +# Copyright (c) 2012-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + if [ $# -gt 1 ]; then cd "$2" fi diff --git a/share/qt/Info.plist.in b/share/qt/Info.plist.in index 6a34d64cd53..5ca6d9d015b 100644 --- a/share/qt/Info.plist.in +++ b/share/qt/Info.plist.in @@ -3,7 +3,7 @@ LSMinimumSystemVersion - 10.7.0 + 10.8.0 LSArchitecturePriority diff --git a/share/qt/extract_strings_qt.py b/share/qt/extract_strings_qt.py index 2ba8bb9b3ac..f0f6a4f4781 100755 --- a/share/qt/extract_strings_qt.py +++ b/share/qt/extract_strings_qt.py @@ -1,4 +1,7 @@ #!/usr/bin/python +# Copyright (c) 2012-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' Extract _("...") strings for translation and convert to Qt stringdefs so that they can be picked up by Qt linguist. diff --git a/src/Makefile.am b/src/Makefile.am index e3eaacdb4c9..1e033de9daf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,3 +1,7 @@ +# Copyright (c) 2013-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + DIST_SUBDIRS = secp256k1 univalue AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index 4067ceb3993..8c024a8c4ad 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -1,3 +1,7 @@ +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + bin_PROGRAMS += bench/bench_bitcoin BENCH_SRCDIR = bench BENCH_BINARY = bench/bench_bitcoin$(EXEEXT) diff --git a/src/Makefile.leveldb.include b/src/Makefile.leveldb.include index 4b3cd6364a2..d7346aa181d 100644 --- a/src/Makefile.leveldb.include +++ b/src/Makefile.leveldb.include @@ -1,3 +1,7 @@ +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + LIBLEVELDB_INT = leveldb/libleveldb.a LIBMEMENV_INT = leveldb/libmemenv.a diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 7730aba375c..8e6805d4aaf 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -1,3 +1,7 @@ +# Copyright (c) 2013-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + bin_PROGRAMS += qt/bitcoin-qt EXTRA_LIBRARIES += qt/libbitcoinqt.a @@ -7,8 +11,8 @@ QT_TS = \ qt/locale/bitcoin_af_ZA.ts \ qt/locale/bitcoin_ar.ts \ qt/locale/bitcoin_be_BY.ts \ - qt/locale/bitcoin_bg.ts \ qt/locale/bitcoin_bg_BG.ts \ + qt/locale/bitcoin_bg.ts \ qt/locale/bitcoin_ca_ES.ts \ qt/locale/bitcoin_ca.ts \ qt/locale/bitcoin_ca@valencia.ts \ @@ -60,6 +64,7 @@ QT_TS = \ qt/locale/bitcoin_mn.ts \ qt/locale/bitcoin_ms_MY.ts \ qt/locale/bitcoin_nb.ts \ + qt/locale/bitcoin_ne.ts \ qt/locale/bitcoin_nl.ts \ qt/locale/bitcoin_pam.ts \ qt/locale/bitcoin_pl.ts \ @@ -280,7 +285,7 @@ RES_ICONS = \ qt/res/icons/verify.png \ qt/res/icons/transaction_abandoned.png -BITCOIN_QT_CPP = \ +BITCOIN_QT_BASE_CPP = \ qt/bantablemodel.cpp \ qt/bitcoinaddressvalidator.cpp \ qt/bitcoinamountfield.cpp \ @@ -303,12 +308,9 @@ BITCOIN_QT_CPP = \ qt/trafficgraphwidget.cpp \ qt/utilitydialog.cpp -if TARGET_WINDOWS -BITCOIN_QT_CPP += qt/winshutdownmonitor.cpp -endif +BITCOIN_QT_WINDOWS_CPP = qt/winshutdownmonitor.cpp -if ENABLE_WALLET -BITCOIN_QT_CPP += \ +BITCOIN_QT_WALLET_CPP = \ qt/addressbookpage.cpp \ qt/addresstablemodel.cpp \ qt/askpassphrasedialog.cpp \ @@ -335,6 +337,13 @@ BITCOIN_QT_CPP += \ qt/walletmodel.cpp \ qt/walletmodeltransaction.cpp \ qt/walletview.cpp + +BITCOIN_QT_CPP = $(BITCOIN_QT_BASE_CPP) +if TARGET_WINDOWS +BITCOIN_QT_CPP += $(BITCOIN_QT_WINDOWS_CPP) +endif +if ENABLE_WALLET +BITCOIN_QT_CPP += $(BITCOIN_QT_WALLET_CPP) endif RES_IMAGES = @@ -403,7 +412,7 @@ $(srcdir)/qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wal @test -n $(XGETTEXT) || echo "xgettext is required for updating translations" $(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) PACKAGE_NAME="$(PACKAGE_NAME)" COPYRIGHT_HOLDERS="$(COPYRIGHT_HOLDERS)" COPYRIGHT_HOLDERS_SUBSTITUTION="$(COPYRIGHT_HOLDERS_SUBSTITUTION)" $(PYTHON) ../share/qt/extract_strings_qt.py $^ -translate: $(srcdir)/qt/bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM) +translate: $(srcdir)/qt/bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_BASE_CPP) $(BITCOIN_QT_WINDOWS_CPP) $(BITCOIN_QT_WALLET_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM) @test -n $(LUPDATE) || echo "lupdate is required for updating translations" $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(LUPDATE) $^ -locations relative -no-obsolete -ts $(srcdir)/qt/locale/bitcoin_en.ts diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index 813a343ffa3..22c5f6a0b3d 100644 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -1,13 +1,20 @@ +# Copyright (c) 2013-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + bin_PROGRAMS += qt/test/test_bitcoin-qt TESTS += qt/test/test_bitcoin-qt -TEST_QT_MOC_CPP = qt/test/moc_uritests.cpp +TEST_QT_MOC_CPP = \ + qt/test/moc_compattests.cpp \ + qt/test/moc_uritests.cpp if ENABLE_WALLET TEST_QT_MOC_CPP += qt/test/moc_paymentservertests.cpp endif TEST_QT_H = \ + qt/test/compattests.h \ qt/test/uritests.h \ qt/test/paymentrequestdata.h \ qt/test/paymentservertests.h @@ -16,6 +23,7 @@ qt_test_test_bitcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_ $(QT_INCLUDES) $(QT_TEST_INCLUDES) $(PROTOBUF_CFLAGS) qt_test_test_bitcoin_qt_SOURCES = \ + qt/test/compattests.cpp \ qt/test/test_main.cpp \ qt/test/uritests.cpp \ $(TEST_QT_H) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 27e7694748c..25656333229 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -1,3 +1,7 @@ +# Copyright (c) 2013-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + TESTS += test/test_bitcoin bin_PROGRAMS += test/test_bitcoin TEST_SRCDIR = test @@ -46,7 +50,7 @@ BITCOIN_TESTS =\ test/bip32_tests.cpp \ test/blockencodings_tests.cpp \ test/bloom_tests.cpp \ - test/Checkpoints_tests.cpp \ + test/bswap_tests.cpp \ test/coins_tests.cpp \ test/compress_tests.cpp \ test/crypto_tests.cpp \ diff --git a/src/bench/bench.cpp b/src/bench/bench.cpp index 227546a7a78..8942da8c74a 100644 --- a/src/bench/bench.cpp +++ b/src/bench/bench.cpp @@ -64,8 +64,11 @@ bool State::KeepRunning() return true; } if (elapsed*16 < maxElapsed) { - countMask = ((countMask<<1)|1) & ((1LL<<60)-1); - countMaskInv = 1./(countMask+1); + uint64_t newCountMask = ((countMask<<1)|1) & ((1LL<<60)-1); + if ((count & newCountMask)==0) { + countMask = newCountMask; + countMaskInv = 1./(countMask+1); + } } } lastTime = now; diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index a04101d3ed8..bf6f11a50d8 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -28,6 +28,7 @@ using namespace std; static const char DEFAULT_RPCCONNECT[] = "127.0.0.1"; static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900; +static const int CONTINUE_EXECUTION=-1; std::string HelpMessageCli() { @@ -67,7 +68,11 @@ class CConnectionFailed : public std::runtime_error }; -static bool AppInitRPC(int argc, char* argv[]) +// +// This function returns either one of EXIT_ codes when it's expected to stop the process or +// CONTINUE_EXECUTION when it's expected to continue further. +// +static int AppInitRPC(int argc, char* argv[]) { // // Parameters @@ -85,31 +90,35 @@ static bool AppInitRPC(int argc, char* argv[]) } fprintf(stdout, "%s", strUsage.c_str()); - return false; + if (argc < 2) { + fprintf(stderr, "Error: too few parameters\n"); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; } if (!boost::filesystem::is_directory(GetDataDir(false))) { fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str()); - return false; + return EXIT_FAILURE; } try { ReadConfigFile(mapArgs, mapMultiArgs); } catch (const std::exception& e) { fprintf(stderr,"Error reading configuration file: %s\n", e.what()); - return false; + return EXIT_FAILURE; } // Check for -testnet or -regtest parameter (BaseParams() calls are only valid after this clause) try { SelectBaseParams(ChainNameFromCommandLine()); } catch (const std::exception& e) { fprintf(stderr, "Error: %s\n", e.what()); - return false; + return EXIT_FAILURE; } if (GetBoolArg("-rpcssl", false)) { fprintf(stderr, "Error: SSL mode for RPC (-rpcssl) is no longer supported.\n"); - return false; + return EXIT_FAILURE; } - return true; + return CONTINUE_EXECUTION; } @@ -318,8 +327,9 @@ int main(int argc, char* argv[]) } try { - if(!AppInitRPC(argc, argv)) - return EXIT_FAILURE; + int ret = AppInitRPC(argc, argv); + if (ret != CONTINUE_EXECUTION) + return ret; } catch (const std::exception& e) { PrintExceptionContinue(&e, "AppInitRPC()"); diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 8e8ac47455c..c5ae33da88a 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -30,8 +30,13 @@ using namespace std; static bool fCreateBlank; static map registers; +static const int CONTINUE_EXECUTION=-1; -static bool AppInitRawTx(int argc, char* argv[]) +// +// This function returns either one of EXIT_ codes when it's expected to stop the process or +// CONTINUE_EXECUTION when it's expected to continue further. +// +static int AppInitRawTx(int argc, char* argv[]) { // // Parameters @@ -43,7 +48,7 @@ static bool AppInitRawTx(int argc, char* argv[]) SelectParams(ChainNameFromCommandLine()); } catch (const std::exception& e) { fprintf(stderr, "Error: %s\n", e.what()); - return false; + return EXIT_FAILURE; } fCreateBlank = GetBoolArg("-create", false); @@ -89,9 +94,13 @@ static bool AppInitRawTx(int argc, char* argv[]) strUsage += HelpMessageOpt("set=NAME:JSON-STRING", _("Set register NAME to given JSON-STRING")); fprintf(stdout, "%s", strUsage.c_str()); - return false; + if (argc < 2) { + fprintf(stderr, "Error: too few parameters\n"); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; } - return true; + return CONTINUE_EXECUTION; } static void RegisterSetJson(const string& key, const string& rawJson) @@ -164,7 +173,7 @@ static void RegisterLoad(const string& strInput) static void MutateTxVersion(CMutableTransaction& tx, const string& cmdVal) { int64_t newVersion = atoi64(cmdVal); - if (newVersion < 1 || newVersion > CTransaction::CURRENT_VERSION) + if (newVersion < 1 || newVersion > CTransaction::MAX_STANDARD_VERSION) throw runtime_error("Invalid TX version requested"); tx.nVersion = (int) newVersion; @@ -680,8 +689,9 @@ int main(int argc, char* argv[]) SetupEnvironment(); try { - if(!AppInitRawTx(argc, argv)) - return EXIT_FAILURE; + int ret = AppInitRawTx(argc, argv); + if (ret != CONTINUE_EXECUTION) + return ret; } catch (const std::exception& e) { PrintExceptionContinue(&e, "AppInitRawTx()"); diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 28bc374acc7..823b9ce5817 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -93,7 +93,7 @@ bool AppInit(int argc, char* argv[]) } fprintf(stdout, "%s", strUsage.c_str()); - return false; + return true; } try @@ -127,7 +127,7 @@ bool AppInit(int argc, char* argv[]) if (fCommandLine) { fprintf(stderr, "Error: There is no RPC client functionality in bitcoind anymore. Use the bitcoin-cli utility instead.\n"); - exit(1); + exit(EXIT_FAILURE); } #ifndef WIN32 fDaemon = GetBoolArg("-daemon", false); @@ -187,5 +187,5 @@ int main(int argc, char* argv[]) // Connect bitcoind signal handlers noui_connect(); - return (AppInit(argc, argv) ? 0 : 1); + return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp index 5c4c3bd2748..737102f1680 100644 --- a/src/blockencodings.cpp +++ b/src/blockencodings.cpp @@ -17,7 +17,7 @@ #define MIN_TRANSACTION_BASE_SIZE (::GetSerializeSize(CTransaction(), SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS)) -CBlockHeaderAndShortTxIDs::CBlockHeaderAndShortTxIDs(const CBlock& block) : +CBlockHeaderAndShortTxIDs::CBlockHeaderAndShortTxIDs(const CBlock& block, bool fUseWTXID) : nonce(GetRand(std::numeric_limits::max())), shorttxids(block.vtx.size() - 1), prefilledtxn(1), header(block) { FillShortTxIDSelector(); @@ -25,7 +25,7 @@ CBlockHeaderAndShortTxIDs::CBlockHeaderAndShortTxIDs(const CBlock& block) : prefilledtxn[0] = {0, block.vtx[0]}; for (size_t i = 1; i < block.vtx.size(); i++) { const CTransaction& tx = block.vtx[i]; - shorttxids[i - 1] = GetShortID(tx.GetHash()); + shorttxids[i - 1] = GetShortID(fUseWTXID ? tx.GetWitnessHash() : tx.GetHash()); } } @@ -75,7 +75,7 @@ ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c } prefilled_count = cmpctblock.prefilledtxn.size(); - // Calculate map of txids -> positions and check mempool to see what we have (or dont) + // Calculate map of txids -> positions and check mempool to see what we have (or don't) // Because well-formed cmpctblock messages will have a (relatively) uniform distribution // of short IDs, any highly-uneven distribution of elements can be safely treated as a // READ_STATUS_FAILED. @@ -167,7 +167,7 @@ ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector< // check its own merkle root and cache that check. if (state.CorruptionPossible()) return READ_STATUS_FAILED; // Possible Short ID collision - return READ_STATUS_INVALID; + return READ_STATUS_CHECKBLOCK_FAILED; } LogPrint("cmpctblock", "Successfully reconstructed block %s with %lu txn prefilled, %lu txn from mempool and %lu txn requested\n", header.GetHash().ToString(), prefilled_count, mempool_count, vtx_missing.size()); diff --git a/src/blockencodings.h b/src/blockencodings.h index b980e9e2866..cab847ee3af 100644 --- a/src/blockencodings.h +++ b/src/blockencodings.h @@ -124,6 +124,8 @@ typedef enum ReadStatus_t READ_STATUS_OK, READ_STATUS_INVALID, // Invalid object, peer is sending bogus crap READ_STATUS_FAILED, // Failed to process object + READ_STATUS_CHECKBLOCK_FAILED, // Used only by FillBlock to indicate a + // failure in CheckBlock. } ReadStatus; class CBlockHeaderAndShortTxIDs { @@ -146,7 +148,7 @@ class CBlockHeaderAndShortTxIDs { // Dummy for deserialization CBlockHeaderAndShortTxIDs() {} - CBlockHeaderAndShortTxIDs(const CBlock& block); + CBlockHeaderAndShortTxIDs(const CBlock& block, bool fUseWTXID); uint64_t GetShortID(const uint256& txhash) const; diff --git a/src/chain.h b/src/chain.h index 76a774c1238..6588e8f57d2 100644 --- a/src/chain.h +++ b/src/chain.h @@ -137,15 +137,15 @@ enum BlockStatus: uint32_t { BLOCK_VALID_MASK = BLOCK_VALID_HEADER | BLOCK_VALID_TREE | BLOCK_VALID_TRANSACTIONS | BLOCK_VALID_CHAIN | BLOCK_VALID_SCRIPTS, - BLOCK_HAVE_DATA = 8, //! full block available in blk*.dat - BLOCK_HAVE_UNDO = 16, //! undo data available in rev*.dat + BLOCK_HAVE_DATA = 8, //!< full block available in blk*.dat + BLOCK_HAVE_UNDO = 16, //!< undo data available in rev*.dat BLOCK_HAVE_MASK = BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO, - BLOCK_FAILED_VALID = 32, //! stage after last reached validness failed - BLOCK_FAILED_CHILD = 64, //! descends from failed block + BLOCK_FAILED_VALID = 32, //!< stage after last reached validness failed + BLOCK_FAILED_CHILD = 64, //!< descends from failed block BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD, - BLOCK_OPT_WITNESS = 128, //! block data in blk*.data was received with a witness-enforcing client + BLOCK_OPT_WITNESS = 128, //!< block data in blk*.data was received with a witness-enforcing client }; /** The block chain is a tree shaped structure starting with the diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 86bef1e1050..7544e71a023 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -92,10 +92,13 @@ class CMainParams : public CChainParams { consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1462060800; // May 1st, 2016 consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1493596800; // May 1st, 2017 - // Deployment of SegWit (BIP141 and BIP143) + // Deployment of SegWit (BIP141, BIP143, and BIP147) consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1; - consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 0; - consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 0; // Never / undefined + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1479168000; // November 15th, 2016. + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1510704000; // November 15th, 2017. + + // The best chain should have at least this much work. + consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000003418b3ccbe5e93bcb39b43"); /** * The message start string is designed to be unlikely to occur in normal data. @@ -114,12 +117,13 @@ class CMainParams : public CChainParams { assert(consensus.hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); - vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be", true)); // Pieter Wuille - vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me")); // Matt Corallo + // Note that of those with the service bits flag, most only support a subset of possible options + vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be", true)); // Pieter Wuille, only supports x1, x5, x9, and xd + vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me", true)); // Matt Corallo, only supports x9 vSeeds.push_back(CDNSSeedData("dashjr.org", "dnsseed.bitcoin.dashjr.org")); // Luke Dashjr - vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com")); // Christian Decker + vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com", true)); // Christian Decker, supports x1 - xf vSeeds.push_back(CDNSSeedData("xf2.org", "bitseed.xf2.org")); // Jeff Garzik - vSeeds.push_back(CDNSSeedData("bitcoin.jonasschnelli.ch", "seed.bitcoin.jonasschnelli.ch")); // Jonas Schnelli + vSeeds.push_back(CDNSSeedData("bitcoin.jonasschnelli.ch", "seed.bitcoin.jonasschnelli.ch", true)); // Jonas Schnelli, only supports x1, x5, x9, and xd base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,0); base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,5); @@ -188,11 +192,14 @@ class CTestNetParams : public CChainParams { consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1456790400; // March 1st, 2016 consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1493596800; // May 1st, 2017 - // Deployment of SegWit (BIP141 and BIP143) + // Deployment of SegWit (BIP141, BIP143, and BIP147) consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1; consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1462060800; // May 1st 2016 consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1493596800; // May 1st 2017 + // The best chain should have at least this much work. + consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000001b3fcc3e766e365e4b"); + pchMessageStart[0] = 0x0b; pchMessageStart[1] = 0x11; pchMessageStart[2] = 0x09; @@ -227,6 +234,7 @@ class CTestNetParams : public CChainParams { fMineBlocksOnDemand = false; fTestnetToBeDeprecatedFieldRPC = true; + checkpointData = (CCheckpointData) { boost::assign::map_list_of ( 546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")), @@ -269,6 +277,9 @@ class CRegTestParams : public CChainParams { consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 0; consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 999999999999ULL; + // The best chain should have at least this much work. + consensus.nMinimumChainWork = uint256S("0x00"); + pchMessageStart[0] = 0xfa; pchMessageStart[1] = 0xbf; pchMessageStart[2] = 0xb5; @@ -303,6 +314,12 @@ class CRegTestParams : public CChainParams { base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container >(); base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container >(); } + + void UpdateBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout) + { + consensus.vDeployments[d].nStartTime = nStartTime; + consensus.vDeployments[d].nTimeout = nTimeout; + } }; static CRegTestParams regTestParams; @@ -330,4 +347,9 @@ void SelectParams(const std::string& network) SelectBaseParams(network); pCurrentParams = &Params(network); } + +void UpdateRegtestBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout) +{ + regTestParams.UpdateBIP9Parameters(d, nStartTime, nTimeout); +} diff --git a/src/chainparams.h b/src/chainparams.h index 638893e9ad9..0c3820b7c6e 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -112,4 +112,9 @@ CChainParams& Params(const std::string& chain); */ void SelectParams(const std::string& chain); +/** + * Allows modifying the BIP9 regtest parameters. + */ +void UpdateRegtestBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout); + #endif // BITCOIN_CHAINPARAMS_H diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index aefddce4641..d22c188c16e 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -55,16 +55,6 @@ namespace Checkpoints { return fWorkBefore / (fWorkBefore + fWorkAfter); } - int GetTotalBlocksEstimate(const CCheckpointData& data) - { - const MapCheckpoints& checkpoints = data.mapCheckpoints; - - if (checkpoints.empty()) - return 0; - - return checkpoints.rbegin()->first; - } - CBlockIndex* GetLastCheckpoint(const CCheckpointData& data) { const MapCheckpoints& checkpoints = data.mapCheckpoints; diff --git a/src/checkpoints.h b/src/checkpoints.h index cd25ea5379d..04346f35ffa 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -19,9 +19,6 @@ struct CCheckpointData; namespace Checkpoints { -//! Return conservative estimate of total number of blocks, 0 if unknown -int GetTotalBlocksEstimate(const CCheckpointData& data); - //! Returns last CBlockIndex* in mapBlockIndex that is a checkpoint CBlockIndex* GetLastCheckpoint(const CCheckpointData& data); diff --git a/src/clientversion.h b/src/clientversion.h index 47263d5344f..eb0ee5973c8 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -15,12 +15,12 @@ //! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 0 -#define CLIENT_VERSION_MINOR 12 -#define CLIENT_VERSION_REVISION 99 +#define CLIENT_VERSION_MINOR 13 +#define CLIENT_VERSION_REVISION 2 #define CLIENT_VERSION_BUILD 0 //! Set to true for release, false for prerelease or test build -#define CLIENT_VERSION_IS_RELEASE false +#define CLIENT_VERSION_IS_RELEASE true /** * Copyright year (2009-this) diff --git a/src/coins.cpp b/src/coins.cpp index 39db7dedfbb..8ff652b474b 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -275,7 +275,7 @@ double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight, CAmount assert(coins); if (!coins->IsAvailable(txin.prevout.n)) continue; if (coins->nHeight <= nHeight) { - dResult += coins->vout[txin.prevout.n].nValue * (nHeight-coins->nHeight); + dResult += (double)(coins->vout[txin.prevout.n].nValue) * (nHeight-coins->nHeight); inChainInputValue += coins->vout[txin.prevout.n].nValue; } } diff --git a/src/compat.h b/src/compat.h index 79a297e5e40..2578d6d3445 100644 --- a/src/compat.h +++ b/src/compat.h @@ -34,6 +34,7 @@ #else #include #include +#include #include #include #include diff --git a/src/compat/byteswap.h b/src/compat/byteswap.h index 899220bdc54..5c86499d7b9 100644 --- a/src/compat/byteswap.h +++ b/src/compat/byteswap.h @@ -15,6 +15,23 @@ #include #endif +#if defined(__APPLE__) + +#if !defined(bswap_16) + +// Mac OS X / Darwin features; we include a check for bswap_16 because if it is already defined, protobuf has +// defined these macros for us already; if it isn't, we do it ourselves. In either case, we get the exact same +// result regardless which path was taken +#include +#define bswap_16(x) OSSwapInt16(x) +#define bswap_32(x) OSSwapInt32(x) +#define bswap_64(x) OSSwapInt64(x) + +#endif // !defined(bswap_16) + +#else +// Non-Mac OS X / non-Darwin + #if HAVE_DECL_BSWAP_16 == 0 inline uint16_t bswap_16(uint16_t x) { @@ -44,4 +61,6 @@ inline uint64_t bswap_64(uint64_t x) } #endif // HAVE_DECL_BSWAP64 +#endif // defined(__APPLE__) + #endif // BITCOIN_COMPAT_BYTESWAP_H diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h index 81f40593b21..69085658660 100644 --- a/src/consensus/consensus.h +++ b/src/consensus/consensus.h @@ -10,8 +10,8 @@ /** The maximum allowed size for a serialized block, in bytes (only for buffer size limits) */ static const unsigned int MAX_BLOCK_SERIALIZED_SIZE = 4000000; -/** The maximum allowed cost for a block, see BIP 141 (network rule) */ -static const unsigned int MAX_BLOCK_COST = 4000000; +/** The maximum allowed weight for a block, see BIP 141 (network rule) */ +static const unsigned int MAX_BLOCK_WEIGHT = 4000000; /** The maximum allowed size for a block excluding witness data, in bytes (network rule) */ static const unsigned int MAX_BLOCK_BASE_SIZE = 1000000; /** The maximum allowed number of signature check operations in a block (network rule) */ diff --git a/src/consensus/params.h b/src/consensus/params.h index 822ec87d69e..7aa876d6501 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -16,7 +16,7 @@ enum DeploymentPos { DEPLOYMENT_TESTDUMMY, DEPLOYMENT_CSV, // Deployment of BIP68, BIP112, and BIP113. - DEPLOYMENT_SEGWIT, // Deployment of BIP141 and BIP143 + DEPLOYMENT_SEGWIT, // Deployment of BIP141, BIP143, and BIP147. // NOTE: Also add new deployments to VersionBitsDeploymentInfo in versionbits.cpp MAX_VERSION_BITS_DEPLOYMENTS }; @@ -61,6 +61,7 @@ struct Params { int64_t nPowTargetSpacing; int64_t nPowTargetTimespan; int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; } + uint256 nMinimumChainWork; }; } // namespace Consensus diff --git a/src/consensus/validation.h b/src/consensus/validation.h index 000b1972702..3e24294a642 100644 --- a/src/consensus/validation.h +++ b/src/consensus/validation.h @@ -22,9 +22,9 @@ static const unsigned char REJECT_CHECKPOINT = 0x43; class CValidationState { private: enum mode_state { - MODE_VALID, //! everything ok - MODE_INVALID, //! network rule violation (DoS value may be set) - MODE_ERROR, //! run-time error + MODE_VALID, //!< everything ok + MODE_INVALID, //!< network rule violation (DoS value may be set) + MODE_ERROR, //!< run-time error } mode; int nDoS; std::string strRejectReason; diff --git a/src/core_io.h b/src/core_io.h index b559d44bf5a..44a732b6970 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -25,7 +25,7 @@ extern std::vector 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 std::string EncodeHexTx(const CTransaction& tx, const int serializeFlags = 0); extern void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); extern void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry); diff --git a/src/core_write.cpp b/src/core_write.cpp index 6f9e2266a39..9f859ba9e12 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -116,9 +116,9 @@ string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode) return str; } -string EncodeHexTx(const CTransaction& tx) +string EncodeHexTx(const CTransaction& tx, const int serialFlags) { - CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | serialFlags); ssTx << tx; return HexStr(ssTx.begin(), ssTx.end()); } @@ -151,11 +151,13 @@ void ScriptPubKeyToUniv(const CScript& scriptPubKey, void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry) { entry.pushKV("txid", tx.GetHash().GetHex()); + entry.pushKV("hash", tx.GetWitnessHash().GetHex()); entry.pushKV("version", tx.nVersion); entry.pushKV("locktime", (int64_t)tx.nLockTime); UniValue vin(UniValue::VARR); - BOOST_FOREACH(const CTxIn& txin, tx.vin) { + for (unsigned int i = 0; i < tx.vin.size(); i++) { + const CTxIn& txin = tx.vin[i]; UniValue in(UniValue::VOBJ); if (tx.IsCoinBase()) in.pushKV("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())); @@ -166,6 +168,13 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry) o.pushKV("asm", ScriptToAsmStr(txin.scriptSig, true)); o.pushKV("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())); in.pushKV("scriptSig", o); + if (!tx.wit.IsNull() && i < tx.wit.vtxinwit.size() && !tx.wit.vtxinwit[i].IsNull()) { + UniValue txinwitness(UniValue::VARR); + for (const auto& item : tx.wit.vtxinwit[i].scriptWitness.stack) { + txinwitness.push_back(HexStr(item.begin(), item.end())); + } + in.pushKV("txinwitness", txinwitness); + } } in.pushKV("sequence", (int64_t)txin.nSequence); vin.push_back(in); diff --git a/src/httpserver.h b/src/httpserver.h index 20a119cc5c9..42a142dde85 100644 --- a/src/httpserver.h +++ b/src/httpserver.h @@ -35,7 +35,7 @@ void InterruptHTTPServer(); void StopHTTPServer(); /** Handler for requests to a certain HTTP path */ -typedef boost::function HTTPRequestHandler; +typedef boost::function HTTPRequestHandler; /** Register handler for prefix. * If multiple handlers match a prefix, the first-registered one will * be invoked. diff --git a/src/indirectmap.h b/src/indirectmap.h index 28e1e8deddb..76da4a6bd55 100644 --- a/src/indirectmap.h +++ b/src/indirectmap.h @@ -1,3 +1,7 @@ +// Copyright (c) 2016 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_INDIRECTMAP_H #define BITCOIN_INDIRECTMAP_H diff --git a/src/init.cpp b/src/init.cpp index 509bc45f516..f2dbf575192 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -364,6 +364,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-port=", strprintf(_("Listen for connections on (default: %u or testnet: %u)"), Params(CBaseChainParams::MAIN).GetDefaultPort(), Params(CBaseChainParams::TESTNET).GetDefaultPort())); strUsage += HelpMessageOpt("-proxy=", _("Connect through SOCKS5 proxy")); strUsage += HelpMessageOpt("-proxyrandomize", strprintf(_("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)"), DEFAULT_PROXYRANDOMIZE)); + strUsage += HelpMessageOpt("-rpcserialversion", strprintf(_("Sets the serialization of raw transaction or block hex returned in non-verbose mode, non-segwit(0) or segwit(1) (default: %d)"), DEFAULT_RPC_SERIALIZE_VERSION)); strUsage += HelpMessageOpt("-seednode=", _("Connect to a node to retrieve peer addresses, and disconnect")); strUsage += HelpMessageOpt("-timeout=", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT)); strUsage += HelpMessageOpt("-torcontrol=:", strprintf(_("Tor control port to use if onion listening enabled (default: %s)"), DEFAULT_TOR_CONTROL)); @@ -376,10 +377,10 @@ std::string HelpMessage(HelpMessageMode mode) #endif #endif strUsage += HelpMessageOpt("-whitebind=", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6")); - strUsage += HelpMessageOpt("-whitelist=", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") + + strUsage += HelpMessageOpt("-whitelist=", _("Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or CIDR notated network (e.g. 1.2.3.0/24). 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("-whitelistrelay", strprintf(_("Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d)"), DEFAULT_WHITELISTRELAY)); - strUsage += HelpMessageOpt("-whitelistforcerelay", strprintf(_("Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d)"), DEFAULT_WHITELISTFORCERELAY)); + strUsage += HelpMessageOpt("-whitelistforcerelay", strprintf(_("Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d)"), DEFAULT_WHITELISTFORCERELAY)); strUsage += HelpMessageOpt("-maxuploadtarget=", strprintf(_("Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)"), DEFAULT_MAX_UPLOAD_TARGET)); #ifdef ENABLE_WALLET @@ -410,8 +411,9 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-limitancestorsize=", strprintf("Do not accept transactions whose size with all in-mempool ancestors exceeds kilobytes (default: %u)", DEFAULT_ANCESTOR_SIZE_LIMIT)); strUsage += HelpMessageOpt("-limitdescendantcount=", strprintf("Do not accept transactions if any ancestor would have or more in-mempool descendants (default: %u)", DEFAULT_DESCENDANT_LIMIT)); strUsage += HelpMessageOpt("-limitdescendantsize=", strprintf("Do not accept transactions if any ancestor would have more than kilobytes of in-mempool descendants (default: %u).", DEFAULT_DESCENDANT_SIZE_LIMIT)); + strUsage += HelpMessageOpt("-bip9params=deployment:start:end", "Use given start/end times for specified bip9 deployment (regtest-only)"); } - string debugCategories = "addrman, alert, bench, coindb, db, http, libevent, lock, mempool, mempoolrej, net, proxy, prune, rand, reindex, rpc, selectcoins, tor, zmq"; // Don't translate these and qt below + string debugCategories = "addrman, alert, bench, cmpctblock, coindb, db, http, libevent, lock, mempool, mempoolrej, net, proxy, prune, rand, reindex, rpc, selectcoins, tor, zmq"; // Don't translate these and qt below if (mode == HMM_BITCOIN_QT) debugCategories += ", qt"; strUsage += HelpMessageOpt("-debug=", strprintf(_("Output debugging information (default: %u, supplying is optional)"), 0) + ". " + @@ -446,13 +448,13 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageGroup(_("Node relay options:")); if (showDebug) strUsage += HelpMessageOpt("-acceptnonstdtxn", strprintf("Relay and mine \"non-standard\" transactions (%sdefault: %u)", "testnet/regtest only; ", !Params(CBaseChainParams::TESTNET).RequireStandard())); - strUsage += HelpMessageOpt("-bytespersigop", strprintf(_("Minimum bytes per sigop in transactions we relay and mine (default: %u)"), DEFAULT_BYTES_PER_SIGOP)); + strUsage += HelpMessageOpt("-bytespersigop", strprintf(_("Equivalent bytes per sigop in transactions for relay and mining (default: %u)"), DEFAULT_BYTES_PER_SIGOP)); strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), DEFAULT_ACCEPT_DATACARRIER)); strUsage += HelpMessageOpt("-datacarriersize", strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY)); strUsage += HelpMessageOpt("-mempoolreplacement", strprintf(_("Enable transaction replacement in the memory pool (default: %u)"), DEFAULT_ENABLE_REPLACEMENT)); strUsage += HelpMessageGroup(_("Block creation options:")); - strUsage += HelpMessageOpt("-blockmaxcost=", strprintf(_("Set maximum BIP141 block cost (default: %d)"), DEFAULT_BLOCK_MAX_COST)); + strUsage += HelpMessageOpt("-blockmaxweight=", strprintf(_("Set maximum BIP141 block weight (default: %d)"), DEFAULT_BLOCK_MAX_WEIGHT)); strUsage += HelpMessageOpt("-blockmaxsize=", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE)); strUsage += HelpMessageOpt("-blockprioritysize=", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE)); if (showDebug) @@ -510,6 +512,21 @@ static void BlockNotifyCallback(bool initialSync, const CBlockIndex *pBlockIndex boost::thread t(runCommand, strCmd); // thread runs free } +static bool fHaveGenesis = false; +static boost::mutex cs_GenesisWait; +static CConditionVariable condvar_GenesisWait; + +static void BlockNotifyGenesisWait(bool, const CBlockIndex *pBlockIndex) +{ + if (pBlockIndex != NULL) { + { + boost::unique_lock lock_GenesisWait(cs_GenesisWait); + fHaveGenesis = true; + } + condvar_GenesisWait.notify_all(); + } +} + struct CImportingNow { CImportingNow() { @@ -838,7 +855,9 @@ 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 nBind = std::max( + (mapMultiArgs.count("-bind") ? mapMultiArgs.at("-bind").size() : 0) + + (mapMultiArgs.count("-whitebind") ? mapMultiArgs.at("-whitebind").size() : 0), size_t(1)); int nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS); nMaxConnections = std::max(nUserMaxConnections, 0); @@ -964,6 +983,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS)) nLocalServices = ServiceFlags(nLocalServices | NODE_BLOOM); + if (GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) < 0) + return InitError("rpcserialversion must be non-negative."); + + if (GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) > 1) + return InitError("unknown rpcserialversion requested."); + nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE); fEnableReplacement = GetBoolArg("-mempoolreplacement", DEFAULT_ENABLE_REPLACEMENT); @@ -975,6 +1000,41 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) fEnableReplacement = (std::find(vstrReplacementModes.begin(), vstrReplacementModes.end(), "fee") != vstrReplacementModes.end()); } + if (!mapMultiArgs["-bip9params"].empty()) { + // Allow overriding bip9 parameters for testing + if (!Params().MineBlocksOnDemand()) { + return InitError("BIP9 parameters may only be overridden on regtest."); + } + const vector& deployments = mapMultiArgs["-bip9params"]; + for (auto i : deployments) { + std::vector vDeploymentParams; + boost::split(vDeploymentParams, i, boost::is_any_of(":")); + if (vDeploymentParams.size() != 3) { + return InitError("BIP9 parameters malformed, expecting deployment:start:end"); + } + int64_t nStartTime, nTimeout; + if (!ParseInt64(vDeploymentParams[1], &nStartTime)) { + return InitError(strprintf("Invalid nStartTime (%s)", vDeploymentParams[1])); + } + if (!ParseInt64(vDeploymentParams[2], &nTimeout)) { + return InitError(strprintf("Invalid nTimeout (%s)", vDeploymentParams[2])); + } + bool found = false; + for (int i=0; i<(int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++i) + { + if (vDeploymentParams[0].compare(VersionBitsDeploymentInfo[i].name) == 0) { + UpdateRegtestBIP9Parameters(Consensus::DeploymentPos(i), nStartTime, nTimeout); + found = true; + LogPrintf("Setting BIP9 activation parameters for %s to start=%ld, timeout=%ld\n", vDeploymentParams[0], nStartTime, nTimeout); + break; + } + } + if (!found) { + return InitError(strprintf("Invalid deployment (%s)", vDeploymentParams[0])); + } + } + } + // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log // Initialize elliptic curve code @@ -1216,7 +1276,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // cache size calculations int64_t nTotalCache = (GetArg("-dbcache", nDefaultDbCache) << 20); nTotalCache = std::max(nTotalCache, nMinDbCache << 20); // total cache cannot be less than nMinDbCache - nTotalCache = std::min(nTotalCache, nMaxDbCache << 20); // total cache cannot be greated than nMaxDbcache + nTotalCache = std::min(nTotalCache, nMaxDbCache << 20); // total cache cannot be greater than nMaxDbcache int64_t nBlockTreeDBCache = nTotalCache / 8; nBlockTreeDBCache = std::min(nBlockTreeDBCache, (GetBoolArg("-txindex", DEFAULT_TXINDEX) ? nMaxBlockDBAndTxIndexCache : nMaxBlockDBCache) << 20); nTotalCache -= nBlockTreeDBCache; @@ -1286,7 +1346,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) break; } - if (!fReindex) { + if (!fReindex && chainActive.Tip() != NULL) { uiInterface.InitMessage(_("Rewinding blocks...")); if (!RewindBlockIndex(chainparams)) { strLoadError = _("Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain"); @@ -1403,6 +1463,17 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // ********************************************************* Step 10: import blocks + if (!CheckDiskSpace()) + return false; + + // Either install a handler to notify us when genesis activates, or set fHaveGenesis directly. + // No locking, as this happens before any background thread is started. + if (chainActive.Tip() == NULL) { + uiInterface.NotifyBlockTip.connect(BlockNotifyGenesisWait); + } else { + fHaveGenesis = true; + } + if (mapArgs.count("-blocknotify")) uiInterface.NotifyBlockTip.connect(BlockNotifyCallback); @@ -1412,26 +1483,20 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) BOOST_FOREACH(const std::string& strFile, mapMultiArgs["-loadblock"]) vImportFiles.push_back(strFile); } + threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles)); // Wait for genesis block to be processed - bool fHaveGenesis = false; - while (!fHaveGenesis && !fRequestShutdown) { - { - LOCK(cs_main); - fHaveGenesis = (chainActive.Tip() != NULL); - } - - if (!fHaveGenesis) { - MilliSleep(10); + { + boost::unique_lock lock(cs_GenesisWait); + while (!fHaveGenesis) { + condvar_GenesisWait.wait(lock); } + uiInterface.NotifyBlockTip.disconnect(BlockNotifyGenesisWait); } // ********************************************************* Step 11: start node - if (!CheckDiskSpace()) - return false; - if (!strErrors.str().empty()) return InitError(strErrors.str()); diff --git a/src/main.cpp b/src/main.cpp index 73fbe53afb6..e2fc7d1b12b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin Core developers +// Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -74,7 +74,6 @@ bool fHavePruned = false; bool fPruneMode = false; bool fIsBareMultisigStd = DEFAULT_PERMIT_BAREMULTISIG; bool fRequireStandard = true; -unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP; bool fCheckBlockIndex = false; bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED; size_t nCoinCacheUsage = 5000 * 300; @@ -179,8 +178,10 @@ namespace { * Sources of received blocks, saved to be able to send them reject * messages or ban them when processing happens afterwards. Protected by * cs_main. + * Set mapBlockSource[hash].second to false if the node should not be + * punished if the block is invalid. */ - map mapBlockSource; + map> mapBlockSource; /** * Filter for transactions that were recently rejected by @@ -293,10 +294,21 @@ struct CNodeState { bool fPreferHeaders; //! Whether this peer wants invs or cmpctblocks (when possible) for block announcements. bool fPreferHeaderAndIDs; - //! Whether this peer will send us cmpctblocks if we request them + /** + * Whether this peer will send us cmpctblocks if we request them. + * This is not used to gate request logic, as we really only care about fSupportsDesiredCmpctVersion, + * but is used as a flag to "lock in" the version of compact blocks (fWantsCmpctWitness) we send. + */ bool fProvidesHeaderAndIDs; //! Whether this peer can give us witnesses bool fHaveWitness; + //! Whether this peer wants witnesses in cmpctblocks/blocktxns + bool fWantsCmpctWitness; + /** + * If we've announced NODE_WITNESS to this peer: whether the peer sends witnesses in cmpctblocks/blocktxns, + * otherwise: whether this peer sends non-witnesses in cmpctblocks/blocktxns. + */ + bool fSupportsDesiredCmpctVersion; CNodeState() { fCurrentlyConnected = false; @@ -317,6 +329,8 @@ struct CNodeState { fPreferHeaderAndIDs = false; fProvidesHeaderAndIDs = false; fHaveWitness = false; + fWantsCmpctWitness = false; + fSupportsDesiredCmpctVersion = false; } }; @@ -476,24 +490,28 @@ void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) { } void MaybeSetPeerAsAnnouncingHeaderAndIDs(const CNodeState* nodestate, CNode* pfrom) { - if (nLocalServices & NODE_WITNESS) { - // Don't ever request compact blocks when segwit is enabled. + if (!nodestate->fSupportsDesiredCmpctVersion) { + // Never ask from peers who can't provide witnesses. return; } if (nodestate->fProvidesHeaderAndIDs) { - BOOST_FOREACH(const NodeId nodeid, lNodesAnnouncingHeaderAndIDs) - if (nodeid == pfrom->GetId()) + for (std::list::iterator it = lNodesAnnouncingHeaderAndIDs.begin(); it != lNodesAnnouncingHeaderAndIDs.end(); it++) { + if (*it == pfrom->GetId()) { + lNodesAnnouncingHeaderAndIDs.erase(it); + lNodesAnnouncingHeaderAndIDs.push_back(pfrom->GetId()); return; + } + } bool fAnnounceUsingCMPCTBLOCK = false; - uint64_t nCMPCTBLOCKVersion = 1; + uint64_t nCMPCTBLOCKVersion = (nLocalServices & NODE_WITNESS) ? 2 : 1; if (lNodesAnnouncingHeaderAndIDs.size() >= 3) { // As per BIP152, we only get 3 of our peers to announce // blocks using compact encodings. CNode* pnodeStop = FindNode(lNodesAnnouncingHeaderAndIDs.front()); if (pnodeStop) { pnodeStop->PushMessage(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion); - lNodesAnnouncingHeaderAndIDs.pop_front(); } + lNodesAnnouncingHeaderAndIDs.pop_front(); } fAnnounceUsingCMPCTBLOCK = true; pfrom->PushMessage(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion); @@ -538,7 +556,7 @@ CBlockIndex* LastCommonAncestor(CBlockIndex* pa, CBlockIndex* pb) { /** Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has * at most count entries. */ -void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector& vBlocks, NodeId& nodeStaller) { +void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector& vBlocks, NodeId& nodeStaller, const Consensus::Params& consensusParams) { if (count == 0) return; @@ -595,6 +613,10 @@ void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vectorfHaveWitness && IsWitnessEnabled(pindex->pprev, consensusParams)) { + // We wouldn't download this block or its descendants from this peer. + return; + } if (pindex->nStatus & BLOCK_HAVE_DATA || chainActive.Contains(pindex)) { if (pindex->nChainTx) state->pindexLastCommonBlock = pindex; @@ -694,8 +716,8 @@ bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(c // have been mined or received. // 100 orphans, each of which is at most 99,999 bytes big is // at most 10 megabytes of orphans and somewhat more byprev index (in the worst case): - unsigned int sz = GetTransactionCost(tx); - if (sz >= MAX_STANDARD_TX_COST) + unsigned int sz = GetTransactionWeight(tx); + if (sz >= MAX_STANDARD_TX_WEIGHT) { LogPrint("mempool", "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString()); return false; @@ -1144,13 +1166,14 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C } // Reject transactions with witness before segregated witness activates (override with -prematurewitness) - if (!GetBoolArg("-prematurewitness",false) && !tx.wit.IsNull() && !IsWitnessEnabled(chainActive.Tip(), Params().GetConsensus())) { + bool witnessEnabled = IsWitnessEnabled(chainActive.Tip(), Params().GetConsensus()); + if (!GetBoolArg("-prematurewitness",false) && !tx.wit.IsNull() && !witnessEnabled) { return state.DoS(0, false, REJECT_NONSTANDARD, "no-witness-yet", true); } // Rather not work on nonstandard transactions (unless -testnet/-regtest) string reason; - if (fRequireStandard && !IsStandardTx(tx, reason)) + if (fRequireStandard && !IsStandardTx(tx, reason, witnessEnabled)) return state.DoS(0, false, REJECT_NONSTANDARD, reason); // Only accept nLockTime-using transactions that can be mined in the next @@ -1179,7 +1202,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C // nSequence >= maxint-1 on all inputs. // // maxint-1 is picked to still allow use of nLockTime by - // non-replacable transactions. All inputs rather than just one + // non-replaceable transactions. All inputs rather than just one // is for the sake of multi-party protocols, where we don't // want a single party to be able to disable replacement. // @@ -1265,6 +1288,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C if (fRequireStandard && !AreInputsStandard(tx, view)) return state.Invalid(false, REJECT_NONSTANDARD, "bad-txns-nonstandard-inputs"); + // Check for non-standard witness in P2WSH + if (!tx.wit.IsNull() && fRequireStandard && !IsWitnessStandard(tx, view)) + return state.DoS(0, false, REJECT_NONSTANDARD, "bad-witness-nonstandard", true); + int64_t nSigOpsCost = GetTransactionSigOpCost(tx, view, STANDARD_SCRIPT_VERIFY_FLAGS); CAmount nValueOut = tx.GetValueOut(); @@ -1296,7 +1323,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than // merely non-standard transaction. - if ((nSigOpsCost > MAX_STANDARD_TX_SIGOPS_COST) || (nBytesPerSigOp && nSigOpsCost > nSize * WITNESS_SCALE_FACTOR / nBytesPerSigOp)) + if (nSigOpsCost > MAX_STANDARD_TX_SIGOPS_COST) return state.DoS(0, false, REJECT_NONSTANDARD, "bad-txns-too-many-sigops", false, strprintf("%d", nSigOpsCost)); @@ -1497,13 +1524,14 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C // Check against previous transactions // This is done last to help prevent CPU exhaustion denial-of-service attacks. - if (!CheckInputs(tx, state, view, true, scriptVerifyFlags, true)) { + PrecomputedTransactionData txdata(tx); + if (!CheckInputs(tx, state, view, true, scriptVerifyFlags, true, txdata)) { // SCRIPT_VERIFY_CLEANSTACK requires SCRIPT_VERIFY_WITNESS, so we // need to turn both off, and compare against just turning off CLEANSTACK // to see if the failure is specifically due to witness validation. - if (CheckInputs(tx, state, view, true, scriptVerifyFlags & ~(SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_CLEANSTACK), true) && - !CheckInputs(tx, state, view, true, scriptVerifyFlags & ~SCRIPT_VERIFY_CLEANSTACK, true)) { - // Only the witness is wrong, so the transaction itself may be fine. + if (tx.wit.IsNull() && CheckInputs(tx, state, view, true, scriptVerifyFlags & ~(SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_CLEANSTACK), true, txdata) && + !CheckInputs(tx, state, view, true, scriptVerifyFlags & ~SCRIPT_VERIFY_CLEANSTACK, true, txdata)) { + // Only the witness is missing, so the transaction itself may be fine. state.SetCorruptionPossible(); } return false; @@ -1518,7 +1546,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C // There is a similar check in CreateNewBlock() to prevent creating // invalid blocks, however allowing such transactions into the mempool // can be exploited as a DoS attack. - if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true)) + if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata)) { return error("%s: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); @@ -1563,7 +1591,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa return res; } -/** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */ +/** Return transaction in txOut, and if it was found inside a block, its hash is placed in hashBlock */ bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::Params& consensusParams, uint256 &hashBlock, bool fAllowSlow) { CBlockIndex *pindexSlow = NULL; @@ -1719,13 +1747,14 @@ bool IsInitialBlockDownload() return false; if (fImporting || fReindex) return true; - if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints())) + if (chainActive.Tip() == NULL) + return true; + if (chainActive.Tip()->nChainWork < UintToArith256(chainParams.GetConsensus().nMinimumChainWork)) + return true; + if (chainActive.Tip()->GetBlockTime() < (GetTime() - nMaxTipAge)) return true; - bool state = (chainActive.Height() < pindexBestHeader->nHeight - 24 * 6 || - std::max(chainActive.Tip()->GetBlockTime(), pindexBestHeader->GetBlockTime()) < GetTime() - nMaxTipAge); - if (!state) - latchToFalse.store(true, std::memory_order_relaxed); - return state; + latchToFalse.store(true, std::memory_order_relaxed); + return false; } bool fLargeWorkForkFound = false; @@ -1753,7 +1782,7 @@ void CheckForkWarningConditions() { AssertLockHeld(cs_main); // Before we get past initial download, we cannot reliably alert about forks - // (we assume we don't get stuck on a fork before the last checkpoint) + // (we assume we don't get stuck on a fork before finishing our initial sync) if (IsInitialBlockDownload()) return; @@ -1863,13 +1892,13 @@ void static InvalidChainFound(CBlockIndex* pindexNew) void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state) { int nDoS = 0; if (state.IsInvalid(nDoS)) { - std::map::iterator it = mapBlockSource.find(pindex->GetBlockHash()); - if (it != mapBlockSource.end() && State(it->second)) { + std::map>::iterator it = mapBlockSource.find(pindex->GetBlockHash()); + if (it != mapBlockSource.end() && State(it->second.first)) { 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); + State(it->second.first)->rejects.push_back(reject); + if (nDoS > 0 && it->second.second) + Misbehaving(it->second.first, nDoS); } } if (!state.CorruptionPossible()) { @@ -1915,7 +1944,7 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight) bool CScriptCheck::operator()() { const CScript &scriptSig = ptxTo->vin[nIn].scriptSig; const CScriptWitness *witness = (nIn < ptxTo->wit.vtxinwit.size()) ? &ptxTo->wit.vtxinwit[nIn].scriptWitness : NULL; - if (!VerifyScript(scriptSig, scriptPubKey, witness, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, amount, cacheStore), &error)) { + if (!VerifyScript(scriptSig, scriptPubKey, witness, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, amount, cacheStore, *txdata), &error)) { return false; } return true; @@ -1974,7 +2003,7 @@ bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoins } }// namespace Consensus -bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, std::vector *pvChecks) +bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, PrecomputedTransactionData& txdata, std::vector *pvChecks) { if (!tx.IsCoinBase()) { @@ -1993,7 +2022,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // is safe because block merkle hashes are still computed and checked, // and any change will be caught at the next checkpoint. Of course, if // the checkpoint is for a chain that's invalid due to false scriptSigs - // this optimisation would allow an invalid chain to be accepted. + // this optimization would allow an invalid chain to be accepted. if (fScriptChecks) { for (unsigned int i = 0; i < tx.vin.size(); i++) { const COutPoint &prevout = tx.vin[i].prevout; @@ -2001,7 +2030,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi assert(coins); // Verify signature - CScriptCheck check(*coins, tx, i, flags, cacheStore); + CScriptCheck check(*coins, tx, i, flags, cacheStore, &txdata); if (pvChecks) { pvChecks->push_back(CScriptCheck()); check.swap(pvChecks->back()); @@ -2014,7 +2043,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // avoid splitting the network between upgraded and // non-upgraded nodes. CScriptCheck check2(*coins, tx, i, - flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore); + flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore, &txdata); if (check2()) return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError()))); } @@ -2068,7 +2097,7 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uin // Open history file to read CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION); if (filein.IsNull()) - return error("%s: OpenBlockFile failed", __func__); + return error("%s: OpenUndoFile failed", __func__); // Read block uint256 hashChecksum; @@ -2394,6 +2423,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // Start enforcing WITNESS rules using versionbits logic. if (IsWitnessEnabled(pindex->pprev, chainparams.GetConsensus())) { flags |= SCRIPT_VERIFY_WITNESS; + flags |= SCRIPT_VERIFY_NULLDUMMY; } int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1; @@ -2412,6 +2442,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin std::vector > vPos; vPos.reserve(block.vtx.size()); blockundo.vtxundo.reserve(block.vtx.size() - 1); + std::vector txdata; + txdata.reserve(block.vtx.size()); // Required so that pointers to individual PrecomputedTransactionData don't get invalidated for (unsigned int i = 0; i < block.vtx.size(); i++) { const CTransaction &tx = block.vtx[i]; @@ -2458,13 +2490,14 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin return state.DoS(100, error("ConnectBlock(): too many sigops"), REJECT_INVALID, "bad-blk-sigops"); + txdata.emplace_back(tx); if (!tx.IsCoinBase()) { nFees += view.GetValueIn(tx)-tx.GetValueOut(); std::vector vChecks; bool fCacheResults = fJustCheck; /* Don't cache results if we're actually connecting blocks (still consult the cache, though) */ - if (!CheckInputs(tx, state, view, fScriptChecks, flags, fCacheResults, nScriptCheckThreads ? &vChecks : NULL)) + if (!CheckInputs(tx, state, view, fScriptChecks, flags, fCacheResults, txdata[i], nScriptCheckThreads ? &vChecks : NULL)) return error("ConnectBlock(): CheckInputs on %s failed with %s", tx.GetHash().ToString(), FormatStateMessage(state)); control.Add(vChecks); @@ -3078,13 +3111,10 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, } } // Relay inventory, but don't relay old inventory during initial block download. - int nBlockEstimate = 0; - if (fCheckpointsEnabled) - nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()); { LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) { - if (nNewHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) { + if (nNewHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 0)) { BOOST_REVERSE_FOREACH(const uint256& hash, vHashes) { pnode->PushBlockHash(hash); } @@ -3144,6 +3174,7 @@ bool InvalidateBlock(CValidationState& state, const CChainParams& chainparams, C InvalidChainFound(pindex); mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS); + uiInterface.NotifyBlockTip(IsInitialBlockDownload(), pindex->pprev); return true; } @@ -3471,15 +3502,8 @@ std::vector GenerateCoinbaseCommitment(CBlock& block, const CBloc { std::vector commitment; int commitpos = GetWitnessCommitmentIndex(block); - bool fHaveWitness = false; - for (size_t t = 1; t < block.vtx.size(); t++) { - if (!block.vtx[t].wit.IsNull()) { - fHaveWitness = true; - break; - } - } std::vector ret(32, 0x00); - if (fHaveWitness && IsWitnessEnabled(pindexPrev, consensusParams)) { + if (consensusParams.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout != 0) { if (commitpos == -1) { uint256 witnessroot = BlockWitnessMerkleRoot(block, NULL); CHash256().Write(witnessroot.begin(), 32).Write(&ret[0], 32).Finalize(witnessroot.begin()); @@ -3596,13 +3620,13 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn } // After the coinbase witness nonce and commitment are verified, - // we can check if the block cost passes (before we've checked the - // coinbase witness, it would be possible for the cost to be too + // we can check if the block weight passes (before we've checked the + // coinbase witness, it would be possible for the weight to be too // large by filling up the coinbase witness, which doesn't change // the block hash, so we couldn't mark the block as permanently // failed). - if (GetBlockCost(block) > MAX_BLOCK_COST) { - return state.DoS(100, error("ContextualCheckBlock(): cost limit failed"), REJECT_INVALID, "bad-blk-cost"); + if (GetBlockWeight(block) > MAX_BLOCK_WEIGHT) { + return state.DoS(100, error("ContextualCheckBlock(): weight limit failed"), REJECT_INVALID, "bad-blk-weight"); } return true; @@ -3735,7 +3759,7 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned } -bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp) +bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp, bool fMayBanPeerIfInvalid) { { LOCK(cs_main); @@ -3747,7 +3771,7 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, C bool fNewBlock = false; bool ret = AcceptBlock(*pblock, state, chainparams, &pindex, fRequested, dbp, &fNewBlock); if (pindex && pfrom) { - mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId(); + mapBlockSource[pindex->GetBlockHash()] = std::make_pair(pfrom->GetId(), fMayBanPeerIfInvalid); if (fNewBlock) pfrom->nLastBlockTime = GetTime(); } CheckBlockIndex(chainparams.GetConsensus()); @@ -3954,7 +3978,7 @@ CBlockIndex * InsertBlockIndex(uint256 hash) // Create new CBlockIndex* pindexNew = new CBlockIndex(); if (!pindexNew) - throw runtime_error("LoadBlockIndex(): new CBlockIndex failed"); + throw runtime_error(std::string(__func__) + ": new CBlockIndex failed"); mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; pindexNew->phashBlock = &((*mi).first); @@ -4331,8 +4355,6 @@ bool InitBlockIndex(const CChainParams& chainparams) CBlockIndex *pindex = AddToBlockIndex(block); if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) return error("LoadBlockIndex(): genesis block not accepted"); - if (!ActivateBestChain(state, chainparams, &block)) - return error("LoadBlockIndex(): genesis block cannot be activated"); // Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data return FlushStateToDisk(state, FLUSH_STATE_ALWAYS); } catch (const std::runtime_error& e) { @@ -4647,6 +4669,7 @@ std::string GetWarnings(const std::string& strFor) string strStatusBar; string strRPC; string strGUI; + const string uiAlertSeperator = "
"; if (!CLIENT_VERSION_IS_RELEASE) { strStatusBar = "This is a pre-release test build - use at your own risk - do not use for mining or merchant applications"; @@ -4659,18 +4682,19 @@ std::string GetWarnings(const std::string& strFor) // Misc warnings like out of disk space and clock is wrong if (strMiscWarning != "") { - strStatusBar = strGUI = strMiscWarning; + strStatusBar = strMiscWarning; + strGUI += (strGUI.empty() ? "" : uiAlertSeperator) + strMiscWarning; } if (fLargeWorkForkFound) { strStatusBar = strRPC = "Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues."; - strGUI = _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues."); + strGUI += (strGUI.empty() ? "" : uiAlertSeperator) + _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues."); } else if (fLargeWorkInvalidChainFound) { strStatusBar = strRPC = "Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."; - strGUI = _("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."); + strGUI += (strGUI.empty() ? "" : uiAlertSeperator) + _("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."); } if (strFor == "gui") @@ -4691,7 +4715,6 @@ std::string GetWarnings(const std::string& strFor) ////////////////////////////////////////////////////////////////////////////// -// // Messages // @@ -4793,10 +4816,16 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam pfrom->PushMessage(NetMsgType::BLOCK, block); else if (inv.type == MSG_FILTERED_BLOCK) { - LOCK(pfrom->cs_filter); - if (pfrom->pfilter) + bool send = false; + CMerkleBlock merkleBlock; { - CMerkleBlock merkleBlock(block, *pfrom->pfilter); + LOCK(pfrom->cs_filter); + if (pfrom->pfilter) { + send = true; + merkleBlock = CMerkleBlock(block, *pfrom->pfilter); + } + } + if (send) { pfrom->PushMessage(NetMsgType::MERKLEBLOCK, merkleBlock); // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see // This avoids hurting performance by pointlessly requiring a round-trip @@ -4815,13 +4844,14 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam { // If a peer is asking for old blocks, we're almost guaranteed // they wont have a useful mempool to match against a compact block, - // and we dont feel like constructing the object for them, so + // and we don't feel like constructing the object for them, so // instead we respond with the full, non-compact block. - if (mi->second->nHeight >= chainActive.Height() - 10) { - CBlockHeaderAndShortTxIDs cmpctblock(block); - pfrom->PushMessageWithFlag(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::CMPCTBLOCK, cmpctblock); + bool fPeerWantsWitness = State(pfrom->GetId())->fWantsCmpctWitness; + if (CanDirectFetch(consensusParams) && mi->second->nHeight >= chainActive.Height() - MAX_CMPCTBLOCK_DEPTH) { + CBlockHeaderAndShortTxIDs cmpctblock(block, fPeerWantsWitness); + pfrom->PushMessageWithFlag(fPeerWantsWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::CMPCTBLOCK, cmpctblock); } else - pfrom->PushMessageWithFlag(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCK, block); + pfrom->PushMessageWithFlag(fPeerWantsWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCK, block); } // Trigger the peer node to send a getblocks request for the next batch of inventory @@ -4883,7 +4913,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam uint32_t GetFetchFlags(CNode* pfrom, CBlockIndex* pprev, const Consensus::Params& chainparams) { uint32_t nFetchFlags = 0; - if (IsWitnessEnabled(pprev, chainparams) && State(pfrom->GetId())->fHaveWitness) { + if ((nLocalServices & NODE_WITNESS) && State(pfrom->GetId())->fHaveWitness) { nFetchFlags |= MSG_WITNESS_FLAG; } return nFetchFlags; @@ -4917,6 +4947,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (strCommand == NetMsgType::VERSION) { + // Feeler connections exist only to verify if address is online. + if (pfrom->fFeeler) { + assert(pfrom->fInbound == false); + pfrom->fDisconnect = true; + } + // Each connection can only send one version message if (pfrom->nVersion != 0) { @@ -5035,12 +5071,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->fGetAddr = true; } addrman.Good(pfrom->addr); - } else { - if (((CNetAddr)pfrom->addr) == (CNetAddr)addrFrom) - { - addrman.Add(addrFrom, addrFrom); - addrman.Good(addrFrom); - } } pfrom->fSuccessfullyConnected = true; @@ -5087,13 +5117,16 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->PushMessage(NetMsgType::SENDHEADERS); } if (pfrom->nVersion >= SHORT_IDS_BLOCKS_VERSION) { - // Tell our peer we are willing to provide version-1 cmpctblocks + // Tell our peer we are willing to provide version 1 or 2 cmpctblocks // However, we do not request new block announcements using // cmpctblock messages. // We send this to non-NODE NETWORK peers as well, because // they may wish to request compact blocks from us bool fAnnounceUsingCMPCTBLOCK = false; - uint64_t nCMPCTBLOCKVersion = 1; + uint64_t nCMPCTBLOCKVersion = 2; + if (nLocalServices & NODE_WITNESS) + pfrom->PushMessage(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion); + nCMPCTBLOCKVersion = 1; pfrom->PushMessage(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion); } } @@ -5173,12 +5206,23 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, else if (strCommand == NetMsgType::SENDCMPCT) { bool fAnnounceUsingCMPCTBLOCK = false; - uint64_t nCMPCTBLOCKVersion = 1; + uint64_t nCMPCTBLOCKVersion = 0; vRecv >> fAnnounceUsingCMPCTBLOCK >> nCMPCTBLOCKVersion; - if (nCMPCTBLOCKVersion == 1) { + if (nCMPCTBLOCKVersion == 1 || ((nLocalServices & NODE_WITNESS) && nCMPCTBLOCKVersion == 2)) { LOCK(cs_main); - State(pfrom->GetId())->fProvidesHeaderAndIDs = true; - State(pfrom->GetId())->fPreferHeaderAndIDs = fAnnounceUsingCMPCTBLOCK; + // fProvidesHeaderAndIDs is used to "lock in" version of compact blocks we send (fWantsCmpctWitness) + if (!State(pfrom->GetId())->fProvidesHeaderAndIDs) { + State(pfrom->GetId())->fProvidesHeaderAndIDs = true; + State(pfrom->GetId())->fWantsCmpctWitness = nCMPCTBLOCKVersion == 2; + } + if (State(pfrom->GetId())->fWantsCmpctWitness == (nCMPCTBLOCKVersion == 2)) // ignore later version announces + State(pfrom->GetId())->fPreferHeaderAndIDs = fAnnounceUsingCMPCTBLOCK; + if (!State(pfrom->GetId())->fSupportsDesiredCmpctVersion) { + if (nLocalServices & NODE_WITNESS) + State(pfrom->GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 2); + else + State(pfrom->GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 1); + } } } @@ -5236,7 +5280,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER && (!IsWitnessEnabled(chainActive.Tip(), chainparams.GetConsensus()) || State(pfrom->GetId())->fHaveWitness)) { inv.type |= nFetchFlags; - if (nodestate->fProvidesHeaderAndIDs && !(nLocalServices & NODE_WITNESS)) + if (nodestate->fSupportsDesiredCmpctVersion) vToFetch.push_back(CInv(MSG_CMPCT_BLOCK, inv.hash)); else vToFetch.push_back(inv); @@ -5341,15 +5385,28 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, BlockTransactionsRequest req; vRecv >> req; + LOCK(cs_main); + BlockMap::iterator it = mapBlockIndex.find(req.blockhash); if (it == mapBlockIndex.end() || !(it->second->nStatus & BLOCK_HAVE_DATA)) { - Misbehaving(pfrom->GetId(), 100); LogPrintf("Peer %d sent us a getblocktxn for a block we don't have", pfrom->id); return true; } - if (it->second->nHeight < chainActive.Height() - 15) { - LogPrint("net", "Peer %d sent us a getblocktxn for a block > 15 deep", pfrom->id); + if (it->second->nHeight < chainActive.Height() - MAX_BLOCKTXN_DEPTH) { + // If an older block is requested (should never happen in practice, + // but can happen in tests) send a block response instead of a + // blocktxn response. Sending a full block response instead of a + // small blocktxn response is preferable in the case where a peer + // might maliciously send lots of getblocktxn requests to trigger + // expensive disk reads, because it will require the peer to + // actually receive all the data read from disk over the network. + LogPrint("net", "Peer %d sent us a getblocktxn for a block > %i deep", pfrom->id, MAX_BLOCKTXN_DEPTH); + CInv inv; + inv.type = State(pfrom->GetId())->fWantsCmpctWitness ? MSG_WITNESS_BLOCK : MSG_BLOCK; + inv.hash = req.blockhash; + pfrom->vRecvGetData.push_back(inv); + ProcessGetData(pfrom, chainparams.GetConsensus()); return true; } @@ -5365,7 +5422,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } resp.txn[i] = block.vtx[req.indexes[i]]; } - pfrom->PushMessageWithFlag(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCKTXN, resp); + pfrom->PushMessageWithFlag(State(pfrom->GetId())->fWantsCmpctWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCKTXN, resp); } @@ -5492,7 +5549,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, else if (!fMissingInputs2) { int nDos = 0; - if (stateDummy.IsInvalid(nDos) && nDos > 0 && (!state.CorruptionPossible() || State(fromPeer)->fHaveWitness)) + if (stateDummy.IsInvalid(nDos) && nDos > 0) { // Punish peer that gave us an invalid orphan tx Misbehaving(fromPeer, nDos); @@ -5503,7 +5560,10 @@ 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); - if (!stateDummy.CorruptionPossible()) { + if (orphanTx.wit.IsNull() && !stateDummy.CorruptionPossible()) { + // Do not use rejection cache for witness transactions or + // witness-stripped transactions, as they can have been malleated. + // See https://github.com/bitcoin/bitcoin/issues/8279 for details. assert(recentRejects); recentRejects->insert(orphanHash); } @@ -5525,10 +5585,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } } if (!fRejectedParents) { + uint32_t nFetchFlags = GetFetchFlags(pfrom, chainActive.Tip(), chainparams.GetConsensus()); BOOST_FOREACH(const CTxIn& txin, tx.vin) { - CInv inv(MSG_TX, txin.prevout.hash); - pfrom->AddInventoryKnown(inv); - if (!AlreadyHave(inv)) pfrom->AskFor(inv); + CInv _inv(MSG_TX | nFetchFlags, txin.prevout.hash); + pfrom->AddInventoryKnown(_inv); + if (!AlreadyHave(_inv)) pfrom->AskFor(_inv); } AddOrphanTx(tx, pfrom->GetId()); @@ -5541,7 +5602,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LogPrint("mempool", "not keeping orphan with rejected parents %s\n",tx.GetHash().ToString()); } } else { - if (!state.CorruptionPossible()) { + if (tx.wit.IsNull() && !state.CorruptionPossible()) { + // Do not use rejection cache for witness transactions or + // witness-stripped transactions, as they can have been malleated. + // See https://github.com/bitcoin/bitcoin/issues/8279 for details. assert(recentRejects); recentRejects->insert(tx.GetHash()); } @@ -5573,9 +5637,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (state.GetRejectCode() < REJECT_INTERNAL) // Never send AcceptToMemoryPool's internal codes over P2P pfrom->PushMessage(NetMsgType::REJECT, strCommand, (unsigned char)state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); - if (nDoS > 0 && (!state.CorruptionPossible() || State(pfrom->id)->fHaveWitness)) { - // When a non-witness-supporting peer gives us a transaction that would - // be accepted if witness validation was off, we can't blame them for it. + if (nDoS > 0) { Misbehaving(pfrom->GetId(), nDoS); } } @@ -5588,6 +5650,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, CBlockHeaderAndShortTxIDs cmpctblock; vRecv >> cmpctblock; + // Keep a CBlock for "optimistic" compactblock reconstructions (see + // below) + CBlock block; + bool fBlockReconstructed = false; + LOCK(cs_main); if (mapBlockIndex.find(cmpctblock.header.hashPrevBlock) == mapBlockIndex.end()) { @@ -5625,10 +5692,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // We requested this block for some reason, but our mempool will probably be useless // so we just grab the block via normal getdata std::vector vInv(1); - vInv[0] = CInv(MSG_BLOCK, cmpctblock.header.GetHash()); + vInv[0] = CInv(MSG_BLOCK | GetFetchFlags(pfrom, pindex->pprev, chainparams.GetConsensus()), cmpctblock.header.GetHash()); pfrom->PushMessage(NetMsgType::GETDATA, vInv); - return true; } + return true; } // If we're not close to tip yet, give up and let parallel block fetch work its magic @@ -5637,6 +5704,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, CNodeState *nodestate = State(pfrom->GetId()); + if (IsWitnessEnabled(pindex->pprev, chainparams.GetConsensus()) && !nodestate->fSupportsDesiredCmpctVersion) { + // Don't bother trying to process compact blocks from v1 peers + // after segwit activates. + return true; + } + // We want to be a bit conservative just to be extra careful about DoS // possibilities in compact block processing... if (pindex->nHeight <= chainActive.Height() + 2) { @@ -5663,11 +5736,17 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } else if (status == READ_STATUS_FAILED) { // Duplicate txindexes, the block is now in-flight, so just request it std::vector vInv(1); - vInv[0] = CInv(MSG_BLOCK, cmpctblock.header.GetHash()); + vInv[0] = CInv(MSG_BLOCK | GetFetchFlags(pfrom, pindex->pprev, chainparams.GetConsensus()), cmpctblock.header.GetHash()); pfrom->PushMessage(NetMsgType::GETDATA, vInv); return true; } + if (!fAlreadyInFlight && mapBlocksInFlight.size() == 1 && pindex->pprev->IsValid(BLOCK_VALID_CHAIN)) { + // We seem to be rather well-synced, so it appears pfrom was the first to provide us + // with this block! Let's get them to announce using compact blocks in the future. + MaybeSetPeerAsAnnouncingHeaderAndIDs(nodestate, pfrom); + } + BlockTransactionsRequest req; for (size_t i = 0; i < cmpctblock.BlockTxCount(); i++) { if (!partialBlock.IsTxAvailable(i)) @@ -5684,13 +5763,30 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, req.blockhash = pindex->GetBlockHash(); pfrom->PushMessage(NetMsgType::GETBLOCKTXN, req); } + } else { + // This block is either already in flight from a different + // peer, or this peer has too many blocks outstanding to + // download from. + // Optimistically try to reconstruct anyway since we might be + // able to without any round trips. + PartiallyDownloadedBlock tempBlock(&mempool); + ReadStatus status = tempBlock.InitData(cmpctblock); + if (status != READ_STATUS_OK) { + // TODO: don't ignore failures + return true; + } + std::vector dummy; + status = tempBlock.FillBlock(block, dummy); + if (status == READ_STATUS_OK) { + fBlockReconstructed = true; + } } } else { if (fAlreadyInFlight) { // We requested this block, but its far into the future, so our // mempool will probably be useless - request the block normally std::vector vInv(1); - vInv[0] = CInv(MSG_BLOCK, cmpctblock.header.GetHash()); + vInv[0] = CInv(MSG_BLOCK | GetFetchFlags(pfrom, pindex->pprev, chainparams.GetConsensus()), cmpctblock.header.GetHash()); pfrom->PushMessage(NetMsgType::GETDATA, vInv); return true; } else { @@ -5704,6 +5800,33 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } } + if (fBlockReconstructed) { + // If we got here, we were able to optimistically reconstruct a + // block that is in flight from some other peer. However, this + // cmpctblock may be invalid. In particular, while we've checked + // that the block merkle root commits to the transaction ids, we + // haven't yet checked that tx witnesses are properly committed to + // in the coinbase witness commitment. + // + // ProcessNewBlock will call MarkBlockAsReceived(), which will + // clear any in-flight compact block state that might be present + // from some other peer. We don't want a malleated compact block + // request to interfere with block relay, so we don't want to call + // ProcessNewBlock until we've already checked that the witness + // commitment is correct. + { + LOCK(cs_main); + CValidationState dummy; + if (!ContextualCheckBlock(block, dummy, pindex->pprev)) { + // TODO: could send reject message to peer? + return true; + } + } + CValidationState state; + ProcessNewBlock(state, chainparams, pfrom, &block, true, NULL, false); + // TODO: could send reject message if block is invalid? + } + CheckBlockIndex(chainparams.GetConsensus()); } @@ -5732,20 +5855,36 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } else if (status == READ_STATUS_FAILED) { // Might have collided, fall back to getdata now :( std::vector invs; - invs.push_back(CInv(MSG_BLOCK, resp.blockhash)); + invs.push_back(CInv(MSG_BLOCK | GetFetchFlags(pfrom, chainActive.Tip(), chainparams.GetConsensus()), resp.blockhash)); pfrom->PushMessage(NetMsgType::GETDATA, invs); } else { + // Block is either okay, or possibly we received + // READ_STATUS_CHECKBLOCK_FAILED. + // Note that CheckBlock can only fail for one of a few reasons: + // 1. bad-proof-of-work (impossible here, because we've already + // accepted the header) + // 2. merkleroot doesn't match the transactions given (already + // caught in FillBlock with READ_STATUS_FAILED, so + // impossible here) + // 3. the block is otherwise invalid (eg invalid coinbase, + // block is too big, too many legacy sigops, etc). + // So if CheckBlock failed, #3 is the only possibility. + // Under BIP 152, we don't DoS-ban unless proof of work is + // invalid (we don't require all the stateless checks to have + // been run). This is handled below, so just treat this as + // though the block was successfully read, and rely on the + // handling in ProcessNewBlock to ensure the block index is + // updated, reject messages go out, etc. CValidationState state; - ProcessNewBlock(state, chainparams, pfrom, &block, false, NULL); + // BIP 152 permits peers to relay compact blocks after validating + // the header only; we should not punish peers if the block turns + // out to be invalid. + ProcessNewBlock(state, chainparams, pfrom, &block, false, NULL, false); int nDoS; if (state.IsInvalid(nDoS)) { assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes pfrom->PushMessage(NetMsgType::REJECT, strCommand, (unsigned char)state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), block.GetHash()); - if (nDoS > 0) { - LOCK(cs_main); - Misbehaving(pfrom->GetId(), nDoS); - } } } } @@ -5881,7 +6020,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pindexLast->GetBlockHash().ToString(), pindexLast->nHeight); } if (vGetData.size() > 0) { - if (nodestate->fProvidesHeaderAndIDs && vGetData.size() == 1 && mapBlocksInFlight.size() == 1 && pindexLast->pprev->IsValid(BLOCK_VALID_CHAIN) && !(nLocalServices & NODE_WITNESS)) { + if (nodestate->fSupportsDesiredCmpctVersion && vGetData.size() == 1 && mapBlocksInFlight.size() == 1 && pindexLast->pprev->IsValid(BLOCK_VALID_CHAIN)) { // We seem to be rather well-synced, so it appears pfrom was the first to provide us // with this block! Let's get them to announce using compact blocks in the future. MaybeSetPeerAsAnnouncingHeaderAndIDs(nodestate, pfrom); @@ -5912,7 +6051,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Such an unrequested block may still be processed, subject to the // conditions in AcceptBlock(). bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload(); - ProcessNewBlock(state, chainparams, pfrom, &block, forceProcessing, NULL); + ProcessNewBlock(state, chainparams, pfrom, &block, forceProcessing, NULL, true); int nDoS; if (state.IsInvalid(nDoS)) { assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes @@ -6059,8 +6198,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, CBloomFilter filter; vRecv >> filter; - LOCK(pfrom->cs_filter); - if (!filter.IsWithinSizeConstraints()) { // There is no excuse for sending a too-large filter @@ -6069,11 +6206,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } else { + LOCK(pfrom->cs_filter); delete pfrom->pfilter; pfrom->pfilter = new CBloomFilter(filter); pfrom->pfilter->UpdateEmptyFull(); + pfrom->fRelayTxes = true; } - pfrom->fRelayTxes = true; } @@ -6084,20 +6222,21 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Nodes must NEVER send a data item > 520 bytes (the max size for a script data object, // and thus, the maximum size any matched object can have) in a filteradd message - if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE) - { - LOCK(cs_main); - Misbehaving(pfrom->GetId(), 100); + bool bad = false; + if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE) { + bad = true; } else { LOCK(pfrom->cs_filter); - if (pfrom->pfilter) + if (pfrom->pfilter) { pfrom->pfilter->insert(vData); - else - { - LOCK(cs_main); - Misbehaving(pfrom->GetId(), 100); + } else { + bad = true; } } + if (bad) { + LOCK(cs_main); + Misbehaving(pfrom->GetId(), 100); + } } @@ -6146,6 +6285,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } } + else if (strCommand == NetMsgType::NOTFOUND) { + // We do not care about the NOTFOUND message, but logging an Unknown Command + // message would be undesirable as we transmit it ourselves. + } + else { // Ignore unknown commands for extensibility LogPrint("net", "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->id); @@ -6319,7 +6463,7 @@ bool SendMessages(CNode* pto) // Ping automatically sent as a latency probe & keepalive. pingSend = true; } - if (pingSend) { + if (pingSend && !pto->fDisconnect) { uint64_t nonce = 0; while (nonce == 0) { GetRandBytes((unsigned char*)&nonce, sizeof(nonce)); @@ -6400,7 +6544,7 @@ bool SendMessages(CNode* pto) if (pindexBestHeader == NULL) pindexBestHeader = chainActive.Tip(); bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->fOneShot); // Download if this is a nice peer, or we have no nice peers and this one might do. - if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) { + if (!state.fSyncStarted && !pto->fClient && !pto->fDisconnect && !fImporting && !fReindex) { // Only actively request headers from a single peer, unless we're close to today. if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) { state.fSyncStarted = true; @@ -6504,8 +6648,8 @@ bool SendMessages(CNode* pto) //TODO: Shouldn't need to reload block from disk, but requires refactor CBlock block; assert(ReadBlockFromDisk(block, pBestIndex, consensusParams)); - CBlockHeaderAndShortTxIDs cmpctblock(block); - pto->PushMessageWithFlag(SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::CMPCTBLOCK, cmpctblock); + CBlockHeaderAndShortTxIDs cmpctblock(block, state.fWantsCmpctWitness); + pto->PushMessageWithFlag(state.fWantsCmpctWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::CMPCTBLOCK, cmpctblock); state.pindexBestHeaderSent = pBestIndex; } else if (state.fPreferHeaders) { if (vHeaders.size() > 1) { @@ -6715,15 +6859,13 @@ bool SendMessages(CNode* pto) if (!pto->fDisconnect && !pto->fClient && (fFetch || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { vector vToDownload; NodeId staller = -1; - FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller); + FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller, consensusParams); BOOST_FOREACH(CBlockIndex *pindex, vToDownload) { - if (State(pto->GetId())->fHaveWitness || !IsWitnessEnabled(pindex->pprev, consensusParams)) { - uint32_t nFetchFlags = GetFetchFlags(pto, pindex->pprev, consensusParams); - vGetData.push_back(CInv(MSG_BLOCK | nFetchFlags, pindex->GetBlockHash())); - MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), consensusParams, pindex); - LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(), - pindex->nHeight, pto->id); - } + uint32_t nFetchFlags = GetFetchFlags(pto, pindex->pprev, consensusParams); + vGetData.push_back(CInv(MSG_BLOCK | nFetchFlags, pindex->GetBlockHash())); + MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), consensusParams, pindex); + LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(), + pindex->nHeight, pto->id); } if (state.nBlocksInFlight == 0 && staller != -1) { if (State(staller)->nStallingSince == 0) { @@ -6762,7 +6904,7 @@ bool SendMessages(CNode* pto) // Message: feefilter // // We don't want white listed peers to filter txs to us if we have -whitelistforcerelay - if (pto->nVersion >= FEEFILTER_VERSION && GetBoolArg("-feefilter", DEFAULT_FEEFILTER) && + if (!pto->fDisconnect && pto->nVersion >= FEEFILTER_VERSION && GetBoolArg("-feefilter", DEFAULT_FEEFILTER) && !(pto->fWhitelisted && GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY))) { CAmount currentFilter = mempool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFeePerK(); int64_t timeNow = GetTimeMicros(); diff --git a/src/main.h b/src/main.h index 65ae2488f90..024f35cd399 100644 --- a/src/main.h +++ b/src/main.h @@ -39,6 +39,7 @@ class CTxMemPool; class CValidationInterface; class CValidationState; +struct PrecomputedTransactionData; struct CNodeStateStats; struct LockPoints; @@ -88,6 +89,11 @@ static const unsigned int BLOCK_STALLING_TIMEOUT = 2; /** Number of headers sent in one getheaders result. We rely on the assumption that if a peer sends * less than this number, we reached its tip. Changing this value is a protocol upgrade. */ static const unsigned int MAX_HEADERS_RESULTS = 2000; +/** Maximum depth of blocks we're willing to serve as compact blocks to peers + * when requested. For older blocks, a regular BLOCK response will be sent. */ +static const int MAX_CMPCTBLOCK_DEPTH = 5; +/** Maximum depth of blocks we're willing to respond to GETBLOCKTXN requests for. */ +static const int MAX_BLOCKTXN_DEPTH = 10; /** Size of the "block download window": how far ahead of our current height do we fetch? * Larger windows tolerate larger download speed differences between peer, but increase the potential * degree of disordering of blocks on disk (which make reindexing and in the future perhaps pruning @@ -124,7 +130,6 @@ static const int64_t DEFAULT_MAX_TIP_AGE = 24 * 60 * 60; /** Default for -permitbaremultisig */ static const bool DEFAULT_PERMIT_BAREMULTISIG = true; -static const unsigned int DEFAULT_BYTES_PER_SIGOP = 20; static const bool DEFAULT_CHECKPOINTS_ENABLED = true; static const bool DEFAULT_TXINDEX = false; static const unsigned int DEFAULT_BANSCORE_THRESHOLD = 100; @@ -155,7 +160,7 @@ typedef boost::unordered_map BlockMap; extern BlockMap mapBlockIndex; extern uint64_t nLastBlockTx; extern uint64_t nLastBlockSize; -extern uint64_t nLastBlockCost; +extern uint64_t nLastBlockWeight; extern const std::string strMessageMagic; extern CWaitableCriticalSection csBestBlock; extern CConditionVariable cvBlockChange; @@ -165,7 +170,6 @@ extern int nScriptCheckThreads; extern bool fTxIndex; extern bool fIsBareMultisigStd; extern bool fRequireStandard; -extern unsigned int nBytesPerSigOp; extern bool fCheckBlockIndex; extern bool fCheckpointsEnabled; extern size_t nCoinCacheUsage; @@ -193,7 +197,7 @@ extern uint64_t nPruneTarget; /** Block files containing a block-height within MIN_BLOCKS_TO_KEEP of chainActive.Tip() will not be pruned. */ static const unsigned int MIN_BLOCKS_TO_KEEP = 288; -static const signed int DEFAULT_CHECKBLOCKS = MIN_BLOCKS_TO_KEEP; +static const signed int DEFAULT_CHECKBLOCKS = 6; static const unsigned int DEFAULT_CHECKLEVEL = 3; // Require that user allocate at least 550MB for block & undo files (blk???.dat and rev???.dat) @@ -216,14 +220,14 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals); * block is made active. Note that it does not, however, guarantee that the * specific block passed to it has been checked for validity! * - * @param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganisation; or it may be set to an Invalid state if pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface (see validationinterface.h) - this will have its BlockChecked method called whenever *any* block completes validation. + * @param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganization; or it may be set to an Invalid state if pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface (see validationinterface.h) - this will have its BlockChecked method called whenever *any* block completes validation. * @param[in] pfrom The node which we are receiving the block from; it is added to mapBlockSource and may be penalised if the block is invalid. * @param[in] pblock The block we want to process. * @param[in] fForceProcessing Process this block even if unrequested; used for non-network block sources and whitelisted peers. * @param[out] dbp The already known disk position of pblock, or NULL if not yet stored. * @return True if state.IsValid() */ -bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp); +bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp, bool fMayBanPeerIfInvalid); /** Check whether enough disk space is available for an incoming block */ bool CheckDiskSpace(uint64_t nAdditionalBytes = 0); /** Open a block file (blk?????.dat) */ @@ -349,7 +353,7 @@ int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& i * instead of being performed inline. */ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &view, bool fScriptChecks, - unsigned int flags, bool cacheStore, std::vector *pvChecks = NULL); + unsigned int flags, bool cacheStore, PrecomputedTransactionData& txdata, std::vector *pvChecks = NULL); /** Apply the effects of this transaction on the UTXO set represented by view */ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight); @@ -410,12 +414,13 @@ class CScriptCheck unsigned int nFlags; bool cacheStore; ScriptError error; + PrecomputedTransactionData *txdata; public: CScriptCheck(): amount(0), ptxTo(0), nIn(0), nFlags(0), cacheStore(false), error(SCRIPT_ERR_UNKNOWN_ERROR) {} - CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, bool cacheIn) : + CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, bool cacheIn, PrecomputedTransactionData* txdataIn) : scriptPubKey(txFromIn.vout[txToIn.vin[nInIn].prevout.n].scriptPubKey), amount(txFromIn.vout[txToIn.vin[nInIn].prevout.n].nValue), - ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), cacheStore(cacheIn), error(SCRIPT_ERR_UNKNOWN_ERROR) { } + ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), cacheStore(cacheIn), error(SCRIPT_ERR_UNKNOWN_ERROR), txdata(txdataIn) { } bool operator()(); @@ -427,6 +432,7 @@ class CScriptCheck std::swap(nFlags, check.nFlags); std::swap(cacheStore, check.cacheStore); std::swap(error, check.error); + std::swap(txdata, check.txdata); } ScriptError GetScriptError() const { return error; } diff --git a/src/miner.cpp b/src/miner.cpp index 8153fb9f9ec..6cb40dae8d9 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -45,7 +45,7 @@ using namespace std; uint64_t nLastBlockTx = 0; uint64_t nLastBlockSize = 0; -uint64_t nLastBlockCost = 0; +uint64_t nLastBlockWeight = 0; class ScoreCompare { @@ -77,30 +77,30 @@ BlockAssembler::BlockAssembler(const CChainParams& _chainparams) : chainparams(_chainparams) { // Block resource limits - // If neither -blockmaxsize or -blockmaxcost is given, limit to DEFAULT_BLOCK_MAX_* + // If neither -blockmaxsize or -blockmaxweight is given, limit to DEFAULT_BLOCK_MAX_* // If only one is given, only restrict the specified resource. // If both are given, restrict both. - nBlockMaxCost = DEFAULT_BLOCK_MAX_COST; + nBlockMaxWeight = DEFAULT_BLOCK_MAX_WEIGHT; nBlockMaxSize = DEFAULT_BLOCK_MAX_SIZE; - bool fCostSet = false; - if (mapArgs.count("-blockmaxcost")) { - nBlockMaxCost = GetArg("-blockmaxcost", DEFAULT_BLOCK_MAX_COST); + bool fWeightSet = false; + if (mapArgs.count("-blockmaxweight")) { + nBlockMaxWeight = GetArg("-blockmaxweight", DEFAULT_BLOCK_MAX_WEIGHT); nBlockMaxSize = MAX_BLOCK_SERIALIZED_SIZE; - fCostSet = true; + fWeightSet = true; } if (mapArgs.count("-blockmaxsize")) { nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE); - if (!fCostSet) { - nBlockMaxCost = nBlockMaxSize * WITNESS_SCALE_FACTOR; + if (!fWeightSet) { + nBlockMaxWeight = nBlockMaxSize * WITNESS_SCALE_FACTOR; } } - // Limit cost to between 4K and MAX_BLOCK_COST-4K for sanity: - nBlockMaxCost = std::max((unsigned int)4000, std::min((unsigned int)(MAX_BLOCK_COST-4000), nBlockMaxCost)); + // Limit weight to between 4K and MAX_BLOCK_WEIGHT-4K for sanity: + nBlockMaxWeight = std::max((unsigned int)4000, std::min((unsigned int)(MAX_BLOCK_WEIGHT-4000), nBlockMaxWeight)); // Limit size to between 1K and MAX_BLOCK_SERIALIZED_SIZE-1K for sanity: nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SERIALIZED_SIZE-1000), nBlockMaxSize)); - // Whether we need to account for byte usage (in addition to cost usage) + // Whether we need to account for byte usage (in addition to weight usage) fNeedSizeAccounting = (nBlockMaxSize < MAX_BLOCK_SERIALIZED_SIZE-1000); } @@ -110,7 +110,7 @@ void BlockAssembler::resetBlock() // Reserve space for coinbase tx nBlockSize = 1000; - nBlockCost = 4000; + nBlockWeight = 4000; nBlockSigOpsCost = 400; fIncludeWitness = false; @@ -167,8 +167,7 @@ CBlockTemplate* BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn) nLastBlockTx = nBlockTx; nLastBlockSize = nBlockSize; - nLastBlockCost = nBlockCost; - LogPrintf("CreateNewBlock(): total size %u txs: %u fees: %ld sigops %d\n", nBlockSize, nBlockTx, nFees, nBlockSigOpsCost); + nLastBlockWeight = nBlockWeight; // Create coinbase transaction. CMutableTransaction coinbaseTx; @@ -182,12 +181,15 @@ CBlockTemplate* BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn) pblocktemplate->vchCoinbaseCommitment = GenerateCoinbaseCommitment(*pblock, pindexPrev, chainparams.GetConsensus()); pblocktemplate->vTxFees[0] = -nFees; + uint64_t nSerializeSize = GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION); + LogPrintf("CreateNewBlock(): total size: %u block weight: %u txs: %u fees: %ld sigops %d\n", nSerializeSize, GetBlockWeight(*pblock), nBlockTx, nFees, nBlockSigOpsCost); + // Fill in header pblock->hashPrevBlock = pindexPrev->GetBlockHash(); UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, chainparams.GetConsensus()); pblock->nNonce = 0; - pblocktemplate->vTxSigOpsCost[0] = GetLegacySigOpCount(pblock->vtx[0]); + pblocktemplate->vTxSigOpsCost[0] = WITNESS_SCALE_FACTOR * GetLegacySigOpCount(pblock->vtx[0]); CValidationState state; if (!TestBlockValidity(state, chainparams, *pblock, pindexPrev, false, false)) { @@ -223,8 +225,8 @@ void BlockAssembler::onlyUnconfirmed(CTxMemPool::setEntries& testSet) bool BlockAssembler::TestPackage(uint64_t packageSize, int64_t packageSigOpsCost) { - // TODO: switch to cost-based accounting for packages instead of vsize-based accounting. - if (nBlockCost + WITNESS_SCALE_FACTOR * packageSize >= nBlockMaxCost) + // TODO: switch to weight-based accounting for packages instead of vsize-based accounting. + if (nBlockWeight + WITNESS_SCALE_FACTOR * packageSize >= nBlockMaxWeight) return false; if (nBlockSigOpsCost + packageSigOpsCost >= MAX_BLOCK_SIGOPS_COST) return false; @@ -257,17 +259,17 @@ bool BlockAssembler::TestPackageTransactions(const CTxMemPool::setEntries& packa bool BlockAssembler::TestForBlock(CTxMemPool::txiter iter) { - if (nBlockCost + iter->GetTxCost() >= nBlockMaxCost) { + if (nBlockWeight + iter->GetTxWeight() >= nBlockMaxWeight) { // If the block is so close to full that no more txs will fit // or if we've tried more than 50 times to fill remaining space // then flag that the block is finished - if (nBlockCost > nBlockMaxCost - 400 || lastFewTxs > 50) { + if (nBlockWeight > nBlockMaxWeight - 400 || lastFewTxs > 50) { blockFinished = true; return false; } - // Once we're within 4000 cost of a full block, only look at 50 more txs + // Once we're within 4000 weight of a full block, only look at 50 more txs // to try to fill the remaining space. - if (nBlockCost > nBlockMaxCost - 4000) { + if (nBlockWeight > nBlockMaxWeight - 4000) { lastFewTxs++; } return false; @@ -315,7 +317,7 @@ void BlockAssembler::AddToBlock(CTxMemPool::txiter iter) if (fNeedSizeAccounting) { nBlockSize += ::GetSerializeSize(iter->GetTx(), SER_NETWORK, PROTOCOL_VERSION); } - nBlockCost += iter->GetTxCost(); + nBlockWeight += iter->GetTxWeight(); ++nBlockTx; nBlockSigOpsCost += iter->GetSigOpCost(); nFees += iter->GetFee(); diff --git a/src/miner.h b/src/miner.h index d16e37bb599..11753f5e437 100644 --- a/src/miner.h +++ b/src/miner.h @@ -141,11 +141,11 @@ class BlockAssembler // Configuration parameters for the block size bool fIncludeWitness; - unsigned int nBlockMaxCost, nBlockMaxSize; + unsigned int nBlockMaxWeight, nBlockMaxSize; bool fNeedSizeAccounting; // Information on the current status of the block - uint64_t nBlockCost; + uint64_t nBlockWeight; uint64_t nBlockSize; uint64_t nBlockTx; uint64_t nBlockSigOpsCost; diff --git a/src/net.cpp b/src/net.cpp index 4cbc43e4d84..0b8bfd86009 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -42,6 +42,9 @@ // Dump addresses to peers.dat and banlist.dat every 15 minutes (900s) #define DUMP_ADDRESSES_INTERVAL 900 +// We add a random period time (0 to 1 seconds) to feeler connections to prevent synchronization. +#define FEELER_SLEEP_WINDOW 1 + #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL) #define MSG_NOSIGNAL 0 #endif @@ -60,6 +63,7 @@ namespace { const int MAX_OUTBOUND_CONNECTIONS = 8; + const int MAX_FEELER_CONNECTIONS = 1; struct ListenSocket { SOCKET socket; @@ -175,7 +179,7 @@ static std::vector convertSeed6(const std::vector &vSeedsIn // one by discovery. CAddress GetLocalAddress(const CNetAddr *paddrPeer) { - CAddress ret(CService("0.0.0.0",GetListenPort()), NODE_NONE); + CAddress ret(CService("0.0.0.0",GetListenPort()), nLocalServices); CService addr; if (GetLocal(addr, paddrPeer)) { @@ -495,7 +499,7 @@ void CNode::PushVersion() int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime()); CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0", 0), addr.nServices)); - CAddress addrMe = GetLocalAddress(&addr); + CAddress addrMe = CAddress(CService(), nLocalServices); GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); if (fLogIPs) LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), id); @@ -873,7 +877,7 @@ struct NodeEvictionCandidate int64_t nMinPingUsecTime; int64_t nLastBlockTime; int64_t nLastTXTime; - bool fNetworkNode; + bool fRelevantServices; bool fRelayTxes; bool fBloomFilter; CAddress addr; @@ -898,7 +902,7 @@ static bool CompareNodeBlockTime(const NodeEvictionCandidate &a, const NodeEvict { // There is a fall-through here because it is common for a node to have many peers which have not yet relayed a block. if (a.nLastBlockTime != b.nLastBlockTime) return a.nLastBlockTime < b.nLastBlockTime; - if (a.fNetworkNode != b.fNetworkNode) return b.fNetworkNode; + if (a.fRelevantServices != b.fRelevantServices) return b.fRelevantServices; return a.nTimeConnected > b.nTimeConnected; } @@ -932,7 +936,8 @@ static bool AttemptToEvictConnection() { if (node->fDisconnect) continue; NodeEvictionCandidate candidate = {node->id, node->nTimeConnected, node->nMinPingUsecTime, - node->nLastBlockTime, node->nLastTXTime, node->fNetworkNode, + node->nLastBlockTime, node->nLastTXTime, + (node->nServices & nRelevantServices) == nRelevantServices, node->fRelayTxes, node->pfilter != NULL, node->addr, node->nKeyedNetGroup}; vEvictionCandidates.push_back(candidate); } @@ -1016,7 +1021,7 @@ static void AcceptConnection(const ListenSocket& hListenSocket) { SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len); CAddress addr; int nInbound = 0; - int nMaxInbound = nMaxConnections - MAX_OUTBOUND_CONNECTIONS; + int nMaxInbound = nMaxConnections - (MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS); if (hSocket != INVALID_SOCKET) if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr)) @@ -1484,6 +1489,7 @@ static std::string GetDNSHost(const CDNSSeedData& data, ServiceFlags* requiredSe return data.host; } + // See chainparams.cpp, most dnsseeds only support one or two possible servicebits hostnames return strprintf("x%x.%s", *requiredServiceBits, data.host); } @@ -1491,12 +1497,19 @@ static std::string GetDNSHost(const CDNSSeedData& data, ServiceFlags* requiredSe void ThreadDNSAddressSeed() { // goal: only query DNS seeds if address need is acute + // Avoiding DNS seeds when we don't need them improves user privacy by + // creating fewer identifying DNS requests, reduces trust by giving seeds + // less influence on the network topology, and reduces traffic to the seeds. if ((addrman.size() > 0) && (!GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) { MilliSleep(11 * 1000); LOCK(cs_vNodes); - if (vNodes.size() >= 2) { + int nRelevant = 0; + for (auto pnode : vNodes) { + nRelevant += pnode->fSuccessfullyConnected && ((pnode->nServices & nRelevantServices) == nRelevantServices); + } + if (nRelevant >= 2) { LogPrintf("P2P peers available. Skipped DNS seeding.\n"); return; } @@ -1609,6 +1622,9 @@ void ThreadOpenConnections() // Initiate network connections int64_t nStart = GetTime(); + + // Minimum time before next feeler connection (in microseconds). + int64_t nNextFeeler = PoissonNextSend(nStart*1000*1000, FEELER_INTERVAL); while (true) { ProcessOneShot(); @@ -1647,12 +1663,34 @@ void ThreadOpenConnections() } } - int64_t nANow = GetAdjustedTime(); + // Feeler Connections + // + // Design goals: + // * Increase the number of connectable addresses in the tried table. + // + // Method: + // * Choose a random address from new and attempt to connect to it if we can connect + // successfully it is added to tried. + // * Start attempting feeler connections only after node finishes making outbound + // connections. + // * Only make a feeler connection once every few minutes. + // + bool fFeeler = false; + if (nOutbound >= MAX_OUTBOUND_CONNECTIONS) { + int64_t nTime = GetTimeMicros(); // The current time right now (in microseconds). + if (nTime > nNextFeeler) { + nNextFeeler = PoissonNextSend(nTime, FEELER_INTERVAL); + fFeeler = true; + } else { + continue; + } + } + int64_t nANow = GetAdjustedTime(); int nTries = 0; while (true) { - CAddrInfo addr = addrman.Select(); + CAddrInfo addr = addrman.Select(fFeeler); // if we selected an invalid address, restart if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr)) @@ -1676,8 +1714,8 @@ void ThreadOpenConnections() if (nANow - addr.nLastTry < 600 && nTries < 30) continue; - // only consider nodes missing relevant services after 40 failed attemps - if ((addr.nServices & nRelevantServices) != nRelevantServices && nTries < 40) + // only consider nodes missing relevant services after 40 failed attempts and only if less than half the outbound are up. + if ((addr.nServices & nRelevantServices) != nRelevantServices && (nTries < 40 || nOutbound >= (MAX_OUTBOUND_CONNECTIONS >> 1))) continue; // do not allow non-default ports, unless after 50 invalid addresses selected already @@ -1688,8 +1726,17 @@ void ThreadOpenConnections() break; } - if (addrConnect.IsValid()) - OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant); + if (addrConnect.IsValid()) { + + if (fFeeler) { + // Add small amount of random noise before connection to avoid synchronization. + int randsleep = GetRandInt(FEELER_SLEEP_WINDOW * 1000); + MilliSleep(randsleep); + LogPrint("net", "Making feeler connection to %s\n", addrConnect.ToString()); + } + + OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant, NULL, false, fFeeler); + } } } @@ -1771,7 +1818,7 @@ void ThreadOpenAddedConnections() } // if successful, this moves the passed grant to the constructed node -bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot) +bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot, bool fFeeler) { // // Initiate outbound network connection @@ -1795,6 +1842,8 @@ bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSem pnode->fNetworkNode = true; if (fOneShot) pnode->fOneShot = true; + if (fFeeler) + pnode->fFeeler = true; return true; } @@ -2050,11 +2099,13 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) DumpBanlist(); } + uiInterface.InitMessage(_("Starting network threads...")); + fAddressesInitialized = true; if (semOutbound == NULL) { // initialize semaphore - int nMaxOutbound = std::min(MAX_OUTBOUND_CONNECTIONS, nMaxConnections); + int nMaxOutbound = std::min((MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS), nMaxConnections); semOutbound = new CSemaphore(nMaxOutbound); } @@ -2096,7 +2147,7 @@ bool StopNode() LogPrintf("StopNode()\n"); MapPort(false); if (semOutbound) - for (int i=0; ipost(); if (fAddressesInitialized) @@ -2182,11 +2233,7 @@ void CNode::RecordBytesSent(uint64_t bytes) void CNode::SetMaxOutboundTarget(uint64_t limit) { LOCK(cs_totalBytesSent); - uint64_t recommendedMinimum = (nMaxOutboundTimeframe / 600) * MAX_BLOCK_SERIALIZED_SIZE; nMaxOutboundLimit = limit; - - if (limit > 0 && limit < recommendedMinimum) - LogPrintf("Max outbound target is very small (%s bytes) and will be overshot. Recommended minimum is %s bytes.\n", nMaxOutboundLimit, recommendedMinimum); } uint64_t CNode::GetMaxOutboundTarget() @@ -2437,6 +2484,7 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa fWhitelisted = false; fOneShot = false; fClient = false; // set by version message + fFeeler = false; fInbound = fInboundIn; fNetworkNode = false; fSuccessfullyConnected = false; diff --git a/src/net.h b/src/net.h index 41315fc9b9f..63bb2c2ecfb 100644 --- a/src/net.h +++ b/src/net.h @@ -41,6 +41,8 @@ namespace boost { static const int PING_INTERVAL = 2 * 60; /** Time after which to disconnect, after waiting for a ping response (or inactivity). */ static const int TIMEOUT_INTERVAL = 20 * 60; +/** Run the feeler connection loop once every 2 minutes or 120 seconds. **/ +static const int FEELER_INTERVAL = 120; /** The maximum number of entries in an 'inv' protocol message */ static const unsigned int MAX_INV_SZ = 50000; /** The maximum number of new addresses to accumulate before announcing. */ @@ -89,7 +91,7 @@ CNode* FindNode(const CSubNet& subNet); CNode* FindNode(const std::string& addrName); CNode* FindNode(const CService& ip); CNode* FindNode(const NodeId id); //TODO: Remove this -bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false); +bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false, bool fFeeler = false); void MapPort(bool fUseUPnP); unsigned short GetListenPort(); bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false); @@ -350,6 +352,7 @@ class CNode // the network or wire types and the cleaned string used when displayed or logged. std::string strSubVer, cleanSubVer; bool fWhitelisted; // This peer can bypass DoS banning. + bool fFeeler; // If true this node is being used as a short lived feeler. bool fOneShot; bool fClient; bool fInbound; diff --git a/src/netbase.cpp b/src/netbase.cpp index e2a516986c1..ebf30d43e30 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -96,30 +96,9 @@ bool static LookupIntern(const char *pszName, std::vector& vIP, unsign } } -#ifdef HAVE_GETADDRINFO_A - struct in_addr ipv4_addr; -#ifdef HAVE_INET_PTON - if (inet_pton(AF_INET, pszName, &ipv4_addr) > 0) { - vIP.push_back(CNetAddr(ipv4_addr)); - return true; - } - - struct in6_addr ipv6_addr; - if (inet_pton(AF_INET6, pszName, &ipv6_addr) > 0) { - vIP.push_back(CNetAddr(ipv6_addr)); - return true; - } -#else - ipv4_addr.s_addr = inet_addr(pszName); - if (ipv4_addr.s_addr != INADDR_NONE) { - vIP.push_back(CNetAddr(ipv4_addr)); - return true; - } -#endif -#endif - struct addrinfo aiHint; memset(&aiHint, 0, sizeof(struct addrinfo)); + aiHint.ai_socktype = SOCK_STREAM; aiHint.ai_protocol = IPPROTO_TCP; aiHint.ai_family = AF_UNSPEC; @@ -128,33 +107,8 @@ bool static LookupIntern(const char *pszName, std::vector& vIP, unsign #else aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST; #endif - struct addrinfo *aiRes = NULL; -#ifdef HAVE_GETADDRINFO_A - struct gaicb gcb, *query = &gcb; - memset(query, 0, sizeof(struct gaicb)); - gcb.ar_name = pszName; - gcb.ar_request = &aiHint; - int nErr = getaddrinfo_a(GAI_NOWAIT, &query, 1, NULL); - if (nErr) - return false; - - do { - // Should set the timeout limit to a reasonable value to avoid - // generating unnecessary checking call during the polling loop, - // while it can still response to stop request quick enough. - // 2 seconds looks fine in our situation. - struct timespec ts = { 2, 0 }; - gai_suspend(&query, 1, &ts); - boost::this_thread::interruption_point(); - - nErr = gai_error(query); - if (0 == nErr) - aiRes = query->ar_result; - } while (nErr == EAI_INPROGRESS); -#else int nErr = getaddrinfo(pszName, NULL, &aiHint, &aiRes); -#endif if (nErr) return false; diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index 7b0e8b7d08c..453b4a57d95 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -495,7 +495,8 @@ void CBlockPolicyEstimator::processBlock(unsigned int nBlockHeight, CFeeRate CBlockPolicyEstimator::estimateFee(int confTarget) { // Return failure if trying to analyze a target we're not tracking - if (confTarget <= 0 || (unsigned int)confTarget > feeStats.GetMaxConfirms()) + // It's not possible to get reasonable estimates for confTarget of 1 + if (confTarget <= 1 || (unsigned int)confTarget > feeStats.GetMaxConfirms()) return CFeeRate(0); double median = feeStats.EstimateMedianVal(confTarget, SUFFICIENT_FEETXS, MIN_SUCCESS_PCT, true, nBestSeenHeight); @@ -514,6 +515,10 @@ CFeeRate CBlockPolicyEstimator::estimateSmartFee(int confTarget, int *answerFoun if (confTarget <= 0 || (unsigned int)confTarget > feeStats.GetMaxConfirms()) return CFeeRate(0); + // It's not possible to get reasonable estimates for confTarget of 1 + if (confTarget == 1) + confTarget = 2; + double median = -1; while (median < 0 && (unsigned int)confTarget <= feeStats.GetMaxConfirms()) { median = feeStats.EstimateMedianVal(confTarget++, SUFFICIENT_FEETXS, MIN_SUCCESS_PCT, true, nBestSeenHeight); diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index f2148bfe105..ae42b2bd74f 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin developers +// Copyright (c) 2009-2016 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -31,7 +31,7 @@ * DUP CHECKSIG DROP ... repeated 100 times... OP_1 */ -bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) +bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType, const bool witnessEnabled) { std::vector > vSolutions; if (!Solver(scriptPubKey, whichType, vSolutions)) @@ -50,10 +50,13 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) (!fAcceptDatacarrier || scriptPubKey.size() > nMaxDatacarrierBytes)) return false; + else if (!witnessEnabled && (whichType == TX_WITNESS_V0_KEYHASH || whichType == TX_WITNESS_V0_SCRIPTHASH)) + return false; + return whichType != TX_NONSTANDARD; } -bool IsStandardTx(const CTransaction& tx, std::string& reason) +bool IsStandardTx(const CTransaction& tx, std::string& reason, const bool witnessEnabled) { if (tx.nVersion > CTransaction::MAX_STANDARD_VERSION || tx.nVersion < 1) { reason = "version"; @@ -64,8 +67,8 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason) // almost as much to process as they cost the sender in fees, because // computing signature hashes is O(ninputs*txsize). Limiting transactions // to MAX_STANDARD_TX_SIZE mitigates CPU exhaustion attacks. - unsigned int sz = GetTransactionCost(tx); - if (sz >= MAX_STANDARD_TX_COST) { + unsigned int sz = GetTransactionWeight(tx); + if (sz >= MAX_STANDARD_TX_WEIGHT) { reason = "tx-size"; return false; } @@ -92,7 +95,7 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason) unsigned int nDataOut = 0; txnouttype whichType; BOOST_FOREACH(const CTxOut& txout, tx.vout) { - if (!::IsStandard(txout.scriptPubKey, whichType)) { + if (!::IsStandard(txout.scriptPubKey, whichType, witnessEnabled)) { reason = "scriptpubkey"; return false; } @@ -151,12 +154,66 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) return true; } -int64_t GetVirtualTransactionSize(int64_t nCost) +bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) +{ + if (tx.IsCoinBase()) + return true; // Coinbases are skipped + + for (unsigned int i = 0; i < tx.vin.size(); i++) + { + // We don't care if witness for this input is empty, since it must not be bloated. + // If the script is invalid without witness, it would be caught sooner or later during validation. + if (tx.wit.vtxinwit[i].IsNull()) + continue; + + const CTxOut &prev = mapInputs.GetOutputFor(tx.vin[i]); + + // get the scriptPubKey corresponding to this input: + CScript prevScript = prev.scriptPubKey; + + if (prevScript.IsPayToScriptHash()) { + std::vector > stack; + // If the scriptPubKey is P2SH, we try to extract the redeemScript casually by converting the scriptSig + // into a stack. We do not check IsPushOnly nor compare the hash as these will be done later anyway. + // If the check fails at this stage, we know that this txid must be a bad one. + if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SIGVERSION_BASE)) + return false; + if (stack.empty()) + return false; + prevScript = CScript(stack.back().begin(), stack.back().end()); + } + + int witnessversion = 0; + std::vector witnessprogram; + + // Non-witness program must not be associated with any witness + if (!prevScript.IsWitnessProgram(witnessversion, witnessprogram)) + return false; + + // Check P2WSH standard limits + if (witnessversion == 0 && witnessprogram.size() == 32) { + if (tx.wit.vtxinwit[i].scriptWitness.stack.back().size() > MAX_STANDARD_P2WSH_SCRIPT_SIZE) + return false; + size_t sizeWitnessStack = tx.wit.vtxinwit[i].scriptWitness.stack.size() - 1; + if (sizeWitnessStack > MAX_STANDARD_P2WSH_STACK_ITEMS) + return false; + for (unsigned int j = 0; j < sizeWitnessStack; j++) { + if (tx.wit.vtxinwit[i].scriptWitness.stack[j].size() > MAX_STANDARD_P2WSH_STACK_ITEM_SIZE) + return false; + } + } + } + return true; +} + +unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP; + +int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost) { - return (nCost + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR; + return (std::max(nWeight, nSigOpCost * nBytesPerSigOp) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR; } -int64_t GetVirtualTransactionSize(const CTransaction& tx) +int64_t GetVirtualTransactionSize(const CTransaction& tx, int64_t nSigOpCost) { - return GetVirtualTransactionSize(GetTransactionCost(tx)); + return GetVirtualTransactionSize(GetTransactionWeight(tx), nSigOpCost); } diff --git a/src/policy/policy.h b/src/policy/policy.h index 29a8cc57c20..814e6c0b6ff 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin developers +// Copyright (c) 2009-2016 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -18,16 +18,24 @@ class CCoinsViewCache; static const unsigned int DEFAULT_BLOCK_MAX_SIZE = 750000; /** Default for -blockprioritysize, maximum space for zero/low-fee transactions **/ static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 0; -/** Default for -blockmaxcost, which control the range of block costs the mining code will create **/ -static const unsigned int DEFAULT_BLOCK_MAX_COST = 3000000; -/** The maximum size for transactions we're willing to relay/mine */ -static const unsigned int MAX_STANDARD_TX_COST = 400000; +/** Default for -blockmaxweight, which controls the range of block weights the mining code will create **/ +static const unsigned int DEFAULT_BLOCK_MAX_WEIGHT = 3000000; +/** The maximum weight for transactions we're willing to relay/mine */ +static const unsigned int MAX_STANDARD_TX_WEIGHT = 400000; /** Maximum number of signature check operations in an IsStandard() P2SH script */ static const unsigned int MAX_P2SH_SIGOPS = 15; /** The maximum number of sigops we're willing to relay/mine in a single tx */ static const unsigned int MAX_STANDARD_TX_SIGOPS_COST = MAX_BLOCK_SIGOPS_COST/5; /** Default for -maxmempool, maximum megabytes of mempool memory usage */ static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE = 300; +/** Default for -bytespersigop */ +static const unsigned int DEFAULT_BYTES_PER_SIGOP = 20; +/** The maximum number of witness stack items in a standard P2WSH script */ +static const unsigned int MAX_STANDARD_P2WSH_STACK_ITEMS = 100; +/** The maximum size of each witness stack item in a standard P2WSH script */ +static const unsigned int MAX_STANDARD_P2WSH_STACK_ITEM_SIZE = 80; +/** The maximum size of a standard witnessScript */ +static const unsigned int MAX_STANDARD_P2WSH_SCRIPT_SIZE = 3600; /** * Standard script verification flags that standard transactions will comply * with. However scripts violating these flags may still be present in valid @@ -40,11 +48,14 @@ static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY SCRIPT_VERIFY_NULLDUMMY | SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS | SCRIPT_VERIFY_CLEANSTACK | + SCRIPT_VERIFY_MINIMALIF | + SCRIPT_VERIFY_NULLFAIL | SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY | SCRIPT_VERIFY_CHECKSEQUENCEVERIFY | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_WITNESS | - SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM; + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM | + SCRIPT_VERIFY_WITNESS_PUBKEYTYPE; /** For convenience, standard but not mandatory verify flags. */ static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS; @@ -53,21 +64,29 @@ static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_ static const unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS = LOCKTIME_VERIFY_SEQUENCE | LOCKTIME_MEDIAN_TIME_PAST; -bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType); +bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType, const bool witnessEnabled = false); /** * Check for standard transaction types * @return True if all outputs (scriptPubKeys) use only standard transaction forms */ -bool IsStandardTx(const CTransaction& tx, std::string& reason); +bool IsStandardTx(const CTransaction& tx, std::string& reason, const bool witnessEnabled = false); /** * Check for standard transaction types * @param[in] mapInputs Map of previous transactions that have outputs we're spending * @return True if all inputs (scriptSigs) use only standard transaction forms */ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs); + /** + * Check if the transaction is over standard P2WSH resources limit: + * 3600bytes witnessScript size, 80bytes per witness stack element, 100 witness stack elements + * These limits are adequate for multi-signature up to n-of-100 using OP_CHECKSIG, OP_ADD, and OP_EQUAL, + */ +bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs); + +extern unsigned int nBytesPerSigOp; -/** Compute the virtual transaction size (cost reinterpreted as bytes). */ -int64_t GetVirtualTransactionSize(int64_t nCost); -int64_t GetVirtualTransactionSize(const CTransaction& tx); +/** Compute the virtual transaction size (weight reinterpreted as bytes). */ +int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost); +int64_t GetVirtualTransactionSize(const CTransaction& tx, int64_t nSigOpCost = 0); #endif // BITCOIN_POLICY_POLICY_H diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index df900388f26..0e6ab4dd718 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -32,11 +32,11 @@ std::string CBlock::ToString() const return s.str(); } -int64_t GetBlockCost(const CBlock& block) +int64_t GetBlockWeight(const CBlock& block) { - // This implements the cost = (stripped_size * 4) + witness_size formula, + // This implements the weight = (stripped_size * 4) + witness_size formula, // using only serialization with and without witness data. As witness_size // is equal to total_size - stripped_size, this formula is identical to: - // cost = (stripped_size * 3) + total_size. + // weight = (stripped_size * 3) + total_size. return ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION); } diff --git a/src/primitives/block.h b/src/primitives/block.h index e2a309e63d8..72dfed985ae 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -154,7 +154,7 @@ struct CBlockLocator } }; -/** Compute the consensus-critical block cost (see BIP 141). */ -int64_t GetBlockCost(const CBlock& tx); +/** Compute the consensus-critical block weight (see BIP 141). */ +int64_t GetBlockWeight(const CBlock& tx); #endif // BITCOIN_PRIMITIVES_BLOCK_H diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 7f10409c053..2fdc59ea077 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -100,7 +100,7 @@ CAmount CTransaction::GetValueOut() const { nValueOut += it->nValue; if (!MoneyRange(it->nValue) || !MoneyRange(nValueOut)) - throw std::runtime_error("CTransaction::GetValueOut(): value out of range"); + throw std::runtime_error(std::string(__func__) + ": value out of range"); } return nValueOut; } @@ -121,7 +121,7 @@ unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const // Providing any more cleanup incentive than making additional inputs free would // risk encouraging people to create junk outputs to redeem later. if (nTxSize == 0) - nTxSize = (GetTransactionCost(*this) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR; + nTxSize = (GetTransactionWeight(*this) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR; for (std::vector::const_iterator it(vin.begin()); it != vin.end(); ++it) { unsigned int offset = 41U + std::min(110U, (unsigned int)it->scriptSig.size()); @@ -149,7 +149,7 @@ std::string CTransaction::ToString() const return str; } -int64_t GetTransactionCost(const CTransaction& tx) +int64_t GetTransactionWeight(const CTransaction& tx) { return ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR -1) + ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); } diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 8a2d5dd22c8..d37890667f9 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -459,7 +459,7 @@ struct CMutableTransaction uint256 GetHash() const; }; -/** Compute the cost of a transaction, as defined by BIP 141 */ -int64_t GetTransactionCost(const CTransaction &tx); +/** Compute the weight of a transaction, as defined by BIP 141 */ +int64_t GetTransactionWeight(const CTransaction &tx); #endif // BITCOIN_PRIMITIVES_TRANSACTION_H diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index 135f15ffa85..727956c88dd 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -83,7 +83,7 @@ AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode mode, deleteAction = new QAction(ui->deleteAddress->text(), this); // Build context menu - contextMenu = new QMenu(); + contextMenu = new QMenu(this); contextMenu->addAction(copyAddressAction); contextMenu->addAction(copyLabelAction); contextMenu->addAction(editAction); diff --git a/src/qt/bantablemodel.cpp b/src/qt/bantablemodel.cpp index d95106b5ac8..7707ce7b6be 100644 --- a/src/qt/bantablemodel.cpp +++ b/src/qt/bantablemodel.cpp @@ -86,7 +86,7 @@ BanTableModel::BanTableModel(ClientModel *parent) : clientModel(parent) { columns << tr("IP/Netmask") << tr("Banned Until"); - priv = new BanTablePriv(); + priv.reset(new BanTablePriv()); // default to unsorted priv->sortColumn = -1; @@ -94,6 +94,11 @@ BanTableModel::BanTableModel(ClientModel *parent) : refresh(); } +BanTableModel::~BanTableModel() +{ + // Intentionally left empty +} + int BanTableModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); diff --git a/src/qt/bantablemodel.h b/src/qt/bantablemodel.h index fe9600ac0bd..3c03d05c051 100644 --- a/src/qt/bantablemodel.h +++ b/src/qt/bantablemodel.h @@ -40,6 +40,7 @@ class BanTableModel : public QAbstractTableModel public: explicit BanTableModel(ClientModel *parent = 0); + ~BanTableModel(); void startAutoRefresh(); void stopAutoRefresh(); @@ -66,7 +67,7 @@ public Q_SLOTS: private: ClientModel *clientModel; QStringList columns; - BanTablePriv *priv; + std::unique_ptr priv; }; #endif // BITCOIN_QT_BANTABLEMODEL_H diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 64b5c83d72a..dbf372b12fa 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -245,6 +245,7 @@ public Q_SLOTS: #endif int returnValue; const PlatformStyle *platformStyle; + std::unique_ptr shutdownWindow; void startThread(); }; @@ -365,9 +366,8 @@ void BitcoinApplication::createWindow(const NetworkStyle *networkStyle) void BitcoinApplication::createSplashScreen(const NetworkStyle *networkStyle) { SplashScreen *splash = new SplashScreen(0, networkStyle); - // We don't hold a direct pointer to the splash screen after creation, so use - // Qt::WA_DeleteOnClose to make sure that the window will be deleted eventually. - splash->setAttribute(Qt::WA_DeleteOnClose); + // We don't hold a direct pointer to the splash screen after creation, but the splash + // screen will take care of deleting itself when slotFinish happens. splash->show(); connect(this, SIGNAL(splashFinished(QWidget*)), splash, SLOT(slotFinish(QWidget*))); connect(this, SIGNAL(requestedShutdown()), splash, SLOT(close())); @@ -409,6 +409,11 @@ void BitcoinApplication::requestInitialize() void BitcoinApplication::requestShutdown() { + // Show a simple window indicating shutdown status + // Do this first as some of the steps may take some time below, + // for example the RPC console may still be executing a command. + shutdownWindow.reset(ShutdownWindow::showShutdownWindow(window)); + qDebug() << __func__ << ": Requesting shutdown"; startThread(); window->hide(); @@ -423,9 +428,6 @@ void BitcoinApplication::requestShutdown() delete clientModel; clientModel = 0; - // Show a simple window indicating shutdown status - ShutdownWindow::showShutdownWindow(window); - // Request shutdown from core thread Q_EMIT requestedShutdown(); } @@ -496,7 +498,7 @@ void BitcoinApplication::shutdownResult(int retval) void BitcoinApplication::handleRunawayException(const QString &message) { QMessageBox::critical(0, "Runaway exception", BitcoinGUI::tr("A fatal error occurred. Bitcoin can no longer continue safely and will quit.") + QString("\n\n") + message); - ::exit(1); + ::exit(EXIT_FAILURE); } WId BitcoinApplication::getMainWinId() const @@ -573,12 +575,13 @@ int main(int argc, char *argv[]) { HelpMessageDialog help(NULL, mapArgs.count("-version")); help.showOrPrint(); - return 1; + return EXIT_SUCCESS; } /// 5. Now that settings and translations are available, ask user for data directory // User language is set up: pick a data directory - Intro::pickDataDirectory(); + if (!Intro::pickDataDirectory()) + return EXIT_SUCCESS; /// 6. Determine availability of data directory and parse bitcoin.conf /// - Do not call GetDataDir(true) before this step finishes @@ -586,14 +589,14 @@ int main(int argc, char *argv[]) { QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"]))); - return 1; + return EXIT_FAILURE; } try { ReadConfigFile(mapArgs, mapMultiArgs); } catch (const std::exception& e) { QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: Cannot parse configuration file: %1. Only use key=value syntax.").arg(e.what())); - return false; + return EXIT_FAILURE; } /// 7. Determine network (and switch to network specific options) @@ -607,7 +610,7 @@ int main(int argc, char *argv[]) SelectParams(ChainNameFromCommandLine()); } catch(std::exception &e) { QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: %1").arg(e.what())); - return 1; + return EXIT_FAILURE; } #ifdef ENABLE_WALLET // Parse URIs on command line -- this can affect Params() @@ -629,7 +632,7 @@ int main(int argc, char *argv[]) // - Do this after creating app and setting up translations, so errors are // translated properly. if (PaymentServer::ipcSendCommandLine()) - exit(0); + exit(EXIT_SUCCESS); // Start up the payment server early, too, so impatient users that click on // bitcoin: links repeatedly have their payment requests routed to this process: diff --git a/src/qt/bitcoin_locale.qrc b/src/qt/bitcoin_locale.qrc index 8dd07c3d417..aae07ffb7e8 100644 --- a/src/qt/bitcoin_locale.qrc +++ b/src/qt/bitcoin_locale.qrc @@ -4,8 +4,8 @@ locale/bitcoin_af_ZA.qm locale/bitcoin_ar.qm locale/bitcoin_be_BY.qm - locale/bitcoin_bg.qm locale/bitcoin_bg_BG.qm + locale/bitcoin_bg.qm locale/bitcoin_ca_ES.qm locale/bitcoin_ca.qm locale/bitcoin_ca@valencia.qm @@ -57,6 +57,7 @@ locale/bitcoin_mn.qm locale/bitcoin_ms_MY.qm locale/bitcoin_nb.qm + locale/bitcoin_ne.qm locale/bitcoin_nl.qm locale/bitcoin_pam.qm locale/bitcoin_pl.qm diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 9042e3b56a3..38cfc262b85 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -496,6 +496,15 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel) // Disable context menu on tray icon trayIconMenu->clear(); } + // Propagate cleared model to child objects + rpcConsole->setClientModel(nullptr); +#ifdef ENABLE_WALLET + if (walletFrame) + { + walletFrame->setClientModel(nullptr); + } +#endif // ENABLE_WALLET + unitDisplayControl->setOptionsModel(nullptr); } } @@ -902,17 +911,22 @@ void BitcoinGUI::closeEvent(QCloseEvent *event) #ifndef Q_OS_MAC // Ignored on Mac if(clientModel && clientModel->getOptionsModel()) { - if(!clientModel->getOptionsModel()->getMinimizeToTray() && - !clientModel->getOptionsModel()->getMinimizeOnClose()) + if(!clientModel->getOptionsModel()->getMinimizeOnClose()) { // close rpcConsole in case it was open to make some space for the shutdown window rpcConsole->close(); QApplication::quit(); } + else + { + QMainWindow::showMinimized(); + event->ignore(); + } } -#endif +#else QMainWindow::closeEvent(event); +#endif } void BitcoinGUI::showEvent(QShowEvent *event) @@ -1142,7 +1156,7 @@ void UnitDisplayStatusBarControl::mousePressEvent(QMouseEvent *event) /** Creates context menu, its actions, and wires up all the relevant signals for mouse events. */ void UnitDisplayStatusBarControl::createContextMenu() { - menu = new QMenu(); + menu = new QMenu(this); Q_FOREACH(BitcoinUnits::Unit u, BitcoinUnits::availableUnits()) { QAction *menuAction = new QAction(QString(BitcoinUnits::name(u)), this); diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index bca5b72827f..7f90a51c562 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -60,6 +60,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" QT_TRANSLATE_NOOP("bitcoin-core", "" "Do not keep transactions in the mempool longer than hours (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Equivalent bytes per sigop in transactions for relay and mining (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "Error loading %s: You can't enable HD on a already existing non-HD wallet"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Error reading %s! All keys read correctly, but transaction data or address " @@ -82,8 +84,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Fees (in %s/kB) smaller than this are considered zero fee for transaction " "creation (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Force relay of transactions from whitelisted peers even they violate local " -"relay policy (default: %d)"), +"Force relay of transactions from whitelisted peers even if they violate " +"local relay policy (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "How thorough the block verification of -checkblocks is (0-4, default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -143,6 +145,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Set the number of script verification threads (%u to %d, 0 = auto, <0 = " "leave that many cores free, default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Sets the serialization of raw transaction or block hex returned in non-" +"verbose mode, non-segwit(0) or segwit(1) (default: %d)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "Support filtering of blocks and transaction with bloom filters (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "The block database contains a block which appears to be from the future. " @@ -199,8 +204,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Warning: We do not appear to fully agree with our peers! You may need to " "upgrade, or other nodes may need to upgrade."), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Whitelist peers connecting from the given netmask or IP address. Can be " -"specified multiple times."), +"Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or CIDR " +"notated network (e.g. 1.2.3.0/24). Can be specified multiple times."), QT_TRANSLATE_NOOP("bitcoin-core", "" "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"), @@ -273,6 +278,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=: '%s' ( QT_TRANSLATE_NOOP("bitcoin-core", "Invalid netmask specified in -whitelist: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most unconnectable transactions in memory (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Keep the transaction memory pool below megabytes (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Keypool ran out, please call keypoolrefill first"), QT_TRANSLATE_NOOP("bitcoin-core", "Listen for JSON-RPC connections on (default: %u or testnet: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on (default: %u or testnet: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."), @@ -284,7 +290,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Maintain at most connections to peers (de QT_TRANSLATE_NOOP("bitcoin-core", "Make the wallet broadcast transactions"), QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection receive buffer, *1000 bytes (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, *1000 bytes (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Minimum bytes per sigop in transactions we relay and mine (default: %u)"), 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."), @@ -311,7 +316,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to console instead of d QT_TRANSLATE_NOOP("bitcoin-core", "Send transactions as zero-fee transactions if possible (default: %u)"), 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 (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Set maximum BIP141 block cost (default: %d)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Set maximum BIP141 block weight (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set maximum block size in bytes (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set the number of threads to service RPC calls (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Show all debugging options (usage: --help -help-debug)"), @@ -324,6 +329,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: %s)"), 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", "Starting network threads..."), QT_TRANSLATE_NOOP("bitcoin-core", "The source code is available from %s."), QT_TRANSLATE_NOOP("bitcoin-core", "The transaction amount is too small to pay the fee"), QT_TRANSLATE_NOOP("bitcoin-core", "This is experimental software."), diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 14661b857a5..9530b63a27f 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -6,6 +6,7 @@ #include "bantablemodel.h" #include "guiconstants.h" +#include "guiutil.h" #include "peertablemodel.h" #include "chainparams.h" @@ -186,7 +187,7 @@ QString ClientModel::formatClientStartupTime() const QString ClientModel::dataDir() const { - return QString::fromStdString(GetDataDir().string()); + return GUIUtil::boostPathToQString(GetDataDir()); } void ClientModel::updateBanlist() diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 837f8ba6c18..866d3872c6f 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -35,6 +35,13 @@ QList CoinControlDialog::payAmounts; CCoinControl* CoinControlDialog::coinControl = new CCoinControl(); bool CoinControlDialog::fSubtractFeeFromAmount = false; +bool CCoinControlWidgetItem::operator<(const QTreeWidgetItem &other) const { + int column = treeWidget()->sortColumn(); + if (column == CoinControlDialog::COLUMN_AMOUNT || column == CoinControlDialog::COLUMN_DATE || column == CoinControlDialog::COLUMN_CONFIRMATIONS) + return data(column, Qt::UserRole).toLongLong() < other.data(column, Qt::UserRole).toLongLong(); + return QTreeWidgetItem::operator<(other); +} + CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget *parent) : QDialog(parent), ui(new Ui::CoinControlDialog), @@ -52,7 +59,7 @@ CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget unlockAction = new QAction(tr("Unlock unspent"), this); // we need to enable/disable this // context menu - contextMenu = new QMenu(); + contextMenu = new QMenu(this); contextMenu->addAction(copyAddressAction); contextMenu->addAction(copyLabelAction); contextMenu->addAction(copyAmountAction); @@ -132,12 +139,9 @@ CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget ui->treeWidget->setColumnWidth(COLUMN_PRIORITY, 100); ui->treeWidget->setColumnHidden(COLUMN_TXHASH, true); // store transaction hash in this column, but don't show it ui->treeWidget->setColumnHidden(COLUMN_VOUT_INDEX, true); // store vout index in this column, but don't show it - ui->treeWidget->setColumnHidden(COLUMN_AMOUNT_INT64, true); // store amount int64 in this column, but don't show it - ui->treeWidget->setColumnHidden(COLUMN_PRIORITY_INT64, true); // store priority int64 in this column, but don't show it - ui->treeWidget->setColumnHidden(COLUMN_DATE_INT64, true); // store date int64 in this column, but don't show it // default view is sorted by amount desc - sortView(COLUMN_AMOUNT_INT64, Qt::DescendingOrder); + sortView(COLUMN_AMOUNT, Qt::DescendingOrder); // restore list mode and sortorder as a convenience feature QSettings settings; @@ -169,15 +173,6 @@ void CoinControlDialog::setModel(WalletModel *model) } } -// helper function str_pad -QString CoinControlDialog::strPad(QString s, int nPadLength, QString sPadding) -{ - while (s.length() < nPadLength) - s = sPadding + s; - - return s; -} - // ok button void CoinControlDialog::buttonBoxClicked(QAbstractButton* button) { @@ -349,7 +344,7 @@ void CoinControlDialog::sortView(int column, Qt::SortOrder order) sortColumn = column; sortOrder = order; ui->treeWidget->sortItems(column, order); - ui->treeWidget->header()->setSortIndicator(getMappedColumn(sortColumn), sortOrder); + ui->treeWidget->header()->setSortIndicator(sortColumn, sortOrder); } // treeview: clicked on header @@ -357,12 +352,10 @@ void CoinControlDialog::headerSectionClicked(int logicalIndex) { if (logicalIndex == COLUMN_CHECKBOX) // click on most left column -> do nothing { - ui->treeWidget->header()->setSortIndicator(getMappedColumn(sortColumn), sortOrder); + ui->treeWidget->header()->setSortIndicator(sortColumn, sortOrder); } else { - logicalIndex = getMappedColumn(logicalIndex, false); - if (sortColumn == logicalIndex) sortOrder = ((sortOrder == Qt::AscendingOrder) ? Qt::DescendingOrder : Qt::AscendingOrder); else @@ -708,7 +701,7 @@ void CoinControlDialog::updateView() model->listCoins(mapCoins); BOOST_FOREACH(const PAIRTYPE(QString, std::vector)& coins, mapCoins) { - QTreeWidgetItem *itemWalletAddress = new QTreeWidgetItem(); + CCoinControlWidgetItem *itemWalletAddress = new CCoinControlWidgetItem(); itemWalletAddress->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked); QString sWalletAddress = coins.first; QString sWalletLabel = model->getAddressTableModel()->labelForAddress(sWalletAddress); @@ -739,9 +732,9 @@ void CoinControlDialog::updateView() nSum += out.tx->vout[out.i].nValue; nChildren++; - QTreeWidgetItem *itemOutput; - if (treeMode) itemOutput = new QTreeWidgetItem(itemWalletAddress); - else itemOutput = new QTreeWidgetItem(ui->treeWidget); + CCoinControlWidgetItem *itemOutput; + if (treeMode) itemOutput = new CCoinControlWidgetItem(itemWalletAddress); + else itemOutput = new CCoinControlWidgetItem(ui->treeWidget); itemOutput->setFlags(flgCheckbox); itemOutput->setCheckState(COLUMN_CHECKBOX,Qt::Unchecked); @@ -779,19 +772,20 @@ void CoinControlDialog::updateView() // amount itemOutput->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, out.tx->vout[out.i].nValue)); - itemOutput->setText(COLUMN_AMOUNT_INT64, strPad(QString::number(out.tx->vout[out.i].nValue), 15, " ")); // padding so that sorting works correctly + itemOutput->setData(COLUMN_AMOUNT, Qt::UserRole, QVariant((qlonglong)out.tx->vout[out.i].nValue)); // padding so that sorting works correctly // date itemOutput->setText(COLUMN_DATE, GUIUtil::dateTimeStr(out.tx->GetTxTime())); - itemOutput->setText(COLUMN_DATE_INT64, strPad(QString::number(out.tx->GetTxTime()), 20, " ")); + itemOutput->setData(COLUMN_DATE, Qt::UserRole, QVariant((qlonglong)out.tx->GetTxTime())); // confirmations - itemOutput->setText(COLUMN_CONFIRMATIONS, strPad(QString::number(out.nDepth), 8, " ")); + itemOutput->setText(COLUMN_CONFIRMATIONS, QString::number(out.nDepth)); + itemOutput->setData(COLUMN_CONFIRMATIONS, Qt::UserRole, QVariant((qlonglong)out.nDepth)); // priority double dPriority = ((double)out.tx->vout[out.i].nValue / (nInputSize + 78)) * (out.nDepth+1); // 78 = 2 * 34 + 10 itemOutput->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(dPriority, mempoolEstimatePriority)); - itemOutput->setText(COLUMN_PRIORITY_INT64, strPad(QString::number((int64_t)dPriority), 20, " ")); + itemOutput->setData(COLUMN_PRIORITY, Qt::UserRole, QVariant((qlonglong)dPriority)); dPrioritySum += (double)out.tx->vout[out.i].nValue * (out.nDepth+1); nInputSum += nInputSize; @@ -822,9 +816,9 @@ void CoinControlDialog::updateView() dPrioritySum = dPrioritySum / (nInputSum + 78); itemWalletAddress->setText(COLUMN_CHECKBOX, "(" + QString::number(nChildren) + ")"); itemWalletAddress->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, nSum)); - itemWalletAddress->setText(COLUMN_AMOUNT_INT64, strPad(QString::number(nSum), 15, " ")); + itemWalletAddress->setData(COLUMN_AMOUNT, Qt::UserRole, QVariant((qlonglong)nSum)); itemWalletAddress->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(dPrioritySum, mempoolEstimatePriority)); - itemWalletAddress->setText(COLUMN_PRIORITY_INT64, strPad(QString::number((int64_t)dPrioritySum), 20, " ")); + itemWalletAddress->setData(COLUMN_PRIORITY, Qt::UserRole, QVariant((qlonglong)dPrioritySum)); } } diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index 1a467eb2ffb..785079b1adc 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -28,6 +28,17 @@ namespace Ui { #define ASYMP_UTF8 "\xE2\x89\x88" +class CCoinControlWidgetItem : public QTreeWidgetItem +{ +public: + CCoinControlWidgetItem(QTreeWidget *parent, int type = Type) : QTreeWidgetItem(parent, type) {} + CCoinControlWidgetItem(int type = Type) : QTreeWidgetItem(type) {} + CCoinControlWidgetItem(QTreeWidgetItem *parent, int type = Type) : QTreeWidgetItem(parent, type) {} + + bool operator<(const QTreeWidgetItem &other) const; +}; + + class CoinControlDialog : public QDialog { Q_OBJECT @@ -60,13 +71,12 @@ class CoinControlDialog : public QDialog const PlatformStyle *platformStyle; - QString strPad(QString, int, QString); void sortView(int, Qt::SortOrder); void updateView(); enum { - COLUMN_CHECKBOX, + COLUMN_CHECKBOX = 0, COLUMN_AMOUNT, COLUMN_LABEL, COLUMN_ADDRESS, @@ -75,35 +85,8 @@ class CoinControlDialog : public QDialog COLUMN_PRIORITY, COLUMN_TXHASH, COLUMN_VOUT_INDEX, - COLUMN_AMOUNT_INT64, - COLUMN_PRIORITY_INT64, - COLUMN_DATE_INT64 }; - - // some columns have a hidden column containing the value used for sorting - int getMappedColumn(int column, bool fVisibleColumn = true) - { - if (fVisibleColumn) - { - if (column == COLUMN_AMOUNT_INT64) - return COLUMN_AMOUNT; - else if (column == COLUMN_PRIORITY_INT64) - return COLUMN_PRIORITY; - else if (column == COLUMN_DATE_INT64) - return COLUMN_DATE; - } - else - { - if (column == COLUMN_AMOUNT) - return COLUMN_AMOUNT_INT64; - else if (column == COLUMN_PRIORITY) - return COLUMN_PRIORITY_INT64; - else if (column == COLUMN_DATE) - return COLUMN_DATE_INT64; - } - - return column; - } + friend class CCoinControlWidgetItem; private Q_SLOTS: void showMenu(const QPoint &); diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui index 6d792d1475f..4a6ee92508d 100644 --- a/src/qt/forms/overviewpage.ui +++ b/src/qt/forms/overviewpage.ui @@ -20,7 +20,7 @@ false - background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop:0 #F0D0A0, stop:1 #F8D488); color:#000000; + QLabel { background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop:0 #F0D0A0, stop:1 #F8D488); color:#000000; } true @@ -28,6 +28,9 @@ 3 + + Qt::TextSelectableByMouse + diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 947a4c6821d..dec3e56ec5e 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -591,7 +591,8 @@ void TableViewLastColumnResizingFixer::on_geometriesChanged() * Initializes all internal variables and prepares the * the resize modes of the last 2 columns of the table and */ -TableViewLastColumnResizingFixer::TableViewLastColumnResizingFixer(QTableView* table, int lastColMinimumWidth, int allColsMinimumWidth) : +TableViewLastColumnResizingFixer::TableViewLastColumnResizingFixer(QTableView* table, int lastColMinimumWidth, int allColsMinimumWidth, QObject *parent) : + QObject(parent), tableView(table), lastColumnMinimumWidth(lastColMinimumWidth), allColumnsMinimumWidth(allColsMinimumWidth) diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 9267e0a6c9d..83cd6b5d46e 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -150,7 +150,7 @@ namespace GUIUtil Q_OBJECT public: - TableViewLastColumnResizingFixer(QTableView* table, int lastColMinimumWidth, int allColsMinimumWidth); + TableViewLastColumnResizingFixer(QTableView* table, int lastColMinimumWidth, int allColsMinimumWidth, QObject *parent); void stretchColumnWidth(int column); private: diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index 6d6af54290f..83b2107d2a2 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -23,7 +23,7 @@ static const uint64_t GB_BYTES = 1000000000LL; /* Minimum free space (in GB) needed for data directory */ -static const uint64_t BLOCK_CHAIN_SIZE = 80; +static const uint64_t BLOCK_CHAIN_SIZE = 100; /* Minimum free space (in GB) needed for data directory when pruned; Does not include prune target */ static const uint64_t CHAIN_STATE_SIZE = 2; /* Total required space (in GB) depending on user choice (prune, not prune) */ @@ -165,20 +165,20 @@ QString Intro::getDefaultDataDirectory() return GUIUtil::boostPathToQString(GetDefaultDataDir()); } -void Intro::pickDataDirectory() +bool Intro::pickDataDirectory() { namespace fs = boost::filesystem; QSettings settings; /* If data directory provided on command line, no need to look at settings or show a picking dialog */ if(!GetArg("-datadir", "").empty()) - return; + return true; /* 1) Default data directory for operating system */ QString dataDir = getDefaultDataDirectory(); /* 2) Allow QSettings to override default dir */ dataDir = settings.value("strDataDir", dataDir).toString(); - if(!fs::exists(GUIUtil::qstringToBoostPath(dataDir)) || GetBoolArg("-choosedatadir", DEFAULT_CHOOSE_DATADIR)) + if(!fs::exists(GUIUtil::qstringToBoostPath(dataDir)) || GetBoolArg("-choosedatadir", DEFAULT_CHOOSE_DATADIR) || settings.value("fReset", false).toBool() || GetBoolArg("-resetguisettings", false)) { /* If current default data directory does not exist, let the user choose one */ Intro intro; @@ -190,7 +190,7 @@ void Intro::pickDataDirectory() if(!intro.exec()) { /* Cancel clicked */ - exit(0); + return false; } dataDir = intro.getDataDirectory(); try { @@ -204,6 +204,7 @@ void Intro::pickDataDirectory() } settings.setValue("strDataDir", dataDir); + settings.setValue("fReset", false); } /* Only override -datadir if different from the default, to make it possible to * override -datadir in the bitcoin.conf file in the default data directory @@ -211,6 +212,7 @@ void Intro::pickDataDirectory() */ if(dataDir != getDefaultDataDirectory()) SoftSetArg("-datadir", GUIUtil::qstringToBoostPath(dataDir).string()); // use OS locale for path setting + return true; } void Intro::setStatus(int status, const QString &message, quint64 bytesAvailable) diff --git a/src/qt/intro.h b/src/qt/intro.h index 9e2e96dc9ec..ee768a7ad8d 100644 --- a/src/qt/intro.h +++ b/src/qt/intro.h @@ -35,10 +35,13 @@ class Intro : public QDialog /** * Determine data directory. Let the user choose if the current one doesn't exist. * + * @returns true if a data directory was selected, false if the user cancelled the selection + * dialog. + * * @note do NOT call global GetDataDir() before calling this function, this * will cause the wrong path to be cached. */ - static void pickDataDirectory(); + static bool pickDataDirectory(); /** * Determine default data directory for operating system. diff --git a/src/qt/locale/bitcoin_af.ts b/src/qt/locale/bitcoin_af.ts index 97ada8dd5c6..0b8a738ea0d 100644 --- a/src/qt/locale/bitcoin_af.ts +++ b/src/qt/locale/bitcoin_af.ts @@ -22,6 +22,10 @@ &Dupliseer + C&lose + S&luit + + Delete the currently selected address from the list Verwyder die adres wat u gekies het van die lys @@ -37,7 +41,10 @@ &Delete &Vee uit - + + + AddressTableModel + AskPassphraseDialog @@ -56,7 +63,7 @@ Repeat new passphrase Herhaal nuwe wagwoord - + BanTableModel @@ -87,14 +94,42 @@ &Transaksies + Browse transaction history + Blaai deur transaksiegeskiedenis + + + E&xit + &Sluit + + Quit application Stop en verlaat die applikasie + &About %1 + &Oor %1 + + + Show information about %1 + Wys inligting oor %1 + + + About &Qt + Oor &Qt + + + Show information about Qt + Wys inligting oor Qt + + &Options... &Opsies + Modify configuration options for %1 + Verander konfigurasie-opsies vir %1 + + &Encrypt Wallet... &Kodifiseer Beursie @@ -171,6 +206,10 @@ &Help + Tabs toolbar + Orebalk + + Request payments (generates QR codes and bitcoin: URIs) Versoek betalings (genereer QR-kodes en bitcoin: URI's) @@ -186,39 +225,389 @@ Open a bitcoin: URI or payment request Skep 'n bitcoin: URI of betalingsversoek + + Indexing blocks on disk... + Blokke op skyf word geïndekseer... + + + Processing blocks on disk... + Blokke op skyf word geprosesseer... + + + No block source available... + Geen blokbron beskikbaar... + + + Processed %n block(s) of transaction history. + %n blok van transaksiegeskiedenis geprosesseer.%n blokke van transaksiegeskiedenis geprosesseer. + + + %n hour(s) + %n uur%n ure + + + %n day(s) + %n dag%n dae + + + %n week(s) + %n week%n weke + + + %1 and %2 + %1 en %2 + + + %n year(s) + %n jaar%n jare + + + %1 behind + %1 agter + + + Last received block was generated %1 ago. + Laaste ontvange blok is %1 gelede gegenereer. + + + Transactions after this will not yet be visible. + Transaksies hierna sal nog nie sigbaar wees nie. + + + Error + Fout + + + Warning + Waarskuwing + + + Information + Inligting + + + Up to date + Op datum + + + Catching up... + Word op datum gebring... + + + Date: %1 + + Datum: %1 + + + + Address: %1 + + Adres: %1 + + + + Sent transaction + Gestuurde transaksie + + + Incoming transaction + Inkomende transaksie + CoinControlDialog + + Bytes: + Grepe: + + + Priority: + Prioriteit: + + + Fee: + Fooi: + + + Dust: + Stof: + + + After Fee: + Na Fooi: + + + (un)select all + (de)selekteer alle + + + List mode + Lysmodus + + + Date + Datum + + + Confirmations + Bevestigings + + + Confirmed + Bevestig + + + Priority + Prioriteit + EditAddressDialog + + Edit Address + Wysig Adres + FreespaceChecker + + name + naam + HelpMessageDialog - + + version + weergawe + + + About %1 + Ongeveer %1 + + + UI Options: + Gebruikerkoppelvlakopsies: + + + Start minimized + Begin geminimeer + + + Reset all settings changed in the GUI + Alle instellings wat in die grafiese gebruikerkoppelvlak gewysig is, terugstel + + Intro + + Welcome + Welkom + + + Welcome to %1. + Welkom by %1. + + + Error + Fout + OpenURIDialog OptionsDialog + + Options + Opsies + + + MB + MG + + + Accept connections from outside + Verbindings van buite toelaat + + + Allow incoming connections + Inkomende verbindings toelaat + + + Reset all client options to default. + Alle kliëntopsies na verstek terugstel. + + + Expert + Kenner + + + IPv6 + IPv6 + + + Tor + Tor + + + default + verstek + + + none + geen + + + Confirm options reset + Bevestig terugstel van opsies + + + Client restart required to activate changes. + Kliënt moet herbegin word om veranderinge te aktiveer. + OverviewPage + + Available: + Beskikbaar: + + + Pending: + Hangend: + + + Immature: + Onvolwasse: + + + Balances + Balanse + + + Total: + Totaal: + + + Your current total balance + U huidige totale balans + + + Spendable: + Besteebaar: + + + Recent transactions + Onlangse transaksies + + + + PaymentServer PeerTableModel + + User Agent + Gebruikeragent + QObject + + %1 d + %1 d + + + %1 h + %1 u + + + %1 m + %1 m + + + %1 s + %1 s + + + None + Geen + + + N/A + n.v.t. + + + %1 ms + %1 ms + + + + QRImageWidget RPCConsole + + N/A + n.v.t. + + + Client version + Kliëntweergawe + + + General + Algemeen + + + Network + Netwerk + + + Name + Naam + + + Number of connections + Aantal verbindings + + + Block chain + Blokketting + + + Current number of blocks + Huidige aantal blokke + + + Received + Ontvang + + + Sent + Gestuur + + + Banned peers + Verbanne porture + + + Whitelisted + Gewitlys + + + Direction + Rigting + + + Version + Weergawe + + + User Agent + Gebruikeragent + ReceiveCoinsDialog @@ -227,12 +616,62 @@ ReceiveRequestDialog + RecentRequestsTableModel + + SendCoinsDialog + + Bytes: + Grepe: + + + Priority: + Prioriteit: + + + Fee: + Fooi: + + + After Fee: + Na Fooi: + + + Transaction Fee: + Transaksiefooi: + + + Choose... + Kies... + + + per kilobyte + per kilogreep + + + Hide + Versteek + + + total at least + totaal ten minste + + + Dust: + Stof: + + + Balance: + Balans: + SendCoinsEntry + SendConfirmationDialog + + ShutdownWindow @@ -245,20 +684,70 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Bitcoin Core Bitcoin Kern + Information + Inligting + + + Warning + Waarskuwing + + Do not keep transactions in the mempool longer than <n> hours (default: %u) Moenie transaksies vir langer as <n> ure in die geheuepoel hou nie (verstek: %u) - + + Insufficient funds + Onvoldoende fondse + + + Loading block index... + Blokindeks word gelaai... + + + Loading wallet... + Beursie word gelaai... + + + Rescanning... + Word herskandeer... + + + Done loading + Klaar met laai + + + Error + Fout + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_af_ZA.ts b/src/qt/locale/bitcoin_af_ZA.ts index e553fc77593..1d4d726c75f 100644 --- a/src/qt/locale/bitcoin_af_ZA.ts +++ b/src/qt/locale/bitcoin_af_ZA.ts @@ -13,7 +13,10 @@ &Delete &Verwyder - + + + AddressTableModel + AskPassphraseDialog @@ -32,7 +35,7 @@ Repeat new passphrase Herhaal nuwe wagfrase - + BanTableModel @@ -140,7 +143,7 @@ &Address &Adres - + FreespaceChecker @@ -180,6 +183,9 @@ + PaymentServer + + PeerTableModel @@ -190,6 +196,9 @@ + QRImageWidget + + RPCConsole &Information @@ -211,6 +220,9 @@ ReceiveRequestDialog + RecentRequestsTableModel + + SendCoinsDialog Send Coins @@ -240,7 +252,7 @@ S&end S&tuur - + SendCoinsEntry @@ -253,6 +265,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -277,12 +292,30 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_ar.ts b/src/qt/locale/bitcoin_ar.ts index af62207df2b..4077889894a 100644 --- a/src/qt/locale/bitcoin_ar.ts +++ b/src/qt/locale/bitcoin_ar.ts @@ -23,7 +23,7 @@ C&lose - &اغلاق + ا&غلاق Delete the currently selected address from the list @@ -41,7 +41,10 @@ &Delete &أمسح - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase ادخل كلمة المرور الجديدة مرة أخرى - + BanTableModel @@ -411,7 +414,7 @@ Priority أفضلية - + EditAddressDialog @@ -434,7 +437,7 @@ &Address &العنوان - + FreespaceChecker @@ -538,7 +541,7 @@ Select payment request file حدد ملف طلب الدفع - + OptionsDialog @@ -662,6 +665,9 @@ + PaymentServer + + PeerTableModel @@ -684,6 +690,9 @@ + QRImageWidget + + RPCConsole N/A @@ -868,7 +877,7 @@ Remove ازل - + ReceiveRequestDialog @@ -887,7 +896,10 @@ &Save Image... &حفظ الصورة - + + + RecentRequestsTableModel + SendCoinsDialog @@ -978,7 +990,7 @@ S&end &ارسال - + SendCoinsEntry @@ -1031,6 +1043,9 @@ + SendConfirmationDialog + + ShutdownWindow Do not shut down the computer until this window disappears. @@ -1099,16 +1114,34 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction يبين هذا الجزء وصفا مفصلا لهده المعاملة - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_be_BY.ts b/src/qt/locale/bitcoin_be_BY.ts index 5894148fe03..dfbf3873ae7 100644 --- a/src/qt/locale/bitcoin_be_BY.ts +++ b/src/qt/locale/bitcoin_be_BY.ts @@ -41,7 +41,10 @@ &Delete Выдаліць - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Паўтарыце новую кодавую фразу - + BanTableModel @@ -415,7 +418,7 @@ Priority Прыярытэт - + EditAddressDialog @@ -430,7 +433,7 @@ &Address Адрас - + FreespaceChecker @@ -514,6 +517,9 @@ + PaymentServer + + PeerTableModel @@ -524,6 +530,9 @@ + QRImageWidget + + RPCConsole &Information @@ -553,6 +562,9 @@ + RecentRequestsTableModel + + SendCoinsDialog Send Coins @@ -641,7 +653,10 @@ Memo: Памятка: - + + + SendConfirmationDialog + ShutdownWindow @@ -675,16 +690,34 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Гэтая панэль паказвае дэтальнае апісанне транзакцыі - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_bg.ts b/src/qt/locale/bitcoin_bg.ts index acb60cf41c5..b1d772ea134 100644 --- a/src/qt/locale/bitcoin_bg.ts +++ b/src/qt/locale/bitcoin_bg.ts @@ -41,7 +41,10 @@ &Delete &Изтриване - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Въведете новата парола повторно - + BanTableModel @@ -463,7 +466,7 @@ Priority Приоритет - + EditAddressDialog @@ -486,7 +489,7 @@ &Address &Адрес - + FreespaceChecker @@ -830,6 +833,9 @@ + PaymentServer + + PeerTableModel User Agent @@ -880,6 +886,9 @@ + QRImageWidget + + RPCConsole N/A @@ -1112,7 +1121,7 @@ Remove Премахване - + ReceiveRequestDialog @@ -1131,7 +1140,10 @@ &Save Image... &Запиши изображение... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1254,7 +1266,7 @@ S&end И&зпрати - + SendCoinsEntry @@ -1305,7 +1317,10 @@ Memo: Бележка: - + + + SendConfirmationDialog + ShutdownWindow @@ -1391,16 +1406,34 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Описание на транзакцията - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_bg_BG.ts b/src/qt/locale/bitcoin_bg_BG.ts index 4bddb5ff4a8..977fbf57e5e 100644 --- a/src/qt/locale/bitcoin_bg_BG.ts +++ b/src/qt/locale/bitcoin_bg_BG.ts @@ -41,7 +41,10 @@ &Delete Изтрий - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Повтори парола - + BanTableModel @@ -188,12 +191,18 @@ OverviewPage + PaymentServer + + PeerTableModel QObject + QRImageWidget + + RPCConsole @@ -203,12 +212,18 @@ ReceiveRequestDialog + RecentRequestsTableModel + + SendCoinsDialog SendCoinsEntry + SendConfirmationDialog + + ShutdownWindow @@ -221,12 +236,30 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Bitcoin Core diff --git a/src/qt/locale/bitcoin_ca.ts b/src/qt/locale/bitcoin_ca.ts index ed259c4d08d..c4cb86d82b1 100644 --- a/src/qt/locale/bitcoin_ca.ts +++ b/src/qt/locale/bitcoin_ca.ts @@ -41,6 +41,77 @@ &Delete &Elimina + + Choose the address to send coins to + Trieu l'adreça on enviar les monedes + + + Choose the address to receive coins with + Trieu l'adreça on rebre les monedes + + + C&hoose + &Tria + + + Sending addresses + Adreces d'enviament + + + Receiving addresses + Adreces de recepció + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Aquestes són les vostres adreces de Bitcoin per enviar els pagaments. Sempre reviseu l'import i l'adreça del destinatari abans de transferir monedes. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Aquestes són les vostres adreces Bitcoin per rebre pagaments. Es recomana utilitzar una adreça nova de recepció per a cada transacció. + + + &Copy Address + &Copia l'adreça + + + Copy &Label + Copia l'eti&queta + + + &Edit + &Edita + + + Export Address List + Exporta la llista d'adreces + + + Comma separated file (*.csv) + Fitxer separat per comes (*.csv) + + + Exporting Failed + L'exportació ha fallat + + + There was an error trying to save the address list to %1. Please try again. + S'ha produït un error en desar la llista d'adreces a %1. Torneu-ho a provar. + + + + AddressTableModel + + Label + Etiqueta + + + Address + Adreça + + + (no label) + (sense etiqueta) + AskPassphraseDialog @@ -60,6 +131,94 @@ Repeat new passphrase Repetiu la nova contrasenya + + 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>. + 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>. + + + Encrypt wallet + Encripta el moneder + + + This operation needs your wallet passphrase to unlock the wallet. + Aquesta operació requereix la contrasenya del moneder per a desbloquejar-lo. + + + Unlock wallet + Desbloqueja el moneder + + + This operation needs your wallet passphrase to decrypt the wallet. + Aquesta operació requereix la contrasenya del moneder per desencriptar-lo. + + + Decrypt wallet + Desencripta el moneder + + + Change passphrase + Canvia la contrasenya + + + Enter the old passphrase and new passphrase to the wallet. + Introduïu la contrasenya antiga i la contrasenya nova al moneder. + + + Confirm wallet encryption + Confirma l'encriptació del moneder + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Avís: si encripteu el vostre moneder i perdeu la contrasenya, <b>PERDREU TOTS ELS VOSTRES BITCOINS</b>! + + + Are you sure you wish to encrypt your wallet? + Esteu segur que voleu encriptar el vostre moneder? + + + Wallet encrypted + Moneder encriptat + + + %1 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. + Ara es tancarà el %1 per finalitzar el procés d'encriptació. Recordeu que encriptar el vostre moneder no garanteix que les vostres bitcoins no puguin ser robades per programari maliciós que infecti l'ordinador. + + + 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. + IMPORTANT: Tota copia de seguretat que hàgiu realitzat hauria de ser reemplaçada pel, recentment generat, fitxer encriptat del moneder. Per motius de seguretat, les còpies de seguretat anteriors del fitxer de moneder no encriptat esdevindran inusables tan aviat com començar a utilitzar el nou moneder encriptat. + + + Wallet encryption failed + L'encriptació del moneder ha fallat + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + L'encriptació del moneder ha fallat per un error intern. El moneder no ha estat encriptat. + + + The supplied passphrases do not match. + Les contrasenyes introduïdes no coincideixen. + + + Wallet unlock failed + El desbloqueig del moneder ha fallat + + + The passphrase entered for the wallet decryption was incorrect. + La contrasenya introduïda per a desencriptar el moneder és incorrecta. + + + Wallet decryption failed + La desencriptació del moneder ha fallat + + + Wallet passphrase was successfully changed. + La contrasenya del moneder ha estat modificada correctament. + + + Warning: The Caps Lock key is on! + Avís: Les lletres majúscules estan activades! + BanTableModel @@ -111,6 +270,14 @@ Surt de l'aplicació + &About %1 + Qu&ant al %1 + + + Show information about %1 + Mosta informació sobre el %1 + + About &Qt Quant a &Qt @@ -123,6 +290,10 @@ &Opcions... + Modify configuration options for %1 + Modifica les opcions de configuració de %1 + + &Encrypt Wallet... &Encripta el moneder... @@ -140,7 +311,7 @@ &Receiving addresses... - Adreces de &recepció + Adreces de &recepció... Open &URI... @@ -251,6 +422,14 @@ %n connexió activa a la xarxa Bitcoin%n connexions actives a la xarxa Bitcoin + Indexing blocks on disk... + S'estan indexant els blocs al disc... + + + Processing blocks on disk... + S'estan processant els blocs al disc... + + No block source available... No hi ha cap font de bloc disponible... @@ -307,6 +486,14 @@ Al dia + Show the %1 help message to get a list with possible Bitcoin command-line options + Mostra el missatge d'ajuda del %1 per obtenir una llista amb les possibles opcions de línia d'ordres de Bitcoin + + + %1 client + Client de %1 + + Catching up... S'està posant al dia ... @@ -435,6 +622,142 @@ Priority Prioritat + + Copy address + Copia l'adreça + + + Copy label + Copia l'etiqueta + + + Copy amount + Copia l'import + + + Copy transaction ID + Copia l'ID de transacció + + + Copy quantity + Copia la quantitat + + + Copy fee + Copia la comissió + + + Copy after fee + Copia la comissió posterior + + + Copy bytes + Copia els bytes + + + Copy priority + Copia la prioritat + + + Copy dust + Copia el polsim + + + Copy change + Copia el canvi + + + highest + el més alt + + + higher + més alt + + + high + alt + + + medium-high + mig-alt + + + medium + mig + + + low-medium + baix-mig + + + low + baix + + + lower + més baix + + + lowest + el més baix + + + (%1 locked) + (%1 bloquejada) + + + none + cap + + + yes + + + + no + no + + + This label turns red if the transaction size is greater than 1000 bytes. + Aquesta etiqueta es torna en vermell si la transacció és superior a 1000 bytes. + + + This means a fee of at least %1 per kB is required. + Això comporta que cal una comissió d'almenys %1 per kB. + + + Can vary +/- 1 byte per input. + Pot variar +/- 1 byte per entrada. + + + Transactions with higher priority are more likely to get included into a block. + Les transaccions amb una major prioritat són més propenses a ser incloses en un bloc. + + + This label turns red if the priority is smaller than "medium". + Aquesta etiqueta es torna en vermell si la propietat és inferior que la «mitjana». + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Aquesta etiqueta es torna vermella si cap recipient rep un import inferior al llindar de polsim actual. + + + Can vary +/- %1 satoshi(s) per input. + Pot variar en +/- %1 satoshi(s) per entrada. + + + (no label) + (sense etiqueta) + + + change from %1 (%2) + canvia de %1 (%2) + + + (change) + (canvia) + EditAddressDialog @@ -458,6 +781,38 @@ &Address &Adreça + + New receiving address + Nova adreça de recepció + + + New sending address + Nova adreça d'enviament + + + Edit receiving address + Edita l'adreça de recepció + + + Edit sending address + Edita l'adreça d'enviament + + + The entered address "%1" is not a valid Bitcoin address. + L'adreça introduïda «%1» no és una adreça de Bitcoin vàlida. + + + The entered address "%1" is already in the address book. + L'adreça introduïda «%1» ja és present a la llibreta d'adreces. + + + Could not unlock wallet. + No s'ha pogut desbloquejar el moneder. + + + New key generation failed. + Ha fallat la generació d'una clau nova. + FreespaceChecker @@ -493,6 +848,10 @@ (%1-bit) + About %1 + Quant al %1 + + Command-line options Opcions de línia d'ordres @@ -528,12 +887,28 @@ Show splash screen on startup (default: %u) Mostra la pantalla de benvinguda a l'inici (per defecte: %u) - + + Reset all settings changed in the GUI + Reinicialitza tots els canvis de configuració fets des de la interfície gràfica + + Intro Welcome - Us donem la benviguda + Us donem la benvinguda + + + Welcome to %1. + Us donem la benvinguda a %1. + + + As this is the first time the program is launched, you can choose where %1 will store its data. + Com és la primera vegada que s'executa el programa, podeu triar on %1 emmagatzemarà les dades. + + + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 baixarà i emmagatzemarà una còpia de la cadena de blocs de Bitcoin. Com a mínim %2GB de dades s'emmagatzemaran en aquest directori, i augmentarà al llarg del temps. El moneder també s'emmagatzemarà en aquest directori. Use the default data directory @@ -578,6 +953,10 @@ Select payment request file Selecciona un fitxer de sol·licitud de pagament + + Select payment request file to open + Seleccioneu el fitxer de sol·licitud de pagament per obrir + OptionsDialog @@ -590,6 +969,14 @@ &Principal + Automatically start %1 after logging in to the system. + Inicieu %1 automàticament després d'entrar en el sistema. + + + &Start %1 on system login + &Inicia %1 en l'entrada al sistema + + Size of &database cache Mida de la memòria cau de la base de &dades @@ -726,6 +1113,14 @@ &Finestra + &Hide the icon from the system tray. + Ama&ga la icona de la safata del sistema. + + + Hide tray icon + Amaga la icona de la safata + + Show only a tray icon after minimizing the window. Mostra només la icona de la barra en minimitzar la finestra. @@ -746,6 +1141,10 @@ &Llengua de la interfície d'usuari: + The user interface language can be set here. This setting will take effect after restarting %1. + Aquí es pot definir la llengua de la interfície d'usuari. Aquest paràmetre tindrà efecte en reiniciar el %1. + + &Unit to show amounts in: &Unitats per mostrar els imports en: @@ -870,6 +1269,29 @@ + PaymentServer + + Payment request error + Error de la sol·licitud de pagament + + + Cannot start bitcoin: click-to-pay handler + No es pot iniciar bitcoin: controlador click-to-pay + + + URI handling + Gestió d'URI + + + Network request error + Error en la sol·licitud de xarxa + + + Payment acknowledged + Pagament reconegut + + + PeerTableModel User Agent @@ -924,6 +1346,25 @@ + QRImageWidget + + &Save Image... + De&sa la imatge... + + + &Copy Image + &Copia la imatge + + + Save QR Code + Desa el codi QR + + + PNG Image (*.png) + Imatge PNG (*.png) + + + RPCConsole N/A @@ -950,6 +1391,10 @@ Utilitzant BerkeleyDB versió + Datadir + Datadir + + Startup time &Temps d'inici @@ -1264,6 +1709,14 @@ Remove Esborra + + Copy label + Copia l'etiqueta + + + Copy amount + Copia l'import + ReceiveRequestDialog @@ -1283,6 +1736,65 @@ &Save Image... De&sa la imatge... + + Request payment to %1 + Sol·licita un pagament a %1 + + + Payment information + Informació de pagament + + + URI + URI + + + Address + Adreça + + + Amount + Import + + + Label + Etiqueta + + + Message + Missatge + + + + RecentRequestsTableModel + + Date + Data + + + Label + Etiqueta + + + Message + Missatge + + + (no label) + (sense etiqueta) + + + (no message) + (sense missatge) + + + (no amount requested) + (no s'ha sol·licitat import) + + + Requested + Sol·licitat + SendCoinsDialog @@ -1434,6 +1946,78 @@ S&end E&nvia + + Copy quantity + Copia la quantitat + + + Copy amount + Copia l'import + + + Copy fee + Copia la comissió + + + Copy after fee + Copia la comissió posterior + + + Copy bytes + Copia els bytes + + + Copy priority + Copia la prioritat + + + Copy dust + Copia el polsim + + + Copy change + Copia el canvi + + + Total Amount %1 + Import total %1 + + + or + o + + + Confirm send coins + Confirma l'enviament de monedes + + + The recipient address is not valid. Please recheck. + L'adreça del destinatari no és vàlida. Torneu-la a comprovar. + + + The amount to pay must be larger than 0. + L'import a pagar ha de ser major que 0. + + + The amount exceeds your balance. + L'import supera el vostre balanç. + + + The total exceeds your balance when the %1 transaction fee is included. + El total excedeix el vostre balanç quan s'afegeix la comissió a la transacció %1. + + + Duplicate address found: addresses should only be used once each. + S'ha trobat una adreça duplicada: les adreces només s'haurien d'utilitzar una vegada cada una. + + + Transaction creation failed! + La creació de la transacció ha fallat! + + + (no label) + (sense etiqueta) + SendCoinsEntry @@ -1513,7 +2097,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1607,7 +2194,7 @@ Reset all verify message fields Neteja tots els camps de verificació de missatge - + SplashScreen @@ -1623,12 +2210,189 @@ + TransactionDesc + + Status + Estat + + + Date + Data + + + Source + Font + + + Generated + Generada + + + From + De + + + unknown + desconegut + + + To + A + + + own address + adreça pròpia + + + Debit + Dèbit + + + Total debit + Dèbit total + + + Total credit + Crèdit total + + + Transaction fee + Comissió de transacció + + + Net amount + Import net + + + Message + Missatge + + + Comment + Comentari + + + Transaction ID + ID de la transacció + + + Amount + Import + + + TransactionDescDialog This pane shows a detailed description of the transaction Aquest panell mostra una descripció detallada de la transacció - + + + TransactionTableModel + + Date + Data + + + Type + Tipus + + + Label + Etiqueta + + + Offline + Fora de línia + + + Unconfirmed + Sense confirmar + + + Abandoned + Abandonada + + + Received with + Rebuda amb + + + Received from + Rebuda de + + + Sent to + Enviada a + + + Payment to yourself + Pagament a un mateix + + + Mined + Minada + + + (no label) + (sense etiqueta) + + + + TransactionView + + Received with + Rebuda amb + + + Sent to + Enviada a + + + Mined + Minada + + + Copy address + Copia l'adreça + + + Copy label + Copia l'etiqueta + + + Copy amount + Copia l'import + + + Copy transaction ID + Copia l'ID de transacció + + + Comma separated file (*.csv) + Fitxer separat per comes (*.csv) + + + Date + Data + + + Type + Tipus + + + Label + Etiqueta + + + Address + Adreça + + + Exporting Failed + L'exportació ha fallat + + UnitDisplayStatusBarControl @@ -1637,6 +2401,15 @@ + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: @@ -2135,10 +2908,6 @@ Defineix la mida clau disponible a <n> (per defecte: %u) - Set minimum block size in bytes (default: %u) - Defineix la mida de bloc mínima en bytes (per defecte: %u) - - Set the number of threads to service RPC calls (default: %d) Defineix el nombre de fils a crides de servei RPC (per defecte: %d) diff --git a/src/qt/locale/bitcoin_ca@valencia.ts b/src/qt/locale/bitcoin_ca@valencia.ts index df0f750a613..213e57ce1ba 100644 --- a/src/qt/locale/bitcoin_ca@valencia.ts +++ b/src/qt/locale/bitcoin_ca@valencia.ts @@ -41,7 +41,10 @@ &Delete &Elimina - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Repetiu la nova contrasenya - + BanTableModel @@ -427,7 +430,7 @@ Priority Prioritat - + EditAddressDialog @@ -450,7 +453,7 @@ &Address &Adreça - + FreespaceChecker @@ -546,7 +549,7 @@ Select payment request file Selecciona un fitxer de sol·licitud de pagament - + OptionsDialog @@ -814,6 +817,9 @@ + PaymentServer + + PeerTableModel User Agent @@ -868,6 +874,9 @@ + QRImageWidget + + RPCConsole N/A @@ -1136,7 +1145,7 @@ Remove Esborra - + ReceiveRequestDialog @@ -1155,7 +1164,10 @@ &Save Image... &Guarda la imatge... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1306,7 +1318,7 @@ S&end E&nvia - + SendCoinsEntry @@ -1385,7 +1397,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1479,7 +1494,7 @@ Reset all verify message fields Neteja tots els camps de verificació de missatge - + SplashScreen @@ -1495,12 +1510,21 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Este panell mostra una descripció detallada de la transacció - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1509,6 +1533,15 @@ + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: @@ -1967,10 +2000,6 @@ Defineix la mida clau disponible a <n> (per defecte: %u) - Set minimum block size in bytes (default: %u) - Defineix la mida de bloc mínima en bytes (per defecte: %u) - - Set the number of threads to service RPC calls (default: %d) Defineix el nombre de fils a crides de servei RPC (per defecte: %d) diff --git a/src/qt/locale/bitcoin_ca_ES.ts b/src/qt/locale/bitcoin_ca_ES.ts index f985a6928d9..410b6e616ed 100644 --- a/src/qt/locale/bitcoin_ca_ES.ts +++ b/src/qt/locale/bitcoin_ca_ES.ts @@ -41,6 +41,77 @@ &Delete &Elimina + + Choose the address to send coins to + Trieu l'adreça on enviar les monedes + + + Choose the address to receive coins with + Trieu l'adreça on rebre les monedes + + + C&hoose + &Tria + + + Sending addresses + Adreces d'enviament + + + Receiving addresses + Adreces de recepció + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Aquestes són les vostres adreces de Bitcoin per enviar els pagaments. Sempre reviseu l'import i l'adreça del destinatari abans de transferir monedes. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Aquestes són les vostres adreces Bitcoin per rebre pagaments. Es recomana utilitzar una adreça nova de recepció per a cada transacció. + + + &Copy Address + &Copia l'adreça + + + Copy &Label + Copia l'eti&queta + + + &Edit + &Edita + + + Export Address List + Exporta la llista d'adreces + + + Comma separated file (*.csv) + Fitxer separat per comes (*.csv) + + + Exporting Failed + L'exportació ha fallat + + + There was an error trying to save the address list to %1. Please try again. + S'ha produït un error en desar la llista d'adreces a %1. Torneu-ho a provar. + + + + AddressTableModel + + Label + Etiqueta + + + Address + Adreça + + + (no label) + (sense etiqueta) + AskPassphraseDialog @@ -60,6 +131,94 @@ Repeat new passphrase Repetiu la nova contrasenya + + 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>. + 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>. + + + Encrypt wallet + Encripta el moneder + + + This operation needs your wallet passphrase to unlock the wallet. + Aquesta operació requereix la contrasenya del moneder per a desbloquejar-lo. + + + Unlock wallet + Desbloqueja el moneder + + + This operation needs your wallet passphrase to decrypt the wallet. + Aquesta operació requereix la contrasenya del moneder per desencriptar-lo. + + + Decrypt wallet + Desencripta el moneder + + + Change passphrase + Canvia la contrasenya + + + Enter the old passphrase and new passphrase to the wallet. + Introduïu la contrasenya antiga i la contrasenya nova al moneder. + + + Confirm wallet encryption + Confirma l'encriptació del moneder + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Avís: si encripteu el vostre moneder i perdeu la contrasenya, <b>PERDREU TOTS ELS VOSTRES BITCOINS</b>! + + + Are you sure you wish to encrypt your wallet? + Esteu segur que voleu encriptar el vostre moneder? + + + Wallet encrypted + Moneder encriptat + + + %1 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. + Ara es tancarà el %1 per finalitzar el procés d'encriptació. Recordeu que encriptar el vostre moneder no garanteix que les vostres bitcoins no puguin ser robades per programari maliciós que infecti l'ordinador. + + + 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. + IMPORTANT: Tota copia de seguretat que hàgiu realitzat hauria de ser reemplaçada pel, recentment generat, fitxer encriptat del moneder. Per motius de seguretat, les còpies de seguretat anteriors del fitxer de moneder no encriptat esdevindran inusables tan aviat com començar a utilitzar el nou moneder encriptat. + + + Wallet encryption failed + L'encriptació del moneder ha fallat + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + L'encriptació del moneder ha fallat per un error intern. El moneder no ha estat encriptat. + + + The supplied passphrases do not match. + Les contrasenyes introduïdes no coincideixen. + + + Wallet unlock failed + El desbloqueig del moneder ha fallat + + + The passphrase entered for the wallet decryption was incorrect. + La contrasenya introduïda per a desencriptar el moneder és incorrecta. + + + Wallet decryption failed + La desencriptació del moneder ha fallat + + + Wallet passphrase was successfully changed. + La contrasenya del moneder ha estat modificada correctament. + + + Warning: The Caps Lock key is on! + Avís: Les lletres majúscules estan activades! + BanTableModel @@ -111,6 +270,14 @@ Surt de l'aplicació + &About %1 + Qu&ant al %1 + + + Show information about %1 + Mosta informació sobre el %1 + + About &Qt Quant a &Qt @@ -123,6 +290,10 @@ &Opcions... + Modify configuration options for %1 + Modifica les opcions de configuració de %1 + + &Encrypt Wallet... &Encripta el moneder... @@ -140,7 +311,7 @@ &Receiving addresses... - Adreces de &recepció + Adreces de &recepció... Open &URI... @@ -251,6 +422,14 @@ %n connexió activa a la xarxa Bitcoin%n connexions actives a la xarxa Bitcoin + Indexing blocks on disk... + S'estan indexant els blocs al disc... + + + Processing blocks on disk... + S'estan processant els blocs al disc... + + No block source available... No hi ha cap font de bloc disponible... @@ -307,6 +486,14 @@ Al dia + Show the %1 help message to get a list with possible Bitcoin command-line options + Mostra el missatge d'ajuda del %1 per obtenir una llista amb les possibles opcions de línia d'ordres de Bitcoin + + + %1 client + Client de %1 + + Catching up... S'està posant al dia ... @@ -435,6 +622,142 @@ Priority Prioritat + + Copy address + Copia l'adreça + + + Copy label + Copia l'etiqueta + + + Copy amount + Copia l'import + + + Copy transaction ID + Copia l'ID de transacció + + + Copy quantity + Copia la quantitat + + + Copy fee + Copia la comissió + + + Copy after fee + Copia la comissió posterior + + + Copy bytes + Copia els bytes + + + Copy priority + Copia la prioritat + + + Copy dust + Copia el polsim + + + Copy change + Copia el canvi + + + highest + el més alt + + + higher + més alt + + + high + alt + + + medium-high + mig-alt + + + medium + mig + + + low-medium + baix-mig + + + low + baix + + + lower + més baix + + + lowest + el més baix + + + (%1 locked) + (%1 bloquejada) + + + none + cap + + + yes + + + + no + no + + + This label turns red if the transaction size is greater than 1000 bytes. + Aquesta etiqueta es torna en vermell si la transacció és superior a 1000 bytes. + + + This means a fee of at least %1 per kB is required. + Això comporta que cal una comissió d'almenys %1 per kB. + + + Can vary +/- 1 byte per input. + Pot variar +/- 1 byte per entrada. + + + Transactions with higher priority are more likely to get included into a block. + Les transaccions amb una major prioritat són més propenses a ser incloses en un bloc. + + + This label turns red if the priority is smaller than "medium". + Aquesta etiqueta es torna en vermell si la propietat és inferior que la «mitjana». + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Aquesta etiqueta es torna vermella si cap recipient rep un import inferior al llindar de polsim actual. + + + Can vary +/- %1 satoshi(s) per input. + Pot variar en +/- %1 satoshi(s) per entrada. + + + (no label) + (sense etiqueta) + + + change from %1 (%2) + canvia de %1 (%2) + + + (change) + (canvia) + EditAddressDialog @@ -458,6 +781,38 @@ &Address &Adreça + + New receiving address + Nova adreça de recepció + + + New sending address + Nova adreça d'enviament + + + Edit receiving address + Edita l'adreça de recepció + + + Edit sending address + Edita l'adreça d'enviament + + + The entered address "%1" is not a valid Bitcoin address. + L'adreça introduïda «%1» no és una adreça de Bitcoin vàlida. + + + The entered address "%1" is already in the address book. + L'adreça introduïda «%1» ja és present a la llibreta d'adreces. + + + Could not unlock wallet. + No s'ha pogut desbloquejar el moneder. + + + New key generation failed. + Ha fallat la generació d'una clau nova. + FreespaceChecker @@ -493,6 +848,10 @@ (%1-bit) + About %1 + Quant al %1 + + Command-line options Opcions de línia d'ordres @@ -528,12 +887,28 @@ Show splash screen on startup (default: %u) Mostra la pantalla de benvinguda a l'inici (per defecte: %u) - + + Reset all settings changed in the GUI + Reinicialitza tots els canvis de configuració fets des de la interfície gràfica + + Intro Welcome - Us donem la benviguda + Us donem la benvinguda + + + Welcome to %1. + Us donem la benvinguda a %1. + + + As this is the first time the program is launched, you can choose where %1 will store its data. + Com és la primera vegada que s'executa el programa, podeu triar on %1 emmagatzemarà les dades. + + + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 baixarà i emmagatzemarà una còpia de la cadena de blocs de Bitcoin. Com a mínim %2GB de dades s'emmagatzemaran en aquest directori, i augmentarà al llarg del temps. El moneder també s'emmagatzemarà en aquest directori. Use the default data directory @@ -578,6 +953,10 @@ Select payment request file Selecciona un fitxer de sol·licitud de pagament + + Select payment request file to open + Seleccioneu el fitxer de sol·licitud de pagament per obrir + OptionsDialog @@ -590,6 +969,14 @@ &Principal + Automatically start %1 after logging in to the system. + Inicieu %1 automàticament després d'entrar en el sistema. + + + &Start %1 on system login + &Inicia %1 en l'entrada al sistema + + Size of &database cache Mida de la memòria cau de la base de &dades @@ -726,6 +1113,14 @@ &Finestra + &Hide the icon from the system tray. + Ama&ga la icona de la safata del sistema. + + + Hide tray icon + Amaga la icona de la safata + + Show only a tray icon after minimizing the window. Mostra només la icona de la barra en minimitzar la finestra. @@ -746,6 +1141,10 @@ &Llengua de la interfície d'usuari: + The user interface language can be set here. This setting will take effect after restarting %1. + Aquí es pot definir la llengua de la interfície d'usuari. Aquest paràmetre tindrà efecte en reiniciar el %1. + + &Unit to show amounts in: &Unitats per mostrar els imports en: @@ -870,6 +1269,29 @@ + PaymentServer + + Payment request error + Error de la sol·licitud de pagament + + + Cannot start bitcoin: click-to-pay handler + No es pot iniciar bitcoin: controlador click-to-pay + + + URI handling + Gestió d'URI + + + Network request error + Error en la sol·licitud de xarxa + + + Payment acknowledged + Pagament reconegut + + + PeerTableModel User Agent @@ -924,6 +1346,25 @@ + QRImageWidget + + &Save Image... + De&sa la imatge... + + + &Copy Image + &Copia la imatge + + + Save QR Code + Desa el codi QR + + + PNG Image (*.png) + Imatge PNG (*.png) + + + RPCConsole N/A @@ -950,6 +1391,10 @@ Utilitzant BerkeleyDB versió + Datadir + Datadir + + Startup time &Temps d'inici @@ -1264,6 +1709,14 @@ Remove Esborra + + Copy label + Copia l'etiqueta + + + Copy amount + Copia l'import + ReceiveRequestDialog @@ -1283,6 +1736,65 @@ &Save Image... De&sa la imatge... + + Request payment to %1 + Sol·licita un pagament a %1 + + + Payment information + Informació de pagament + + + URI + URI + + + Address + Adreça + + + Amount + Import + + + Label + Etiqueta + + + Message + Missatge + + + + RecentRequestsTableModel + + Date + Data + + + Label + Etiqueta + + + Message + Missatge + + + (no label) + (sense etiqueta) + + + (no message) + (sense missatge) + + + (no amount requested) + (no s'ha sol·licitat import) + + + Requested + Sol·licitat + SendCoinsDialog @@ -1434,6 +1946,78 @@ S&end E&nvia + + Copy quantity + Copia la quantitat + + + Copy amount + Copia l'import + + + Copy fee + Copia la comissió + + + Copy after fee + Copia la comissió posterior + + + Copy bytes + Copia els bytes + + + Copy priority + Copia la prioritat + + + Copy dust + Copia el polsim + + + Copy change + Copia el canvi + + + Total Amount %1 + Import total %1 + + + or + o + + + Confirm send coins + Confirma l'enviament de monedes + + + The recipient address is not valid. Please recheck. + L'adreça del destinatari no és vàlida. Torneu-la a comprovar. + + + The amount to pay must be larger than 0. + L'import a pagar ha de ser major que 0. + + + The amount exceeds your balance. + L'import supera el vostre balanç. + + + The total exceeds your balance when the %1 transaction fee is included. + El total excedeix el vostre balanç quan s'afegeix la comissió a la transacció %1. + + + Duplicate address found: addresses should only be used once each. + S'ha trobat una adreça duplicada: les adreces només s'haurien d'utilitzar una vegada cada una. + + + Transaction creation failed! + La creació de la transacció ha fallat! + + + (no label) + (sense etiqueta) + SendCoinsEntry @@ -1513,7 +2097,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1607,7 +2194,7 @@ Reset all verify message fields Neteja tots els camps de verificació de missatge - + SplashScreen @@ -1623,12 +2210,189 @@ + TransactionDesc + + Status + Estat + + + Date + Data + + + Source + Font + + + Generated + Generada + + + From + De + + + unknown + desconegut + + + To + A + + + own address + adreça pròpia + + + Debit + Dèbit + + + Total debit + Dèbit total + + + Total credit + Crèdit total + + + Transaction fee + Comissió de transacció + + + Net amount + Import net + + + Message + Missatge + + + Comment + Comentari + + + Transaction ID + ID de la transacció + + + Amount + Import + + + TransactionDescDialog This pane shows a detailed description of the transaction Aquest panell mostra una descripció detallada de la transacció - + + + TransactionTableModel + + Date + Data + + + Type + Tipus + + + Label + Etiqueta + + + Offline + Fora de línia + + + Unconfirmed + Sense confirmar + + + Abandoned + Abandonada + + + Received with + Rebuda amb + + + Received from + Rebuda de + + + Sent to + Enviada a + + + Payment to yourself + Pagament a un mateix + + + Mined + Minada + + + (no label) + (sense etiqueta) + + + + TransactionView + + Received with + Rebuda amb + + + Sent to + Enviada a + + + Mined + Minada + + + Copy address + Copia l'adreça + + + Copy label + Copia l'etiqueta + + + Copy amount + Copia l'import + + + Copy transaction ID + Copia l'ID de transacció + + + Comma separated file (*.csv) + Fitxer separat per comes (*.csv) + + + Date + Data + + + Type + Tipus + + + Label + Etiqueta + + + Address + Adreça + + + Exporting Failed + L'exportació ha fallat + + UnitDisplayStatusBarControl @@ -1637,6 +2401,15 @@ + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: @@ -1704,7 +2477,11 @@ Bitcoin Core - Nucli de Bitcoin + Bitcoin Core + + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee és molt elevat. Aquesta és la comissió de transacció que podeu pagar quan les estimacions de comissions no estan disponibles. Bind to given address and always listen on it. Use [host]:port notation for IPv6 @@ -2131,10 +2908,6 @@ Defineix la mida clau disponible a <n> (per defecte: %u) - Set minimum block size in bytes (default: %u) - Defineix la mida de bloc mínima en bytes (per defecte: %u) - - Set the number of threads to service RPC calls (default: %d) Defineix el nombre de fils a crides de servei RPC (per defecte: %d) diff --git a/src/qt/locale/bitcoin_cs.ts b/src/qt/locale/bitcoin_cs.ts index 2dfa295ce07..02e959d0182 100644 --- a/src/qt/locale/bitcoin_cs.ts +++ b/src/qt/locale/bitcoin_cs.ts @@ -15,7 +15,7 @@ Copy the currently selected address to the system clipboard - Zkopíruj aktuálně vybranou adresu do systémové schránky + Zkopíruj tuto adresu do systémové schránky &Copy @@ -27,7 +27,7 @@ Delete the currently selected address from the list - Smaž zvolenou adresu ze seznamu + Smaž tuto adresu ze seznamu Export the data in the current tab to a file @@ -41,6 +41,77 @@ &Delete S&maž + + Choose the address to send coins to + Zvol adresu, na kterou pošleš mince + + + Choose the address to receive coins with + Zvol adres na příjem mincí + + + C&hoose + &Zvol + + + Sending addresses + Odesílací adresy + + + Receiving addresses + Přijímací adresy + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Tohle jsou tvé Bitcoinové adresy pro posílání plateb. Před odesláním mincí si vždy zkontroluj částku a cílovou adresu. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Tohle jsou tvé Bitcoinové adresy pro příjem plateb. Nezapomeň si pro každou transakci vždy vygenerovat novou adresu. + + + &Copy Address + &Kopíruj adresu + + + Copy &Label + Kopíruj &označení + + + &Edit + &Uprav + + + Export Address List + Export seznamu adres + + + Comma separated file (*.csv) + Formát CSV (*.csv) + + + Exporting Failed + Exportování selhalo + + + There was an error trying to save the address list to %1. Please try again. + Při ukládání seznamu adres do %1 se přihodila nějaká chyba. Zkus to prosím znovu. + + + + AddressTableModel + + Label + Označení + + + Address + Adresa + + + (no label) + (bez označení) + AskPassphraseDialog @@ -60,10 +131,106 @@ Repeat new passphrase Totéž heslo ještě jednou + + 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>. + Zadej nové heslo k peněžence.<br/>Použij <b>alespoň deset náhodných znaků</b> nebo <b>alespoň osm slov</b>. + + + Encrypt wallet + Zašifruj peněženku + + + This operation needs your wallet passphrase to unlock the wallet. + K provedení této operace musíš zadat heslo k peněžence, aby se mohla odemknout. + + + Unlock wallet + Odemkni peněženku + + + This operation needs your wallet passphrase to decrypt the wallet. + K provedení této operace musíš zadat heslo k peněžence, aby se mohla dešifrovat. + + + Decrypt wallet + Dešifruj peněženku + + + Change passphrase + Změň heslo + + + Enter the old passphrase and new passphrase to the wallet. + Zadej staré a nové heslo k peněžence. + + + Confirm wallet encryption + Potvrď zašifrování peněženky + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Upozornění: Pokud si zašifruješ peněženku a ztratíš či zapomeneš heslo, <b>PŘIJDEŠ O VŠECHNY BITCOINY</b>! + + + Are you sure you wish to encrypt your wallet? + Jsi si jistý, že chceš peněženku zašifrovat? + + + Wallet encrypted + Peněženka je zašifrována + + + %1 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. + %1 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. + + + 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. + 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. + + + Wallet encryption failed + Zašifrování peněženky selhalo + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Zašifrování peněženky selhalo kvůli vnitřní chybě. Tvá peněženka tedy nebyla zašifrována. + + + The supplied passphrases do not match. + Zadaná hesla nejsou shodná. + + + Wallet unlock failed + Nepodařilo se odemknout peněženku + + + The passphrase entered for the wallet decryption was incorrect. + Nezadal jsi správné heslo pro dešifrování peněženky. + + + Wallet decryption failed + Nepodařilo se dešifrovat peněženku + + + Wallet passphrase was successfully changed. + Heslo k peněžence bylo v pořádku změněno. + + + Warning: The Caps Lock key is on! + Upozornění: Caps Lock je zapnutý! + BanTableModel - + + IP/Netmask + IP/Maska + + + Banned Until + Blokován do + + BitcoinGUI @@ -103,6 +270,14 @@ Ukonči aplikaci + &About %1 + O &%1 + + + Show information about %1 + Zobraz informace o %1 + + About &Qt O &Qt @@ -115,6 +290,10 @@ &Možnosti... + Modify configuration options for %1 + Uprav nastavení %1 + + &Encrypt Wallet... Zaši&fruj peněženku... @@ -243,6 +422,14 @@ %n aktivní spojení do Bitcoinové sítě%n aktivní spojení do Bitcoinové sítě%n aktivních spojení do Bitcoinové sítě + Indexing blocks on disk... + Vytvářím index bloků na disku... + + + Processing blocks on disk... + Zpracovávám bloky na disku... + + No block source available... Není dostupný žádný zdroj bloků... @@ -280,7 +467,7 @@ Transactions after this will not yet be visible. - Novější transakce zatím nejsou vidět. + Následné transakce ještě nebudou vidět. Error @@ -299,6 +486,14 @@ Aktuální + Show the %1 help message to get a list with possible Bitcoin command-line options + Seznam argumentů Bitcoinu pro příkazovou řádku získáš v nápovědě %1 + + + %1 client + %1 klient + + Catching up... Stahuji... @@ -427,6 +622,86 @@ Priority Priorita + + Copy address + Kopíruj adresu + + + Copy label + Kopíruj její označení + + + Copy amount + Kopíruj částku + + + Copy transaction ID + Kopíruj ID transakce + + + Lock unspent + Zamkni neutracené + + + Unlock unspent + Odemkni k utracení + + + Copy quantity + Kopíruj počet + + + Copy fee + Kopíruj poplatek + + + Copy after fee + Kopíruj čistou částku + + + Copy bytes + Kopíruj bajty + + + Copy dust + Kopíruj prach + + + Copy change + Kopíruj drobné + + + (%1 locked) + (%1 zamčeno) + + + yes + ano + + + no + ne + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Popisek zčervená, pokud má některý příjemce obdržet částku menší, než je aktuální práh pro prach. + + + Can vary +/- %1 satoshi(s) per input. + Může se lišit o +/– %1 satoshi na každý vstup. + + + (no label) + (bez označení) + + + change from %1 (%2) + drobné z %1 (%2) + + + (change) + (drobné) + EditAddressDialog @@ -450,6 +725,38 @@ &Address &Adresa + + New receiving address + Nová přijímací adresa + + + New sending address + Nová odesílací adresa + + + Edit receiving address + Uprav přijímací adresu + + + Edit sending address + Uprav odesílací adresu + + + The entered address "%1" is not a valid Bitcoin address. + Zadaná adresa „%1“ není platná Bitcoinová adresa. + + + The entered address "%1" is already in the address book. + Zadaná adresa „%1“ už v adresáři je. + + + Could not unlock wallet. + Nemohu odemknout peněženku. + + + New key generation failed. + Nepodařilo se mi vygenerovat nový klíč. + FreespaceChecker @@ -485,6 +792,10 @@ (%1-bit) + About %1 + O %1 + + Command-line options Argumenty příkazové řádky @@ -520,7 +831,11 @@ Show splash screen on startup (default: %u) Zobrazit startovací obrazovku (výchozí: %u) - + + Reset all settings changed in the GUI + Vrátit všechny volby měněné v GUI na výchozí hodnoty + + Intro @@ -528,6 +843,18 @@ Vítej + Welcome to %1. + Vítej v %1. + + + As this is the first time the program is launched, you can choose where %1 will store its data. + Tohle je poprvé, co spouštíš %1, takže si můžeš zvolit, kam bude ukládat svá data. + + + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 bude stahovat kopii řetězce bloků. Proto bude potřeba do tohoto adresáře uložit nejméně %2 GB dat – toto číslo bude navíc v průběhu času růst. Tvá peněženka bude rovněž uložena v tomto adresáři. + + Use the default data directory Použij výchozí adresář pro data @@ -570,6 +897,10 @@ Select payment request file Vyber soubor platebního požadavku + + Select payment request file to open + Vyber soubor platebního požadavku k načtení + OptionsDialog @@ -582,6 +913,14 @@ &Hlavní + Automatically start %1 after logging in to the system. + Automaticky spustí %1 po přihlášení do systému. + + + &Start %1 on system login + S&pustit %1 po přihlášení do systému + + Size of &database cache Velikost &databázové cache @@ -619,7 +958,7 @@ Active command-line options that override above options: - Aktivní argumenty z příkazové řádky, které mají přednost před nastavením výše: + Aktivní argumenty z příkazové řádky, které přetloukly tato nastavení: Reset all client options to default. @@ -687,7 +1026,7 @@ Used for reaching peers via: - Použije se k připojování k protějškům přes: + Použije se k připojování k protějskům přes: Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. @@ -718,6 +1057,14 @@ O&kno + &Hide the icon from the system tray. + Skryje ikonu, která se zobrazuje v panelu. + + + Hide tray icon + Skrýt &ikonu z panelu + + Show only a tray icon after minimizing the window. Po minimalizaci okna zobrazí pouze ikonu v panelu. @@ -738,6 +1085,10 @@ &Jazyk uživatelského rozhraní: + The user interface language can be set here. This setting will take effect after restarting %1. + Tady lze nastavit jazyk uživatelského rozhraní. Nastavení se projeví až po restartování %1. + + &Unit to show amounts in: Je&dnotka pro částky: @@ -751,7 +1102,7 @@ &OK - &Použít + &Budiž &Cancel @@ -779,7 +1130,7 @@ This change would require a client restart. - Tato změna vyžaduje restart aplikace. + Tahle změna bude chtít restartovat klienta. The supplied proxy address is invalid. @@ -826,7 +1177,7 @@ Balances - Stav účtů + Stavy účtů Total: @@ -862,6 +1213,97 @@ + PaymentServer + + Payment request error + Chyba platebního požadavku + + + Cannot start bitcoin: click-to-pay handler + Nemůžu spustit bitcoin: obsluha click-to-pay + + + URI handling + Zpracování URI + + + Payment request fetch URL is invalid: %1 + Zdrojová URL platebního požadavku není platná: %1 + + + Invalid payment address %1 + Neplatná platební adresa %1 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + Nepodařilo se analyzovat URI! Důvodem může být neplatná Bitcoinová adresa nebo poškozené parametry URI. + + + Payment request file handling + Zpracování souboru platebního požadavku + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + Soubor platebního požadavku nejde přečíst nebo zpracovat! Příčinou může být špatný soubor platebního požadavku. + + + Payment request rejected + Platební požadavek byl odmítnut + + + Payment request network doesn't match client network. + Síť platebního požadavku neodpovídá síti klienta. + + + Payment request expired. + Platební požadavek vypršel. + + + Payment request is not initialized. + Platební požadavek není zahájený. + + + Unverified payment requests to custom payment scripts are unsupported. + Neověřené platební požadavky k uživatelským platebním skriptům nejsou podporované. + + + Invalid payment request. + Neplatný platební požadavek. + + + Requested payment amount of %1 is too small (considered dust). + Požadovaná platební částka %1 je příliš malá (je považována za prach). + + + Refund from %1 + Vrácení peněz od %1 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + Platební požadavek %1 je moc velký (%2 bajtů, povoleno %3 bajtů). + + + Error communicating with %1: %2 + Chyba při komunikaci s %1: %2 + + + Payment request cannot be parsed! + Platební požadavek je nečitelný! + + + Bad response from server %1 + Chybná odpověď ze serveru %1 + + + Network request error + Chyba síťového požadavku + + + Payment acknowledged + Platba potvrzena + + + PeerTableModel User Agent @@ -916,10 +1358,29 @@ + QRImageWidget + + &Save Image... + &Ulož obrázek... + + + &Copy Image + &Kopíruj obrázek + + + Save QR Code + Ulož QR kód + + + PNG Image (*.png) + PNG obrázek (*.png) + + + RPCConsole N/A - N/A + nedostupná informace Client version @@ -942,6 +1403,10 @@ Používaná verze BerkeleyDB + Datadir + Adresář s daty + + Startup time Čas spuštění @@ -966,8 +1431,16 @@ Aktuální počet bloků + Memory Pool + Transakční zásobník + + + Current number of transactions + Aktuální množství transakcí + + Memory usage - Využití paměti + Obsazenost paměti Received @@ -982,10 +1455,18 @@ &Protějšky + Banned peers + Protějšky pod klatbou (blokované) + + Select a peer to view detailed information. Vyber protějšek a uvidíš jeho detailní informace. + Whitelisted + Vždy vítán + + Direction Směr @@ -994,21 +1475,45 @@ Verze - User Agent - Typ klienta + Starting Block + Počáteční blok - Services - Služby + Synced Headers + Aktuálně hlaviček - Ban Score - Skóre pro klatbu + Synced Blocks + Aktuálně bloků - Connection Time - Doba spojení - + User Agent + Typ klienta + + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + Otevři soubor s ladicími záznamy %1 z aktuálního datového adresáře. U velkých žurnálů to může pár vteřin zabrat. + + + Decrease font size + Zmenšit písmo + + + Increase font size + Zvětšit písmo + + + Services + Služby + + + Ban Score + Skóre pro klatbu + + + Connection Time + Doba spojení + Last Send Poslední odeslání @@ -1022,6 +1527,14 @@ Odezva + The duration of a currently outstanding ping. + Jak dlouho už čekám na pong. + + + Ping Wait + Doba čekání na odezvu + + Time Offset Časový posun @@ -1094,6 +1607,10 @@ &Zbavit uzel klatby + Welcome to the %1 RPC console. + Vítej v RPC konzoli %1. + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. V historii se pohybuješ šipkami nahoru a dolů a pomocí <b>Ctrl-L</b> čistíš obrazovku. @@ -1220,6 +1737,18 @@ Remove Smazat + + Copy label + Kopíruj její označení + + + Copy message + Kopíruj zprávu + + + Copy amount + Kopíruj částku + ReceiveRequestDialog @@ -1239,6 +1768,73 @@ &Save Image... &Ulož obrázek... + + Request payment to %1 + Platební požadavek: %1 + + + Payment information + Informace o platbě + + + URI + URI + + + Address + Adresa + + + Amount + Částka + + + Label + Označení + + + Message + Zpráva + + + Resulting URI too long, try to reduce the text for label / message. + Výsledná URI je příliš dlouhá, zkus zkrátit text označení/zprávy. + + + Error encoding URI into QR Code. + Chyba při kódování URI do QR kódu. + + + + RecentRequestsTableModel + + Date + Datum + + + Label + Označení + + + Message + Zpráva + + + (no label) + (bez označení) + + + (no message) + (bez zprávy) + + + (no amount requested) + (bez požadované částky) + + + Requested + Požádáno + SendCoinsDialog @@ -1390,6 +1986,110 @@ S&end Pošl&i + + Copy quantity + Kopíruj počet + + + Copy amount + Kopíruj částku + + + Copy fee + Kopíruj poplatek + + + Copy after fee + Kopíruj čistou částku + + + Copy bytes + Kopíruj bajty + + + Copy dust + Kopíruj prach + + + Copy change + Kopíruj drobné + + + %1 to %2 + %1 pro %2 + + + Are you sure you want to send? + Jsi si jistý, že to chceš poslat? + + + added as transaction fee + přidán jako transakční poplatek + + + Total Amount %1 + Celková částka %1 + + + or + nebo + + + Confirm send coins + Potvrď odeslání mincí + + + The recipient address is not valid. Please recheck. + Adresa příjemce je neplatná – překontroluj ji prosím. + + + The amount to pay must be larger than 0. + Odesílaná částka musí být větší než 0. + + + The amount exceeds your balance. + Částka překračuje stav účtu. + + + The total exceeds your balance when the %1 transaction fee is included. + Celková částka při připočítání poplatku %1 překročí stav účtu. + + + Duplicate address found: addresses should only be used once each. + Zaznamenána duplicitní adresa: každá adresa by ale měla být použita vždy jen jednou. + + + Transaction creation failed! + Vytvoření transakce selhalo! + + + A fee higher than %1 is considered an absurdly high fee. + Poplatek vyšší než %1 je považován za absurdně vysoký. + + + Payment request expired. + Platební požadavek vypršel. + + + Pay only the required fee of %1 + Zaplatit pouze vyžadovaný poplatek %1 + + + Estimated to begin confirmation within %n block(s). + Potvrzování by podle odhadu mělo začít během %n bloku.Potvrzování by podle odhadu mělo začít během %n bloků.Potvrzování by podle odhadu mělo začít během %n bloků. + + + Warning: Invalid Bitcoin address + Upozornění: Neplatná Bitcoinová adresa + + + Warning: Unknown change address + Upozornění: Neznámá adresa pro drobné + + + (no label) + (bez označení) + SendCoinsEntry @@ -1469,10 +2169,25 @@ Memo: Poznámka: + + Enter a label for this address to add it to your address book + Zadej označení této adresy; obojí se ti pak uloží do adresáře + + + + SendConfirmationDialog + + Yes + Ano + ShutdownWindow + %1 is shutting down... + %1 se ukončuje... + + Do not shut down the computer until this window disappears. Nevypínej počítač, dokud toto okno nezmizí. @@ -1563,6 +2278,58 @@ Reset all verify message fields Vymaž všechna pole formuláře pro ověření zrávy + + Click "Sign Message" to generate signature + Kliknutím na „Podepiš zprávu“ vygeneruješ podpis + + + The entered address is invalid. + Zadaná adresa je neplatná. + + + Please check the address and try again. + Zkontroluj ji prosím a zkus to pak znovu. + + + The entered address does not refer to a key. + Zadaná adresa nepasuje ke klíči. + + + Wallet unlock was cancelled. + Odemčení peněženky bylo zrušeno. + + + Private key for the entered address is not available. + Soukromý klíč pro zadanou adresu není dostupný. + + + Message signing failed. + Nepodařilo se podepsat zprávu. + + + Message signed. + Zpráva podepsána. + + + The signature could not be decoded. + Podpis nejde dekódovat. + + + Please check the signature and try again. + Zkontroluj ho prosím a zkus to pak znovu. + + + The signature did not match the message digest. + Podpis se neshoduje s hašem zprávy. + + + Message verification failed. + Nepodařilo se ověřit zprávu. + + + Message verified. + Zpráva ověřena. + SplashScreen @@ -1579,11 +2346,456 @@ + TransactionDesc + + Open for %n more block(s) + Otevřeno pro %n další blokOtevřeno pro %n další blokyOtevřeno pro %n dalších bloků + + + Open until %1 + Otřevřeno dokud %1 + + + conflicted with a transaction with %1 confirmations + koliduje s transakcí o %1 konfirmacích + + + %1/offline + %1/offline + + + 0/unconfirmed, %1 + 0/nepotvrzeno, %1 + + + in memory pool + v transakčním zásobníku + + + not in memory pool + není ani v transakčním zásobníku + + + abandoned + zanechaná + + + %1/unconfirmed + %1/nepotvrzeno + + + %1 confirmations + %1 potvrzení + + + Status + Stav + + + , has not been successfully broadcast yet + , ještě nebylo rozesláno + + + , broadcast through %n node(s) + , rozesláno přes %n uzel, rozesláno přes %n uzly, rozesláno přes %n uzlů + + + Date + Datum + + + Source + Zdroj + + + Generated + Vygenerováno + + + From + Od + + + unknown + neznámo + + + To + Pro + + + own address + vlastní adresa + + + watch-only + sledovaná + + + label + označení + + + Credit + Příjem + + + matures in %n more block(s) + dozraje po %n blokudozraje po %n blocíchdozraje po %n blocích + + + not accepted + neakceptováno + + + Debit + Výdaj + + + Total debit + Celkové výdaje + + + Total credit + Celkové příjmy + + + Transaction fee + Transakční poplatek + + + Net amount + Čistá částka + + + Message + Zpráva + + + Comment + Komentář + + + Transaction ID + ID transakce + + + Output index + Pořadí výstupu + + + Merchant + Obchodník + + + 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. + Vygenerované mince musí čekat %1 bloků, než mohou být utraceny. Když jsi vygeneroval tenhle blok, tak byl rozposlán do sítě, aby byl přidán do řetězce bloků. Pokud se mu nepodaří dostat se do řetězce, změní se na „neakceptovaný“ a nepůjde utratit. To se občas může stát, pokud jiný uzel vygeneruje blok zhruba ve stejném okamžiku jako ty. + + + Debug information + Ladicí informace + + + Transaction + Transakce + + + Inputs + Vstupy + + + Amount + Částka + + + true + true + + + false + false + + + TransactionDescDialog This pane shows a detailed description of the transaction Toto okno zobrazuje detailní popis transakce + + Details for %1 + Podrobnosti o %1 + + + + TransactionTableModel + + Date + Datum + + + Type + Typ + + + Label + Označení + + + Open for %n more block(s) + Otevřeno pro %n další blokOtevřeno pro %n další blokyOtevřeno pro %n dalších bloků + + + Open until %1 + Otřevřeno dokud %1 + + + Offline + Offline + + + Unconfirmed + Nepotvrzeno + + + Abandoned + Zanechaná + + + Confirming (%1 of %2 recommended confirmations) + Potvrzuje se (%1 z %2 doporučených potvrzení) + + + Confirmed (%1 confirmations) + Potvrzeno (%1 potvrzení) + + + Conflicted + V kolizi + + + Immature (%1 confirmations, will be available after %2) + Nedozráno (%1 potvrzení, dozraje při %2 potvrzeních) + + + This block was not received by any other nodes and will probably not be accepted! + Tento blok nedostal žádný jiný uzel a pravděpodobně nebude akceptován! + + + Generated but not accepted + Vygenerováno, ale neakceptováno + + + Received with + Přijato do + + + Received from + Přijato od + + + Sent to + Posláno na + + + Payment to yourself + Platba sama sobě + + + Mined + Vytěženo + + + watch-only + sledovací + + + (n/a) + (n/a) + + + (no label) + (bez označení) + + + Transaction status. Hover over this field to show number of confirmations. + Stav transakce. Najetím myši na toto políčko si zobrazíš počet potvrzení. + + + Date and time that the transaction was received. + Datum a čas přijetí transakce. + + + Type of transaction. + Druh transakce. + + + Whether or not a watch-only address is involved in this transaction. + Zda tato transakce zahrnuje i některou sledovanou adresu. + + + User-defined intent/purpose of the transaction. + Uživatelsky určený účel transakce. + + + Amount removed from or added to balance. + Částka odečtená z nebo přičtená k účtu. + + + + TransactionView + + All + Vše + + + Today + Dnes + + + This week + Tento týden + + + This month + Tento měsíc + + + Last month + Minulý měsíc + + + This year + Letos + + + Range... + Rozsah... + + + Received with + Přijato + + + Sent to + Posláno + + + To yourself + Sám sobě + + + Mined + Vytěženo + + + Other + Ostatní + + + Enter address or label to search + Zadej adresu nebo označení pro její vyhledání + + + Min amount + Minimální částka + + + Abandon transaction + Zapomenout transakci + + + Copy address + Kopíruj adresu + + + Copy label + Kopíruj její označení + + + Copy amount + Kopíruj částku + + + Copy transaction ID + Kopíruj ID transakce + + + Copy raw transaction + Kopíruj surovou transakci + + + Copy full transaction details + Kopíruj kompletní podrobnosti o transakci + + + Edit label + Uprav označení + + + Show transaction details + Zobraz detaily transakce + + + Export Transaction History + Exportuj transakční historii + + + Comma separated file (*.csv) + Formát CSV (*.csv) + + + Confirmed + Potvrzeno + + + Watch-only + Sledovaná + + + Date + Datum + + + Type + Typ + + + Label + Označení + + + Address + Adresa + + + ID + ID + + + Exporting Failed + Exportování selhalo + + + There was an error trying to save the transaction history to %1. + Při ukládání transakční historie do %1 se přihodila nějaká chyba. + + + Exporting Successful + Úspěšně vyexportováno + + + The transaction history was successfully saved to %1. + Transakční historie byla v pořádku uložena do %1. + + + Range: + Rozsah: + + + to + + UnitDisplayStatusBarControl @@ -1593,6 +2805,55 @@ + WalletFrame + + No wallet has been loaded. + Žádná peněženka se nenačetla. + + + + WalletModel + + Send Coins + Pošli mince + + + + WalletView + + &Export + &Export + + + Export the data in the current tab to a file + Exportuj data z tohoto panelu do souboru + + + Backup Wallet + Záloha peněženky + + + Wallet Data (*.dat) + Data peněženky (*.dat) + + + Backup Failed + Zálohování selhalo + + + There was an error trying to save the wallet data to %1. + Při ukládání peněženky do %1 se přihodila nějaká chyba. + + + Backup Successful + Úspěšně zazálohováno + + + The wallet data was successfully saved to %1. + Data z peněženky byla v pořádku uložena do %1. + + + bitcoin-core Options: @@ -1679,6 +2940,10 @@ Poslouchat na zadané adrese. Pro zápis IPv6 adresy použij notaci [adresa]:port + Cannot obtain a lock on data directory %s. %s is probably already running. + Nedaří se mi získat zámek na datový adresář %s. %s pravděpodobně už jednou běží. + + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup Smazat všechny transakce peněženky a při startu obnovit pouze relevantní části řetězce bloků pomocí -rescan @@ -1691,8 +2956,16 @@ Spustit příkaz, když se objeví transakce týkající se peněženky (%s se v příkazu nahradí za TxID) - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Vynutit přeposílání transakcí od vždy vítaných protějšků (tj. těch na bílé listině), i když porušují místní zásady pro přeposílání (výchozí: %d) + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + Horní hranice pro celkový poplatek (v %s) za jednu transakci z peněženky nebo jednu surovou transakci; příliš nízká hodnota může zmařit velké transakce (výchozí: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + Zkontroluj, že máš v počítači správně nastavený datum a čas! Pokud jsou nastaveny špatně, %s nebude fungovat správně. + + + Please contribute if you find %s useful. Visit %s for further information about the software. + Prosíme, zapoj se nebo přispěj, pokud ti %s přijde užitečný. Více informací o programu je na %s. Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) @@ -1723,6 +2996,14 @@ Vždy vítat protějšky připojující se z dané podsítě či IP adresy. Lze zadat i vícekrát. + You need to rebuild the database using -reindex-chainstate to change -txindex + Je třeba přestavět databázi použitím -reindex-chainstate, aby bylo možné změnit -txindex + + + %s corrupt, salvage failed + %s je poškozen, jeho záchrana se nezdařila + + -maxmempool must be at least %d MB -maxmempool musí být alespoň %d MB @@ -1735,10 +3016,18 @@ Připojit komentář k typu klienta + Attempt to recover private keys from a corrupt wallet on startup + Pokusit se při startu zachránit soukromé klíče z poškozeného souboru s klíči + + Block creation options: Možnosti vytváření bloku: + Cannot resolve -%s address: '%s' + Nemohu přeložit -%s adresu: '%s' + + Connect only to the specified node(s) Připojit se pouze k zadanému uzlu (příp. zadaným uzlům) @@ -1747,6 +3036,10 @@ Možnosti připojení: + Copyright (C) %i-%i + Copyright (C) %i–%i + + Corrupted block database detected Bylo zjištěno poškození databáze bloků @@ -1763,6 +3056,10 @@ Chceš přestavět databázi bloků hned teď? + Enable transaction replacement in the memory pool (default: %u) + Povolit výměnu transakcí v transakčním zásobníku (výchozí: %u) + + Error initializing block database Chyba při zakládání databáze bloků @@ -1771,6 +3068,18 @@ Chyba při vytváření databázového prostředí %s pro peněženku! + Error loading %s + Chyba při načítání %s + + + Error loading %s: Wallet corrupted + Chyba při načítání %s: peněženka je poškozená + + + Error loading %s: Wallet requires newer version of %s + Chyba při načítání %s: peněženka vyžaduje novější verzi %s + + Error loading block database Chyba při načítání databáze bloků @@ -1795,10 +3104,18 @@ Nemám žádný nebo jen špatný genesis blok. Není špatně nastavený datadir? + Initialization sanity check failed. %s is shutting down. + Selhala úvodní zevrubná prověrka. %s se ukončuje. + + Invalid -onion address: '%s' Neplatná -onion adresa: '%s' + Invalid amount for -%s=<amount>: '%s' + Neplatná částka pro -%s=<částka>: '%s' + + Invalid amount for -fallbackfee=<amount>: '%s' Neplatná částka pro -fallbackfee=<částka>: '%s' @@ -1807,12 +3124,12 @@ Udržovat zasobník transakcí menší než <n> megabajtů (výchozí: %u) - Location of the auth cookie (default: data dir) - Místo pro autentizační cookie (výchozí: adresář pro data) + Loading banlist... + Načítám seznam klateb... - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Minimální počet bajtů na každý sigop v transakcích, které přeposíláme a těžíme (výchozí: %u) + Location of the auth cookie (default: data dir) + Místo pro autentizační cookie (výchozí: adresář pro data) Not enough file descriptors available. @@ -1823,6 +3140,10 @@ Připojovat se pouze k uzlům v <net> síti (ipv4, ipv6 nebo onion) + Print this help message and exit + Vypsat tuto nápovědu a skončit + + Print version and exit Vypsat verzi a skončit @@ -1835,6 +3156,10 @@ Prořezávací režim není kompatibilní s -txindex. + Rebuild chain state and block index from the blk*.dat files on disk + Při startu znovu vytvořit index řetězce bloků z aktuálních blk*.dat souborů + + Set database cache size in megabytes (%d to %d, default: %d) Nastavit velikost databázové vyrovnávací paměti v megabajtech (%d až %d, výchozí: %d) @@ -1847,6 +3172,10 @@ Udej název souboru s peněženkou (v rámci datového adresáře) + Unable to bind to %s on this computer. %s is probably already running. + Nedaří se mi připojit na %s na tomhle počítači. %s už pravděpodobně jednou běží. + + Unsupported argument -benchmark ignored, use -debug=bench. Nepodporovaný argument -benchmark se ignoruje, použij -debug=bench. @@ -1879,6 +3208,14 @@ Peněženka %s se nachází mimo datový adresář %s + Wallet debugging/testing options: + Možnosti ladění/testování peněženky: + + + Wallet needed to be rewritten: restart %s to complete + Soubor s peněženkou potřeboval přepsat: restartuj %s, aby se operace dokončila + + Wallet options: Možnosti peněženky: @@ -1915,6 +3252,10 @@ Poplatky (v %s/kB) menší než tato hodnota jsou považovány za nulové pro účely přeposílání, těžení a vytváření transakcí (výchozí: %s) + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + Vynutit přeposílání transakcí od vždy vítaných protějšků (tj. těch na bílé listině), i když porušují místní zásady pro přeposílání (výchozí: %d) + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) 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) @@ -2083,6 +3424,10 @@ Upozornění + Warning: unknown new rules activated (versionbit %i) + Upozornění: aktivována neznámá nová pravidla (verzový bit %i) + + Whether to operate in a blocks only mode (default: %u) Zda fungovat v čistě blokovém režimu (výchozí: %u) @@ -2175,6 +3520,10 @@ Uživatelské jméno a zahašované heslo pro JSON-RPC spojení. Pole <userpw> má formát: <UŽIVATELSKÉ_JMÉNO>:<SŮL>$<HAŠ>. Pomocný pythonní skript je přiložen v share/rpcuser. Tuto volbu lze použít i vícekrát + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + Upozornění: soubor s peněženkou je poškozený, data jsou však zachráněna! Původní soubor %s je uložený jako %s v %s. Pokud nejsou stav tvého účtu nebo transakce v pořádku, zřejmě bys měl obnovit zálohu. + + (default: %s) (výchozí: %s) @@ -2235,10 +3584,6 @@ Nastavit zásobník klíčů na velikost <n> (výchozí: %u) - Set minimum block size in bytes (default: %u) - Nastavit minimální velikost bloku v bajtech (výchozí: %u) - - Set the number of threads to service RPC calls (default: %d) Nastavení počtu vláken pro servisní RPC volání (výchozí: %d) diff --git a/src/qt/locale/bitcoin_cs_CZ.ts b/src/qt/locale/bitcoin_cs_CZ.ts index 70aa981f503..e7e38d65acc 100644 --- a/src/qt/locale/bitcoin_cs_CZ.ts +++ b/src/qt/locale/bitcoin_cs_CZ.ts @@ -29,7 +29,10 @@ &Delete &Odstranit - + + + AddressTableModel + AskPassphraseDialog @@ -44,7 +47,7 @@ Repeat new passphrase Zopakujte nové heslo - + BanTableModel @@ -160,7 +163,7 @@ &Address &Adresa - + FreespaceChecker @@ -200,6 +203,9 @@ OverviewPage + PaymentServer + + PeerTableModel @@ -210,6 +216,9 @@ + QRImageWidget + + RPCConsole Name @@ -231,6 +240,9 @@ ReceiveRequestDialog + RecentRequestsTableModel + + SendCoinsDialog Amount: @@ -253,6 +265,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -269,16 +284,34 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Toto podokno zobrazuje detailní popis transakce - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_cy.ts b/src/qt/locale/bitcoin_cy.ts index 38bc45775bc..9fcd5eeb8c6 100644 --- a/src/qt/locale/bitcoin_cy.ts +++ b/src/qt/locale/bitcoin_cy.ts @@ -29,7 +29,10 @@ &Delete &Dileu - + + + AddressTableModel + AskPassphraseDialog @@ -44,7 +47,7 @@ Repeat new passphrase Ailadroddwch gyfrinymadrodd newydd - + BanTableModel @@ -252,7 +255,7 @@ &Address &Cyfeiriad - + FreespaceChecker @@ -332,12 +335,18 @@ + PaymentServer + + PeerTableModel QObject + QRImageWidget + + RPCConsole &Information @@ -367,6 +376,9 @@ + RecentRequestsTableModel + + SendCoinsDialog Send Coins @@ -417,6 +429,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -445,12 +460,30 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts index d298c81bd45..eee6cf20aae 100644 --- a/src/qt/locale/bitcoin_da.ts +++ b/src/qt/locale/bitcoin_da.ts @@ -41,6 +41,77 @@ &Delete &Slet + + Choose the address to send coins to + Vælg adresse at sende bitcoins til + + + Choose the address to receive coins with + Vælg adresse at modtage bitcoins med + + + C&hoose + &Vælg + + + Sending addresses + Afsendelsesadresser + + + Receiving addresses + Modtagelsesadresser + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Disse er dine Bitcoin-adresser til afsendelse af betalinger. Tjek altid beløb og modtagelsesadresse, inden du sender bitcoins. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Dette er dine Bitcoin-adresser til modtagelse af betalinger. Det anbefales at bruge en ny modtagelsesadresse for hver transaktion. + + + &Copy Address + &Kopiér adresse + + + Copy &Label + Kopiér &mærkat + + + &Edit + &Redigér + + + Export Address List + Eksportér adresseliste + + + Comma separated file (*.csv) + Kommasepareret fil (*.csv) + + + Exporting Failed + Eksport mislykkedes + + + There was an error trying to save the address list to %1. Please try again. + Der opstod en fejl under gemning af adresselisten til %1. Prøv venligst igen. + + + + AddressTableModel + + Label + Mærkat + + + Address + Adresse + + + (no label) + (ingen mærkat) + AskPassphraseDialog @@ -60,6 +131,94 @@ Repeat new passphrase Gentag ny adgangskode + + 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>. + Indtast det nye kodeord til tegnebogen.<br/>Brug venligst et kodeord på <b>ti eller flere tilfældige tegn</b> eller <b>otte eller flere ord</b>. + + + Encrypt wallet + Kryptér tegnebog + + + This operation needs your wallet passphrase to unlock the wallet. + Denne funktion har brug for din tegnebogs adgangskode for at låse tegnebogen op. + + + Unlock wallet + Lås tegnebog op + + + This operation needs your wallet passphrase to decrypt the wallet. + Denne funktion har brug for din tegnebogs adgangskode for at dekryptere tegnebogen. + + + Decrypt wallet + Dekryptér tegnebog + + + Change passphrase + Skift adgangskode + + + Enter the old passphrase and new passphrase to the wallet. + Indtast den gamle adgangskode og en ny adgangskode til tegnebogen. + + + Confirm wallet encryption + Bekræft tegnebogskryptering + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Advarsel: Hvis du krypterer din tegnebog og mister din adgangskode, vil du <b>MISTE ALLE DINE BITCOINS</b>! + + + Are you sure you wish to encrypt your wallet? + Er du sikker på, at du ønsker at kryptere din tegnebog? + + + Wallet encrypted + Tegnebog krypteret + + + %1 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. + %1 vil nu lukke for at færdiggøre krypteringsprocessen. Husk at kryptering af din tegnebog kan ikke beskytte dine bitcoin fuldt ud mod at blive stjålet af eventuel malware, der måtte have inficeret din computer. + + + 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. + VIGTIGT: Enhver tidligere sikkerhedskopi, som du har lavet af tegnebogsfilen, bør blive erstattet af den nyligt genererede, krypterede tegnebogsfil. Af sikkerhedsmæssige årsager vil tidligere sikkerhedskopier af den ikke-krypterede tegnebogsfil blive ubrugelige i det øjeblik, du starter med at anvende den nye, krypterede tegnebog. + + + Wallet encryption failed + Tegnebogskryptering mislykkedes + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Tegnebogskryptering mislykkedes på grund af en intern fejl. Din tegnebog blev ikke krypteret. + + + The supplied passphrases do not match. + De angivne adgangskoder stemmer ikke overens. + + + Wallet unlock failed + Tegnebogsoplåsning mislykkedes + + + The passphrase entered for the wallet decryption was incorrect. + Den angivne adgangskode for tegnebogsdekrypteringen er forkert. + + + Wallet decryption failed + Tegnebogsdekryptering mislykkedes + + + Wallet passphrase was successfully changed. + Tegnebogens adgangskode blev ændret. + + + Warning: The Caps Lock key is on! + Advarsel: Caps Lock-tasten er aktiveret! + BanTableModel @@ -76,7 +235,7 @@ BitcoinGUI Sign &message... - Underskriv &besked… + Signér &besked… Synchronizing with network... @@ -216,11 +375,11 @@ Sign messages with your Bitcoin addresses to prove you own them - Underskriv beskeder med dine Bitcoin-adresser for at bevise, at de tilhører dig + Signér beskeder med dine Bitcoin-adresser for at bevise, at de tilhører dig Verify messages to ensure they were signed with specified Bitcoin addresses - Verificér beskeder for at sikre, at de er underskrevet med de angivne Bitcoin-adresser + Verificér beskeder for at sikre, at de er signeret med de angivne Bitcoin-adresser &File @@ -463,6 +622,150 @@ Priority Prioritet + + Copy address + Kopiér adresse + + + Copy label + Kopiér mærkat + + + Copy amount + Kopiér beløb + + + Copy transaction ID + Kopiér transaktions-ID + + + Lock unspent + Fastlås ubrugte + + + Unlock unspent + Lås ubrugte op + + + Copy quantity + Kopiér mængde + + + Copy fee + Kopiér gebyr + + + Copy after fee + Kopiér eftergebyr + + + Copy bytes + Kopiér byte + + + Copy priority + Kopiér prioritet + + + Copy dust + Kopiér støv + + + Copy change + Kopiér byttepenge + + + highest + højest + + + higher + højere + + + high + højt + + + medium-high + mellemhøjt + + + medium + medium + + + low-medium + mellemlavt + + + low + lavt + + + lower + lavere + + + lowest + lavest + + + (%1 locked) + (%1 fastlåst) + + + none + ingen + + + yes + ja + + + no + nej + + + This label turns red if the transaction size is greater than 1000 bytes. + Denne mærkat bliver rød, hvis transaktionsstørrelsen er større end 1000 byte. + + + This means a fee of at least %1 per kB is required. + Dette betyder, at et gebyr på mindst %1 pr. kB er nødvendigt. + + + Can vary +/- 1 byte per input. + Kan variere ±1 byte pr. input. + + + Transactions with higher priority are more likely to get included into a block. + Transaktioner med højere prioritet har højere sansynlighed for at blive inkluderet i en blok. + + + This label turns red if the priority is smaller than "medium". + Denne mærkat bliver rød, hvis prioriteten er mindre end "medium". + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Denne mærkat bliver rød, hvis en eller flere modtagere modtager et beløb, der er mindre end den aktuelle støvgrænse. + + + Can vary +/- %1 satoshi(s) per input. + Kan variere med ±%1 satoshi per input. + + + (no label) + (ingen mærkat) + + + change from %1 (%2) + byttepenge fra %1 (%2) + + + (change) + (byttepange) + EditAddressDialog @@ -486,6 +789,38 @@ &Address &Adresse + + New receiving address + Ny modtagelsesadresse + + + New sending address + Ny afsendelsesadresse + + + Edit receiving address + Redigér modtagelsesadresse + + + Edit sending address + Redigér afsendelsesadresse + + + The entered address "%1" is not a valid Bitcoin address. + Den indtastede adresse "%1" er ikke en gyldig Bitcoin-adresse. + + + The entered address "%1" is already in the address book. + Den indtastede adresse "%1" er allerede i adressebogen. + + + Could not unlock wallet. + Kunne ikke låse tegnebog op. + + + New key generation failed. + Ny nøglegenerering mislykkedes. + FreespaceChecker @@ -605,7 +940,7 @@ (of %n GB needed) - (ud af %n GB behøvet)(ud af %n GB behøvet) + (ud af %n GB nødvendig)(ud af %n GB nødvendig) @@ -626,6 +961,10 @@ Select payment request file Vælg fil for betalingsanmodning + + Select payment request file to open + Vælg fil for betalingsanmodning til åbning + OptionsDialog @@ -938,6 +1277,97 @@ + PaymentServer + + Payment request error + Fejl i betalingsanmodning + + + Cannot start bitcoin: click-to-pay handler + Kan ikke starte bitcoin: click-to-pay-håndtering + + + URI handling + URI-håndtering + + + Payment request fetch URL is invalid: %1 + Hentnings-URL for betalingsanmodning er ugyldig: %1 + + + Invalid payment address %1 + Ugyldig betalingsadresse %1 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + URI kan ikke tolkes! Dette kan skyldes en ugyldig Bitcoin-adresse eller forkert udformede URL-parametre. + + + Payment request file handling + Filhåndtering for betalingsanmodninger + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + Fil for betalingsanmodning kan ikke læses! Dette kan skyldes en ugyldig fil for betalingsanmodning. + + + Payment request rejected + Betalingsanmodning afvist + + + Payment request network doesn't match client network. + Netværk for betalingsanmodning stemmer ikke overens med klientens netværk. + + + Payment request expired. + Betalingsanmodning er udløbet. + + + Payment request is not initialized. + Betalingsanmodning er ikke klargjort. + + + Unverified payment requests to custom payment scripts are unsupported. + Ikke-verificerede betalingsanmodninger for tilpassede betalings-scripts understøttes ikke. + + + Invalid payment request. + Ugyldig betalingsanmodning. + + + Requested payment amount of %1 is too small (considered dust). + Anmodet betalingsbeløb på %1 er for lille (regnes som støv). + + + Refund from %1 + Tilbagebetaling fra %1 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + Betalingsanmodning %1 er for stor (%2 byte; %3 byte tilladt). + + + Error communicating with %1: %2 + Fejl under kommunikation med %1: %2 + + + Payment request cannot be parsed! + Betalingsanmodning kan ikke tolkes! + + + Bad response from server %1 + Fejlagtigt svar fra server %1 + + + Network request error + Fejl i netværksforespørgsel + + + Payment acknowledged + Betaling anerkendt + + + PeerTableModel User Agent @@ -992,6 +1422,25 @@ + QRImageWidget + + &Save Image... + Gem billede… + + + &Copy Image + &Kopiér foto + + + Save QR Code + Gem QR-kode + + + PNG Image (*.png) + PNG-billede (*.png) + + + RPCConsole N/A @@ -1352,6 +1801,18 @@ Remove Fjern + + Copy label + Kopiér mærkat + + + Copy message + Kopiér besked + + + Copy amount + Kopiér beløb + ReceiveRequestDialog @@ -1371,40 +1832,107 @@ &Save Image... &Gem billede… - - - SendCoinsDialog - Send Coins - Send bitcoins + Request payment to %1 + Anmod om betaling til %1 - Coin Control Features - Egenskaber for coin-styring + Payment information + Betalingsinformation - Inputs... - Inputs… + URI + URI - automatically selected - valgt automatisk + Address + Adresse - Insufficient funds! - Utilstrækkelige midler! + Amount + Beløb - Quantity: - Mængde: + Label + Mærkat - Bytes: - Byte: + Message + Besked - Amount: - Beløb: + Resulting URI too long, try to reduce the text for label / message. + Resulterende URI var for lang; prøv at forkorte teksten til mærkaten/beskeden. + + + Error encoding URI into QR Code. + Fejl ved kodning fra URI til QR-kode. + + + + RecentRequestsTableModel + + Date + Dato + + + Label + Mærkat + + + Message + Besked + + + (no label) + (ingen mærkat) + + + (no message) + (ingen besked) + + + (no amount requested) + (intet anmodet beløb) + + + Requested + Anmodet + + + + SendCoinsDialog + + Send Coins + Send bitcoins + + + Coin Control Features + Egenskaber for coin-styring + + + Inputs... + Inputs… + + + automatically selected + valgt automatisk + + + Insufficient funds! + Utilstrækkelige midler! + + + Quantity: + Mængde: + + + Bytes: + Byte: + + + Amount: + Beløb: Priority: @@ -1522,6 +2050,118 @@ S&end &Afsend + + Copy quantity + Kopiér mængde + + + Copy amount + Kopiér beløb + + + Copy fee + Kopiér gebyr + + + Copy after fee + Kopiér eftergebyr + + + Copy bytes + Kopiér byte + + + Copy priority + Kopiér prioritet + + + Copy dust + Kopiér støv + + + Copy change + Kopiér byttepenge + + + %1 to %2 + %1 til %2 + + + Are you sure you want to send? + Er du sikker på, at du vil sende? + + + added as transaction fee + tilføjet som transaktionsgebyr + + + Total Amount %1 + Beløb i alt %1 + + + or + eller + + + Confirm send coins + Bekræft afsendelse af bitcoins + + + The recipient address is not valid. Please recheck. + Modtageradressen er ikke gyldig. Tjek venligst igen. + + + The amount to pay must be larger than 0. + Beløbet til betaling skal være større end 0. + + + The amount exceeds your balance. + Beløbet overstiger din saldo. + + + The total exceeds your balance when the %1 transaction fee is included. + Totalen overstiger din saldo, når transaktionsgebyret på %1 er inkluderet. + + + Duplicate address found: addresses should only be used once each. + Adressegenganger fundet. Adresser bør kun bruges én gang hver. + + + Transaction creation failed! + Oprettelse af transaktion mislykkedes! + + + 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. + Transaktionen blev afvist! Dette kan ske, hvis nogle af dine bitcoins i din tegnebog allerede er brugt, som hvis du brugte en kopi af wallet.dat og dine bitcoins er blevet brugt i kopien, men ikke er markeret som brugt her. + + + A fee higher than %1 is considered an absurdly high fee. + Et gebyr højere end %1 opfattes som et absurd højt gebyr. + + + Payment request expired. + Betalingsanmodning er udløbet. + + + Pay only the required fee of %1 + Betal kun det påkrævede gebyr på %1 + + + Estimated to begin confirmation within %n block(s). + Bekræftelse estimeret til at begynde inden for %n blok.Bekræftelse estimeret til at begynde inden for %n blokke. + + + Warning: Invalid Bitcoin address + Advarsel: Ugyldig Bitcoin-adresse + + + Warning: Unknown change address + Advarsel: Ukendt byttepengeadresse + + + (no label) + (ingen mærkat) + SendCoinsEntry @@ -1601,6 +2241,17 @@ Memo: Memo: + + Enter a label for this address to add it to your address book + Indtast en mærkat for denne adresse for at føje den til din adressebog + + + + SendConfirmationDialog + + Yes + Ja + ShutdownWindow @@ -1617,11 +2268,11 @@ SignVerifyMessageDialog Signatures - Sign / Verify a Message - Signature - Underskriv/verificér en besked + Signaturer – Underskriv/verificér en besked &Sign Message - &Underskriv besked + &Singér besked 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. @@ -1649,27 +2300,27 @@ Enter the message you want to sign here - Indtast her beskeden, du ønsker at underskrive + Indtast her beskeden, du ønsker at signere Signature - Underskrift + Signatur Copy the current signature to the system clipboard - Kopiér den nuværende underskrift til systemets udklipsholder + Kopiér den nuværende signatur til systemets udklipsholder Sign the message to prove you own this Bitcoin address - Underskriv denne besked for at bevise, at Bitcoin-adressen tilhører dig + Signér denne besked for at bevise, at Bitcoin-adressen tilhører dig Sign &Message - Underskriv &besked + Signér &besked Reset all sign message fields - Nulstil alle "underskriv besked"-felter + Nulstil alle "signér besked"-felter Clear &All @@ -1689,7 +2340,7 @@ Verify the message to ensure it was signed with the specified Bitcoin address - Verificér beskeden for at sikre, at den er underskrevet med den angivne Bitcoin-adresse + Verificér beskeden for at sikre, at den er signeret med den angivne Bitcoin-adresse Verify &Message @@ -1699,6 +2350,58 @@ Reset all verify message fields Nulstil alle "verificér besked"-felter + + Click "Sign Message" to generate signature + Klik "Signér besked" for at generere underskriften + + + The entered address is invalid. + Den indtastede adresse er ugyldig. + + + Please check the address and try again. + Tjek venligst adressen og forsøg igen. + + + The entered address does not refer to a key. + Den indtastede adresse henviser ikke til en nøgle. + + + Wallet unlock was cancelled. + Tegnebogsoplåsning annulleret. + + + Private key for the entered address is not available. + Den private nøgle for den indtastede adresse er ikke tilgængelig. + + + Message signing failed. + Signering af besked mislykkedes. + + + Message signed. + Besked signeret. + + + The signature could not be decoded. + Signaturen kunne ikke afkodes. + + + Please check the signature and try again. + Tjek venligst signaturen og forsøg igen. + + + The signature did not match the message digest. + Signaturen passer ikke overens med beskedens indhold. + + + Message verification failed. + Verificering af besked mislykkedes. + + + Message verified. + Besked verificeret. + SplashScreen @@ -1715,11 +2418,456 @@ + TransactionDesc + + Open for %n more block(s) + Åbn yderligere %n blokÅbn yderligere %n blokke + + + Open until %1 + Åben indtil %1 + + + conflicted with a transaction with %1 confirmations + i konflikt med en transaktion, der har %1 bekræftelser + + + %1/offline + %1/offline + + + 0/unconfirmed, %1 + 0/ubekræftet, %1 + + + in memory pool + i hukommelsespulje + + + not in memory pool + ikke i hukommelsespulje + + + abandoned + opgivet + + + %1/unconfirmed + %1/ubekræftet + + + %1 confirmations + %1 bekræftelser + + + Status + Status + + + , has not been successfully broadcast yet + , er ikke blevet transmitteret endnu + + + , broadcast through %n node(s) + , transmitteret igennem %n knude, transmitteret igennem %n knuder + + + Date + Dato + + + Source + Kilde + + + Generated + Genereret + + + From + Fra + + + unknown + ukendt + + + To + Til + + + own address + egen adresse + + + watch-only + kigge + + + label + mærkat + + + Credit + Kredit + + + matures in %n more block(s) + modner efter yderligere %n blokmodner efter yderligere %n blokke + + + not accepted + ikke accepteret + + + Debit + Debet + + + Total debit + Total debet + + + Total credit + Total kredit + + + Transaction fee + Transaktionsgebyr + + + Net amount + Nettobeløb + + + Message + Besked + + + Comment + Kommentar + + + Transaction ID + Transaktions-ID + + + Output index + Outputindeks + + + Merchant + Forretningsdrivende + + + 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. + Minede bitcoins skal modne %1 blokke, før de kan bruges. Da du genererede denne blok, blev den transmitteret til netværket for at blive føjet til blokkæden. Hvis det ikke lykkes at få den i kæden, vil dens tilstand ændres til "ikke accepteret", og den vil ikke kunne bruges. Dette kan ske nu og da, hvis en anden knude udvinder en blok inden for nogle få sekunder fra din. + + + Debug information + Fejlsøgningsinformation + + + Transaction + Transaktion + + + Inputs + Input + + + Amount + Beløb + + + true + sand + + + false + falsk + + + TransactionDescDialog This pane shows a detailed description of the transaction Denne rude viser en detaljeret beskrivelse af transaktionen + + Details for %1 + Detaljer for %1 + + + + TransactionTableModel + + Date + Dato + + + Type + Type + + + Label + Mærkat + + + Open for %n more block(s) + Åben i yderligere %n blokÅben i yderligere %n blokke + + + Open until %1 + Åben indtil %1 + + + Offline + Offline + + + Unconfirmed + Ubekræftet + + + Abandoned + Opgivet + + + Confirming (%1 of %2 recommended confirmations) + Bekræfter (%1 af %2 anbefalede bekræftelser) + + + Confirmed (%1 confirmations) + Bekræftet (%1 bekræftelser) + + + Conflicted + Konflikt + + + Immature (%1 confirmations, will be available after %2) + Umoden (%1 bekræftelser; vil være tilgængelig efter %2) + + + This block was not received by any other nodes and will probably not be accepted! + Denne blok blev ikke modtaget af nogen andre knuder og vil formentlig ikke blive accepteret! + + + Generated but not accepted + Genereret, men ikke accepteret + + + Received with + Modtaget med + + + Received from + Modtaget fra + + + Sent to + Sendt til + + + Payment to yourself + Betaling til dig selv + + + Mined + Minet + + + watch-only + kigge + + + (n/a) + (n/a) + + + (no label) + (ingen mærkat) + + + Transaction status. Hover over this field to show number of confirmations. + Transaktionsstatus. Hold musen over dette felt for at vise antallet af bekræftelser. + + + Date and time that the transaction was received. + Dato og klokkeslæt for modtagelse af transaktionen. + + + Type of transaction. + Transaktionstype. + + + Whether or not a watch-only address is involved in this transaction. + Afgør hvorvidt en kigge-adresse er involveret i denne transaktion. + + + User-defined intent/purpose of the transaction. + Brugerdefineret hensigt/formål med transaktionen. + + + Amount removed from or added to balance. + Beløb trukket fra eller tilføjet balance. + + + + TransactionView + + All + Alle + + + Today + I dag + + + This week + Denne uge + + + This month + Denne måned + + + Last month + Sidste måned + + + This year + I år + + + Range... + Interval… + + + Received with + Modtaget med + + + Sent to + Sendt til + + + To yourself + Til dig selv + + + Mined + Minet + + + Other + Andet + + + Enter address or label to search + Indtast adresse eller mærkat for at søge + + + Min amount + Minimumsbeløb + + + Abandon transaction + Opgiv transaktion + + + Copy address + Kopiér adresse + + + Copy label + Kopiér mærkat + + + Copy amount + Kopiér beløb + + + Copy transaction ID + Kopiér transaktions-ID + + + Copy raw transaction + Kopiér rå transaktion + + + Copy full transaction details + Kopiér komplette transaktionsdetaljer + + + Edit label + Redigér mærkat + + + Show transaction details + Vis transaktionsdetaljer + + + Export Transaction History + Eksportér transaktionshistorik + + + Comma separated file (*.csv) + Kommasepareret fil (*.csv) + + + Confirmed + Bekræftet + + + Watch-only + Kigge + + + Date + Dato + + + Type + Type + + + Label + Mærkat + + + Address + Adresse + + + ID + ID + + + Exporting Failed + Eksport mislykkedes + + + There was an error trying to save the transaction history to %1. + En fejl opstod under gemning af transaktionshistorik til %1. + + + Exporting Successful + Eksport problemfri + + + The transaction history was successfully saved to %1. + Transaktionshistorikken blev gemt til %1. + + + Range: + Interval: + + + to + til + UnitDisplayStatusBarControl @@ -1729,6 +2877,55 @@ + WalletFrame + + No wallet has been loaded. + Ingen tegnebog er indlæst. + + + + WalletModel + + Send Coins + Send bitcoins + + + + WalletView + + &Export + &Eksportér + + + Export the data in the current tab to a file + Eksportér den aktuelle visning til en fil + + + Backup Wallet + Sikkerhedskopiér tegnebog + + + Wallet Data (*.dat) + Tegnebogsdata (*.dat) + + + Backup Failed + Sikkerhedskopiering mislykkedes + + + There was an error trying to save the wallet data to %1. + Der skete en fejl under gemning af tegnebogsdata til %1. + + + Backup Successful + Sikkerhedskopiering problemfri + + + The wallet data was successfully saved to %1. + Tegnebogsdata blev gemt til %1. + + + bitcoin-core Options: @@ -1831,6 +3028,10 @@ Distribueret under MIT-softwarelicensen; se den vedlagte fil COPYING eller <http://www.opensource.org/licenses/mit-license.php>. + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Tilsvarende bytes pr. sigop i transaktioner, som videresendes og mines (standard: %u) + + Error loading %s: You can't enable HD on a already existing non-HD wallet Fejl under indlæsning af %s: Du kan ikke aktivere HD på en allerede eksisterende ikke-HD-tegnebog @@ -1843,10 +3044,6 @@ Udfør kommando, når en transaktion i tegnebogen ændres (%s i kommandoen erstattes med TxID) - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Gennemtving videresendelse af transaktioner fra hvidlistede knuder, selv om de overtræder lokal videresendelsespolitik (standard: %d) - - Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) Justering af maksimalt tilladt gennemsnitlig afvigelse fra peer-tid. Den lokale opfattelse af tid kan blive påvirket frem eller tilbage af peers med denne mængde tid. (standard: %u sekunder) @@ -2055,10 +3252,6 @@ Placering for autentificerings-cookie (standard: datamappe) - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Minimum bytes pr. sigop i transaktioner, vi videresender og miner (standard: %u) - - Not enough file descriptors available. For få tilgængelige fildeskriptorer. @@ -2099,8 +3292,8 @@ Sæt cache-størrelse for database i megabytes (%d til %d; standard: %d) - Set maximum block cost (default: %d) - Sæt maksimal blokudgift (standard: %d) + Set maximum BIP141 block weight (default: %d) + Sæt maksimal BIP141-blokvægt (standard: %d) Set maximum block size in bytes (default: %d) @@ -2111,6 +3304,10 @@ Angiv tegnebogsfil (inden for datamappe) + Starting network threads... + Starter netværkstråde… + + The source code is available from %s. Kildekoden er tilgængelig fra %s. @@ -2195,6 +3392,10 @@ Gebyrer (i %s/kB) mindre end dette opfattes som intet gebyr for videresendelse, mining og oprettelse af transaktioner (standard: %s) + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + Gennemtving videresendelse af transaktioner fra hvidlistede knuder, selv om de overtræder lokal videresendelsespolitik (standard: %d) + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Hvis paytxfee ikke er sat, inkluderes nok gebyr til at transaktioner begynder at blive bekræftet ingen for gennemsnitligt n blokke (standard: %u) @@ -2316,7 +3517,7 @@ Signing transaction failed - Underskrift af transaktion mislykkedes + Signering af transaktion mislykkedes The transaction amount is too small to pay the fee @@ -2532,10 +3733,6 @@ - Set minimum block size in bytes (default: %u) - Angiv minimumsblokstørrelse i byte (standard: %u) - - Set the number of threads to service RPC calls (default: %d) Angiv antallet af tråde til at håndtere RPC-kald (standard: %d) diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts index 2708324d172..939dfe6c0ef 100644 --- a/src/qt/locale/bitcoin_de.ts +++ b/src/qt/locale/bitcoin_de.ts @@ -41,6 +41,77 @@ &Delete &Löschen + + Choose the address to send coins to + Wählen Sie die Adresse aus, an die Sie Bitcoins überweisen möchten + + + Choose the address to receive coins with + Wählen Sie die Adresse aus, über die Sie Bitcoins empfangen wollen + + + C&hoose + &Auswählen + + + Sending addresses + Zahlungsadressen + + + Receiving addresses + Empfangsadressen + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Dies sind ihre Bitcoin-Adressen zum Tätigen von Überweisungen. Bitte prüfen Sie den Betrag und die Empfangsadresse, bevor Sie Bitcoins überweisen. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Dies sind Ihre Bitcoin-Adressen zum Empfangen von Zahlungen. Es wird empfohlen, für jede Transaktion eine neue Empfangsadresse zu verwenden. + + + &Copy Address + Adresse &kopieren + + + Copy &Label + &Bezeichnung kopieren + + + &Edit + &Editieren + + + Export Address List + Addressliste exportieren + + + Comma separated file (*.csv) + Kommagetrennte-Datei (*.csv) + + + Exporting Failed + Exportieren fehlgeschlagen + + + There was an error trying to save the address list to %1. Please try again. + Beim Speichern der Adressliste nach %1 ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut. + + + + AddressTableModel + + Label + Bezeichnung + + + Address + Adresse + + + (no label) + (keine Bezeichnung) + AskPassphraseDialog @@ -60,6 +131,94 @@ Repeat new passphrase Neue Passphrase bestätigen + + 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>. + Geben Sie die neue Passphrase für die Wallet ein.<br>Bitte benutzen Sie eine Passphrase bestehend aus <b>zehn oder mehr zufälligen Zeichen</b> oder <b>acht oder mehr Wörtern</b>. + + + Encrypt wallet + Wallet verschlüsseln + + + This operation needs your wallet passphrase to unlock the wallet. + Dieser Vorgang benötigt ihre Passphrase, um die Wallet zu entsperren. + + + Unlock wallet + Wallet entsperren + + + This operation needs your wallet passphrase to decrypt the wallet. + Dieser Vorgang benötigt Ihre Passphrase, um die Wallet zu entschlüsseln. + + + Decrypt wallet + Wallet entschlüsseln + + + Change passphrase + Passphrase ändern + + + Enter the old passphrase and new passphrase to the wallet. + Geben Sie die alte und neue Wallet-Passphrase ein. + + + Confirm wallet encryption + Wallet-Verschlüsselung bestätigen + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Warnung: Wenn Sie Ihre Wallet verschlüsseln und Ihre Passphrase verlieren, werden Sie <b>alle Ihre Bitcoins verlieren</b>! + + + Are you sure you wish to encrypt your wallet? + Sind Sie sich sicher, dass Sie Ihre Wallet verschlüsseln möchten? + + + Wallet encrypted + Wallet verschlüsselt + + + %1 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. + %1 wird jetzt beendet, um den Verschlüsselungsprozess abzuschließen. Bitte beachten Sie, dass die Wallet-Verschlüsselung nicht vollständig vor Diebstahl Ihrer Bitcoins durch Schadprogramme schützt, die Ihren Computer befällt. + + + 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. + WICHTIG: Alle vorherigen Wallet-Sicherungen sollten durch die neu erzeugte, verschlüsselte Wallet ersetzt werden. Aus Sicherheitsgründen werden vorherige Sicherungen der unverschlüsselten Wallet nutzlos, sobald Sie die neue, verschlüsselte Wallet verwenden. + + + Wallet encryption failed + Wallet-Verschlüsselung fehlgeschlagen + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Die Wallet-Verschlüsselung ist aufgrund eines internen Fehlers fehlgeschlagen. Ihre Wallet wurde nicht verschlüsselt. + + + The supplied passphrases do not match. + Die eingegebenen Passphrasen stimmen nicht überein. + + + Wallet unlock failed + Wallet-Entsperrung fehlgeschlagen + + + The passphrase entered for the wallet decryption was incorrect. + Die eingegebene Passphrase zur Wallet-Entschlüsselung war nicht korrekt. + + + Wallet decryption failed + Wallet-Entschlüsselung fehlgeschlagen + + + Wallet passphrase was successfully changed. + Die Wallet-Passphrase wurde erfolgreich geändert. + + + Warning: The Caps Lock key is on! + Warnung: Die Feststelltaste ist aktiviert! + BanTableModel @@ -112,7 +271,7 @@ &About %1 - &Über %1 + Über %1 Show information about %1 @@ -463,6 +622,150 @@ Priority Priorität + + Copy address + Adresse kopieren + + + Copy label + Bezeichnung kopieren + + + Copy amount + Betrag kopieren + + + Copy transaction ID + Transaktionskennung kopieren + + + Lock unspent + Nicht ausgegebenen Betrag sperren + + + Unlock unspent + Nicht ausgegebenen Betrag entsperren + + + Copy quantity + Anzahl kopieren + + + Copy fee + Gebühr kopieren + + + Copy after fee + Abzüglich Gebühr kopieren + + + Copy bytes + Byte kopieren + + + Copy priority + Priorität kopieren + + + Copy dust + "Staub" kopieren + + + Copy change + Wechselgeld kopieren + + + highest + am höchsten + + + higher + höher + + + high + hoch + + + medium-high + mittel-hoch + + + medium + mittel + + + low-medium + niedrig-mittel + + + low + niedrig + + + lower + niedriger + + + lowest + am niedrigsten + + + (%1 locked) + (%1 gesperrt) + + + none + keine + + + yes + ja + + + no + nein + + + This label turns red if the transaction size is greater than 1000 bytes. + Diese Bezeichnung wird rot, wenn die Transaktion größer als 1000 Byte ist. + + + This means a fee of at least %1 per kB is required. + Das bedeutet, dass eine Gebühr von mindestens %1 pro kB erforderlich ist. + + + Can vary +/- 1 byte per input. + Kann um +/- 1 Byte pro Eingabe variieren. + + + Transactions with higher priority are more likely to get included into a block. + Transaktionen mit höherer Priorität haben eine größere Chance in einen Block aufgenommen zu werden. + + + This label turns red if the priority is smaller than "medium". + Diese Bezeichnung wird rot, wenn die Priorität niedriger als "mittel" ist. + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Diese Bezeichnung wird rot, wenn irgendein Empfänger einen Betrag kleiner als die derzeitige "Staubgrenze" erhält. + + + Can vary +/- %1 satoshi(s) per input. + Kann pro Eingabe um +/- %1 Satoshi(s) abweichen. + + + (no label) + (keine Bezeichnung) + + + change from %1 (%2) + Wechselgeld von %1 (%2) + + + (change) + (Wechselgeld) + EditAddressDialog @@ -486,6 +789,38 @@ &Address &Adresse + + New receiving address + Neue Empfangsadresse + + + New sending address + Neue Zahlungsadresse + + + Edit receiving address + Empfangsadresse bearbeiten + + + Edit sending address + Zahlungsadresse bearbeiten + + + The entered address "%1" is not a valid Bitcoin address. + Die eingegebene Adresse "%1" ist keine gültige Bitcoin-Adresse. + + + The entered address "%1" is already in the address book. + Die eingegebene Adresse "%1" befindet sich bereits im Adressbuch. + + + Could not unlock wallet. + Wallet konnte nicht entsperrt werden. + + + New key generation failed. + Erzeugung eines neuen Schlüssels fehlgeschlagen. + FreespaceChecker @@ -626,6 +961,10 @@ Select payment request file Zahlungsanforderungsdatei auswählen + + Select payment request file to open + Zu öffnende Zahlungsanforderungsdatei auswählen + OptionsDialog @@ -810,6 +1149,10 @@ &Sprache der Benutzeroberfläche: + The user interface language can be set here. This setting will take effect after restarting %1. + Die Benutzeroberflächensprache kann hier festgelegt werden. Diese Einstellung wird nach einem Neustart von %1 wirksam werden. + + &Unit to show amounts in: &Einheit der Beträge: @@ -934,6 +1277,97 @@ + PaymentServer + + Payment request error + fehlerhafte Zahlungsanforderung + + + Cannot start bitcoin: click-to-pay handler + "bitcoin: Klicken-zum-Bezahlen"-Handler konnte nicht gestartet werden + + + URI handling + URI-Verarbeitung + + + Payment request fetch URL is invalid: %1 + Abruf-URL der Zahlungsanforderung ist ungültig: %1 + + + Invalid payment address %1 + Ungültige Zahlungsadresse %1 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + URI kann nicht analysiert werden! Dies kann durch eine ungültige Bitcoin-Adresse oder fehlerhafte URI-Parameter verursacht werden. + + + Payment request file handling + Zahlungsanforderungsdatei-Verarbeitung + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + Zahlungsanforderungsdatei kann nicht gelesen werden! Dies kann durch eine ungültige Zahlungsanforderungsdatei verursacht werden. + + + Payment request rejected + Zahlungsanforderung abgelehnt + + + Payment request network doesn't match client network. + Netzwerk der Zahlungsanforderung stimmt nicht mit dem Client-Netzwerk überein. + + + Payment request expired. + Zahlungsanforderung abgelaufen. + + + Payment request is not initialized. + Zahlungsanforderung ist nicht initialisiert. + + + Unverified payment requests to custom payment scripts are unsupported. + Unverifizierte Zahlungsanforderungen an benutzerdefinierte Zahlungsskripte werden nicht unterstützt. + + + Invalid payment request. + Ungültige Zahlungsanforderung. + + + Requested payment amount of %1 is too small (considered dust). + Angeforderter Zahlungsbetrag in Höhe von %1 ist zu niedrig und wurde als "Staub" eingestuft. + + + Refund from %1 + Rücküberweisung von %1 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + Zahlungsanforderung %1 ist zu groß (%2 Byte, erlaubt sind %3 Byte). + + + Error communicating with %1: %2 + Kommunikationsfehler mit %1: %2 + + + Payment request cannot be parsed! + Zahlungsanforderung kann nicht verarbeitet werden! + + + Bad response from server %1 + Fehlerhafte Antwort vom Server: %1 + + + Network request error + fehlerhafte Netzwerkanfrage + + + Payment acknowledged + Zahlung bestätigt + + + PeerTableModel User Agent @@ -988,6 +1422,25 @@ + QRImageWidget + + &Save Image... + Grafik &speichern... + + + &Copy Image + Grafik &kopieren + + + Save QR Code + QR-Code speichern + + + PNG Image (*.png) + PNG-Grafik (*.png) + + + RPCConsole N/A @@ -1348,6 +1801,18 @@ Remove Entfernen + + Copy label + Bezeichnung kopieren + + + Copy message + Nachricht kopieren + + + Copy amount + Betrag kopieren + ReceiveRequestDialog @@ -1367,6 +1832,73 @@ &Save Image... Grafik &speichern... + + Request payment to %1 + Zahlung anfordern an %1 + + + Payment information + Zahlungsinformationen + + + URI + URI + + + Address + Adresse + + + Amount + Betrag + + + Label + Bezeichnung + + + Message + Nachricht + + + Resulting URI too long, try to reduce the text for label / message. + Resultierende URI ist zu lang, bitte den Text für Bezeichnung/Nachricht kürzen. + + + Error encoding URI into QR Code. + Beim Enkodieren der URI in den QR-Code ist ein Fehler aufgetreten. + + + + RecentRequestsTableModel + + Date + Datum + + + Label + Bezeichnung + + + Message + Nachricht + + + (no label) + (keine Bezeichnung) + + + (no message) + (keine Nachricht) + + + (no amount requested) + (kein Betrag angefordert) + + + Requested + Angefordert + SendCoinsDialog @@ -1518,6 +2050,114 @@ S&end &Überweisen + + Copy quantity + Anzahl kopieren + + + Copy amount + Betrag kopieren + + + Copy fee + Gebühr kopieren + + + Copy after fee + Abzüglich Gebühr kopieren + + + Copy bytes + Byte kopieren + + + Copy priority + Priorität kopieren + + + Copy dust + "Staub" kopieren + + + Copy change + Wechselgeld kopieren + + + %1 to %2 + %1 an %2 + + + Are you sure you want to send? + Wollen Sie die Überweisung ausführen? + + + added as transaction fee + als Transaktionsgebühr hinzugefügt + + + Total Amount %1 + Gesamtbetrag %1 + + + or + oder + + + Confirm send coins + Überweisung bestätigen + + + The recipient address is not valid. Please recheck. + Die Zahlungsadresse ist ungültig, bitte nochmals überprüfen. + + + The amount to pay must be larger than 0. + Der zu zahlende Betrag muss größer als 0 sein. + + + The amount exceeds your balance. + Der angegebene Betrag übersteigt Ihren Kontostand. + + + The total exceeds your balance when the %1 transaction fee is included. + Der angegebene Betrag übersteigt aufgrund der Transaktionsgebühr in Höhe von %1 Ihren Kontostand. + + + Duplicate address found: addresses should only be used once each. + Doppelte Adresse entdeckt: Adressen dürfen jeweils nur einmal vorkommen. + + + Transaction creation failed! + Transaktionserstellung fehlgeschlagen! + + + 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. + Die Transaktion wurde abgelehnt! Dies kann passieren, wenn einige Bitcoins aus Ihrer Wallet bereits ausgegeben wurden. Beispielsweise weil Sie eine Kopie Ihrer wallet.dat genutzt, die Bitcoins dort ausgegeben haben und dies daher in der derzeit aktiven Wallet nicht vermerkt ist. + + + A fee higher than %1 is considered an absurdly high fee. + Eine höhere Gebühr als %1 wird als unsinnig hohe Gebühr angesehen. + + + Payment request expired. + Zahlungsanforderung abgelaufen. + + + Pay only the required fee of %1 + Nur die notwendige Gebühr in Höhe von %1 zahlen + + + Estimated to begin confirmation within %n block(s). + Voraussichtlicher Beginn der Bestätigung innerhalb von %n Blöcken.Voraussichtlicher Beginn der Bestätigung innerhalb von %n Blöcken. + + + Warning: Invalid Bitcoin address + Warnung: Ungültige Bitcoin-Adresse + + + (no label) + (keine Bezeichnung) + SendCoinsEntry @@ -1597,7 +2237,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1695,7 +2338,7 @@ Reset all verify message fields Alle "Nachricht verifizieren"-Felder zurücksetzen - + SplashScreen @@ -1711,12 +2354,81 @@ + TransactionDesc + + Date + Datum + + + Message + Nachricht + + + Amount + Betrag + + + TransactionDescDialog This pane shows a detailed description of the transaction Dieser Bereich zeigt eine detaillierte Beschreibung der Transaktion an - + + + TransactionTableModel + + Date + Datum + + + Label + Bezeichnung + + + (no label) + (keine Bezeichnung) + + + + TransactionView + + Copy address + Adresse kopieren + + + Copy label + Bezeichnung kopieren + + + Copy amount + Betrag kopieren + + + Copy transaction ID + Transaktionskennung kopieren + + + Comma separated file (*.csv) + Kommagetrennte-Datei (*.csv) + + + Date + Datum + + + Label + Bezeichnung + + + Address + Adresse + + + Exporting Failed + Exportieren fehlgeschlagen + + UnitDisplayStatusBarControl @@ -1725,6 +2437,47 @@ + WalletFrame + + + WalletModel + + + WalletView + + &Export + E&xportieren + + + Export the data in the current tab to a file + Daten der aktuellen Ansicht in eine Datei exportieren + + + Backup Wallet + Wallet sichern + + + Wallet Data (*.dat) + Wallet-Daten (*.dat) + + + Backup Failed + Sicherung fehlgeschlagen + + + There was an error trying to save the wallet data to %1. + Beim Speichern der Wallet-Daten nach %1 ist ein Fehler aufgetreten. + + + Backup Successful + Sicherung erfolgreich + + + The wallet data was successfully saved to %1. + Speichern der Wallet-Daten nach %1 war erfolgreich. + + + bitcoin-core Options: @@ -1755,10 +2508,18 @@ Kürzungsmodus wurde kleiner als das Minimum in Höhe von %d MiB konfiguriert. Bitte verwenden Sie einen größeren Wert. + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Prune (Kürzung): Die letzte Syncronisation der Wallet liegt vor gekürzten (gelöschten) Blöcken. Es ist ein -reindex (download der gesamten Blockkette) notwendig. + + 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) Speicherplatzanforderung durch kürzen (löschen) alter Blöcke reduzieren. Dieser Modus ist nicht mit -txindex und -rescan kompatibel. Warnung: Die Umkehr dieser Einstellung erfordert das erneute Herunterladen der gesamten Blockkette. (Standard: 0 = deaktiviert das Kürzen von Blöcken, >%u = Zielgröße in MiB, die für Blockdateien verwendet werden darf) + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Rescans sind im pruned mode nicht möglich. Ein -reindex ist notwendig, welcher die gesmate Blockkette erneut herunterlädt. + + Error: A fatal internal error occurred, see debug.log for details Fehler: Ein schwerer interner Fehler ist aufgetreten, siehe debug.log für Details. @@ -1795,6 +2556,10 @@ Eine Transaktionsgebühr (in %s/kB) wird genutzt, wenn für die Gebührenschützung zu wenig Daten vorliegen (Standardwert: %s) + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Geben Sie immer die Transaktionen, die Sie von freigegebenen Peers erhalten haben, weiter (Voreinstellung: %d) + + Bind to given address and always listen on it. Use [host]:port notation for IPv6 An die angegebene Adresse binden und immer abhören. Für IPv6 "[Host]:Port"-Notation verwenden @@ -1811,12 +2576,20 @@ Veröffentlicht unter der MIT-Softwarelizenz, siehe beiligende Datei COPYING oder <http://www.opensource.org/licenses/mit-license.php>. + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Maximale Datengröße in "Data Carrier"-Transaktionen die weitergeleitet und erarbeitet werden (Standard: %u) + + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Befehl ausführen wenn sich eine Wallet-Transaktion verändert (%s im Befehl wird durch die Transaktions-ID ersetzt) - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Leite Transaktionen von Peers auf der Positivliste auf jeden Fall weiter, auch wenn sie die lokale Weiterleitungsregeln verletzen (Standardeinstellung: %d) + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + + + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + Maximale Gesamtgebühr (in %s) in einer Börsentransaktion; wird dies zu niedrig gesetzten können große Transaktionen abgebrochen werden (Standard: %s) Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. @@ -1839,6 +2612,10 @@ Dies ist eine Vorab-Testversion - Verwendung auf eigene Gefahr - nicht für Mining- oder Handelsanwendungen nutzen! + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + Sie müssen die Datenbank mit Hilfe von -reindex neu aufbauen, um zum ungekürzten Modus zurückzukehren. Dies erfordert, dass die gesamte Blockkette erneut heruntergeladen wird. + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) UPnP verwenden, um eine Portweiterleitung einzurichten (Standard: 1, wenn abgehört wird und -proxy nicht gesetzt ist) @@ -1887,6 +2664,10 @@ Kann Adresse in -%s nicht auflösen: '%s' + Change index out of range + Position des Wechselgelds außerhalb des Bereichs + + Connect only to the specified node(s) Mit nur dem oder den angegebenen Knoten verbinden @@ -1931,6 +2712,10 @@ Aktiviere das Veröffentlichen der Roh-Transaktion in <address> + Enable transaction replacement in the memory pool (default: %u) + Maximal <n> nicht-verbindbare Transaktionen im Speicher halten (Standard: %u) + + Error initializing block database Fehler beim Initialisieren der Blockdatenbank @@ -2023,10 +2808,26 @@ Kürzungsmodus ist nicht mit -txindex kompatibel. + Rebuild chain state and block index from the blk*.dat files on disk + Blockkettenindex aus aktuellen Dateien blk000??.dat beim Starten wiederaufbauen + + + Rebuild chain state from the currently indexed blocks + Blockkettenindex aus aktuellen Dateien blk000??.dat wiederaufbauen + + + Rewinding blocks... + Verifiziere Blöcke... + + Set database cache size in megabytes (%d to %d, default: %d) Größe des Datenbankcaches in Megabyte festlegen (%d bis %d, Standard: %d) + Set maximum BIP141 block weight (default: %d) + Maximales BIP141 Blockgewicht festlegen (Standard: %d) + + Set maximum block size in bytes (default: %d) Maximale Blockgröße in Byte festlegen (Standard: %d) @@ -2075,6 +2876,10 @@ Wallet %s liegt außerhalb des Datenverzeichnisses %s + Wallet debugging/testing options: + Wallet Debugging-/Testoptionen: + + Wallet options: Wallet-Optionen: @@ -2111,6 +2916,10 @@ Niedrigere Gebühren (in %s/Kb) als diese werden bei der Transaktionserstellung als gebührenfrei angesehen (Standard: %s) + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + Leite Transaktionen von Peers auf der Positivliste auf jeden Fall weiter, auch wenn sie die lokale Weiterleitungsregeln verletzen (Standardeinstellung: %d) + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) 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) @@ -2143,6 +2952,10 @@ Dieses Produkt enthält Software, die vom OpenSSL-Projekt zur Verwendung im OpenSSL-Toolkit <https://www.openssl.org/> entwickelt wird, sowie von Eric Young geschriebene kryptographische Software und von Thomas Bernard geschriebene UPnP-Software. + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + + 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 Erlaubte Gegenstellen werden nicht für DoS-Attacken gesperrt und ihre Transkationen werden immer weitergeleitet, auch wenn sie sich bereits im Speicherpool befinden, was z.B. für Gateways sinnvoll ist. @@ -2435,10 +3248,6 @@ Größe des Schlüsselpools festlegen auf <n> (Standard: %u) - Set minimum block size in bytes (default: %u) - Minimale Blockgröße in Byte festlegen (Standard: %u) - - Set the number of threads to service RPC calls (default: %d) Maximale Anzahl an Threads zur Verarbeitung von RPC-Anfragen festlegen (Standard: %d) diff --git a/src/qt/locale/bitcoin_el.ts b/src/qt/locale/bitcoin_el.ts index de76a110cfc..8134baeac3b 100644 --- a/src/qt/locale/bitcoin_el.ts +++ b/src/qt/locale/bitcoin_el.ts @@ -7,6 +7,9 @@ + AddressTableModel + + AskPassphraseDialog Enter passphrase @@ -20,7 +23,7 @@ Repeat new passphrase Επαναλάβετε νέο συνθηματικό - + BanTableModel @@ -56,7 +59,7 @@ &Address Διεύθυνση - + FreespaceChecker @@ -92,12 +95,18 @@ OverviewPage + PaymentServer + + PeerTableModel QObject + QRImageWidget + + RPCConsole Services @@ -110,11 +119,14 @@ Remove Αφαίρεση - + ReceiveRequestDialog + RecentRequestsTableModel + + SendCoinsDialog Insufficient funds! @@ -133,6 +145,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -145,12 +160,30 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Insufficient funds diff --git a/src/qt/locale/bitcoin_el_GR.ts b/src/qt/locale/bitcoin_el_GR.ts index 2814e4f6e7a..43b04f1a88a 100644 --- a/src/qt/locale/bitcoin_el_GR.ts +++ b/src/qt/locale/bitcoin_el_GR.ts @@ -41,7 +41,10 @@ &Delete &Διαγραφή - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Επανέλαβε τον νέο κωδικό πρόσβασης - + BanTableModel @@ -407,7 +410,7 @@ Priority Προτεραιότητα - + EditAddressDialog @@ -430,7 +433,7 @@ &Address &Διεύθυνση - + FreespaceChecker @@ -526,7 +529,7 @@ Select payment request file Επιλέξτε πληρωμή αρχείου αίτησης - + OptionsDialog @@ -787,6 +790,9 @@ + PaymentServer + + PeerTableModel Ping Time @@ -833,6 +839,9 @@ + QRImageWidget + + RPCConsole N/A @@ -1053,7 +1062,7 @@ Remove Αφαίρεση - + ReceiveRequestDialog @@ -1072,7 +1081,10 @@ &Save Image... &Αποθήκευση εικόνας... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1203,7 +1215,7 @@ S&end Αποστολη - + SendCoinsEntry @@ -1262,7 +1274,10 @@ Memo: Σημείωση: - + + + SendConfirmationDialog + ShutdownWindow @@ -1348,7 +1363,7 @@ Reset all verify message fields Επαναφορά όλων επαλήθευμενων πεδίων μήνυματος - + SplashScreen @@ -1364,12 +1379,21 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Αυτό το παράθυρο δείχνει μια λεπτομερή περιγραφή της συναλλαγής - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1378,6 +1402,15 @@ + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index 79c3e87b2b1..69fe102327b 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -53,6 +53,94 @@ &Delete &Delete + + + Choose the address to send coins to + + + + + Choose the address to receive coins with + + + + + C&hoose + + + + + Sending addresses + + + + + Receiving addresses + + + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + + + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + + + + + &Copy Address + + + + + Copy &Label + + + + + &Edit + + + + + Export Address List + + + + + Comma separated file (*.csv) + + + + + Exporting Failed + + + + + There was an error trying to save the address list to %1. Please try again. + + + + + AddressTableModel + + + Label + + + + + Address + + + + + (no label) + + AskPassphraseDialog @@ -76,6 +164,124 @@ Repeat new passphrase Repeat new passphrase + + + 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>. + + + + + Encrypt wallet + + + + + This operation needs your wallet passphrase to unlock the wallet. + + + + + Unlock wallet + + + + + This operation needs your wallet passphrase to decrypt the wallet. + + + + + Decrypt wallet + + + + + Change passphrase + + + + + Enter the old passphrase and new passphrase to the wallet. + + + + + Confirm wallet encryption + + + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + + + + + Are you sure you wish to encrypt your wallet? + + + + + + Wallet encrypted + + + + + %1 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. + + + + + 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. + + + + + + + + Wallet encryption failed + + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + + + + + + The supplied passphrases do not match. + + + + + Wallet unlock failed + + + + + + + The passphrase entered for the wallet decryption was incorrect. + + + + + Wallet decryption failed + + + + + Wallet passphrase was successfully changed. + + + + + + Warning: The Caps Lock key is on! + + BanTableModel @@ -98,12 +304,12 @@ Sign &message... - + Synchronizing with network... Synchronizing with network... - + &Overview &Overview @@ -198,12 +404,12 @@ - + Reindexing blocks on disk... Reindexing blocks on disk... - + Send coins to a Bitcoin address Send coins to a Bitcoin address @@ -233,12 +439,12 @@ &Verify message... - + Bitcoin Bitcoin - + Wallet Wallet @@ -323,7 +529,7 @@ - + %n active connection(s) to Bitcoin network %n active connection to Bitcoin network @@ -427,12 +633,12 @@ Up to date - + Show the %1 help message to get a list with possible Bitcoin command-line options - + %1 client @@ -442,7 +648,7 @@ Catching up... - + Date: %1 @@ -589,147 +795,370 @@ Priority - - - EditAddressDialog - - Edit Address - Edit Address + + Copy address + - - &Label - &Label + + Copy label + - - The label associated with this address list entry + + + Copy amount - - The address associated with this address list entry. This can only be modified for sending addresses. + + Copy transaction ID - - &Address - &Address + + Lock unspent + - - - FreespaceChecker - - A new data directory will be created. - A new data directory will be created. + + Unlock unspent + - name - name + Copy quantity + - Directory already exists. Add %1 if you intend to create a new directory here. - Directory already exists. Add %1 if you intend to create a new directory here. + Copy fee + - - Path already exists, and is not a directory. - Path already exists, and is not a directory. + + Copy after fee + - - Cannot create data directory here. - Cannot create data directory here. + + Copy bytes + - - - HelpMessageDialog - - version - version + + Copy priority + - - - (%1-bit) + + Copy dust - - About %1 + + Copy change - - Command-line options + + highest - Usage: - Usage: + higher + - command-line options - command-line options - - - - UI Options: + high - - Choose data directory on startup (default: %u) + + medium-high - Set language, for example "de_DE" (default: system locale) + medium - Start minimized + low-medium - Set SSL root certificates for payment request (default: -system-) + low - Show splash screen on startup (default: %u) + lower - Reset all settings changed in the GUI + lowest - - - Intro - - Welcome - Welcome + + (%1 locked) + - - Welcome to %1. + + none - - As this is the first time the program is launched, you can choose where %1 will store its data. + + yes + + + + + no + + + + + This label turns red if the transaction size is greater than 1000 bytes. + + + + + + This means a fee of at least %1 per kB is required. + + + + + Can vary +/- 1 byte per input. + + + + + Transactions with higher priority are more likely to get included into a block. + + + + + This label turns red if the priority is smaller than "medium". + + + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + + + + + Can vary +/- %1 satoshi(s) per input. + + + + + + (no label) + + + + + change from %1 (%2) + + + + + (change) + + + + + EditAddressDialog + + + Edit Address + Edit Address + + + + &Label + &Label + + + + The label associated with this address list entry + + + + + The address associated with this address list entry. This can only be modified for sending addresses. + + + + + &Address + &Address + + + + New receiving address + + + + + New sending address + + + + + Edit receiving address + + + + + Edit sending address + + + + + The entered address "%1" is not a valid Bitcoin address. + + + + + The entered address "%1" is already in the address book. + + + + + Could not unlock wallet. + + + + + New key generation failed. + + + + + FreespaceChecker + + + A new data directory will be created. + A new data directory will be created. + + + + name + name + + + + Directory already exists. Add %1 if you intend to create a new directory here. + Directory already exists. Add %1 if you intend to create a new directory here. + + + + Path already exists, and is not a directory. + Path already exists, and is not a directory. + + + + Cannot create data directory here. + Cannot create data directory here. + + + + HelpMessageDialog + + + version + version + + + + + (%1-bit) + + + + + About %1 + + + + + Command-line options + + + + + Usage: + Usage: + + + + command-line options + command-line options + + + + UI Options: + + + + + Choose data directory on startup (default: %u) + + + + + Set language, for example "de_DE" (default: system locale) + + + + + Start minimized + + + + + Set SSL root certificates for payment request (default: -system-) + + + + + Show splash screen on startup (default: %u) + + + + + Reset all settings changed in the GUI + + + + + Intro + + + Welcome + Welcome + + + + Welcome to %1. + + + + + As this is the first time the program is launched, you can choose where %1 will store its data. @@ -753,7 +1182,7 @@ - + Error Error @@ -796,6 +1225,11 @@ Select payment request file + + + Select payment request file to open + + OptionsDialog @@ -1106,7 +1540,7 @@ Form - + 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. 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. @@ -1193,48 +1627,174 @@ - PeerTableModel + PaymentServer - - User Agent + + + + + + + Payment request error - - Node/Service + + Cannot start bitcoin: click-to-pay handler - - Ping Time + + + + URI handling - - - QObject - - Amount - Amount + + Payment request fetch URL is invalid: %1 + - - Enter a Bitcoin address (e.g. %1) + + Invalid payment address %1 - - %1 d + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - - %1 h + + Payment request file handling - - %1 m + + Payment request file cannot be read! This can be caused by an invalid payment request file. + + + + + + + + + + Payment request rejected + + + + + Payment request network doesn't match client network. + + + + + Payment request expired. + + + + + Payment request is not initialized. + + + + + Unverified payment requests to custom payment scripts are unsupported. + + + + + + Invalid payment request. + + + + + Requested payment amount of %1 is too small (considered dust). + + + + + Refund from %1 + + + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + + + + + Error communicating with %1: %2 + + + + + Payment request cannot be parsed! + + + + + Bad response from server %1 + + + + + Network request error + + + + + Payment acknowledged + + + + + PeerTableModel + + + User Agent + + + + + Node/Service + + + + + Ping Time + + + + + QObject + + + Amount + Amount + + + + Enter a Bitcoin address (e.g. %1) + + + + + %1 d + + + + + %1 h + + + + + %1 m @@ -1260,6 +1820,29 @@ + QRImageWidget + + + &Save Image... + + + + + &Copy Image + + + + + Save QR Code + + + + + PNG Image (*.png) + + + + RPCConsole @@ -1392,8 +1975,8 @@ - - + + Select a peer to view detailed information. @@ -1524,7 +2107,7 @@ - + In: @@ -1544,7 +2127,7 @@ Clear console - + &Disconnect Node @@ -1582,7 +2165,7 @@ - + Welcome to the %1 RPC console. @@ -1597,7 +2180,7 @@ Type <b>help</b> for an overview of available commands. - + %1 B @@ -1749,6 +2332,21 @@ Remove + + + Copy label + + + + + Copy message + + + + + Copy amount + + ReceiveRequestDialog @@ -1772,11 +2370,95 @@ &Save Image... + + + Request payment to %1 + + + + + Payment information + + + + + URI + + + + + Address + + + + + Amount + Amount + + + + Label + + + + + Message + + + + + Resulting URI too long, try to reduce the text for label / message. + + + + + Error encoding URI into QR Code. + + + + + RecentRequestsTableModel + + + Date + Date + + + + Label + + + + + Message + + + + + (no label) + + + + + (no message) + + + + + (no amount requested) + + + + + Requested + + SendCoinsDialog + Send Coins Send Coins @@ -1962,71 +2644,217 @@ S&end S&end - - - SendCoinsEntry - - - - A&mount: - A&mount: + + Copy quantity + - - Pay &To: - Pay &To: + + Copy amount + - - &Label: - &Label: + + Copy fee + - - Choose previously used address + + Copy after fee - - This is a normal payment. + + Copy bytes - - The Bitcoin address to send the payment to + + Copy priority - - Alt+A - Alt+A + + Copy dust + - - Paste address from clipboard - Paste address from clipboard + + Copy change + - - Alt+P - Alt+P + + + + + %1 to %2 + - - - - Remove this entry + + Are you sure you want to send? - - 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. + + added as transaction fee - - S&ubtract fee from amount + + Total Amount %1 + + + + + or + + + + + Confirm send coins + + + + + The recipient address is not valid. Please recheck. + + + + + The amount to pay must be larger than 0. + + + + + The amount exceeds your balance. + + + + + The total exceeds your balance when the %1 transaction fee is included. + + + + + Duplicate address found: addresses should only be used once each. + + + + + Transaction creation failed! + + + + + 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. + + + + + A fee higher than %1 is considered an absurdly high fee. + + + + + Payment request expired. + + + + + Pay only the required fee of %1 + + + + + Estimated to begin confirmation within %n block(s). + + + + + + + + Warning: Invalid Bitcoin address + + + + + Warning: Unknown change address + + + + + (no label) + + + + + SendCoinsEntry + + + + + A&mount: + A&mount: + + + + Pay &To: + Pay &To: + + + + &Label: + &Label: + + + + Choose previously used address + + + + + This is a normal payment. + + + + + The Bitcoin address to send the payment to + + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Paste address from clipboard + + + + Alt+P + Alt+P + + + + + + Remove this entry + + + + + 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. + + + + + S&ubtract fee from amount @@ -2035,198 +2863,923 @@ - - This is an unauthenticated payment request. + + This is an unauthenticated payment request. + + + + + This is an authenticated payment request. + + + + + Enter a label for this address to add it to the list of used addresses + + + + + 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. + + + + + + Pay To: + + + + + + Memo: + + + + + Enter a label for this address to add it to your address book + + + + + SendConfirmationDialog + + + + Yes + + + + + ShutdownWindow + + + %1 is shutting down... + + + + + Do not shut down the computer until this window disappears. + + + + + SignVerifyMessageDialog + + + Signatures - Sign / Verify a Message + Signatures - Sign / Verify a Message + + + + &Sign Message + &Sign Message + + + + 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. + + + + + The Bitcoin address to sign the message with + + + + + + Choose previously used address + + + + + + Alt+A + Alt+A + + + + Paste address from clipboard + Paste address from clipboard + + + + Alt+P + Alt+P + + + + Enter the message you want to sign here + Enter the message you want to sign here + + + + Signature + Signature + + + + Copy the current signature to the system clipboard + Copy the current signature to the system clipboard + + + + Sign the message to prove you own this Bitcoin address + Sign the message to prove you own this Bitcoin address + + + + Sign &Message + Sign &Message + + + + Reset all sign message fields + Reset all sign message fields + + + + + Clear &All + Clear &All + + + + &Verify Message + &Verify Message + + + + 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! + + + + + The Bitcoin address the message was signed with + + + + + Verify the message to ensure it was signed with the specified Bitcoin address + Verify the message to ensure it was signed with the specified Bitcoin address + + + + Verify &Message + Verify &Message + + + + Reset all verify message fields + Reset all verify message fields + + + + Click "Sign Message" to generate signature + + + + + + The entered address is invalid. + + + + + + + + Please check the address and try again. + + + + + + The entered address does not refer to a key. + + + + + Wallet unlock was cancelled. + + + + + Private key for the entered address is not available. + + + + + Message signing failed. + + + + + Message signed. + + + + + The signature could not be decoded. + + + + + + Please check the signature and try again. + + + + + The signature did not match the message digest. + + + + + Message verification failed. + + + + + Message verified. + + + + + SplashScreen + + + [testnet] + [testnet] + + + + TrafficGraphWidget + + + KB/s + + + + + TransactionDesc + + + Open for %n more block(s) + + + + + + + + Open until %1 + + + + + conflicted with a transaction with %1 confirmations + + + + + %1/offline + + + + + 0/unconfirmed, %1 + + + + + in memory pool + + + + + not in memory pool + + + + + abandoned + + + + + %1/unconfirmed + + + + + %1 confirmations + + + + + Status + + + + + , has not been successfully broadcast yet + + + + + , broadcast through %n node(s) + + + + + + + + Date + Date + + + + Source + + + + + Generated + + + + + + + From + + + + + unknown + + + + + + + To + + + + + own address + + + + + + watch-only + + + + + label + + + + + + + + + Credit + + + + + matures in %n more block(s) + + + + + + + + not accepted + + + + + + + Debit + + + + + Total debit + + + + + Total credit + + + + + Transaction fee + + + + + Net amount + + + + + + Message + + + + + Comment + + + + + Transaction ID + + + + + Output index + + + + + Merchant + + + + + 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. + + + + + Debug information + + + + + Transaction + + + + + Inputs + + + + + Amount + Amount + + + + + true + + + + + + false + + + + + TransactionDescDialog + + + This pane shows a detailed description of the transaction + This pane shows a detailed description of the transaction + + + + Details for %1 + + + + + TransactionTableModel + + + Date + Date + + + + Type + + + + + Label + + + + + Open for %n more block(s) + + + + + + + + Open until %1 + + + + + Offline + + + + + Unconfirmed + + + + + Abandoned + + + + + Confirming (%1 of %2 recommended confirmations) + + + + + Confirmed (%1 confirmations) + + + + + Conflicted + + + + + Immature (%1 confirmations, will be available after %2) + + + + + This block was not received by any other nodes and will probably not be accepted! + + + + + Generated but not accepted + + + + + Received with + + + + + Received from + + + + + Sent to + + + + + Payment to yourself + + + + + Mined + + + + + watch-only + + + + + (n/a) + + + + + (no label) + + + + + Transaction status. Hover over this field to show number of confirmations. + + + + + Date and time that the transaction was received. + + + + + Type of transaction. + + + + + Whether or not a watch-only address is involved in this transaction. + + + + + User-defined intent/purpose of the transaction. + + + + + Amount removed from or added to balance. + + + + + TransactionView + + + + All + + + + + Today + + + + + This week + + + + + This month + + + + + Last month + + + + + This year + + + + + Range... + + + + + Received with + + + + + Sent to + + + + + To yourself + + + + + Mined - - This is an authenticated payment request. + + Other - - Enter a label for this address to add it to the list of used addresses + + Enter address or label to search - - 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. + + Min amount - - - Pay To: + + Abandon transaction - - - Memo: + + Copy address - - - ShutdownWindow - - %1 is shutting down... + + Copy label - Do not shut down the computer until this window disappears. + Copy amount - - - SignVerifyMessageDialog - - Signatures - Sign / Verify a Message - Signatures - Sign / Verify a Message + + Copy transaction ID + - - &Sign Message - &Sign Message + + Copy raw transaction + - - 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. + + Copy full transaction details - - The Bitcoin address to sign the message with + + Edit label - - - Choose previously used address + + Show transaction details - - - Alt+A - Alt+A + + Export Transaction History + - - Paste address from clipboard - Paste address from clipboard + + Comma separated file (*.csv) + - - Alt+P - Alt+P + + Confirmed + Confirmed - - Enter the message you want to sign here - Enter the message you want to sign here + + Watch-only + - - Signature - Signature + + Date + Date - - Copy the current signature to the system clipboard - Copy the current signature to the system clipboard + + Type + - - Sign the message to prove you own this Bitcoin address - Sign the message to prove you own this Bitcoin address + + Label + - - Sign &Message - Sign &Message + + Address + - - Reset all sign message fields - Reset all sign message fields + + ID + - - Clear &All - Clear &All - - - - &Verify Message - &Verify Message + Exporting Failed + - - 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! + + There was an error trying to save the transaction history to %1. - - The Bitcoin address the message was signed with + + Exporting Successful - - Verify the message to ensure it was signed with the specified Bitcoin address - Verify the message to ensure it was signed with the specified Bitcoin address + + The transaction history was successfully saved to %1. + - - Verify &Message - Verify &Message + + Range: + - - Reset all verify message fields - Reset all verify message fields + + to + - SplashScreen + UnitDisplayStatusBarControl - - [testnet] - [testnet] + + Unit to show amounts in. Click to select another unit. + - TrafficGraphWidget + WalletFrame - - KB/s + + No wallet has been loaded. - TransactionDescDialog + WalletModel - - This pane shows a detailed description of the transaction - This pane shows a detailed description of the transaction + + Send Coins + Send Coins - UnitDisplayStatusBarControl + WalletView - - Unit to show amounts in. Click to select another unit. + + &Export + &Export + + + + Export the data in the current tab to a file + Export the data in the current tab to a file + + + + Backup Wallet + + + + + Wallet Data (*.dat) + + + + + Backup Failed + + + + + There was an error trying to save the wallet data to %1. + + + + + Backup Successful + + + + + The wallet data was successfully saved to %1. bitcoin-core - + Options: Options: @@ -2251,7 +3804,7 @@ Accept command line and JSON-RPC commands - + If <category> is not supplied or if <category> = 1, output all debugging information. @@ -2276,7 +3829,7 @@ - + Error: A fatal internal error occurred, see debug.log for details @@ -2296,17 +3849,17 @@ Run in the background as a daemon and accept commands - + Unable to start HTTP server. See debug log for details. - + Accept connections from outside (default: 1 if no -proxy or -connect) Accept connections from outside (default: 1 if no -proxy or -connect) - + Bitcoin Core Bitcoin Core @@ -2352,6 +3905,11 @@ + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + + + + Error loading %s: You can't enable HD on a already existing non-HD wallet @@ -2366,12 +3924,7 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) - - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - - - - + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) @@ -2396,7 +3949,7 @@ - + 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 @@ -2426,12 +3979,7 @@ Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. - - Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. - - - - + You need to rebuild the database using -reindex-chainstate to change -txindex @@ -2621,6 +4169,11 @@ + + Keypool ran out, please call keypoolrefill first + + + Loading banlist... @@ -2631,12 +4184,7 @@ - - Minimum bytes per sigop in transactions we relay and mine (default: %u) - - - - + Not enough file descriptors available. Not enough file descriptors available. @@ -2686,7 +4234,12 @@ - + + Set maximum BIP141 block weight (default: %d) + + + + Set maximum block size in bytes (default: %d) @@ -2697,6 +4250,11 @@ + Starting network threads... + + + + The source code is available from %s. @@ -2761,7 +4319,7 @@ - + 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 @@ -2786,7 +4344,7 @@ - + Error: Listening for incoming connections failed (listen returned error %s) @@ -2801,7 +4359,12 @@ - + + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + + + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) @@ -2831,7 +4394,12 @@ - + + Sets the serialization of raw transaction or block hex returned in non-verbose mode, non-segwit(0) or segwit(1) (default: %d) + + + + The transaction amount is too small to send after the fee has been deducted @@ -2846,7 +4414,12 @@ - + + Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or CIDR notated network (e.g. 1.2.3.0/24). 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 @@ -2941,12 +4514,7 @@ - - Set maximum BIP141 block cost (default: %d) - - - - + Show all debugging options (usage: --help -help-debug) @@ -2961,7 +4529,7 @@ Signing transaction failed - + The transaction amount is too small to pay the fee @@ -3041,27 +4609,27 @@ - + Password for JSON-RPC connections Password for JSON-RPC connections - + Execute command when the best block changes (%s in cmd is replaced by block hash) Execute command when the best block changes (%s in cmd is replaced by block hash) - + Allow DNS lookups for -addnode, -seednode and -connect Allow DNS lookups for -addnode, -seednode and -connect - + Loading addresses... Loading addresses... - + (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) @@ -3081,7 +4649,7 @@ - + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) @@ -3106,7 +4674,7 @@ - + Support filtering of blocks and transaction with bloom filters (default: %u) @@ -3176,7 +4744,7 @@ Invalid -proxy address: '%s' - + Listen for JSON-RPC connections on <port> (default: %u or testnet: %u) @@ -3206,7 +4774,7 @@ - + Prepend debug output with timestamp (default: %u) @@ -3251,7 +4819,7 @@ - + Threshold for disconnecting misbehaving peers (default: %u) @@ -3261,27 +4829,27 @@ Unknown network specified in -onlynet: '%s' - + Insufficient funds Insufficient funds - + Loading block index... Loading block index... - + Add a node to connect to and attempt to keep the connection open Add a node to connect to and attempt to keep the connection open - + Loading wallet... Loading wallet... - + Cannot downgrade wallet Cannot downgrade wallet diff --git a/src/qt/locale/bitcoin_en_GB.ts b/src/qt/locale/bitcoin_en_GB.ts index 1893aaca09b..4dbd5ee9c56 100644 --- a/src/qt/locale/bitcoin_en_GB.ts +++ b/src/qt/locale/bitcoin_en_GB.ts @@ -41,6 +41,65 @@ &Delete &Delete + + Choose the address to send coins to + Choose the address to send coins to + + + Choose the address to receive coins with + Choose the address to receive coins with + + + C&hoose + C&hoose + + + Sending addresses + Sending addresses + + + Receiving addresses + Receiving addresses + + + &Copy Address + &Copy Address + + + Copy &Label + Copy &Label + + + &Edit + &Edit + + + Export Address List + Export Address List + + + Comma separated file (*.csv) + Comma separated file (*.csv) + + + Exporting Failed + Exporting Failed + + + + AddressTableModel + + Label + Label + + + Address + Address + + + (no label) + (no label) + AskPassphraseDialog @@ -60,7 +119,11 @@ Repeat new passphrase Repeat new passphrase - + + Encrypt wallet + Encrypt wallet + + BanTableModel @@ -463,7 +526,11 @@ Priority Priority - + + (no label) + (no label) + + EditAddressDialog @@ -486,7 +553,7 @@ &Address &Address - + FreespaceChecker @@ -626,7 +693,7 @@ Select payment request file Select payment request file - + OptionsDialog @@ -938,6 +1005,9 @@ + PaymentServer + + PeerTableModel User Agent @@ -992,6 +1062,9 @@ + QRImageWidget + + RPCConsole N/A @@ -1352,7 +1425,7 @@ Remove Remove - + ReceiveRequestDialog @@ -1371,7 +1444,26 @@ &Save Image... &Save Image... - + + Address + Address + + + Label + Label + + + + RecentRequestsTableModel + + Label + Label + + + (no label) + (no label) + + SendCoinsDialog @@ -1522,6 +1614,10 @@ S&end S&end + + (no label) + (no label) + SendCoinsEntry @@ -1601,7 +1697,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1699,7 +1798,7 @@ Reset all verify message fields Reset all verify message fields - + SplashScreen @@ -1715,12 +1814,45 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction This pane shows a detailed description of the transaction - + + + TransactionTableModel + + Label + Label + + + (no label) + (no label) + + + + TransactionView + + Comma separated file (*.csv) + Comma separated file (*.csv) + + + Label + Label + + + Address + Address + + + Exporting Failed + Exporting Failed + + UnitDisplayStatusBarControl @@ -1729,6 +1861,15 @@ + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: @@ -1831,6 +1972,10 @@ Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + + Error loading %s: You can't enable HD on a already existing non-HD wallet Error loading %s: You can't enable HD on a already existing non-HD wallet @@ -1843,10 +1988,6 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - - Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) @@ -2055,10 +2196,6 @@ Location of the auth cookie (default: data dir) - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Minimum bytes per sigop in transactions we relay and mine (default: %u) - - Not enough file descriptors available. Not enough file descriptors available. @@ -2099,8 +2236,8 @@ Set database cache size in megabytes (%d to %d, default: %d) - Set maximum block cost (default: %d) - Set maximum block cost (default: %d) + Set maximum BIP141 block weight (default: %d) + Set maximum BIP141 block weight (default: %d) Set maximum block size in bytes (default: %d) @@ -2531,10 +2668,6 @@ Set key pool size to <n> (default: %u) - Set minimum block size in bytes (default: %u) - Set minimum block size in bytes (default: %u) - - Set the number of threads to service RPC calls (default: %d) Set the number of threads to service RPC calls (default: %d) diff --git a/src/qt/locale/bitcoin_eo.ts b/src/qt/locale/bitcoin_eo.ts index 4471aeb72e6..e29527063ec 100644 --- a/src/qt/locale/bitcoin_eo.ts +++ b/src/qt/locale/bitcoin_eo.ts @@ -41,7 +41,10 @@ &Delete &Forigi - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Ripetu la novan pasfrazon - + BanTableModel @@ -415,7 +418,7 @@ Priority Prioritato - + EditAddressDialog @@ -438,7 +441,7 @@ &Address &Adreso - + FreespaceChecker @@ -526,7 +529,7 @@ Select payment request file Elektu la dosieron de la pagpeto - + OptionsDialog @@ -710,6 +713,9 @@ + PaymentServer + + PeerTableModel User Agent @@ -740,6 +746,9 @@ + QRImageWidget + + RPCConsole N/A @@ -920,7 +929,7 @@ Remove Forigi - + ReceiveRequestDialog @@ -939,7 +948,10 @@ &Save Image... &Konservi Bildon... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1022,7 +1034,7 @@ S&end Ŝendi - + SendCoinsEntry @@ -1077,7 +1089,10 @@ Memo: Memorando: - + + + SendConfirmationDialog + ShutdownWindow @@ -1155,7 +1170,7 @@ Reset all verify message fields Reagordigi ĉiujn prikontrolajn kampojn - + SplashScreen @@ -1171,16 +1186,34 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Tiu ĉi panelo montras detalan priskribon de la transakcio - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts index c67016637b5..1fbbf74b785 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -41,6 +41,77 @@ &Delete &Eliminar + + Choose the address to send coins to + Seleccione la dirección a la que enviar monedas + + + Choose the address to receive coins with + Seleccione la dirección de la que recibir monedas + + + C&hoose + E&scoger + + + Sending addresses + Enviando direcciones + + + Receiving addresses + Recibiendo direcciones + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Estas son sus direcciones Bitcoin para enviar pagos. Verifique siempre la cantidad y la dirección de recibimiento antes de enviar monedas. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Estas son sus direcciones Bitcoin para recibir pagos. Se recomienda utilizar una nueva dirección de recibimiento para cada transacción + + + &Copy Address + &Copiar Dirección + + + Copy &Label + Copiar &Etiqueta + + + &Edit + &Editar + + + Export Address List + Exportar lista de direcciones + + + Comma separated file (*.csv) + Archivo separado de coma (*.csv) + + + Exporting Failed + Falló la exportación + + + There was an error trying to save the address list to %1. Please try again. + Había un error intentando guardar la lista de direcciones en %1. Por favor inténtelo de nuevo. + + + + AddressTableModel + + Label + Etiqueta + + + Address + Dirección + + + (no label) + (sin etiqueta) + AskPassphraseDialog @@ -60,6 +131,94 @@ Repeat new passphrase Repita la nueva contraseña + + 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>. + Introduzca la nueva frase clave del monedero. <br/>Por favor utilice una frase clave de <b>diez o más carácteres aleatorios</b>, o <b>ocho o más palabras</b>. + + + Encrypt wallet + Monedero encriptado + + + This operation needs your wallet passphrase to unlock the wallet. + Esta operación necesita su frase clave de monedero para desbloquear el monedero. + + + Unlock wallet + Desbloquear monedero + + + This operation needs your wallet passphrase to decrypt the wallet. + Esta operación necesita su frase clave de cartera para desencriptar el monedero. + + + Decrypt wallet + Desencriptar monedero + + + Change passphrase + Cambiar frase clave + + + Enter the old passphrase and new passphrase to the wallet. + Introduzca la vieja frase clave y la nueva flase clave para el monedero. + + + Confirm wallet encryption + Confirmar encriptación del monedero + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Advertencia: Si encripta su monedero y pierde su frase clave <b>PERDERÁ TODOS SUS BITCOINS</b>! + + + Are you sure you wish to encrypt your wallet? + ¿Seguro que desea encriptar su monedero? + + + Wallet encrypted + Monedero encriptado + + + %1 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. + %1 se cerrará ahora para terminar el proceso de encriptación. Recuerde que encriptar su monedero no puede proteger completamente su monedero de ser robado por malware que infecte su ordenador. + + + 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. + IMPORTANTE: Cualquier copia de seguridad anterior que haya hecho en su archivo de monedero debería ser reemplazada con el archivo de monedero encriptado generado recientemente. Por razones de seguridad, las copias de seguridad anteriores del archivo de monedero desencriptado serán inútiles en cuanto empiece a utilizar el nuevo monedero encriptado. + + + Wallet encryption failed + Fracasó la encriptación de monedero + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Falló la encriptación del monedero debido a un error interno. Su monedero no fue encriptado. + + + The supplied passphrases do not match. + La frase clave introducida no coincide. + + + Wallet unlock failed + Fracasó el desbloqueo del monedero + + + The passphrase entered for the wallet decryption was incorrect. + La frase clave introducida para la encriptación del monedero es incorrecta. + + + Wallet decryption failed + Fracasó la encriptación del monedero + + + Wallet passphrase was successfully changed. + La frase clave del monedero se ha cambiado con éxito. + + + Warning: The Caps Lock key is on! + Alerta: ¡La clave de bloqueo Caps está activa! + BanTableModel @@ -463,6 +622,150 @@ Priority Prioridad + + Copy address + Copiar ubicación + + + Copy label + Copiar etiqueta + + + Copy amount + Copiar cantidad + + + Copy transaction ID + Copiar ID de transacción + + + Lock unspent + Bloquear lo no gastado + + + Unlock unspent + Desbloquear lo no gastado + + + Copy quantity + Copiar cantidad + + + Copy fee + Copiar cuota + + + Copy after fee + Copiar después de couta + + + Copy bytes + Copiar bytes + + + Copy priority + Copiar prioridad + + + Copy dust + Copiar polvo + + + Copy change + Copiar cambio + + + highest + el más alto + + + higher + más alto + + + high + alto + + + medium-high + media altura + + + medium + medio + + + low-medium + medio bajo + + + low + bajo + + + lower + más bajo + + + lowest + el más bajo + + + (%1 locked) + (%1 bloqueado) + + + none + ninguno + + + yes + + + + no + no + + + This label turns red if the transaction size is greater than 1000 bytes. + Esta etiqueta se vuelve roja sí el tamaño de transacción es mayor de 1000 bytes. + + + This means a fee of at least %1 per kB is required. + Esto significa que se requiere una couta de al menos %1 por kB. + + + Can vary +/- 1 byte per input. + Puede variar +/- 1 byte por entrada. + + + Transactions with higher priority are more likely to get included into a block. + Las transacciones con mayor prioridad son más probablemente incluídas en un bloque. + + + This label turns red if the priority is smaller than "medium". + Esta etiqueta se vuelve roja si la priodidad es inferior a "medio". + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Esta etiqueta se vuelve roja si algún destinatario recibe una cantidad inferior a la actual puerta polvorienta. + + + Can vary +/- %1 satoshi(s) per input. + Puede variar +/- %1 satoshi(s) por entrada. + + + (no label) + (sin etiqueta) + + + change from %1 (%2) + cambia desde %1 (%2) + + + (change) + (cambio) + EditAddressDialog @@ -486,6 +789,38 @@ &Address &Dirección + + New receiving address + Nueva dirección de recivimiento + + + New sending address + Nueva dirección de envío + + + Edit receiving address + Editar dirección de recivimiento + + + Edit sending address + Editar dirección de envío + + + The entered address "%1" is not a valid Bitcoin address. + La dirección introducida "%1" no es una dirección Bitcoin válida. + + + The entered address "%1" is already in the address book. + La dirección introducida "%1" está ya en la agenda. + + + Could not unlock wallet. + Podría no desbloquear el monedero. + + + New key generation failed. + Falló la generación de la nueva clave. + FreespaceChecker @@ -622,6 +957,10 @@ Select payment request file Seleccionar archivo de sulicitud de pago + + Select payment request file to open + Seleccionar el archivo de solicitud de pago para abrir + OptionsDialog @@ -934,6 +1273,97 @@ + PaymentServer + + Payment request error + Fallo en la solicitud de pago + + + Cannot start bitcoin: click-to-pay handler + No se puede iniciar bitcoin: encargado click-para-pagar + + + URI handling + Manejo de URI + + + Payment request fetch URL is invalid: %1 + La búsqueda de solicitud de pago URL es válida: %1 + + + Invalid payment address %1 + Dirección de pago inválida %1 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + URI no puede ser analizado! Esto puede ser causado por una dirección Bitcoin inválida o parametros URI mal formados. + + + Payment request file handling + Manejo del archivo de solicitud de pago + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + ¡El archivo de solicitud de pago no puede ser leído! Esto puede ser causado por un archivo de solicitud de pago inválido. + + + Payment request rejected + Solicitud de pago rechazada + + + Payment request network doesn't match client network. + La red de solicitud de pago no cimbina la red cliente. + + + Payment request expired. + Solicitud de pago caducada. + + + Payment request is not initialized. + La solicitud de pago no se ha iniciado. + + + Unverified payment requests to custom payment scripts are unsupported. + Solicitudes de pago sin verificar a scripts de pago habitual no se soportan. + + + Invalid payment request. + Solicitud de pago inválida. + + + Requested payment amount of %1 is too small (considered dust). + Cantidad de pago solicitada de %1 es demasiado pequeña (considerado polvo). + + + Refund from %1 + Reembolsar desde %1 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + Solicitud de pago de %1 es demasiado grande (%2 bytes, permitidos %3 bytes). + + + Error communicating with %1: %2 + Fallo al comunicar con %1: %2 + + + Payment request cannot be parsed! + ¡La solicitud de pago no puede ser analizada! + + + Bad response from server %1 + Mala respuesta desde el servidor %1 + + + Network request error + Fallo de solicitud de red + + + Payment acknowledged + Pago declarado + + + PeerTableModel User Agent @@ -988,6 +1418,25 @@ + QRImageWidget + + &Save Image... + &Guardar imagen... + + + &Copy Image + &Copiar imagen + + + Save QR Code + Guardar código QR + + + PNG Image (*.png) + Imagen PNG (*.png) + + + RPCConsole N/A @@ -1348,6 +1797,18 @@ Remove Eliminar + + Copy label + Copiar capa + + + Copy message + Copiar imagen + + + Copy amount + Copiar cantidad + ReceiveRequestDialog @@ -1367,39 +1828,106 @@ &Save Image... Guardar Imagen... - - - SendCoinsDialog - Send Coins - Enviar bitcoins + Request payment to %1 + Solicitar pago a %1 - Coin Control Features - Características de Coin Control + Payment information + Información de pago - Inputs... - Entradas... + URI + URI - automatically selected - Seleccionado automáticamente + Address + Dirección - Insufficient funds! - Fondos insuficientes! + Amount + Cantidad - Quantity: - Cantidad: + Label + Etiqueta - Bytes: - Bytes: + Message + Mensaje - Amount: + Resulting URI too long, try to reduce the text for label / message. + URI resultante demasiado grande, trate de reducir el texto de etiqueta / mensaje. + + + Error encoding URI into QR Code. + Fallo al codificar URI en código QR. + + + + RecentRequestsTableModel + + Date + Fecha + + + Label + Etiqueta + + + Message + Mensaje + + + (no label) + (sin etiqueta) + + + (no message) + (no hay mensaje) + + + (no amount requested) + (no hay solicitud de cantidad) + + + Requested + Solicitado + + + + SendCoinsDialog + + Send Coins + Enviar bitcoins + + + Coin Control Features + Características de Coin Control + + + Inputs... + Entradas... + + + automatically selected + Seleccionado automáticamente + + + Insufficient funds! + Fondos insuficientes! + + + Quantity: + Cantidad: + + + Bytes: + Bytes: + + + Amount: Cuantía: @@ -1518,6 +2046,118 @@ S&end &Enviar + + Copy quantity + Copiar cantidad + + + Copy amount + Copiar cantidad + + + Copy fee + Copiar cuota + + + Copy after fee + Copiar después de couta + + + Copy bytes + Copiar bytes + + + Copy priority + Copiar prioridad + + + Copy dust + Copiar polvo + + + Copy change + Copiar cambio + + + %1 to %2 + %1 a %2 + + + Are you sure you want to send? + ¿Seguro que quiere enviar? + + + added as transaction fee + añadido como transacción de cuota + + + Total Amount %1 + Cantidad total %1 + + + or + o + + + Confirm send coins + Confirmar enviar monedas + + + The recipient address is not valid. Please recheck. + La dirección de destinatario no es válida. Por favor revísela. + + + The amount to pay must be larger than 0. + La cantidad a pagar debe de ser mayor que 0. + + + The amount exceeds your balance. + La cantidad excede su saldo. + + + The total exceeds your balance when the %1 transaction fee is included. + El total excede su saldo cuando la cuota de transacción de %1 es incluida. + + + Duplicate address found: addresses should only be used once each. + Dirección duplicada encontrada: la dirección sólo debería ser utilizada una vez por cada uso. + + + Transaction creation failed! + ¡Falló la creación de transacción! + + + 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. + ¡La transacción fue rechazada! Esto podría pasar si algunas de las monedas de su monedero fueron ya gastadas, así como si ha utilizado una copia del wallet.dat y las monedas fueron gastadas en la copia pero no marcadas como gastadas aquí. + + + A fee higher than %1 is considered an absurdly high fee. + Una couta mayor que %1 se considera una cuota irracionalmente alta. + + + Payment request expired. + Solicitud de pago caducada. + + + Pay only the required fee of %1 + Pagar únicamente la cuota solicitada de %1 + + + Estimated to begin confirmation within %n block(s). + Se estima que sea confirmado dentro del %n bloque(s).Se estima que sea confirmado dentro del %n bloque(s). + + + Warning: Invalid Bitcoin address + Alerta: dirección Bitcoin inválida + + + Warning: Unknown change address + Alerta: dirección cambiada desconocida + + + (no label) + (sin etiqueta) + SendCoinsEntry @@ -1597,6 +2237,17 @@ Memo: Memo: + + Enter a label for this address to add it to your address book + Introduzca una etiqueta para esta dirección para añadirla a su agenda + + + + SendConfirmationDialog + + Yes + + ShutdownWindow @@ -1695,6 +2346,58 @@ Reset all verify message fields Vaciar todos los campos de la verificación de mensaje + + Click "Sign Message" to generate signature + Click en "Fírmar mensaje" para generar una firma + + + The entered address is invalid. + La dirección introducida no es válida. + + + Please check the address and try again. + Por favor revise la dirección e inténtelo de nuevo. + + + The entered address does not refer to a key. + La dirección introducida no remite a una clave. + + + Wallet unlock was cancelled. + El desbloqueo del monedero fue cancelado. + + + Private key for the entered address is not available. + La clave privada de la dirección introducida no está disponible. + + + Message signing failed. + Falló la firma del mensaje. + + + Message signed. + Mensaje firmado. + + + The signature could not be decoded. + La firma no pudo descodificarse. + + + Please check the signature and try again. + Por favor compruebe la firma y pruebe de nuevo. + + + The signature did not match the message digest. + La firma no se combinó con el mensaje. + + + Message verification failed. + Falló la verificación del mensaje. + + + Message verified. + Mensaje verificado. + SplashScreen @@ -1711,11 +2414,456 @@ + TransactionDesc + + Open for %n more block(s) + Abrir para %n más bloque(s)Abrir para %n más bloque(s) + + + Open until %1 + Abierto hasta %1 + + + conflicted with a transaction with %1 confirmations + Hay un conflicto con la traducción de las confirmaciones %1 + + + %1/offline + %1/sin conexión + + + 0/unconfirmed, %1 + 0/no confirmado, %1 + + + in memory pool + en el equipo de memoria + + + not in memory pool + no en el equipo de memoria + + + abandoned + abandonado + + + %1/unconfirmed + %1/no confirmado + + + %1 confirmations + confirmaciones %1 + + + Status + Estado + + + , has not been successfully broadcast yet + , no ha sido emitido con éxito aún + + + , broadcast through %n node(s) + , emisión a través de %n nodo(s), emisión a través de %n nodo(s) + + + Date + Fecha + + + Source + Fuente + + + Generated + Generado + + + From + Desde + + + unknown + desconocido + + + To + Para + + + own address + dirección propia + + + watch-only + de observación + + + label + etiqueta + + + Credit + Credito + + + matures in %n more block(s) + disponible en %n bloque(s) másdisponible en %n bloque(s) más + + + not accepted + no aceptada + + + Debit + Enviado + + + Total debit + Total enviado + + + Total credit + Total recibido + + + Transaction fee + Comisión de transacción + + + Net amount + Cantidad neta + + + Message + Mensaje + + + Comment + Comentario + + + Transaction ID + Identificador de transacción (ID) + + + Output index + Indice de salida + + + Merchant + Vendedor + + + 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. + Los bitcoins generados deben madurar %1 bloques antes de que puedan gastarse. Cuando generó este bloque, se transmitió a la red para que se añadiera a la cadena de bloques. Si no consigue entrar en la cadena, su estado cambiará a "no aceptado" y ya no se podrá gastar. Esto puede ocurrir ocasionalmente si otro nodo genera un bloque a pocos segundos del suyo. + + + Debug information + Información de depuración + + + Transaction + Transacción + + + Inputs + entradas + + + Amount + Cantidad + + + true + verdadero + + + false + falso + + + TransactionDescDialog This pane shows a detailed description of the transaction Esta ventana muestra información detallada sobre la transacción + + Details for %1 + Detalles para %1 + + + + TransactionTableModel + + Date + Fecha + + + Type + Tipo + + + Label + Etiqueta + + + Open for %n more block(s) + Abrir para %n bloque(s) másAbrir para %n bloque(s) más + + + Open until %1 + Abierto hasta %1 + + + Offline + Sin conexion + + + Unconfirmed + Sin confirmar + + + Abandoned + Abandonado + + + Confirming (%1 of %2 recommended confirmations) + Confirmando (%1 de %2 confirmaciones recomendadas) + + + Confirmed (%1 confirmations) + Confirmado (%1 confirmaciones) + + + Conflicted + En conflicto + + + Immature (%1 confirmations, will be available after %2) + No disponible (%1 confirmaciones. Estarán disponibles al cabo de %2) + + + This block was not received by any other nodes and will probably not be accepted! + Este bloque no ha sido recibido por otros nodos y probablemente no sea aceptado! + + + Generated but not accepted + Generado pero no aceptado + + + Received with + Recibido con + + + Received from + Recibidos de + + + Sent to + Enviado a + + + Payment to yourself + Pago proprio + + + Mined + Minado + + + watch-only + de observación + + + (n/a) + (nd) + + + (no label) + (sin etiqueta) + + + Transaction status. Hover over this field to show number of confirmations. + Estado de transacción. Pasa el ratón sobre este campo para ver el número de confirmaciones. + + + Date and time that the transaction was received. + Fecha y hora en que se recibió la transacción. + + + Type of transaction. + Tipo de transacción. + + + Whether or not a watch-only address is involved in this transaction. + Si una dirección watch-only está involucrada en esta transacción o no. + + + User-defined intent/purpose of the transaction. + Descripción de la transacción definido por el usuario. + + + Amount removed from or added to balance. + Cantidad retirada o añadida al saldo. + + + + TransactionView + + All + Todo + + + Today + Hoy + + + This week + Esta semana + + + This month + Este mes + + + Last month + Mes pasado + + + This year + Este año + + + Range... + Rango... + + + Received with + Recibido con + + + Sent to + Enviado a + + + To yourself + A usted mismo + + + Mined + Minado + + + Other + Otra + + + Enter address or label to search + Introduzca una dirección o etiqueta que buscar + + + Min amount + Cantidad mínima + + + Abandon transaction + Transacción abandonada + + + Copy address + Copiar ubicación + + + Copy label + Copiar capa + + + Copy amount + Copiar cantidad + + + Copy transaction ID + Copiar ID de transacción + + + Copy raw transaction + Copiar transacción raw + + + Copy full transaction details + Copiar todos los detalles de la transacción + + + Edit label + Editar etiqueta + + + Show transaction details + Mostrar detalles de la transacción + + + Export Transaction History + Exportar historial de transacciones + + + Comma separated file (*.csv) + Archivo separado de coma (*.csv) + + + Confirmed + Confirmado + + + Watch-only + De observación + + + Date + Fecha + + + Type + Tipo + + + Label + Etiqueta + + + Address + Dirección + + + ID + ID + + + Exporting Failed + Falló la exportación + + + There was an error trying to save the transaction history to %1. + Ha habido un error al intentar guardar la transacción con %1. + + + Exporting Successful + Exportación finalizada + + + The transaction history was successfully saved to %1. + La transacción ha sido guardada en %1. + + + Range: + Rango: + + + to + para + UnitDisplayStatusBarControl @@ -1725,6 +2873,55 @@ + WalletFrame + + No wallet has been loaded. + No se ha cargado ningún monedero + + + + WalletModel + + Send Coins + Enviar + + + + WalletView + + &Export + &Exportar + + + Export the data in the current tab to a file + Exportar a un archivo los datos de esta pestaña + + + Backup Wallet + Copia de seguridad del monedero + + + Wallet Data (*.dat) + Datos de monedero (*.dat) + + + Backup Failed + La copia de seguridad ha fallado + + + There was an error trying to save the wallet data to %1. + Ha habido un error al intentar guardar los datos del monedero en %1. + + + Backup Successful + Se ha completado con éxito la copia de respaldo + + + The wallet data was successfully saved to %1. + Los datos del monedero se han guardado con éxito en %1. + + + bitcoin-core Options: @@ -1830,6 +3027,10 @@ Distribuido bajo la licencia de software MIT, vea la copia del archivo adjunto o <http://www.opensource.org/licenses/mit-license.php>. + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Bytes equivalentes por sigop en transacciones para retrasmisión y minado (predeterminado: %u) + + Error loading %s: You can't enable HD on a already existing non-HD wallet Error cargando %s: No puede habilitar HD en un monedero existente que no es HD @@ -1842,10 +3043,6 @@ Ejecutar comando cuando una transacción del monedero cambia (%s en cmd se remplazará por TxID) - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Fuerza la retransmisión de transacciones desde nodos en la lista blanca incluso si violan la política de retransmisiones local (predeterminado: %d) - - Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) Ajuste máximo permitido del tiempo offset medio de pares. La perspectiva local de tiempo se verá influenciada por los pares anteriores y posteriores a esta cantidad. (Por defecto: %u segundos) @@ -2054,10 +3251,6 @@ Ubicación de la cookie de autenticación (default: data dir) - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Mínimo de bytes por sigop en transacciones que retransmitimos y minamos (predeterminado: %u) - - Not enough file descriptors available. No hay suficientes descriptores de archivo disponibles. @@ -2098,8 +3291,8 @@ Asignar tamaño de cache en megabytes (entre %d y %d; predeterminado: %d) - Set maximum block cost (default: %d) - Establecer tamaño máximo de bloque (por defecto: %d) + Set maximum BIP141 block weight (default: %d) + Establecer peso máximo bloque BIP141 (predeterminado: %d) Set maximum block size in bytes (default: %d) @@ -2110,6 +3303,10 @@ Especificar archivo de monedero (dentro del directorio de datos) + Starting network threads... + Iniciando funciones de red... + + The source code is available from %s. El código fuente esta disponible desde %s. @@ -2194,6 +3391,10 @@ Las comisiones (en %s/kB) mas pequeñas que esto se consideran como cero comisión para la retransmisión, minería y creación de la transacción (predeterminado: %s) + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + Fuerza la retransmisión de transacciones desde nodos en la lista blanca incluso si violan la política de retransmisiones local (predeterminado: %d) + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) 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) @@ -2347,7 +3548,7 @@ Transaction too large - Transacción demasiado grande + Transacción demasiado grande, intenta dividirla en varias. Unable to bind to %s on this computer (bind returned error %s) @@ -2355,7 +3556,7 @@ Upgrade wallet to latest format on startup - Actualizar el monedero al último formato + Actualizar el monedero al último formato al inicio Username for JSON-RPC connections @@ -2401,15 +3602,15 @@ (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) - (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) + (1 = mantener los meta datos de transacción, por ejemplo: propietario e información de pago, 2 = omitir los metadatos) -maxtxfee is set very high! Fees this large could be paid on a single transaction. - -maxtxfee tiene un ajuste muy elevado! Las comisiones así de grandes podrían ser pagadas en una única transaccion. + -maxtxfee tiene un ajuste muy elevado! Comisiones muy grandes podrían ser pagadas en una única transaccion. -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. - -paytxfee tiene un ajuste muy elevado! Esta es la comisión de transacción que pagaras si envías una transaccion. + -paytxfee tiene un valor muy elevado! La comisión de transacción que pagaras si envías una transaccion es alta. Do not keep transactions in the mempool longer than <n> hours (default: %u) @@ -2437,7 +3638,7 @@ Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. - Error: Unsupported argumento -socks encontrados. SOCKS versión ajuste ya no es posible, sólo SOCKS5 proxies son compatibles. + Error: argumento -socks encontrado. El ajuste de la versión SOCKS ya no es posible, sólo proxies SOCKS5 son compatibles. Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. @@ -2520,10 +3721,6 @@ Ajustar el número de claves en reserva <n> (predeterminado: %u) - Set minimum block size in bytes (default: %u) - Establecer tamaño mínimo de bloque en bytes (por defecto: %u) - - Set the number of threads to service RPC calls (default: %d) Establecer el número de procesos para llamadas del servicio RPC (por defecto: %d) @@ -2541,7 +3738,7 @@ Spend unconfirmed change when sending transactions (default: %u) - Gastar cambio no confirmado al enviar transacciones (predeterminado: %u) + Usar cambio aún no confirmado al enviar transacciones (predeterminado: %u) Threshold for disconnecting misbehaving peers (default: %u) @@ -2569,7 +3766,7 @@ Cannot downgrade wallet - No se puede rebajar el monedero + No se puede cambiar a una versión mas antigua el monedero Cannot write default address diff --git a/src/qt/locale/bitcoin_es_AR.ts b/src/qt/locale/bitcoin_es_AR.ts index 40ebaf88560..c1581b798a0 100644 --- a/src/qt/locale/bitcoin_es_AR.ts +++ b/src/qt/locale/bitcoin_es_AR.ts @@ -41,7 +41,10 @@ &Delete &Borrar - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Repetí la nueva Frase de Contraseña - + BanTableModel @@ -92,12 +95,18 @@ OverviewPage + PaymentServer + + PeerTableModel QObject + QRImageWidget + + RPCConsole @@ -107,12 +116,18 @@ ReceiveRequestDialog + RecentRequestsTableModel + + SendCoinsDialog SendCoinsEntry + SendConfirmationDialog + + ShutdownWindow @@ -125,12 +140,30 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core \ No newline at end of file diff --git a/src/qt/locale/bitcoin_es_CL.ts b/src/qt/locale/bitcoin_es_CL.ts index 188641d6e7a..c864753f209 100644 --- a/src/qt/locale/bitcoin_es_CL.ts +++ b/src/qt/locale/bitcoin_es_CL.ts @@ -41,7 +41,10 @@ &Delete &Borrar - + + + AddressTableModel + AskPassphraseDialog @@ -56,7 +59,7 @@ Repeat new passphrase Repite nueva contraseña - + BanTableModel @@ -282,7 +285,7 @@ Priority prioridad - + EditAddressDialog @@ -297,7 +300,7 @@ &Address &Dirección - + FreespaceChecker @@ -442,6 +445,9 @@ + PaymentServer + + PeerTableModel @@ -456,6 +462,9 @@ + QRImageWidget + + RPCConsole N/A @@ -548,7 +557,10 @@ &Save Image... Guardar imagen... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -608,7 +620,7 @@ S&end &Envía - + SendCoinsEntry @@ -645,6 +657,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -709,16 +724,34 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Esta ventana muestra información detallada sobre la transacción - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_es_CO.ts b/src/qt/locale/bitcoin_es_CO.ts index df189190f60..6cf512fdc36 100644 --- a/src/qt/locale/bitcoin_es_CO.ts +++ b/src/qt/locale/bitcoin_es_CO.ts @@ -37,7 +37,10 @@ &Delete &Borrar - + + + AddressTableModel + AskPassphraseDialog @@ -56,7 +59,7 @@ Repeat new passphrase Repetir nueva contraseña - + BanTableModel @@ -198,6 +201,10 @@ Intro + Welcome + bienvenido + + Error Error @@ -212,12 +219,18 @@ OverviewPage + PaymentServer + + PeerTableModel QObject + QRImageWidget + + RPCConsole @@ -227,12 +240,18 @@ ReceiveRequestDialog + RecentRequestsTableModel + + SendCoinsDialog SendCoinsEntry + SendConfirmationDialog + + ShutdownWindow @@ -245,12 +264,30 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Bitcoin Core diff --git a/src/qt/locale/bitcoin_es_DO.ts b/src/qt/locale/bitcoin_es_DO.ts index ba963d2b804..9cb1e93ada4 100644 --- a/src/qt/locale/bitcoin_es_DO.ts +++ b/src/qt/locale/bitcoin_es_DO.ts @@ -37,7 +37,10 @@ &Delete &Eliminar - + + + AddressTableModel + AskPassphraseDialog @@ -56,7 +59,7 @@ Repeat new passphrase Repita la nueva contraseña - + BanTableModel @@ -349,7 +352,7 @@ Priority Prioridad - + EditAddressDialog @@ -372,7 +375,7 @@ &Address &Dirección - + FreespaceChecker @@ -452,7 +455,7 @@ Select payment request file Seleccione archivo de sulicitud de pago - + OptionsDialog @@ -616,6 +619,9 @@ + PaymentServer + + PeerTableModel @@ -638,6 +644,9 @@ + QRImageWidget + + RPCConsole N/A @@ -798,7 +807,7 @@ Remove Eliminar - + ReceiveRequestDialog @@ -817,7 +826,10 @@ &Save Image... Guardar Imagen... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -908,7 +920,7 @@ S&end &Enviar - + SendCoinsEntry @@ -963,7 +975,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1037,7 +1052,7 @@ Reset all verify message fields Limpiar todos los campos de la verificación de mensaje - + SplashScreen @@ -1053,16 +1068,34 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Esta ventana muestra información detallada sobre la transacción - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_es_ES.ts b/src/qt/locale/bitcoin_es_ES.ts index c66a477cc29..8725cff5825 100644 --- a/src/qt/locale/bitcoin_es_ES.ts +++ b/src/qt/locale/bitcoin_es_ES.ts @@ -3,11 +3,11 @@ AddressBookPage Right-click to edit address or label - Haz clic derecho para editar la dirección o la etiqueta + Haz clic derecho para editar la dirección o etiqueta Create a new address - Crea una nueva direccióon + Crear una nueva dirección &New @@ -15,7 +15,7 @@ Copy the currently selected address to the system clipboard - Copia la direccón seleccionada al portapapeles del sistema + Copiar la dirección seleccionada al portapapeles del sistema &Copy @@ -27,11 +27,11 @@ Delete the currently selected address from the list - Elimina la dirección seleccionada de la lista + Eliminar la dirección seleccionada de la lista Export the data in the current tab to a file - Exporta los datos de la pestaña actual a un archivo + Exportar los datos en la ficha actual a un archivo &Export @@ -41,16 +41,87 @@ &Delete &Eliminar + + Choose the address to send coins to + Seleccione la dirección a la que enviar monedas + + + Choose the address to receive coins with + Seleccione la dirección de la que recibir monedas + + + C&hoose + E&scoger + + + Sending addresses + Enviando direcciones + + + Receiving addresses + Recibiendo direcciones + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Estas son sus direcciones Bitcoin para enviar pagos. Verifique siempre la cantidad y la dirección de recibimiento antes de enviar monedas. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Estas son sus direcciones Bitcoin para recibir pagos. Se recomienda utilizar una nueva dirección de recibimiento para cada transacción + + + &Copy Address + &Copiar Dirección + + + Copy &Label + Copiar &Etiqueta + + + &Edit + &Editar + + + Export Address List + Exportar lista de direcciones + + + Comma separated file (*.csv) + Archivo separado de coma (*.csv) + + + Exporting Failed + Falló la exportación + + + There was an error trying to save the address list to %1. Please try again. + Había un error intentando guardar la lista de direcciones en %1. Por favor inténtelo de nuevo. + + + + AddressTableModel + + Label + Etiqueta + + + Address + Dirección + + + (no label) + (sin etiqueta) + AskPassphraseDialog Passphrase Dialog - Dialogo de Contraseña + Diálogo de contraseña Enter passphrase - Introduzca la contraseña + Introducir contraseña New passphrase @@ -58,12 +129,108 @@ Repeat new passphrase - Repite la nueva contraseña + Repita la nueva contraseña + + + 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>. + Introduzca la nueva frase clave del monedero. <br/>Por favor utilice una frase clave de <b>diez o más carácteres aleatorios</b>, o <b>ocho o más palabras</b>. + + + Encrypt wallet + Monedero encriptado + + + This operation needs your wallet passphrase to unlock the wallet. + Esta operación necesita su frase clave de monedero para desbloquear el monedero. + + + Unlock wallet + Desbloquear monedero + + + This operation needs your wallet passphrase to decrypt the wallet. + Esta operación necesita su frase clave de cartera para desencriptar el monedero. + + + Decrypt wallet + Desencriptar monedero + + + Change passphrase + Cambiar frase clave + + + Enter the old passphrase and new passphrase to the wallet. + Introduzca la vieja frase clave y la nueva flase clave para el monedero. + + + Confirm wallet encryption + Confirmar encriptación del monedero + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Advertencia: Si encripta su monedero y pierde su frase clave <b>PERDERÁ TODOS SUS BITCOINS</b>! + + + Are you sure you wish to encrypt your wallet? + ¿Seguro que desea encriptar su monedero? + + + Wallet encrypted + Monedero encriptado + + + %1 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. + %1 se cerrará ahora para terminar el proceso de encriptación. Recuerde que encriptar su monedero no puede proteger completamente su monedero de ser robado por malware que infecte su ordenador. + + + 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. + IMPORTANTE: Cualquier copia de seguridad anterior que haya hecho en su archivo de monedero debería ser reemplazada con el archivo de monedero encriptado generado recientemente. Por razones de seguridad, las copias de seguridad anteriores del archivo de monedero desencriptado serán inútiles en cuanto empiece a utilizar el nuevo monedero encriptado. + + + Wallet encryption failed + Fracasó la encriptación de monedero + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Falló la encriptación del monedero debido a un error interno. Su monedero no fue encriptado. + + + The supplied passphrases do not match. + La frase clave introducida no coincide. + + + Wallet unlock failed + Fracasó el desbloqueo del monedero + + + The passphrase entered for the wallet decryption was incorrect. + La frase clave introducida para la encriptación del monedero es incorrecta. + + + Wallet decryption failed + Fracasó la encriptación del monedero + + + Wallet passphrase was successfully changed. + La frase clave del monedero se ha cambiado con éxito. + + + Warning: The Caps Lock key is on! + Alerta: ¡La clave de bloqueo Caps está activa! BanTableModel - + + IP/Netmask + IP/Máscara + + + Banned Until + Bloqueado Hasta + + BitcoinGUI @@ -72,7 +239,7 @@ Synchronizing with network... - Sincronizando con la red... + Sincronizando con la red… &Overview @@ -84,7 +251,7 @@ Show general overview of wallet - Mostrar vista general de la cartera + Mostrar vista general del monedero &Transactions @@ -92,7 +259,7 @@ Browse transaction history - Navegar historial de transacciones + Examinar el historial de transacciones E&xit @@ -103,36 +270,48 @@ Salir de la aplicación + &About %1 + &Acerca de %1 + + + Show information about %1 + Mostrar información acerca de %1 + + About &Qt Acerca de &Qt Show information about Qt - Muestra información acerca de Qt + Mostrar información acerca de Qt &Options... &Opciones... + Modify configuration options for %1 + Modificar las opciones de configuración para %1 + + &Encrypt Wallet... - &Encriptar Cartera... + &Cifrar monedero… &Backup Wallet... - &Hacer copia de seguridad de la cartera... + &Guardar copia del monedero... &Change Passphrase... - &Cambiar contraseña... + &Cambiar la contraseña… &Sending addresses... - &Enviando direcciones... + Direcciones de &envío... &Receiving addresses... - &Recibiendo direcciones.. + Direcciones de &recepción... Open &URI... @@ -140,93 +319,3470 @@ Reindexing blocks on disk... - Reindexando bloques en el disco... + Reindexando bloques en disco... Send coins to a Bitcoin address - Envia monedas a una dirección Bitcoin + Enviar bitcoins a una dirección Bitcoin Backup wallet to another location - Crea una copia de seguridad de tu cartera en otra ubicación + Copia de seguridad del monedero en otra ubicación - - - CoinControlDialog - - - EditAddressDialog - &Label - Etiqueta + Change the passphrase used for wallet encryption + Cambiar la contraseña utilizada para el cifrado del monedero - &Address - Dirección + &Debug window + &Ventana de depuración + + + Open debugging and diagnostic console + Abrir la consola de depuración y diagnóstico + + + &Verify message... + &Verificar mensaje... + + + Bitcoin + Bitcoin + + + Wallet + Monedero + + + &Send + &Enviar + + + &Receive + &Recibir + + + &Show / Hide + &Mostrar / Ocultar + + + Show or hide the main Window + Mostrar u ocultar la ventana principal + + + Encrypt the private keys that belong to your wallet + Cifrar las claves privadas de su monedero + + + Sign messages with your Bitcoin addresses to prove you own them + Firmar mensajes con sus direcciones Bitcoin para demostrar la propiedad + + + Verify messages to ensure they were signed with specified Bitcoin addresses + Verificar mensajes comprobando que están firmados con direcciones Bitcoin concretas + + + &File + &Archivo + + + &Settings + &Configuración + + + &Help + &Ayuda + + + Tabs toolbar + Barra de pestañas + + + Request payments (generates QR codes and bitcoin: URIs) + Solicitar pagos (generando códigos QR e identificadores URI "bitcoin:") + + + Show the list of used sending addresses and labels + Mostrar la lista de direcciones de envío y etiquetas + + + Show the list of used receiving addresses and labels + Muestra la lista de direcciones de recepción y etiquetas + + + Open a bitcoin: URI or payment request + Abrir un identificador URI "bitcoin:" o una petición de pago + + + &Command-line options + &Opciones de consola de comandos + + + %n active connection(s) to Bitcoin network + %n conexión activa hacia la red Bitcoin%n conexiones activas hacia la red Bitcoin + + + Indexing blocks on disk... + Indexando bloques en disco... + + + Processing blocks on disk... + Procesando bloques en disco... + + + No block source available... + Ninguna fuente de bloques disponible ... + + + Processed %n block(s) of transaction history. + %n bloque procesado del historial de transacciones.%n bloques procesados del historial de transacciones. + + + %n hour(s) + %n hora%n horas + + + %n day(s) + %n día%n días + + + %n week(s) + %n semana%n semanas + + + %1 and %2 + %1 y %2 + + + %n year(s) + %n año%n años + + + %1 behind + %1 atrás + + + Last received block was generated %1 ago. + El último bloque recibido fue generado hace %1. + + + Transactions after this will not yet be visible. + Las transacciones posteriores aún no están visibles. + + + Error + Error + + + Warning + Aviso + + + Information + Información + + + Up to date + Actualizado + + + Show the %1 help message to get a list with possible Bitcoin command-line options + Mostrar el mensaje de ayuda %1 para obtener una lista de los posibles comandos de linea de comandos de Bitcoin + + + %1 client + %1 cliente + + + Catching up... + Actualizando... + + + Date: %1 + + Fecha: %1 + + + + Amount: %1 + + Amount: %1 + + + + Type: %1 + + Tipo: %1 + + + + Label: %1 + + Etiqueta: %1 + + + + Address: %1 + + Dirección: %1 + + + + Sent transaction + Transacción enviada + + + Incoming transaction + Transacción entrante + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + El monedero está <b>cifrado</b> y actualmente <b>desbloqueado</b> + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + El monedero está <b>cifrado</b> y actualmente <b>bloqueado</b> - FreespaceChecker - - - HelpMessageDialog - - - Intro - - - OpenURIDialog - - - OptionsDialog - - - OverviewPage - - - PeerTableModel - - - QObject - - - RPCConsole - - - ReceiveCoinsDialog - - - ReceiveRequestDialog + CoinControlDialog - Copy &Address - &Copiar Direccón + Coin Selection + Selección de la moneda - - - SendCoinsDialog - - - SendCoinsEntry - - - ShutdownWindow - - - SignVerifyMessageDialog - - - SplashScreen - - - TrafficGraphWidget - - - TransactionDescDialog - - - UnitDisplayStatusBarControl - - - bitcoin-core - + + Quantity: + Cantidad: + + + Bytes: + Bytes: + + + Amount: + Cuantía: + + + Priority: + Prioridad: + + + Fee: + Tasa: + + + Dust: + Polvo: + + + After Fee: + Después de aplicar la comisión: + + + Change: + Cambio: + + + (un)select all + (des)marcar todos + + + Tree mode + Modo árbol + + + List mode + Modo lista + + + Amount + Cantidad + + + Received with label + Recibido con etiqueta + + + Received with address + Recibido con dirección + + + Date + Fecha + + + Confirmations + Confirmaciones + + + Confirmed + Confirmado + + + Priority + Prioridad + + + Copy address + Copiar ubicación + + + Copy label + Copiar etiqueta + + + Copy amount + Copiar cantidad + + + Copy transaction ID + Copiar ID de transacción + + + Lock unspent + Bloquear lo no gastado + + + Unlock unspent + Desbloquear lo no gastado + + + Copy quantity + Copiar cantidad + + + Copy fee + Copiar cuota + + + Copy after fee + Copiar después de couta + + + Copy bytes + Copiar bytes + + + Copy priority + Copiar prioridad + + + Copy dust + Copiar polvo + + + Copy change + Copiar cambio + + + highest + el más alto + + + higher + más alto + + + high + alto + + + medium-high + media altura + + + medium + medio + + + low-medium + medio bajo + + + low + bajo + + + lower + más bajo + + + lowest + el más bajo + + + (%1 locked) + (%1 bloqueado) + + + none + ninguno + + + yes + + + + no + no + + + This label turns red if the transaction size is greater than 1000 bytes. + Esta etiqueta se vuelve roja sí el tamaño de transacción es mayor de 1000 bytes. + + + This means a fee of at least %1 per kB is required. + Esto significa que se requiere una couta de al menos %1 por kB. + + + Can vary +/- 1 byte per input. + Puede variar +/- 1 byte por entrada. + + + Transactions with higher priority are more likely to get included into a block. + Las transacciones con mayor prioridad son más probablemente incluídas en un bloque. + + + This label turns red if the priority is smaller than "medium". + Esta etiqueta se vuelve roja si la priodidad es inferior a "medio". + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Esta etiqueta se vuelve roja si algún destinatario recibe una cantidad inferior a la actual puerta polvorienta. + + + Can vary +/- %1 satoshi(s) per input. + Puede variar +/- %1 satoshi(s) por entrada. + + + (no label) + (sin etiqueta) + + + change from %1 (%2) + cambia desde %1 (%2) + + + (change) + (cambio) + + + + EditAddressDialog + + Edit Address + Editar Dirección + + + &Label + &Etiqueta + + + The label associated with this address list entry + La etiqueta asociada con esta entrada de la lista de direcciones + + + The address associated with this address list entry. This can only be modified for sending addresses. + La dirección asociada con esta entrada de la lista de direcciones. Solo puede ser modificada para direcciones de envío. + + + &Address + &Dirección + + + New receiving address + Nueva dirección de recivimiento + + + New sending address + Nueva dirección de envío + + + Edit receiving address + Editar dirección de recivimiento + + + Edit sending address + Editar dirección de envío + + + The entered address "%1" is not a valid Bitcoin address. + La dirección introducida "%1" no es una dirección Bitcoin válida. + + + The entered address "%1" is already in the address book. + La dirección introducida "%1" está ya en la agenda. + + + Could not unlock wallet. + Podría no desbloquear el monedero. + + + New key generation failed. + Falló la generación de la nueva clave. + + + + FreespaceChecker + + A new data directory will be created. + Se creará un nuevo directorio de datos. + + + name + nombre + + + Directory already exists. Add %1 if you intend to create a new directory here. + El directorio ya existe. Añada %1 si pretende crear aquí un directorio nuevo. + + + Path already exists, and is not a directory. + La ruta ya existe y no es un directorio. + + + Cannot create data directory here. + No se puede crear un directorio de datos aquí. + + + + HelpMessageDialog + + version + versión + + + (%1-bit) + (%1-bit) + + + About %1 + Acerda de %1 + + + Command-line options + Opciones de la línea de órdenes + + + Usage: + Uso: + + + command-line options + opciones de la consola de comandos + + + UI Options: + Opciones de interfaz de usuario: + + + Choose data directory on startup (default: %u) + Elegir directorio de datos al iniciar (predeterminado: %u) + + + Set language, for example "de_DE" (default: system locale) + Establecer el idioma, por ejemplo, "es_ES" (predeterminado: configuración regional del sistema) + + + Start minimized + Arrancar minimizado + + + Set SSL root certificates for payment request (default: -system-) + Establecer los certificados raíz SSL para solicitudes de pago (predeterminado: -system-) + + + Reset all settings changed in the GUI + Reiniciar todos los ajustes modificados en el GUI + + + + Intro + + Welcome + Bienvenido + + + Welcome to %1. + Bienvenido a %1 + + + As this is the first time the program is launched, you can choose where %1 will store its data. + Al ser la primera vez que se ejecuta el programa, puede elegir donde %1 almacenara sus datos + + + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 va a descargar y almacenar una copia de la cadena de bloques de Bitcoin. Al menos %2GB de datos seran almacenados en este directorio, que ira creciendo con el tiempo. El monedero se guardara tambien en ese directorio. + + + Use the default data directory + Utilizar el directorio de datos predeterminado + + + Use a custom data directory: + Utilizar un directorio de datos personalizado: + + + Error: Specified data directory "%1" cannot be created. + Error: no ha podido crearse el directorio de datos especificado "%1". + + + Error + Error + + + %n GB of free space available + %n GB de espacio libre%n GB de espacio disponible + + + (of %n GB needed) + (de %n GB necesitados)(de %n GB requeridos) + + + + OpenURIDialog + + Open URI + Abrir URI... + + + Open payment request from URI or file + Abrir solicitud de pago a partir de un identificador URI o de un archivo + + + URI: + URI: + + + Select payment request file + Seleccionar archivo de sulicitud de pago + + + Select payment request file to open + Seleccionar el archivo de solicitud de pago para abrir + + + + OptionsDialog + + Options + Opciones + + + &Main + &Principal + + + Automatically start %1 after logging in to the system. + Iniciar automaticamente %1 al encender el sistema. + + + &Start %1 on system login + &Iniciar %1 al iniciar el sistema + + + Size of &database cache + Tamaño de cache de la &base de datos + + + MB + MB + + + Number of script &verification threads + Número de hilos de &verificación de scripts + + + Accept connections from outside + Aceptar conexiones desde el exterior + + + Allow incoming connections + Aceptar conexiones entrantes + + + IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) + Dirección IP del proxy (p. ej. IPv4: 127.0.0.1 / IPv6: ::1) + + + 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. + 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ú. + + + 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 |. + 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 |. + + + Third party transaction URLs + Identificadores URL de transacciones de terceros + + + Active command-line options that override above options: + Opciones activas de consola de comandos que tienen preferencia sobre las opciones anteriores: + + + Reset all client options to default. + Restablecer todas las opciones predeterminadas del cliente. + + + &Reset Options + &Restablecer opciones + + + &Network + &Red + + + (0 = auto, <0 = leave that many cores free) + (0 = automático, <0 = dejar libres ese número de núcleos) + + + W&allet + &Monedero + + + Expert + Experto + + + Enable coin &control features + Habilitar funcionalidad de &coin control + + + 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. + Si desactiva el gasto del cambio no confirmado, no se podrá usar el cambio de una transacción hasta que se alcance al menos una confirmación. Esto afecta también a cómo se calcula su saldo. + + + &Spend unconfirmed change + &Gastar cambio no confirmado + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Abrir automáticamente el puerto del cliente Bitcoin en el router. Esta opción solo funciona si el router admite UPnP y está activado. + + + Map port using &UPnP + Mapear el puerto mediante &UPnP + + + Connect to the Bitcoin network through a SOCKS5 proxy. + Conectarse a la red Bitcoin a través de un proxy SOCKS5. + + + &Connect through SOCKS5 proxy (default proxy): + &Conectarse a través de proxy SOCKS5 (proxy predeterminado): + + + Proxy &IP: + Dirección &IP del proxy: + + + &Port: + &Puerto: + + + Port of the proxy (e.g. 9050) + Puerto del servidor proxy (ej. 9050) + + + Used for reaching peers via: + Usado para alcanzar compañeros via: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Muestra si el proxy SOCKS5 predeterminado es utilizado para llegar a los pares a traves de este tipo de red. + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Conectar a la red Bitcoin mediante un proxy SOCKS5 por separado para los servicios ocultos de Tor. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Usar distintos proxys SOCKS5 para comunicarse vía Tor de forma anónima: + + + &Window + &Ventana + + + &Hide the icon from the system tray. + &Ocultar el icono de la barra de tareas + + + Hide tray icon + Ocultar barra de tareas + + + Show only a tray icon after minimizing the window. + Minimizar la ventana a la bandeja de iconos del sistema. + + + &Minimize to the tray instead of the taskbar + &Minimizar a la bandeja en vez de a la barra de tareas + + + M&inimize on close + M&inimizar al cerrar + + + &Display + &Interfaz + + + User Interface &language: + I&dioma de la interfaz de usuario + + + The user interface language can be set here. This setting will take effect after restarting %1. + El idioma de la interfaz de usuario puede establecerse aquí. Esta configuración tendrá efecto tras reiniciar %1. + + + &Unit to show amounts in: + Mostrar las cantidades en la &unidad: + + + Choose the default subdivision unit to show in the interface and when sending coins. + Elegir la subdivisión predeterminada para mostrar cantidades en la interfaz y cuando se envían bitcoins. + + + Whether to show coin control features or not. + Mostrar o no funcionalidad de Coin Control + + + &OK + &Aceptar + + + &Cancel + &Cancelar + + + default + predeterminado + + + none + ninguna + + + Confirm options reset + Confirme el restablecimiento de las opciones + + + Client restart required to activate changes. + Se necesita reiniciar el cliente para activar los cambios. + + + Client will be shut down. Do you want to proceed? + El cliente se cerrará. ¿Desea continuar? + + + This change would require a client restart. + Este cambio exige el reinicio del cliente. + + + The supplied proxy address is invalid. + La dirección proxy indicada es inválida. + + + + OverviewPage + + Form + Formulario + + + 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. + La información mostrada puede estar desactualizada. Su monedero se sincroniza automáticamente con la red Bitcoin después de que se haya establecido una conexión, pero este proceso aún no se ha completado. + + + Watch-only: + De observación: + + + Available: + Disponible: + + + Your current spendable balance + Su saldo disponible actual + + + Pending: + Pendiente: + + + Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance + Total de transacciones pendientes de confirmar y que aún no contribuye al saldo disponible + + + Immature: + No madurado: + + + Mined balance that has not yet matured + Saldo recién minado que aún no ha madurado. + + + Balances + Saldos + + + Total: + Total: + + + Your current total balance + Su saldo actual total + + + Your current balance in watch-only addresses + Su saldo actual en direcciones watch-only + + + Spendable: + Gastable: + + + Recent transactions + Transacciones recientes + + + Unconfirmed transactions to watch-only addresses + Transacciones sin confirmar en direcciones watch-only + + + Mined balance in watch-only addresses that has not yet matured + Saldo minado en direcciones watch-only que aún no ha madurado + + + Current total balance in watch-only addresses + Saldo total en las direcciones watch-only + + + + PaymentServer + + Payment request error + Fallo en la solicitud de pago + + + Cannot start bitcoin: click-to-pay handler + No se puede iniciar bitcoin: encargado click-para-pagar + + + URI handling + Manejo de URI + + + Payment request fetch URL is invalid: %1 + La búsqueda de solicitud de pago URL es válida: %1 + + + Invalid payment address %1 + Dirección de pago inválida %1 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + URI no puede ser analizado! Esto puede ser causado por una dirección Bitcoin inválida o parametros URI mal formados. + + + Payment request file handling + Manejo del archivo de solicitud de pago + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + ¡El archivo de solicitud de pago no puede ser leído! Esto puede ser causado por un archivo de solicitud de pago inválido. + + + Payment request rejected + Solicitud de pago rechazada + + + Payment request network doesn't match client network. + La red de solicitud de pago no cimbina la red cliente. + + + Payment request expired. + Solicitud de pago caducada. + + + Payment request is not initialized. + La solicitud de pago no se ha iniciado. + + + Unverified payment requests to custom payment scripts are unsupported. + Solicitudes de pago sin verificar a scripts de pago habitual no se soportan. + + + Invalid payment request. + Solicitud de pago inválida. + + + Requested payment amount of %1 is too small (considered dust). + Cantidad de pago solicitada de %1 es demasiado pequeña (considerado polvo). + + + Refund from %1 + Reembolsar desde %1 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + Solicitud de pago de %1 es demasiado grande (%2 bytes, permitidos %3 bytes). + + + Error communicating with %1: %2 + Fallo al comunicar con %1: %2 + + + Payment request cannot be parsed! + ¡La solicitud de pago no puede ser analizada! + + + Bad response from server %1 + Mala respuesta desde el servidor %1 + + + Network request error + Fallo de solicitud de red + + + Payment acknowledged + Pago declarado + + + + PeerTableModel + + User Agent + User Agent + + + Node/Service + Nodo/Servicio + + + Ping Time + Ping + + + + QObject + + Amount + Cantidad + + + Enter a Bitcoin address (e.g. %1) + Introducir una dirección Bitcoin (p. ej. %1) + + + %1 d + %1 d + + + %1 h + %1 h + + + %1 m + %1 m + + + %1 s + %1 s + + + None + Ninguno + + + N/A + N/D + + + %1 ms + %1 ms + + + + QRImageWidget + + &Save Image... + &Guardar imagen... + + + &Copy Image + &Copiar imagen + + + Save QR Code + Guardar código QR + + + PNG Image (*.png) + Imagen PNG (*.png) + + + + RPCConsole + + N/A + N/D + + + Client version + Versión del cliente + + + &Information + &Información + + + Debug window + Ventana de depuración + + + General + General + + + Using BerkeleyDB version + Utilizando la versión de BerkeleyDB + + + Datadir + Datadir + + + Startup time + Hora de inicio + + + Network + Red + + + Name + Nombre + + + Number of connections + Número de conexiones + + + Block chain + Cadena de bloques + + + Current number of blocks + Número actual de bloques + + + Memory Pool + Piscina de Memoria + + + Current number of transactions + Número actual de transacciones + + + Memory usage + Uso de memoria + + + Received + Recibido + + + Sent + Enviado + + + &Peers + &Pares + + + Banned peers + Peers Bloqueados + + + Select a peer to view detailed information. + Seleccionar un par para ver su información detallada. + + + Whitelisted + En la lista blanca + + + Direction + Dirección + + + Version + Versión + + + Starting Block + Importando bloques... + + + Synced Headers + Sincronizar Cabeceras + + + Synced Blocks + Bloques Sincronizados + + + User Agent + User Agent + + + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + Abrir el archivo de depuración %1 desde el directorio de datos actual. Puede tardar unos segundos para ficheros de gran tamaño. + + + Decrease font size + Disminuir tamaño de letra + + + Increase font size + Aumentar tamaño de letra + + + Services + Servicios + + + Ban Score + Puntuación de bloqueo + + + Connection Time + Duración de la conexión + + + Last Send + Ultimo envío + + + Last Receive + Ultima recepción + + + Ping Time + Ping + + + The duration of a currently outstanding ping. + La duración de un ping actualmente en proceso. + + + Ping Wait + Espera de Ping + + + Time Offset + Desplazamiento de tiempo + + + Last block time + Hora del último bloque + + + &Open + &Abrir + + + &Console + &Consola + + + &Network Traffic + &Tráfico de Red + + + &Clear + &Vaciar + + + Totals + Total: + + + In: + Entrante: + + + Out: + Saliente: + + + Debug log file + Archivo de registro de depuración + + + Clear console + Borrar consola + + + &Disconnect Node + Nodo &Desconectado + + + Ban Node for + Prohibir Nodo para + + + 1 &hour + 1 &hora + + + 1 &day + 1 &día + + + 1 &week + 1 &semana + + + 1 &year + 1 &año + + + &Unban Node + &Desbanear Nodo + + + Welcome to the %1 RPC console. + Bienvenido a la consola RPC %1. + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + Use las flechas arriba y abajo para navegar por el historial y <b>Control+L</b> para vaciar la pantalla. + + + Type <b>help</b> for an overview of available commands. + Escriba <b>help</b> para ver un resumen de los comandos disponibles. + + + %1 B + %1 B + + + %1 KB + %1 KB + + + %1 MB + %1 MB + + + %1 GB + %1 GB + + + (node id: %1) + (nodo: %1) + + + via %1 + via %1 + + + never + nunca + + + Inbound + Entrante + + + Outbound + Saliente + + + Yes + + + + No + No + + + Unknown + Desconocido + + + + ReceiveCoinsDialog + + &Amount: + Cantidad + + + &Label: + &Etiqueta: + + + &Message: + Mensaje: + + + 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. + Reutilizar una de las direcciones previamente usadas para recibir. Reutilizar direcciones tiene problemas de seguridad y privacidad. No lo uses a menos que antes regeneres una solicitud de pago. + + + R&euse an existing receiving address (not recommended) + R&eutilizar una dirección existente para recibir (no recomendado) + + + 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. + Un mensaje opcional para adjuntar a la solicitud de pago, que se muestra cuando se abre la solicitud. Nota: El mensaje no se enviará con el pago por la red Bitcoin. + + + An optional label to associate with the new receiving address. + Etiqueta opcional para asociar con la nueva dirección de recepción. + + + Use this form to request payments. All fields are <b>optional</b>. + Utilice este formulario para solicitar pagos. Todos los campos son <b>opcionales</b>. + + + An optional amount to request. Leave this empty or zero to not request a specific amount. + Para solicitar una cantidad opcional. Deje este vacío o cero para no solicitar una cantidad específica. + + + Clear all fields of the form. + Vaciar todos los campos del formulario. + + + Clear + Vaciar + + + Requested payments history + Historial de pagos solicitados + + + &Request payment + &Solicitar pago + + + Show the selected request (does the same as double clicking an entry) + Muestra la petición seleccionada (También doble clic) + + + Show + Mostrar + + + Remove the selected entries from the list + Borrar de la lista las direcciónes actualmente seleccionadas + + + Remove + Eliminar + + + Copy label + Copiar capa + + + Copy message + Copiar imagen + + + Copy amount + Copiar cantidad + + + + ReceiveRequestDialog + + QR Code + Código QR + + + Copy &URI + Copiar &URI + + + Copy &Address + Copiar &Dirección + + + &Save Image... + Guardar Imagen... + + + Request payment to %1 + Solicitar pago a %1 + + + Payment information + Información de pago + + + URI + URI + + + Address + Dirección + + + Amount + Cantidad + + + Label + Etiqueta + + + Message + Mensaje + + + Resulting URI too long, try to reduce the text for label / message. + URI resultante demasiado grande, trate de reducir el texto de etiqueta / mensaje. + + + Error encoding URI into QR Code. + Fallo al codificar URI en código QR. + + + + RecentRequestsTableModel + + Date + Fecha + + + Label + Etiqueta + + + Message + Mensaje + + + (no label) + (sin etiqueta) + + + (no message) + (no hay mensaje) + + + (no amount requested) + (no hay solicitud de cantidad) + + + Requested + Solicitado + + + + SendCoinsDialog + + Send Coins + Enviar bitcoins + + + Coin Control Features + Características de Coin Control + + + Inputs... + Entradas... + + + automatically selected + Seleccionado automáticamente + + + Insufficient funds! + Fondos insuficientes! + + + Quantity: + Cantidad: + + + Bytes: + Bytes: + + + Amount: + Cuantía: + + + Priority: + Prioridad: + + + Fee: + Tasa: + + + After Fee: + Después de tasas: + + + Change: + Cambio: + + + If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address. + Si se marca esta opción pero la dirección de cambio está vacía o es inválida, el cambio se enviará a una nueva dirección recién generada. + + + Custom change address + Dirección propia + + + Transaction Fee: + Comisión de Transacción: + + + Choose... + Elija... + + + collapse fee-settings + Colapsar ajustes de cuota + + + per kilobyte + por kilobyte + + + 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. + Si la tarifa de aduana se establece en 1000 satoshis y la transacción está a sólo 250 bytes, entonces "por kilobyte" sólo paga 250 satoshis de cuota, mientras que "el mínimo total" pagaría 1.000 satoshis. Para las transacciones más grandes que un kilobyte ambos pagan por kilobyte + + + Hide + Ocultar + + + total at least + total por lo menos + + + 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. + Pagando solamente la cuota mínima es correcto, siempre y cuando haya menos volumen de transacciones que el espacio en los bloques. Pero tenga en cuenta que esto puede terminar en una transacción nunca confirmada, una vez que haya más demanda para transacciones Bitcoin que la red pueda procesar. + + + (read the tooltip) + (leer la sugerencia) + + + Recommended: + Recomendado: + + + Custom: + Personalizado: + + + (Smart fee not initialized yet. This usually takes a few blocks...) + (Tarifa inteligente no inicializado aún. Esto generalmente lleva a pocos bloques...) + + + Confirmation time: + Tiempo de confirmación: + + + normal + normal + + + fast + rápido + + + Send to multiple recipients at once + Enviar a múltiples destinatarios de una vez + + + Add &Recipient + Añadir &destinatario + + + Clear all fields of the form. + Vaciar todos los campos del formulario + + + Dust: + Polvo: + + + Clear &All + Vaciar &todo + + + Balance: + Saldo: + + + Confirm the send action + Confirmar el envío + + + S&end + &Enviar + + + Copy quantity + Copiar cantidad + + + Copy amount + Copiar cantidad + + + Copy fee + Copiar cuota + + + Copy after fee + Copiar después de couta + + + Copy bytes + Copiar bytes + + + Copy priority + Copiar prioridad + + + Copy dust + Copiar polvo + + + Copy change + Copiar cambio + + + %1 to %2 + %1 a %2 + + + Are you sure you want to send? + ¿Seguro que quiere enviar? + + + added as transaction fee + añadido como transacción de cuota + + + Total Amount %1 + Cantidad total %1 + + + or + o + + + Confirm send coins + Confirmar enviar monedas + + + The recipient address is not valid. Please recheck. + La dirección de destinatario no es válida. Por favor revísela. + + + The amount to pay must be larger than 0. + La cantidad a pagar debe de ser mayor que 0. + + + The amount exceeds your balance. + La cantidad excede su saldo. + + + The total exceeds your balance when the %1 transaction fee is included. + El total excede su saldo cuando la cuota de transacción de %1 es incluida. + + + Duplicate address found: addresses should only be used once each. + Dirección duplicada encontrada: la dirección sólo debería ser utilizada una vez por cada uso. + + + Transaction creation failed! + ¡Falló la creación de transacción! + + + 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. + ¡La transacción fue rechazada! Esto podría pasar si algunas de las monedas de su monedero fueron ya gastadas, así como si ha utilizado una copia del wallet.dat y las monedas fueron gastadas en la copia pero no marcadas como gastadas aquí. + + + A fee higher than %1 is considered an absurdly high fee. + Una couta mayor que %1 se considera una cuota irracionalmente alta. + + + Payment request expired. + Solicitud de pago caducada. + + + Pay only the required fee of %1 + Pagar únicamente la cuota solicitada de %1 + + + Estimated to begin confirmation within %n block(s). + Se estima que sea confirmado dentro del %n bloque(s).Se estima que sea confirmado dentro del %n bloque(s). + + + Warning: Invalid Bitcoin address + Alerta: dirección Bitcoin inválida + + + Warning: Unknown change address + Alerta: dirección cambiada desconocida + + + (no label) + (sin etiqueta) + + + + SendCoinsEntry + + A&mount: + Ca&ntidad: + + + Pay &To: + &Pagar a: + + + &Label: + &Etiqueta: + + + Choose previously used address + Escoger direcciones previamente usadas + + + This is a normal payment. + Esto es un pago ordinario. + + + The Bitcoin address to send the payment to + Dirección Bitcoin a la que enviar el pago + + + Alt+A + Alt+A + + + Paste address from clipboard + Pegar dirección desde portapapeles + + + Alt+P + Alt+P + + + Remove this entry + Eliminar esta transacción + + + 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. + La cuota será deducida de la cantidad que sea mandada. El destinatario recibirá menos bitcoins de los que entres en el + + + S&ubtract fee from amount + Restar comisiones a la cantidad + + + Message: + Mensaje: + + + This is an unauthenticated payment request. + Esta es una petición de pago no autentificada. + + + This is an authenticated payment request. + Esta es una petición de pago autentificada. + + + Enter a label for this address to add it to the list of used addresses + Introduce una etiqueta para esta dirección para añadirla a la lista de direcciones utilizadas + + + 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. + Un mensaje que se adjuntó a la bitcoin: URL que será almacenada con la transacción para su referencia. Nota: Este mensaje no se envía a través de la red Bitcoin. + + + Pay To: + Paga a: + + + Memo: + Memo: + + + Enter a label for this address to add it to your address book + Introduzca una etiqueta para esta dirección para añadirla a su agenda + + + + SendConfirmationDialog + + Yes + + + + + ShutdownWindow + + %1 is shutting down... + %1 se esta cerrando... + + + Do not shut down the computer until this window disappears. + No apague el equipo hasta que desaparezca esta ventana. + + + + SignVerifyMessageDialog + + Signatures - Sign / Verify a Message + Firmas - Firmar / verificar un mensaje + + + &Sign Message + &Firmar mensaje + + + 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. + 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. + + + The Bitcoin address to sign the message with + Dirección Bitcoin con la que firmar el mensaje + + + Choose previously used address + Escoger dirección previamente usada + + + Alt+A + Alt+A + + + Paste address from clipboard + Pegar dirección desde portapapeles + + + Alt+P + Alt+P + + + Enter the message you want to sign here + Introduzca el mensaje que desea firmar aquí + + + Signature + Firma + + + Copy the current signature to the system clipboard + Copiar la firma actual al portapapeles del sistema + + + Sign the message to prove you own this Bitcoin address + Firmar el mensaje para demostrar que se posee esta dirección Bitcoin + + + Sign &Message + Firmar &mensaje + + + Reset all sign message fields + Vaciar todos los campos de la firma de mensaje + + + Clear &All + Vaciar &todo + + + &Verify Message + &Verificar mensaje + + + 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! + 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. + + + The Bitcoin address the message was signed with + La dirección Bitcoin con la que se firmó el mensaje + + + Verify the message to ensure it was signed with the specified Bitcoin address + Verificar el mensaje para comprobar que fue firmado con la dirección Bitcoin indicada + + + Verify &Message + Verificar &mensaje + + + Reset all verify message fields + Vaciar todos los campos de la verificación de mensaje + + + Click "Sign Message" to generate signature + Click en "Fírmar mensaje" para generar una firma + + + The entered address is invalid. + La dirección introducida no es válida. + + + Please check the address and try again. + Por favor revise la dirección e inténtelo de nuevo. + + + The entered address does not refer to a key. + La dirección introducida no remite a una clave. + + + Wallet unlock was cancelled. + El desbloqueo del monedero fue cancelado. + + + Private key for the entered address is not available. + La clave privada de la dirección introducida no está disponible. + + + Message signing failed. + Falló la firma del mensaje. + + + Message signed. + Mensaje firmado. + + + The signature could not be decoded. + La firma no pudo descodificarse. + + + Please check the signature and try again. + Por favor compruebe la firma y pruebe de nuevo. + + + The signature did not match the message digest. + La firma no se combinó con el mensaje. + + + Message verification failed. + Falló la verificación del mensaje. + + + Message verified. + Mensaje verificado. + + + + SplashScreen + + [testnet] + [testnet] + + + + TrafficGraphWidget + + KB/s + KB/s + + + + TransactionDesc + + Open for %n more block(s) + Abrir para %n más bloque(s)Abrir para %n más bloque(s) + + + Open until %1 + Abierto hasta %1 + + + conflicted with a transaction with %1 confirmations + Hay un conflicto con la traducción de las confirmaciones %1 + + + %1/offline + %1/sin conexión + + + 0/unconfirmed, %1 + 0/no confirmado, %1 + + + in memory pool + en el equipo de memoria + + + not in memory pool + no en el equipo de memoria + + + abandoned + abandonado + + + %1/unconfirmed + %1/no confirmado + + + %1 confirmations + confirmaciones %1 + + + Status + Estado + + + , has not been successfully broadcast yet + , no ha sido emitido con éxito aún + + + , broadcast through %n node(s) + , emisión a través de %n nodo(s), emisión a través de %n nodo(s) + + + Date + Fecha + + + Source + Fuente + + + Generated + Generado + + + From + Desde + + + unknown + desconocido + + + To + Para + + + own address + dirección propia + + + watch-only + de observación + + + label + etiqueta + + + Credit + Credito + + + matures in %n more block(s) + disponible en %n bloque(s) másdisponible en %n bloque(s) más + + + not accepted + no aceptada + + + Debit + Enviado + + + Total debit + Total enviado + + + Total credit + Total recibido + + + Transaction fee + Comisión de transacción + + + Net amount + Cantidad neta + + + Message + Mensaje + + + Comment + Comentario + + + Transaction ID + Identificador de transacción (ID) + + + Output index + Indice de salida + + + Merchant + Vendedor + + + 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. + Los bitcoins generados deben madurar %1 bloques antes de que puedan gastarse. Cuando generó este bloque, se transmitió a la red para que se añadiera a la cadena de bloques. Si no consigue entrar en la cadena, su estado cambiará a "no aceptado" y ya no se podrá gastar. Esto puede ocurrir ocasionalmente si otro nodo genera un bloque a pocos segundos del suyo. + + + Debug information + Información de depuración + + + Transaction + Transacción + + + Inputs + entradas + + + Amount + Cantidad + + + true + verdadero + + + false + falso + + + + TransactionDescDialog + + This pane shows a detailed description of the transaction + Esta ventana muestra información detallada sobre la transacción + + + Details for %1 + Detalles para %1 + + + + TransactionTableModel + + Date + Fecha + + + Type + Tipo + + + Label + Etiqueta + + + Open for %n more block(s) + Abrir para %n bloque(s) másAbrir para %n bloque(s) más + + + Open until %1 + Abierto hasta %1 + + + Offline + Sin conexion + + + Unconfirmed + Sin confirmar + + + Abandoned + Abandonado + + + Confirming (%1 of %2 recommended confirmations) + Confirmando (%1 de %2 confirmaciones recomendadas) + + + Confirmed (%1 confirmations) + Confirmado (%1 confirmaciones) + + + Conflicted + En conflicto + + + Immature (%1 confirmations, will be available after %2) + No disponible (%1 confirmaciones. Estarán disponibles al cabo de %2) + + + This block was not received by any other nodes and will probably not be accepted! + Este bloque no ha sido recibido por otros nodos y probablemente no sea aceptado! + + + Generated but not accepted + Generado pero no aceptado + + + Received with + Recibido con + + + Received from + Recibidos de + + + Sent to + Enviado a + + + Payment to yourself + Pago proprio + + + Mined + Minado + + + watch-only + de observación + + + (n/a) + (nd) + + + (no label) + (sin etiqueta) + + + Transaction status. Hover over this field to show number of confirmations. + Estado de transacción. Pasa el ratón sobre este campo para ver el número de confirmaciones. + + + Date and time that the transaction was received. + Fecha y hora en que se recibió la transacción. + + + Type of transaction. + Tipo de transacción. + + + Whether or not a watch-only address is involved in this transaction. + Si una dirección watch-only está involucrada en esta transacción o no. + + + User-defined intent/purpose of the transaction. + Descripción de la transacción definido por el usuario. + + + Amount removed from or added to balance. + Cantidad retirada o añadida al saldo. + + + + TransactionView + + All + Todo + + + Today + Hoy + + + This week + Esta semana + + + This month + Este mes + + + Last month + Mes pasado + + + This year + Este año + + + Range... + Rango... + + + Received with + Recibido con + + + Sent to + Enviado a + + + To yourself + A usted mismo + + + Mined + Minado + + + Other + Otra + + + Enter address or label to search + Introduzca una dirección o etiqueta que buscar + + + Min amount + Cantidad mínima + + + Abandon transaction + Transacción abandonada + + + Copy address + Copiar ubicación + + + Copy label + Copiar capa + + + Copy amount + Copiar cantidad + + + Copy transaction ID + Copiar ID de transacción + + + Copy raw transaction + Copiar transacción raw + + + Copy full transaction details + Copiar todos los detalles de la transacción + + + Edit label + Editar etiqueta + + + Show transaction details + Mostrar detalles de la transacción + + + Export Transaction History + Exportar historial de transacciones + + + Comma separated file (*.csv) + Archivo separado de coma (*.csv) + + + Confirmed + Confirmado + + + Watch-only + De observación + + + Date + Fecha + + + Type + Tipo + + + Label + Etiqueta + + + Address + Dirección + + + ID + ID + + + Exporting Failed + Falló la exportación + + + There was an error trying to save the transaction history to %1. + Ha habido un error al intentar guardar la transacción con %1. + + + Exporting Successful + Exportación finalizada + + + The transaction history was successfully saved to %1. + La transacción ha sido guardada en %1. + + + Range: + Rango: + + + to + para + + + + UnitDisplayStatusBarControl + + Unit to show amounts in. Click to select another unit. + Unidad en la que se muestran las cantidades. Haga clic para seleccionar otra unidad. + + + + WalletFrame + + No wallet has been loaded. + No se ha cargado ningún monedero + + + + WalletModel + + Send Coins + Enviar + + + + WalletView + + &Export + &Exportar + + + Export the data in the current tab to a file + Exportar a un archivo los datos de esta pestaña + + + Backup Wallet + Copia de seguridad del monedero + + + Wallet Data (*.dat) + Datos de monedero (*.dat) + + + Backup Failed + La copia de seguridad ha fallado + + + There was an error trying to save the wallet data to %1. + Ha habido un error al intentar guardar los datos del monedero en %1. + + + Backup Successful + Se ha completado con éxito la copia de respaldo + + + The wallet data was successfully saved to %1. + Los datos del monedero se han guardado con éxito en %1. + + + + bitcoin-core + + Options: + Opciones: + + + + Specify data directory + Especificar directorio para los datos + + + Connect to a node to retrieve peer addresses, and disconnect + Conectar a un nodo para obtener direcciones de pares y desconectar + + + Specify your own public address + Especifique su propia dirección pública + + + Accept command line and JSON-RPC commands + Aceptar comandos consola y JSON-RPC + + + + If <category> is not supplied or if <category> = 1, output all debugging information. + Si <category> no es proporcionado o si <category> =1, muestra toda la información de depuración. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + La Poda se ha configurado por debajo del minimo de %d MiB. Por favor utiliza un valor mas alto. + + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Poda: la ultima sincronizacion de la cartera sobrepasa los datos podados. Necesitas reindexar con -reindex (o descargar la cadena de bloques de nuevo en el caso de un nodo podado) + + + 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) + Reduce los requisitos de almacenaje podando (eliminando) los bloques viejos. Este modo es incompatible con -txindex y -rescan. Advertencia: Revertir este ajuste requiere volver a descargar la cadena de bloques al completo. (predeterminado: 0 = deshabilitar la poda de bloques, >%u = objetivo de tamaño en MiB para usar para los archivos de bloques) + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Nos es posible re-escanear en modo podado.Necesitas utilizar -reindex el cual descargara la cadena de bloques al completo de nuevo. + + + Error: A fatal internal error occurred, see debug.log for details + Un error interno fatal ocurrió, ver debug.log para detalles + + + Fee (in %s/kB) to add to transactions you send (default: %s) + Comisión (en %s/KB) para agregar a las transacciones que envíe (por defecto: %s) + + + Pruning blockstore... + Poda blockstore ... + + + Run in the background as a daemon and accept commands + Ejecutar en segundo plano como daemon y aceptar comandos + + + + Unable to start HTTP server. See debug log for details. + No se ha podido comenzar el servidor HTTP. Ver debug log para detalles. + + + Accept connections from outside (default: 1 if no -proxy or -connect) + Aceptar conexiones desde el exterior (predeterminado: 1 si no -proxy o -connect) + + + Bitcoin Core + Bitcoin Core + + + The %s developers + Los %s desarrolladores + + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee tiene un ajuste muy alto! Esta es la comisión de transacción que pagarás cuando las estimaciones de comisiones no estén disponibles. + + + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + Una comision (en %s/kB) que sera usada cuando las estimacion de comision no disponga de suficientes datos (predeterminado: %s) + + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Aceptar transacciones retransmitidas recibidas desde nodos en la lista blanca incluso cuando no estés retransmitiendo transacciones (predeterminado: %d) + + + Bind to given address and always listen on it. Use [host]:port notation for IPv6 + Vincular a la dirección dada y escuchar siempre en ella. Utilice la notación [host]:port para IPv6 + + + Cannot obtain a lock on data directory %s. %s is probably already running. + No se puede bloquear el directorio %s. %s ya se está ejecutando. + + + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup + Borrar todas las transacciones del monedero y sólo recuperar aquellas partes de la cadena de bloques por medio de -rescan on startup. + + + Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. + Distribuido bajo la licencia de software MIT, vea la copia del archivo adjunto o <http://www.opensource.org/licenses/mit-license.php>. + + + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Bytes equivalentes por sigop en transacciones para retrasmisión y minado (predeterminado: %u) + + + Error loading %s: You can't enable HD on a already existing non-HD wallet + Error cargando %s: No puede habilitar HD en un monedero existente que no es HD + + + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Error leyendo %s!. Todas las claves se han leido correctamente, pero los datos de transacciones o la libreta de direcciones pueden faltar o ser incorrectos. + + + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) + Ejecutar comando cuando una transacción del monedero cambia (%s en cmd se remplazará por TxID) + + + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + Ajuste máximo permitido del tiempo offset medio de pares. La perspectiva local de tiempo se verá influenciada por los pares anteriores y posteriores a esta cantidad. (Por defecto: %u segundos) + + + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + Máximas comisiones totales (en %s) para utilizar en una sola transacción de la cartera; establecer esto demasiado bajo puede abortar grandes transacciones (predeterminado: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + Por favor, compruebe si la fecha y hora en su computadora son correctas! Si su reloj esta mal, %s no trabajara correctamente. + + + Please contribute if you find %s useful. Visit %s for further information about the software. + Contribuya si encuentra %s de utilidad. Visite %s para mas información acerca del programa. + + + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) + Establecer el número de hilos (threads) de verificación de scripts (entre %u y %d, 0 = automático, <0 = dejar libres ese número de núcleos; predeterminado: %d) + + + 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 + La base de datos de bloques contiene un bloque que parece ser del futuro. Esto puede ser porque la fecha y hora de tu ordenador están mal ajustados. Reconstruye la base de datos de bloques solo si estas seguro de que la fecha y hora de tu ordenador estan ajustados correctamente. + + + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications + Esta es una versión de pre-prueba - utilícela bajo su propio riesgo. No la utilice para usos comerciales o de minería. + + + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + No es posible reconstruir la base de datos a un estado anterior. Debe descargar de nuevo la cadena de bloques. + + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + Utiliza UPnP para asignar el puerto de escucha (predeterminado: 1 cuando esta escuchando sin -proxy) + + + Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. + Atención: ¡Parece que la red no está totalmente de acuerdo! Algunos mineros están presentando inconvenientes. + + + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. + Atención: ¡Parece que no estamos completamente de acuerdo con nuestros pares! Podría necesitar una actualización, u otros nodos podrían necesitarla. + + + Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. + Poner en lista blanca a los equipos que se conecten desde la máscara de subred o dirección IP especificada. Se puede especificar múltiples veces. + + + You need to rebuild the database using -reindex-chainstate to change -txindex + Necesita reconstruir la base de datos usando -reindex-chainstate para cambiar -txindex + + + %s corrupt, salvage failed + %s corrupto. Fracasó la recuperacion + + + -maxmempool must be at least %d MB + -maxmempool debe ser por lo menos de %d MB + + + <category> can be: + <category> puede ser: + + + Append comment to the user agent string + Adjunta un comentario a la linea de agente de usuario + + + Attempt to recover private keys from a corrupt wallet on startup + Intento de recuperar claves privadas de un monedero corrupto en arranque + + + Block creation options: + Opciones de creación de bloques: + + + Cannot resolve -%s address: '%s' + No se puede resolver -%s direccion: '%s' + + + Change index out of range + Cambio de indice fuera de rango + + + Connect only to the specified node(s) + Conectar sólo a los nodos (o nodo) especificados + + + Connection options: + Opciones de conexión: + + + Copyright (C) %i-%i + Copyright (C) %i-%i + + + Corrupted block database detected + Corrupción de base de datos de bloques detectada. + + + Debugging/Testing options: + Opciones de depuración/pruebas: + + + Do not load the wallet and disable wallet RPC calls + No cargar el monedero y desactivar las llamadas RPC del monedero + + + Do you want to rebuild the block database now? + ¿Quieres reconstruir la base de datos de bloques ahora? + + + Enable publish hash block in <address> + Activar publicar bloque .hash en <.Address> + + + Enable publish hash transaction in <address> + Activar publicar transacción .hash en <.Address> + + + Enable publish raw block in <address> + Habilita la publicacion de bloques en bruto en <direccion> + + + Enable publish raw transaction in <address> + Habilitar publicar transacción en rama en <dirección> + + + Enable transaction replacement in the memory pool (default: %u) + Habilita el reemplazamiento de transacciones en la piscina de memoria (predeterminado: %u) + + + Error initializing block database + Error al inicializar la base de datos de bloques + + + Error initializing wallet database environment %s! + Error al inicializar el entorno de la base de datos del monedero %s + + + Error loading %s + Error cargando %s + + + Error loading %s: Wallet corrupted + Error cargando %s: Monedero dañado + + + Error loading %s: Wallet requires newer version of %s + Error cargando %s: Monedero requiere un versión mas reciente de %s + + + Error loading %s: You can't disable HD on a already existing HD wallet + Error cargando %s: No puede deshabilitar HD en un monedero existente que ya es HD + + + Error loading block database + Error cargando base de datos de bloques + + + Error opening block database + Error al abrir base de datos de bloques. + + + Error: Disk space is low! + Error: ¡Espacio en disco bajo! + + + Failed to listen on any port. Use -listen=0 if you want this. + Ha fallado la escucha en todos los puertos. Use -listen=0 si desea esto. + + + Importing... + Importando... + + + Incorrect or no genesis block found. Wrong datadir for network? + Incorrecto o bloque de génesis no encontrado. Datadir equivocada para la red? + + + Initialization sanity check failed. %s is shutting down. + La inicialización de la verificación de validez falló. Se está apagando %s. + + + Invalid -onion address: '%s' + Dirección -onion inválida: '%s' + + + Invalid amount for -%s=<amount>: '%s' + Cantidad no valida para -%s=<amount>: '%s' + + + Invalid amount for -fallbackfee=<amount>: '%s' + Cantidad inválida para -fallbackfee=<amount>: '%s' + + + Keep the transaction memory pool below <n> megabytes (default: %u) + Mantener la memoria de transacciones por debajo de <n> megabytes (predeterminado: %u) + + + Loading banlist... + Cargando banlist... + + + Location of the auth cookie (default: data dir) + Ubicación de la cookie de autenticación (default: data dir) + + + Not enough file descriptors available. + No hay suficientes descriptores de archivo disponibles. + + + Only connect to nodes in network <net> (ipv4, ipv6 or onion) + Sólo conectar a nodos en redes <net> (ipv4, ipv6 o onion) + + + Print this help message and exit + Imprimir este mensaje de ayuda y salir + + + Print version and exit + Imprimir versión y salir + + + Prune cannot be configured with a negative value. + Pode no se puede configurar con un valor negativo. + + + Prune mode is incompatible with -txindex. + El modo recorte es incompatible con -txindex. + + + Rebuild chain state and block index from the blk*.dat files on disk + Reconstruir el estado de la cadena e indice de bloques a partir de los ficheros blk*.dat en disco + + + Rebuild chain state from the currently indexed blocks + Reconstruir el estado de la cadena a partir de los bloques indexados + + + Rewinding blocks... + Verificando bloques... + + + Set database cache size in megabytes (%d to %d, default: %d) + Asignar tamaño de cache en megabytes (entre %d y %d; predeterminado: %d) + + + Set maximum BIP141 block weight (default: %d) + Establecer peso máximo bloque BIP141 (predeterminado: %d) + + + Set maximum block size in bytes (default: %d) + Establecer tamaño máximo de bloque en bytes (predeterminado: %d) + + + Specify wallet file (within data directory) + Especificar archivo de monedero (dentro del directorio de datos) + + + Starting network threads... + Iniciando funciones de red... + + + The source code is available from %s. + El código fuente esta disponible desde %s. + + + Unable to bind to %s on this computer. %s is probably already running. + No se ha podido conectar con %s en este equipo. %s es posible que este todavia en ejecución. + + + Unsupported argument -benchmark ignored, use -debug=bench. + El argumento -benchmark no es soportado y ha sido ignorado, utiliza -debug=bench + + + Unsupported argument -debugnet ignored, use -debug=net. + Parámetros no compatibles -debugnet ignorados , use -debug = red. + + + Unsupported argument -tor found, use -onion. + Parámetros no compatibles -tor encontrados, use -onion . + + + Use UPnP to map the listening port (default: %u) + Usar UPnP para asignar el puerto de escucha (predeterminado:: %u) + + + User Agent comment (%s) contains unsafe characters. + El comentario del Agente de Usuario (%s) contiene caracteres inseguros. + + + Verifying blocks... + Verificando bloques... + + + Verifying wallet... + Verificando monedero... + + + Wallet %s resides outside data directory %s + El monedero %s se encuentra fuera del directorio de datos %s + + + Wallet debugging/testing options: + Opciones de depuración/pruebas de monedero: + + + Wallet needed to be rewritten: restart %s to complete + Es necesario reescribir el monedero: reiniciar %s para completar + + + Wallet options: + Opciones de monedero: + + + 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 + Permitir conexiones JSON-RPC de origen especificado. Válido para son una sola IP (por ejemplo 1.2.3.4), una red/máscara de red (por ejemplo 1.2.3.4/255.255.255.0) o una red/CIDR (e.g. 1.2.3.4/24). Esta opción se puede especificar varias veces + + + Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6 + Ligar a las direcciones especificadas y poner en lista blanca a los equipos conectados a ellas. Usar la notación para IPv6 [host]:puerto. + + + 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) + Ligar a las direcciones especificadas para escuchar por conexiones JSON-RPC. Usar la notación para IPv6 [host]:puerto. Esta opción se puede especificar múltiples veces (por defecto: ligar a todas las interfaces) + + + Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) + Crear nuevos archivos con permisos por defecto del sistema, en lugar de umask 077 (sólo efectivo con la funcionalidad de monedero desactivada) + + + Discover own IP addresses (default: 1 when listening and no -externalip or -proxy) + Descubra direcciones IP propias (por defecto: 1 cuando se escucha y nadie -externalip o -proxy) + + + Error: Listening for incoming connections failed (listen returned error %s) + Error: la escucha para conexiones entrantes falló (la escucha regresó el error %s) + + + Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) + Ejecutar un comando cuando se reciba una alerta importante o cuando veamos un fork demasiado largo (%s en cmd se reemplazará por el mensaje) + + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + Las comisiones (en %s/kB) mas pequeñas que esto se consideran como cero comisión para la retransmisión, minería y creación de la transacción (predeterminado: %s) + + + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + Fuerza la retransmisión de transacciones desde nodos en la lista blanca incluso si violan la política de retransmisiones local (predeterminado: %d) + + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) + 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) + + + Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) + Cantidad no válida para -maxtxfee=<amount>: '%s' (debe ser por lo menos la cuota de comisión mínima de %s para prevenir transacciones atascadas) + + + Maximum size of data in data carrier transactions we relay and mine (default: %u) + El tamaño máximo de los datos en las operaciones de transporte de datos que transmitimos y el mio (default: %u) + + + Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect) + Consulta de direcciones pares mediante búsqueda de DNS, si bajo en direcciones (por defecto: 1 a menos que - conectar) + + + Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u) + Aleatorizar las credenciales para cada conexión proxy. Esto habilita la Tor stream isolation (por defecto: %u) + + + Set maximum size of high-priority/low-fee transactions in bytes (default: %d) + Establecer tamaño máximo de las transacciones de alta prioridad/baja comisión en bytes (predeterminado: %d) + + + The transaction amount is too small to send after the fee has been deducted + Monto de transacción muy pequeña luego de la deducción por comisión + + + 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. + 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. + + + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + Usar tras BIP32 la generación de llave determinística jerárquica (HD) . Solo tiene efecto durante el primer inicio/generación del monedero + + + 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 + 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. + + + You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain + Necesitas reconstruir la base de datos utilizando -reindex para volver al modo sin recorte. Esto volverá a descargar toda la cadena de bloques + + + (default: %u) + (por defecto: %u) + + + Accept public REST requests (default: %u) + Aceptar solicitudes públicas en FERIADOS (por defecto: %u) + + + Automatically create Tor hidden service (default: %d) + Automáticamente crea el servicio Tor oculto (por defecto: %d) + + + Connect through SOCKS5 proxy + Conectar usando SOCKS5 proxy + + + Error reading from database, shutting down. + Error al leer la base de datos, cerrando. + + + Imports blocks from external blk000??.dat file on startup + Importa los bloques desde un archivo externo blk000?.dat + + + Information + Información + + + Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) + Cantidad inválida para -paytxfee=<amount>: '%s' (debe ser por lo menos %s) + + + Invalid netmask specified in -whitelist: '%s' + Máscara de red inválida especificada en -whitelist: '%s' + + + Keep at most <n> unconnectable transactions in memory (default: %u) + Mantener como máximo <n> transacciones no conectables en memoria (por defecto: %u) + + + Need to specify a port with -whitebind: '%s' + Necesita especificar un puerto con -whitebind: '%s' + + + Node relay options: + Opciones de nodos de retransmisión: + + + RPC server options: + Opciones de servidor RPC: + + + Reducing -maxconnections from %d to %d, because of system limitations. + Reduciendo -maxconnections de %d a %d, debido a limitaciones del sistema. + + + Rescan the block chain for missing wallet transactions on startup + Rescanea la cadena de bloques para transacciones perdidas de la cartera + + + Send trace/debug info to console instead of debug.log file + Enviar información de trazas/depuración a la consola en lugar de al archivo debug.log + + + Send transactions as zero-fee transactions if possible (default: %u) + Mandar transacciones como comisión-cero si es posible (por defecto: %u) + + + Show all debugging options (usage: --help -help-debug) + Muestra todas las opciones de depuración (uso: --help -help-debug) + + + Shrink debug.log file on client startup (default: 1 when no -debug) + Reducir el archivo debug.log al iniciar el cliente (predeterminado: 1 sin -debug) + + + Signing transaction failed + Transacción falló + + + The transaction amount is too small to pay the fee + Cantidad de la transacción demasiado pequeña para pagar la comisión + + + This is experimental software. + Este software es experimental. + + + Tor control port password (default: empty) + Contraseña del puerto de control de Tor (predeterminado: vacio) + + + Tor control port to use if onion listening enabled (default: %s) + Puerto de control de Tor a utilizar si la escucha de onion esta activada (predeterminado: %s) + + + Transaction amount too small + Cantidad de la transacción demasiado pequeña + + + Transaction amounts must be positive + Las cantidades en las transacciones deben ser positivas + + + Transaction too large for fee policy + Operación demasiado grande para la política de tasas + + + Transaction too large + Transacción demasiado grande, intenta dividirla en varias. + + + Unable to bind to %s on this computer (bind returned error %s) + No es posible conectar con %s en este sistema (bind ha dado el error %s) + + + Upgrade wallet to latest format on startup + Actualizar el monedero al último formato al inicio + + + Username for JSON-RPC connections + Nombre de usuario para las conexiones JSON-RPC + + + + Warning + Aviso + + + Warning: unknown new rules activated (versionbit %i) + Advertencia: nuevas reglas desconocidas activadas (versionbit %i) + + + Whether to operate in a blocks only mode (default: %u) + Si se debe o no operar en un modo de solo bloques (predeterminado: %u) + + + Zapping all transactions from wallet... + Eliminando todas las transacciones del monedero... + + + ZeroMQ notification options: + Opciones de notificación ZeroQM: + + + Password for JSON-RPC connections + Contraseña para las conexiones JSON-RPC + + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + Ejecutar un comando cuando cambia el mejor bloque (%s en cmd se sustituye por el hash de bloque) + + + Allow DNS lookups for -addnode, -seednode and -connect + Permitir búsquedas DNS para -addnode, -seednode y -connect + + + Loading addresses... + Cargando direcciones... + + + (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) + (1 = mantener los meta datos de transacción, por ejemplo: propietario e información de pago, 2 = omitir los metadatos) + + + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + -maxtxfee tiene un ajuste muy elevado! Comisiones muy grandes podrían ser pagadas en una única transaccion. + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + -paytxfee tiene un valor muy elevado! La comisión de transacción que pagaras si envías una transaccion es alta. + + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + No mantener transacciones en la memoria mas de <n> horas (predeterminado: %u) + + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Las comisiones (en %s/kB) menores que esto son consideradas de cero comision para la creacion de transacciones (predeterminado: %s) + + + How thorough the block verification of -checkblocks is (0-4, default: %u) + Nivel de rigor en la verificación de bloques de -checkblocks (0-4; predeterminado: %u) + + + Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u) + Mantener el índice completo de transacciones, usado por la llamada rpc de getrawtransaction (por defecto: %u) + + + Number of seconds to keep misbehaving peers from reconnecting (default: %u) + Número de segundos en que se evita la reconexión de pares con mal comportamiento (predeterminado: %u) + + + Output debugging information (default: %u, supplying <category> is optional) + Mostrar depuración (por defecto: %u, proporcionar <category> es opcional) + + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + Error: argumento -socks encontrado. El ajuste de la versión SOCKS ya no es posible, sólo proxies SOCKS5 son compatibles. + + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + El argumento no soportado -whitelistalwaysrelay ha sido ignorado, utiliza -whitelistrelay y/o -whitelistforcerelay. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) + Usar distintos proxys SOCKS5 para comunicarse vía Tor de forma anónima (Por defecto: %s) + + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Nombre de usuario y hash de la contraseña para las conexiones JSON-RPC. El campo <userpw> tiene el formato: <USERNAME>:<SALT>$<HASH>. Se incluye un script python convencional en share/rpcuser. Esta opción puede ser especificada multiples veces + + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Advertencia: Se están minando versiones de bloques desconocidas! Es posible que normas desconocidas estén activas + + + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + Aviso: fichero de monedero corrupto, datos recuperados! Original %s guardado como %s en %s; si su balance de transacciones es incorrecto, debe restaurar desde una copia de seguridad. + + + (default: %s) + (predeterminado: %s) + + + Always query for peer addresses via DNS lookup (default: %u) + Siempre consultar direcciones de otros equipos por medio de DNS lookup (por defecto: %u) + + + How many blocks to check at startup (default: %u, 0 = all) + Cuántos bloques comprobar al iniciar (predeterminado: %u, 0 = todos) + + + Include IP addresses in debug output (default: %u) + Incluir direcciones IP en la salida de depuración (por defecto: %u) + + + Invalid -proxy address: '%s' + Dirección -proxy inválida: '%s' + + + Listen for JSON-RPC connections on <port> (default: %u or testnet: %u) + Escuchar conexiones JSON-RPC en <puerto> (predeterminado: %u o testnet: %u) + + + Listen for connections on <port> (default: %u or testnet: %u) + Escuchar conexiones en <puerto> (predeterminado: %u o testnet: %u) + + + Maintain at most <n> connections to peers (default: %u) + Mantener como máximo <n> conexiones a pares (predeterminado: %u) + + + Make the wallet broadcast transactions + Realiza las operaciones de difusión del monedero + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: %u) + Búfer de recepción máximo por conexión, <n>*1000 bytes (por defecto: %u) + + + Maximum per-connection send buffer, <n>*1000 bytes (default: %u) + Búfer de recepción máximo por conexión, , <n>*1000 bytes (por defecto: %u) + + + Prepend debug output with timestamp (default: %u) + Anteponer marca temporal a la información de depuración (por defecto: %u) + + + Relay and mine data carrier transactions (default: %u) + Retransmitir y minar transacciones de transporte de datos (por defecto: %u) + + + Relay non-P2SH multisig (default: %u) + Relay non-P2SH multisig (default: %u) + + + Set key pool size to <n> (default: %u) + Ajustar el número de claves en reserva <n> (predeterminado: %u) + + + Set the number of threads to service RPC calls (default: %d) + Establecer el número de procesos para llamadas del servicio RPC (por defecto: %d) + + + Specify configuration file (default: %s) + Especificar archivo de configuración (por defecto: %s) + + + Specify connection timeout in milliseconds (minimum: 1, default: %d) + Especificar tiempo de espera de la conexión (mínimo: 1, por defecto: %d) + + + Specify pid file (default: %s) + Especificar archivo pid (predeterminado: %s) + + + Spend unconfirmed change when sending transactions (default: %u) + Usar cambio aún no confirmado al enviar transacciones (predeterminado: %u) + + + Threshold for disconnecting misbehaving peers (default: %u) + Umbral para la desconexión de pares con mal comportamiento (predeterminado: %u) + + + Unknown network specified in -onlynet: '%s' + La red especificada en -onlynet '%s' es desconocida + + + Insufficient funds + Fondos insuficientes + + + Loading block index... + Cargando el índice de bloques... + + + Add a node to connect to and attempt to keep the connection open + Añadir un nodo al que conectarse y tratar de mantener la conexión abierta + + + Loading wallet... + Cargando monedero... + + + Cannot downgrade wallet + No se puede cambiar a una versión mas antigua el monedero + + + Cannot write default address + No se puede escribir la dirección predeterminada + + + Rescanning... + Reexplorando... + + + Done loading + Se terminó de cargar + + + Error + Error + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_es_MX.ts b/src/qt/locale/bitcoin_es_MX.ts index 0a6ea1e1dd1..bfda085d90a 100644 --- a/src/qt/locale/bitcoin_es_MX.ts +++ b/src/qt/locale/bitcoin_es_MX.ts @@ -41,7 +41,10 @@ &Delete &Borrar - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Repita la nueva contraseña - + BanTableModel @@ -293,7 +296,7 @@ Priority Prioridad - + EditAddressDialog @@ -308,7 +311,7 @@ &Address &Dirección - + FreespaceChecker @@ -376,6 +379,9 @@ + PaymentServer + + PeerTableModel @@ -386,6 +392,9 @@ + QRImageWidget + + RPCConsole Debug window @@ -427,6 +436,9 @@ + RecentRequestsTableModel + + SendCoinsDialog Send Coins @@ -521,6 +533,9 @@ + SendConfirmationDialog + + ShutdownWindow Do not shut down the computer until this window disappears. @@ -553,16 +568,34 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Este panel muestras una descripción detallada de la transacción - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_es_UY.ts b/src/qt/locale/bitcoin_es_UY.ts index c565a63cd88..5e37c3f170d 100644 --- a/src/qt/locale/bitcoin_es_UY.ts +++ b/src/qt/locale/bitcoin_es_UY.ts @@ -33,7 +33,10 @@ &Delete &Borrar - + + + AddressTableModel + AskPassphraseDialog @@ -48,7 +51,7 @@ Repeat new passphrase Repetir nueva contraseña - + BanTableModel @@ -224,7 +227,7 @@ Priority Prioridad - + EditAddressDialog @@ -239,7 +242,7 @@ &Address &Direccion - + FreespaceChecker @@ -275,12 +278,18 @@ + PaymentServer + + PeerTableModel QObject + QRImageWidget + + RPCConsole &Information @@ -302,6 +311,9 @@ + RecentRequestsTableModel + + SendCoinsDialog Send Coins @@ -372,6 +384,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -400,12 +415,30 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_es_VE.ts b/src/qt/locale/bitcoin_es_VE.ts index 432adc57eea..322b311ed86 100644 --- a/src/qt/locale/bitcoin_es_VE.ts +++ b/src/qt/locale/bitcoin_es_VE.ts @@ -41,7 +41,10 @@ &Delete &Borrar - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Repetir nueva frase de contraseña - + BanTableModel @@ -301,7 +304,7 @@ Priority Prioridad - + EditAddressDialog @@ -324,7 +327,7 @@ &Address &Dirección - + FreespaceChecker @@ -408,7 +411,7 @@ Select payment request file Seleccionar archivo de solicitud de pago - + OptionsDialog @@ -448,6 +451,9 @@ + PaymentServer + + PeerTableModel @@ -458,6 +464,9 @@ + QRImageWidget + + RPCConsole &Information @@ -495,6 +504,9 @@ + RecentRequestsTableModel + + SendCoinsDialog Quantity: @@ -537,6 +549,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -549,12 +564,30 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_et.ts b/src/qt/locale/bitcoin_et.ts index 0d659fd7195..e65d4e6e474 100644 --- a/src/qt/locale/bitcoin_et.ts +++ b/src/qt/locale/bitcoin_et.ts @@ -2,6 +2,10 @@ AddressBookPage + Right-click to edit address or label + Paremkliki aadressi või sildi muutmiseks + + Create a new address Loo uus aadress @@ -37,6 +41,77 @@ &Delete &Kustuta + + Choose the address to send coins to + Vali aadress millele mündid saata + + + Choose the address to receive coins with + Vali aadress müntide vastuvõtmiseks + + + C&hoose + V&ali + + + Sending addresses + Saatvad aadressid + + + Receiving addresses + Vastuvõtvad aadressid + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Need on sinu Bitcoin aadressid maksete saatmiseks. Ennem müntide saatmist kontrolli alati summat ja makse saaja aadressi. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Need on sinu Bitcoin aadressid sisenevate maksete vastu võtmiseks. Soovitav on iga tehingu tarbeks kasutada uut aadressi. + + + &Copy Address + &Kopeeri Aadress + + + Copy &Label + Kopeeri &Silt + + + &Edit + &Muuda + + + Export Address List + Ekspordi Aadresside Nimekiri + + + Comma separated file (*.csv) + Komadega eraldatud väärtuste fail (*.csv) + + + Exporting Failed + Eksport ebaõnnestus. + + + There was an error trying to save the address list to %1. Please try again. + Tõrge aadressi nimekirja salvestamisel %1. Palun proovi uuesti. + + + + AddressTableModel + + Label + Märge + + + Address + Aadress + + + (no label) + (märge puudub) + AskPassphraseDialog @@ -56,6 +131,86 @@ Repeat new passphrase Korda salafraasi + + 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>. + Sisesta uus salafraas rahakotti.<br/>Kasuta salafraasi millles on<b>kümme või rohkem juhuslikku sümbolit<b>,või<b>kaheksa või rohkem sõna<b/>. + + + Encrypt wallet + Krüpteeri rahakott + + + This operation needs your wallet passphrase to unlock the wallet. + Antud operatsioon vajab rahakoti lahtilukustamiseks salafraasi. + + + Unlock wallet + Ava rahakoti lukk + + + This operation needs your wallet passphrase to decrypt the wallet. + Antud operatsioon vajab rahakoti dekrüpteerimiseks salafraasi. + + + Decrypt wallet + Dekrüpteeri rahakott + + + Change passphrase + Vaheta salafraasi + + + Enter the old passphrase and new passphrase to the wallet. + Sisesta vana salafraas ja uus salafraas rahakotti. + + + Confirm wallet encryption + Kinnita rahakoti krüpteerimine. + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Hoiatus:Kui sa krüpteerid oma rahakoti ja kaotad salafraasi, siis sa<b>KAOTAD OMA BITCOINID</b>! + + + Are you sure you wish to encrypt your wallet? + Kas oled kindel, et soovid rahakoti krüpteerida? + + + Wallet encrypted + Rahakott krüpteeritud + + + Wallet encryption failed + Rahakoti krüpteerimine ebaõnnestus + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Rahakoti krüpteerimine ebaõnnestus sisemise tõrke tõttu. Sinu rahakott ei ole krüpteeritud. + + + The supplied passphrases do not match. + Sisestatud salafraasid ei kattu. + + + Wallet unlock failed + Rahakoti lahtilukustamine ebaõnnestus + + + The passphrase entered for the wallet decryption was incorrect. + Rahakoti dekrüpteerimiseks sisestatud salafraas ei ole õige. + + + Wallet decryption failed + Rahakoti dekrüpteerimine ebaõnnestus + + + Wallet passphrase was successfully changed. + Rahakoti salafraas on edukalt vahetatud. + + + Warning: The Caps Lock key is on! + Hoiatus:Klaviatuuri suurtähelukk on peal. + BanTableModel @@ -95,6 +250,10 @@ Väljumine + &About %1 + &Teave %1 + + About &Qt Teave &Qt kohta @@ -140,7 +299,7 @@ &Debug window - &Debugimise aken + &Silumise aken Open debugging and diagnostic console @@ -164,7 +323,7 @@ &Receive - &Saama + &Võta vastu &Show / Hide @@ -203,10 +362,38 @@ Vahelehe tööriistariba + Request payments (generates QR codes and bitcoin: URIs) + Loo maksepäring (genereerib QR koodid ja bitcoini: URId) + + + Open a bitcoin: URI or payment request + Ava bitcoini: URI või maksepäring + + &Command-line options Käsurea valikud + %n active connection(s) to Bitcoin network + %n aktiivne ühendus Bitcoini võrku%n aktiivset ühendust Bitcoini võrku + + + Indexing blocks on disk... + Kõvakettal olevate plokkide indekseerimine... + + + Processing blocks on disk... + Kõvakettal olevate plokkide töötlemine... + + + No block source available... + Plokkide allikas pole saadaval... + + + Processed %n block(s) of transaction history. + Töödeldud %n plokk transaktsioonide ajaloost.Töödeldud %n plokki transaktsioonide ajaloost. + + %n hour(s) %n tund%n tundi @@ -255,8 +442,12 @@ Ajakohane + %1 client + %1 klient + + Catching up... - Jõuan... + Jõuan järgi... Date: %1 @@ -312,26 +503,182 @@ Kogus: + Bytes: + Baiti: + + Amount: Summa: + Priority: + Prioriteet + + Fee: Tasu: + Dust: + Puru: + + + After Fee: + Peale tehingutasu: + + + Change: + Vahetusraha: + + + Tree mode + Puu režiim + + + List mode + Loetelu režiim + + Amount Kogus + Received with label + Vastuvõetud märgisega + + + Received with address + Vastuvõetud aadressiga + + Date Kuupäev + Confirmations + Kinnitused + + Confirmed Kinnitatud - + + Priority + Prioriteet + + + Copy address + Kopeeri aadress + + + Copy label + Kopeeri märgis + + + Copy amount + Kopeeri summa + + + Copy transaction ID + Kopeeri tehingu ID + + + Copy quantity + Kopeeri kogus + + + Copy fee + Kopeeri tehingutasu + + + Copy bytes + Kopeeri baidid + + + Copy priority + Kopeeri prioriteet + + + Copy dust + Kopeeri puru + + + Copy change + Kopeeri vahetusraha + + + highest + kõrgeim + + + higher + kõrgem + + + high + kõrge + + + medium-high + keskmiselt kõrge + + + medium + keskmine + + + low-medium + keskmiselt madal + + + low + madal + + + lower + madalam + + + lowest + madalaim + + + (%1 locked) + (%1 lukustatud) + + + none + puudub + + + yes + jah + + + no + ei + + + This label turns red if the transaction size is greater than 1000 bytes. + Märgis muutub punaseks kui transaktsiooni suurus ületab 1000 baiti. + + + This means a fee of at least %1 per kB is required. + See tähendab, et vajalik tehingutasu on vähemalt %1 kB kohta + + + This label turns red if the priority is smaller than "medium". + See märgis muutud punaseks kui prioriteet on madalam kui "keskmine". + + + (no label) + (märgis puudub) + + + (change) + (vahetusraha) + + EditAddressDialog @@ -346,6 +693,38 @@ &Address &Aadress + + New receiving address + Uus vastu võttev aadress + + + New sending address + Uus saatev aadress + + + Edit receiving address + Muuda vastuvõtvat aadressi + + + Edit sending address + Muuda saatvat aadressi + + + The entered address "%1" is not a valid Bitcoin address. + Sisestatud aadress "%1" ei ole korrektne Bitcoin aadress. + + + The entered address "%1" is already in the address book. + Sisestatud aadress "%1" on juba aadressi raamatus. + + + Could not unlock wallet. + Rahakoti lahtilukustamine ebaõnnestus. + + + New key generation failed. + Uue võtme genereerimine ebaõnnestus. + FreespaceChecker @@ -372,6 +751,14 @@ command-line options käsurea valikud + + UI Options: + Kasutajaliidese Suvandid: + + + Show splash screen on startup (default: %u) + Käivitamisel kuva laadimisekraani (vaikimisi %u) + Intro @@ -394,7 +781,15 @@ URI: URI: - + + Select payment request file + Vali maksepäringu fail + + + Select payment request file to open + Vali maksepäringu fail mida avada + + OptionsDialog @@ -494,6 +889,10 @@ vaikeväärtus + none + puudub + + Confirm options reset Kinnita valikute algseadistamine @@ -513,6 +912,10 @@ Kuvatav info ei pruugi olla ajakohane. Ühenduse loomisel süngitakse sinu rahakott automaatselt Bitconi võrgustikuga, kuid see toiming on hetkel lõpetamata. + Pending: + Ootel: + + Immature: Ebaküps: @@ -521,11 +924,34 @@ Mitte aegunud mine'itud jääk + Total: + Kokku: + + Recent transactions Hiljutised tehingud + PaymentServer + + Payment request error + Maksepäringu tõrge + + + Payment request rejected + Maksepäring tagasi lükatud + + + Payment request expired. + Maksepäring aegunud. + + + Unverified payment requests to custom payment scripts are unsupported. + Kinnitamata maksepäringud kohandatud makse scriptidele ei ole toetatud. + + + PeerTableModel @@ -540,6 +966,13 @@ + QRImageWidget + + Save QR Code + Salvesta QR Kood + + + RPCConsole N/A @@ -562,6 +995,10 @@ Üldine + Using BerkeleyDB version + Kasutab BerkeleyDB versiooni + + Startup time Käivitamise hetk @@ -586,6 +1023,10 @@ Plokkide hetkearv + Memory usage + Mälu kasutus + + Received Vastuvõetud @@ -602,6 +1043,14 @@ Versioon + Synced Headers + Sünkroniseeritud Päised + + + Synced Blocks + Sünkroniseeritud Plokid + + Services Teenused @@ -619,7 +1068,7 @@ Debug log file - Debugimise logifail + Silumise logifail Clear console @@ -649,7 +1098,27 @@ %1 GB %1 GB - + + Inbound + Sisenev + + + Outbound + Väljuv + + + Yes + Jah + + + No + Ei + + + Unknown + Teadmata + + ReceiveCoinsDialog @@ -665,6 +1134,10 @@ &Sõnum: + Clear all fields of the form. + Puhasta kõik vormi väljad. + + Show Näita @@ -672,13 +1145,76 @@ Remove Eemalda + + Copy label + Kopeeri märgis + + + Copy message + Kopeeri sõnum + + + Copy amount + Kopeeri summa + ReceiveRequestDialog + QR Code + QR Kood + + Copy &Address &Kopeeri Aadress + + Payment information + Makse Informatsioon + + + Address + Aadress + + + Amount + Summa + + + Label + Silt + + + Message + Sõnum + + + Resulting URI too long, try to reduce the text for label / message. + URI liiga pikk, proovi vähendada märke / sõnumi pikkust. + + + + RecentRequestsTableModel + + Date + Kuupäev + + + Label + Silt + + + Message + Sõnum + + + (no label) + (märge puudub) + + + (no message) + (sõnum puudub) + SendCoinsDialog @@ -687,6 +1223,14 @@ Müntide saatmine + Inputs... + Sisendid... + + + automatically selected + automaatselt valitud + + Insufficient funds! Liiga suur summa @@ -695,14 +1239,30 @@ Kogus: + Bytes: + Baiti: + + Amount: Summa: + Priority: + Prioriteet + + Fee: Tasu: + After Fee: + Peale tehingutasu: + + + Change: + Vahetusraha: + + Transaction Fee: Tehingu tasu: @@ -711,6 +1271,10 @@ Vali... + per kilobyte + kilobaidi kohta + + Hide Peida @@ -719,6 +1283,10 @@ Soovitatud: + Confirmation time: + Kinnitamise aeg: + + normal normaalne @@ -735,6 +1303,14 @@ Lisa &Saaja + Clear all fields of the form. + Puhasta kõik vormi väljad. + + + Dust: + Puru: + + Clear &All Puhasta &Kõik @@ -750,6 +1326,62 @@ S&end S&aada + + Copy quantity + Kopeeri kogus + + + Copy amount + Kopeeri summa + + + Copy fee + Kopeeri tehingutasu + + + Copy bytes + Kopeeri baidid + + + Copy priority + Kopeeri prioriteet + + + Copy dust + Kopeeri puru + + + Copy change + Kopeeri vahetusraha + + + Are you sure you want to send? + Oled kindel, et soovid saata? + + + added as transaction fee + lisatud kui tehingutasu + + + or + või + + + The recipient address is not valid. Please recheck. + Saaja aadress ei ole korrektne. Palun kontrolli üle. + + + Payment request expired. + Maksepäring aegunud. + + + Warning: Invalid Bitcoin address + Hoiatus: Ebakorrektne Bitcoin aadress + + + (no label) + (märgis puudub) + SendCoinsEntry @@ -766,6 +1398,10 @@ &Märgis + Choose previously used address + Vali eelnevalt kasutatud aadress + + Alt+A Alt+A @@ -778,6 +1414,10 @@ Alt+P + S&ubtract fee from amount + L&ahuta tehingutasu summast + + Message: Sõnum: @@ -787,8 +1427,23 @@ + SendConfirmationDialog + + Yes + Jah + + + ShutdownWindow - + + %1 is shutting down... + %1 lülitub välja... + + + Do not shut down the computer until this window disappears. + Ära lülita arvutit välja ennem kui see aken on kadunud. + + SignVerifyMessageDialog @@ -800,6 +1455,14 @@ &Allkirjastamise teade + The Bitcoin address to sign the message with + Bitcoin aadress millega sõnum allkirjastada + + + Choose previously used address + Vali eelnevalt kasutatud aadress + + Alt+A Alt+A @@ -844,6 +1507,10 @@ &Kinnita Sõnum + The Bitcoin address the message was signed with + Bitcoin aadress millega sõnum on allkirjastatud + + Verify the message to ensure it was signed with the specified Bitcoin address Kinnita sõnum tõestamaks selle allkirjastatust määratud Bitcoini aadressiga. @@ -855,6 +1522,54 @@ Reset all verify message fields Tühjenda kõik sõnumi kinnitamise väljad + + Click "Sign Message" to generate signature + Allkirja loomiseks vajuta "Allkirjasta Sõnum" + + + The entered address is invalid. + Sisestatud aadress ei ole korrektne + + + Please check the address and try again. + Palun kontrolli aadressi ja proovi uuesti. + + + Wallet unlock was cancelled. + Rahakoti lahtilukustamine on katkestatud. + + + Private key for the entered address is not available. + Sisestatud aadressi privaatvõti pole saadaval. + + + Message signing failed. + Sõnumi allkirjastamine ebaõnnestus. + + + Message signed. + Sõnum allkirjastatud + + + The signature could not be decoded. + Allkirja polnud võimalik dekodeerida. + + + Please check the signature and try again. + Palun kontrolli allkirja ja proovi uuesti. + + + The signature did not match the message digest. + Allkiri ei vastanud sõnumi krüptoräsile. + + + Message verification failed. + Sõnumi verifitseerimine ebaõnnestus. + + + Message verified. + Sõnum verifitseeritud. + SplashScreen @@ -871,16 +1586,190 @@ + TransactionDesc + + %1/unconfirmed + %1/kinnitamata + + + %1 confirmations + %1 kinnitust + + + Status + Olek + + + Date + Kuupäev + + + Generated + Genereeritud + + + label + märgis + + + not accepted + pole vastu võetud + + + Transaction fee + Tehingutasu + + + Message + Sõnum + + + Comment + Kommentaar + + + Merchant + Kaupleja + + + Inputs + Sisendid + + + Amount + Summa + + + true + tõene + + + false + väär + + + TransactionDescDialog This pane shows a detailed description of the transaction Paan kuvab tehingu detailid - + + + TransactionTableModel + + Date + Kuupäev + + + Type + Tüüp + + + Label + Silt + + + Unconfirmed + Kinnitamata + + + (no label) + (silt puudub) + + + + TransactionView + + All + Kõik + + + Today + Täna + + + This week + Käesolev nädal + + + This month + Käesolev kuu + + + Last month + Eelmine kuu + + + This year + Käesolev aasta + + + Range... + Vahemik... + + + Min amount + Minimaalne summa + + + Copy address + Kopeeri aadress + + + Copy label + Kopeeri märgis + + + Copy amount + Kopeeri summa + + + Copy transaction ID + Kopeeri tehingu ID + + + Comma separated file (*.csv) + Komadega eraldatud väärtuste fail (*.csv) + + + Date + Kuupäev + + + Type + Tüüp + + + Label + Silt + + + Address + Aadress + + + ID + ID + + + Exporting Failed + Eksport ebaõnnestus. + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_eu_ES.ts b/src/qt/locale/bitcoin_eu_ES.ts index cbe246f4438..51ee5b0b8ab 100644 --- a/src/qt/locale/bitcoin_eu_ES.ts +++ b/src/qt/locale/bitcoin_eu_ES.ts @@ -41,7 +41,10 @@ &Delete &Ezabatu - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Errepikatu pasahitz berria - + BanTableModel @@ -184,7 +187,7 @@ &Address &Helbidea - + FreespaceChecker @@ -212,6 +215,9 @@ + PaymentServer + + PeerTableModel @@ -222,6 +228,9 @@ + QRImageWidget + + RPCConsole @@ -247,6 +256,9 @@ + RecentRequestsTableModel + + SendCoinsDialog Send Coins @@ -305,6 +317,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -333,16 +348,34 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Panel honek transakzioaren deskribapen xehea erakusten du - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_fa.ts b/src/qt/locale/bitcoin_fa.ts index 98543ded461..5a31ff591a7 100644 --- a/src/qt/locale/bitcoin_fa.ts +++ b/src/qt/locale/bitcoin_fa.ts @@ -41,6 +41,49 @@ &Delete &حذف + + Choose the address to send coins to + آدرس مورد نظر برای ارسال کوین ها را انتخاب کنید + + + Choose the address to receive coins with + آدرس موردنظر برای دریافت کوین ها را انتخاب کنید. + + + C&hoose + انتخاب + + + Sending addresses + آدرس های فرستنده + + + Receiving addresses + آدرس های گیرنده + + + Copy &Label + کپی و برچسب‌&گذاری + + + &Edit + &ویرایش + + + + AddressTableModel + + Label + برچسب + + + Address + آدرس + + + (no label) + (بدون برچسب) + AskPassphraseDialog @@ -60,6 +103,54 @@ Repeat new passphrase تکرار گذرواژهٔ جدید + + Encrypt wallet + رمزنگاری کیف پول + + + Unlock wallet + باز کردن قفل کیف پول + + + Decrypt wallet + رمزگشایی کیف پول + + + Confirm wallet encryption + تأیید رمزنگاری کیف پول + + + Are you sure you wish to encrypt your wallet? + آیا مطمئن هستید که می‌خواهید کیف پول خود را رمزنگاری کنید؟ + + + Wallet encrypted + کیف پول رمزنگاری شد + + + Wallet encryption failed + رمزنگاری کیف پول با شکست مواجه شد + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + رمزنگاری کیف پول بنا به یک خطای داخلی با شکست مواجه شد. کیف پول شما رمزنگاری نشد. + + + Wallet unlock failed + بازگشایی قفل کیف‌پول با شکست مواجه شد + + + Wallet decryption failed + رمزگشایی کیف پول با شکست مواجه شد + + + Wallet passphrase was successfully changed. + گذرواژهٔ کیف پول با موفقیت عوض شد. + + + Warning: The Caps Lock key is on! + هشدار: کلید Caps Lock روشن است! + BanTableModel @@ -131,6 +222,10 @@ &تنظیمات... + Modify configuration options for %1 + تغییر تنظیمات %1 + + &Encrypt Wallet... &رمزنگاری کیف پول... @@ -235,6 +330,10 @@ نوارابزار برگه‌ها + Request payments (generates QR codes and bitcoin: URIs) + درخواست پرداخت ( تولید کد کیوار و ادرس بیت کوین) + + Show the list of used sending addresses and labels نمایش لیست آدرس های ارسال و لیبل ها @@ -243,6 +342,10 @@ نمایش لیست آدرس های دریافت و لیبل ها + Open a bitcoin: URI or payment request + بازکردن یک بیت کوین: آدرس یا درخواست پرداخت + + &Command-line options گزینه‌های خط‌فرمان @@ -251,10 +354,18 @@ %n ارتباط فعال با شبکهٔ بیت‌کوین + Processing blocks on disk... + پردازش بلوک‌ها روی دیسک... + + No block source available... منبعی برای دریافت بلاک در دسترس نیست... + Processed %n block(s) of transaction history. + پردازش %n بلاک از تاریخچه ی تراکنش ها + + %n hour(s) %n ساعت @@ -427,6 +538,98 @@ Priority اولویت + + Copy label + کپی برچسب + + + Copy amount + کپی مقدار + + + Copy transaction ID + کپی شناسهٔ تراکنش + + + Lock unspent + قفل کردن خرج نشده ها + + + Unlock unspent + بازکردن قفل خرج نشده ها + + + Copy quantity + کپی تعداد + + + highest + بیشترین + + + higher + بیشتر + + + high + زیاد + + + medium-high + متوسط رو به بالا + + + medium + متوسط + + + low-medium + متوسط متمایل به کم + + + low + کم + + + lower + کمتر + + + lowest + کمترین + + + (%1 locked) + (%1 قفل شده) + + + none + هیچکدام + + + yes + بله + + + no + خیر + + + This label turns red if the transaction size is greater than 1000 bytes. + اگر حجم تراکنش از 1000 بایت بیشتر شود برچسب قرمز می شود. + + + Can vary +/- 1 byte per input. + ممکن است +/- 1 بایت در ورودی تفاوت داشته باشد. + + + (no label) + (بدون برچسب) + + + (change) + (تغییر) + EditAddressDialog @@ -442,7 +645,35 @@ &Address &نشانی - + + New receiving address + نشانی گیرنده جدید + + + New sending address + نشانی فرستنده جدید + + + Edit receiving address + ویرایش آدرس گیرنده + + + Edit sending address + ویرایش آدرس قرستنده + + + The entered address "%1" is not a valid Bitcoin address. + نشانی وارد شده "%1" یک نشانی معتبر بیت‌کوین نیست. + + + The entered address "%1" is already in the address book. + نشانی وارد شده «%1» در حال حاضر در دفترچه وجود دارد. + + + Could not unlock wallet. + نمی‌توان کیف پول را رمزگشایی کرد. + + FreespaceChecker @@ -488,6 +719,26 @@ command-line options گزینه‌های خط فرمان + + UI Options: + گزینه‌های رابط کاربری: + + + Set language, for example "de_DE" (default: system locale) + زبان را تنظیم کنید؛ برای مثال «de_DE» (پیشفرض: زبان سیستم) + + + Start minimized + شروع برنامه به صورت کوچک‌شده + + + Set SSL root certificates for payment request (default: -system-) + تنظیم گواهی ریشه SSl برای درخواست پرداخت (پیشفرض: -system-) + + + Show splash screen on startup (default: %u) + نمایش پنجرهٔ خوشامدگویی در ابتدای اجرای برنامه (پیش‌فرض: %u) + Intro @@ -522,6 +773,18 @@ Open URI بازکردن آدرس + + Open payment request from URI or file + بازکردن درخواست پرداخت از آدرس یا فایل + + + URI: + آدرس اینترنتی: + + + Select payment request file + انتخاب فایل درخواست پرداخت + OptionsDialog @@ -534,6 +797,14 @@ &عمومی + Automatically start %1 after logging in to the system. + اجرای خودکار %1 بعد زمان ورود به سیستم. + + + MB + مگابایت + + Accept connections from outside پذیرش اتصالات از بیرون @@ -673,6 +944,10 @@ تراز علی‌الحساب شما + Pending: + در انتظار: + + Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance مجموع تراکنش‌هایی که هنوز تأیید نشده‌اند؛ و هنوز روی تراز علی‌الحساب اعمال نشده‌اند @@ -706,6 +981,9 @@ + PaymentServer + + PeerTableModel Ping Time @@ -719,6 +997,10 @@ مبلغ + Enter a Bitcoin address (e.g. %1) + یک آدرس بیت‌کوین وارد کنید (مثلاً %1) + + %1 d %1 روز @@ -748,6 +1030,9 @@ + QRImageWidget + + RPCConsole N/A @@ -794,6 +1079,10 @@ تعداد فعلی بلوک‌ها + Memory Pool + استخر حافظه + + Memory usage مصرف حافظه @@ -814,6 +1103,14 @@ سرویس ها + Connection Time + مدت اتصال + + + Last Send + ارسال شده آخرین بار + + Last Receive آخرین دریافتی @@ -909,6 +1206,14 @@ پیام: + Use this form to request payments. All fields are <b>optional</b>. + برای درخواست پرداخت از این فرم استفاده کنید.تمام قسمت ها <b>اختیاری<b> هستند. + + + Clear all fields of the form. + تمام قسمت های فرم را خالی کن. + + Clear پاک‌کردن @@ -917,9 +1222,21 @@ نمایش + Remove the selected entries from the list + حذف ورودی های انتخاب‌شده از لیست + + Remove حذف کردن + + Copy label + کپی برچسب + + + Copy amount + کپی مقدار + ReceiveRequestDialog @@ -935,7 +1252,26 @@ &Save Image... &ذخیره عکس... - + + Address + آدرس + + + Label + برچسب + + + + RecentRequestsTableModel + + Label + برچسب + + + (no label) + (بدون برچسب) + + SendCoinsDialog @@ -943,6 +1279,14 @@ ارسال سکه + Inputs... + ورودی‌ها... + + + automatically selected + به طور خودکار انتخاب شدند + + Insufficient funds! بود جه نا کافی @@ -979,10 +1323,22 @@ هزینهٔ تراکنش: + Choose... + انتخاب... + + + per kilobyte + در هر کیلوبایت + + Hide پنهان کردن + total at least + در مجموع حداقل + + Recommended: توصیه شده: @@ -1011,6 +1367,10 @@ &دریافت‌کنندهٔ جدید + Clear all fields of the form. + تمام قسمت های فرم را خالی کن. + + Clear &All پاکسازی &همه @@ -1026,6 +1386,18 @@ S&end &ارسال + + Copy quantity + کپی تعداد + + + Copy amount + کپی مقدار + + + (no label) + (بدون برچسب) + SendCoinsEntry @@ -1081,7 +1453,10 @@ Memo: یادداشت: - + + + SendConfirmationDialog + ShutdownWindow @@ -1167,7 +1542,7 @@ Reset all verify message fields بازنشانی تمام فیلدهای پیام - + SplashScreen @@ -1183,16 +1558,62 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction این پانل شامل توصیف کاملی از جزئیات تراکنش است - + + + TransactionTableModel + + Label + برچسب + + + (no label) + (بدون برچسب) + + + + TransactionView + + Copy label + کپی برچسب + + + Copy amount + کپی مقدار + + + Copy transaction ID + کپی شناسهٔ تراکنش + + + Label + برچسب + + + Address + آدرس + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: @@ -1371,6 +1792,10 @@ بار گیری آدرس ها + (default: %s) + (پیش‌فرض %s) + + Invalid -proxy address: '%s' آدرس پراکسی اشتباه %s diff --git a/src/qt/locale/bitcoin_fa_IR.ts b/src/qt/locale/bitcoin_fa_IR.ts index 8faa3ce6592..64faca8fe8f 100644 --- a/src/qt/locale/bitcoin_fa_IR.ts +++ b/src/qt/locale/bitcoin_fa_IR.ts @@ -37,7 +37,10 @@ &Delete حذف - + + + AddressTableModel + AskPassphraseDialog @@ -56,7 +59,7 @@ Repeat new passphrase رمز/پَس فرِیز را دوباره وارد کنید - + BanTableModel @@ -224,7 +227,7 @@ &Address حساب& - + FreespaceChecker @@ -288,6 +291,9 @@ + PaymentServer + + PeerTableModel @@ -298,6 +304,9 @@ + QRImageWidget + + RPCConsole Client version @@ -343,6 +352,9 @@ + RecentRequestsTableModel + + SendCoinsDialog Send Coins @@ -372,7 +384,7 @@ S&end و ارسال - + SendCoinsEntry @@ -411,7 +423,10 @@ Memo: یادداشت: - + + + SendConfirmationDialog + ShutdownWindow @@ -453,16 +468,34 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction این بخش جزئیات تراکنش را نشان می دهد - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: @@ -513,10 +546,6 @@ لود شدن آدرسها.. - Set minimum block size in bytes (default: %u) - تنظیم کمینه اندازه بلاک بر حسب بایت (پیش فرض: %u) - - Set the number of threads to service RPC calls (default: %d) تنظیم تعداد ریسمان ها برای سرویس دهی فراخوانی های RPC (پیش فرض: %d) diff --git a/src/qt/locale/bitcoin_fi.ts b/src/qt/locale/bitcoin_fi.ts index b7b3115e251..9f7974eee96 100644 --- a/src/qt/locale/bitcoin_fi.ts +++ b/src/qt/locale/bitcoin_fi.ts @@ -41,7 +41,10 @@ &Delete &Poista - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Toista uusi tunnuslause - + BanTableModel @@ -115,6 +118,10 @@ &Tietoja %1 + Show information about %1 + Näytä tietoa aiheesta %1 + + About &Qt Tietoja &Qt @@ -127,6 +134,10 @@ &Asetukset... + Modify configuration options for %1 + Muuta kohteen %1 kokoonpanoasetuksia + + &Encrypt Wallet... &Salaa lompakko... @@ -255,6 +266,14 @@ %n aktiivinen yhteys Bitcoin-verkkoon%n aktiivista yhteyttä Bitcoin-verkkoon + Indexing blocks on disk... + Ladataan lohkoindeksiä... + + + Processing blocks on disk... + Käsitellään lohkoja levyllä... + + No block source available... Lohkojen lähdettä ei saatavilla... @@ -311,6 +330,14 @@ Rahansiirtohistoria on ajan tasalla + Show the %1 help message to get a list with possible Bitcoin command-line options + Näytä %1 ohjeet saadaksesi listan mahdollisista Bitcoinin komentorivivalinnoista + + + %1 client + %1-asiakas + + Catching up... Saavutetaan verkkoa... @@ -439,7 +466,7 @@ Priority Prioriteetti - + EditAddressDialog @@ -462,7 +489,7 @@ &Address &Osoite - + FreespaceChecker @@ -497,6 +524,10 @@ (%1-bit) + About %1 + Tietoja %1 + + Command-line options Komentorivi parametrit @@ -532,7 +563,11 @@ Show splash screen on startup (default: %u) Näytä aloitusruutu käynnistyksen yhteydessä (oletus: %u) - + + Reset all settings changed in the GUI + Nollaa kaikki graafisen käyttöliittymän kautta tehdyt muutokset + + Intro @@ -540,6 +575,18 @@ Tervetuloa + Welcome to %1. + Tervetuloa %1 pariin. + + + As this is the first time the program is launched, you can choose where %1 will store its data. + Tämä on ensimmäinen kerta, kun %1 on käynnistetty, joten voit valita data-hakemiston paikan. + + + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 lataa ja tallentaa kopion Bitcoinin lohkoketjusta. Vähintään %2Gt dataa tullaan tallentamaan tähän hakemistoon, ja tarve kasvaa ajan myötä. Lompakko tullaan myös tallentamaan tähän hakemistoon. + + Use the default data directory Käytä oletuskansiota @@ -582,7 +629,7 @@ Select payment request file Valitse maksupyynnön tiedosto - + OptionsDialog @@ -594,6 +641,14 @@ &Yleiset + Automatically start %1 after logging in to the system. + Käynnistä %1 automaattisesti järjestelmään kirjautumisen jälkeen. + + + &Start %1 on system login + &Käynnistä %1 järjestelmään kirjautuessa + + Size of &database cache &Tietokannan välimuistin koko @@ -750,6 +805,10 @@ &Käyttöliittymän kieli + The user interface language can be set here. This setting will take effect after restarting %1. + Tässä voit määritellä käyttöliittymän kielen. Muutokset astuvat voimaan seuraavan kerran, kun %1 käynnistetään. + + &Unit to show amounts in: Yksikkö jona bitcoin-määrät näytetään @@ -874,6 +933,9 @@ + PaymentServer + + PeerTableModel User Agent @@ -928,6 +990,9 @@ + QRImageWidget + + RPCConsole N/A @@ -954,6 +1019,10 @@ Käyttää BerkeleyDB-versiota + Datadir + Data-hakemisto + + Startup time Käynnistysaika @@ -1038,6 +1107,18 @@ Käyttöliittymä + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + Avaa %1 -debug-loki tämänhetkisestä data-hakemistosta. Tämä voi viedä muutaman sekunnin suurille lokitiedostoille. + + + Decrease font size + Pienennä fontin kokoa + + + Increase font size + Suurenna fontin kokoa + + Services Palvelut @@ -1268,7 +1349,7 @@ Remove Poista - + ReceiveRequestDialog @@ -1287,7 +1368,10 @@ &Save Image... &Tallenna kuva - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1430,7 +1514,7 @@ S&end &Lähetä - + SendCoinsEntry @@ -1474,6 +1558,10 @@ Poista tämä alkio + 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. + Kulu vähennetään lähetettävästä määrästä. Saaja vastaanottaa vähemmän bitcoineja kuin merkitset Määrä-kenttään. Jos saajia on monia, kulu jaetaan tasan. + + S&ubtract fee from amount V&ähennä maksukulu määrästä @@ -1505,10 +1593,17 @@ Memo: Muistio: - + + + SendConfirmationDialog + ShutdownWindow + %1 is shutting down... + %1 sulkeutuu... + + Do not shut down the computer until this window disappears. Älä sammuta tietokonetta ennenkuin tämä ikkuna katoaa. @@ -1591,7 +1686,7 @@ Reset all verify message fields Tyhjennä kaikki varmista-viesti-kentät - + SplashScreen @@ -1607,12 +1702,21 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Tämä ruutu näyttää yksityiskohtaisen tiedon rahansiirrosta - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1621,6 +1725,15 @@ + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: @@ -1691,6 +1804,10 @@ Bitcoin-ydin + The %s developers + %s kehittäjät + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. -fallbackfee on asetettu erittäin suureksi! Tämä on rahansiirtokulu jonka voit maksaa kun arvioitu rahansirtokulu ei ole saatavilla. @@ -1699,14 +1816,34 @@ Kytkeydy annettuun osoitteeseen ja pidä linja aina auki. Käytä [host]:portin merkintätapaa IPv6:lle. + Cannot obtain a lock on data directory %s. %s is probably already running. + Ei voida lukita data-hakemistoa %s. %s on luultavasti jo käynnissä. + + + Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. + Jaettu MIT-ohjelmistolisenssin alla, katso mukana tullut tiedosto COPYING tai <http://www.opensource.org/licenses/mit-license.php>. + + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Suorita käsky kun lompakossa rahansiirto muuttuu (%s cmd on vaihdettu TxID kanssa) + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + Tarkistathan että tietokoneesi päivämäärä ja kellonaika ovat oikeassa! Jos kellosi on väärässä, %s ei toimi oikein. + + + Please contribute if you find %s useful. Visit %s for further information about the software. + Ole hyvä ja avusta, jos %s on mielestäsi hyödyllinen. Vieraile %s saadaksesi lisää tietoa ohjelmistosta. + + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Aseta script varmistuksen threadien lukumäärä (%u - %d, 0= auto, <0 = jätä näin monta ydintä vapaaksi, oletus: %d) + 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 + Lohkotietokanta sisältää lohkon, joka vaikuttaa olevan tulevaisuudesta. Tämä saattaa johtua tietokoneesi virheellisesti asetetuista aika-asetuksista. Rakenna lohkotietokanta uudelleen vain jos olet varma, että tietokoneesi päivämäärä ja aika ovat oikein. + + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Tämä on esi-julkaistu testiversio - Käytä omalla riskillä - Ei saa käytää louhimiseen tai kauppasovelluksiin. @@ -1727,6 +1864,14 @@ Salli vertaisten yhdistää annetusta verkkomaskista tai IP-osoitteesta. Voidaan määrittää useampia kertoja. + You need to rebuild the database using -reindex-chainstate to change -txindex + Sinun tulee uudelleenrakentaa tietokanta käyttäen -reindex-chainstate vaihtaaksesi -txindex + + + %s corrupt, salvage failed + %s korruptoitunut, korjaaminen epäonnistui + + -maxmempool must be at least %d MB -maxmempool on oltava vähintään %d MB @@ -1735,10 +1880,18 @@ <category> voi olla: + Attempt to recover private keys from a corrupt wallet on startup + Yritä palauttaa yksityiset avaimet korruptoituneesta lompakosta käynnistyksen yhteydessä + + Block creation options: Lohkon luonnin asetukset: + Cannot resolve -%s address: '%s' + -%s -osoitteen '%s' selvittäminen epäonnistui + + Connect only to the specified node(s) Yhidstä ainoastaan määrättyihin noodeihin @@ -1747,6 +1900,10 @@ Yhteyden valinnat: + Copyright (C) %i-%i + Tekijänoikeus (C) %i-%i + + Corrupted block database detected Vioittunut lohkotietokanta havaittu @@ -1775,6 +1932,18 @@ Virhe alustaessa lompakon tietokantaympäristöä %s! + Error loading %s + Virhe ladattaessa %s + + + Error loading %s: Wallet corrupted + Virhe ladattaessa %s: Lompakko vioittunut + + + Error loading %s: Wallet requires newer version of %s + Virhe ladattaessa %s: Tarvitset uudemman %s -version + + Error loading block database Virhe avattaessa lohkoketjua @@ -1803,6 +1972,22 @@ Virheellinen -onion osoite: '%s' + Invalid amount for -%s=<amount>: '%s' + Virheellinen määrä -%s=<amount>: '%s' + + + Invalid amount for -fallbackfee=<amount>: '%s' + Virheellinen määrä -fallbackfee=<amount>: '%s' + + + Loading banlist... + Ladataan kieltolistaa... + + + Location of the auth cookie (default: data dir) + Todennusevästeen sijainti (oletus: datahakemisto) + + Not enough file descriptors available. Ei tarpeeksi tiedostomerkintöjä vapaana. @@ -1811,6 +1996,14 @@ Yhdistä vain solmukohtiin <net>-verkossa (ipv4, ipv6 tai onion) + Print this help message and exit + Näytä tämä ohjeviesti ja poistu + + + Print version and exit + Näytä versio ja poistu. + + Prune mode is incompatible with -txindex. Karsittu tila ei ole yhteensopiva -txindex:n kanssa. @@ -1819,6 +2012,10 @@ Aseta tietokannan välimuistin koko megatavuissa (%d - %d, oletus: %d + Set maximum BIP141 block weight (default: %d) + Aseta suurin BIP141-lohkopaino (oletus: %d) + + Set maximum block size in bytes (default: %d) Aseta lohkon maksimikoko tavuissa (oletus: %d) @@ -1827,6 +2024,22 @@ Aseta lompakkotiedosto (data-hakemiston sisällä) + The source code is available from %s. + Lähdekoodi löytyy %s. + + + Unsupported argument -benchmark ignored, use -debug=bench. + Argumenttia -benchmark ei tueta, käytä -debug=bench. + + + Unsupported argument -debugnet ignored, use -debug=net. + Argumenttia -debugnet ei tueta, käytä -debug=net. + + + Unsupported argument -tor found, use -onion. + Argumenttia -tor ei tueta, käytä -onion. + + Use UPnP to map the listening port (default: %u) Käytä UPnP:ta kuuntelevan portin kartoittamiseen (oletus: %u) @@ -1843,6 +2056,10 @@ Lompakko %s sijaitsee data-hakemiston ulkopuolella %s + Wallet needed to be rewritten: restart %s to complete + Lompakko tarvitsee uudelleenkirjoittaa: käynnistä %s uudelleen + + Wallet options: Lompakon valinnat: @@ -1855,6 +2072,10 @@ Paljasta omat IP-osoitteet (oletus: 1 kun kuunnellaan ja -externalip tai -proxy ei ole käytössä) + Error: Listening for incoming connections failed (listen returned error %s) + Virhe: Saapuvien yhteyksien kuuntelu epäonnistui (kuuntelu palautti virheen %s) + + Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Aja komento kun olennainen hälytys vastaanotetaan tai nähdään todella pitkä haara (%s komennossa korvataan viestillä) @@ -1863,6 +2084,14 @@ Aseta maksimikoko korkea prioriteetti/pieni palkkio rahansiirtoihin tavuissa (oletus: %d) + The transaction amount is too small to send after the fee has been deducted + Siirtomäärä on liian pieni lähetettäväksi kulun vähentämisen jälkeen. + + + 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. + Tämä tuote sisältää ohjelmistoa, jonka on kehittänyt OpenSSL Project käytettäväksi OpenSSL Toolkit -ohjelmistossa <https://www.openssl.org/>, ja Eric Youngin kirjoittamaa salausohjelmistoa sekä Thomas Bernardin kirjoittamaa UPnP-ohjelmistoa. + + (default: %u) (oletus: %u) @@ -1871,6 +2100,10 @@ Hyväksy julkisia REST-pyyntöjä (oletus: %u) + Automatically create Tor hidden service (default: %d) + Luo Tor-salattu palvelu automaattisesti (oletus: %d) + + Connect through SOCKS5 proxy Yhdistä SOCKS5 proxin kautta @@ -1879,14 +2112,30 @@ Virheitä tietokantaa luettaessa, ohjelma pysäytetään. + Imports blocks from external blk000??.dat file on startup + Tuo lohkot ulkoisesta blk000??.dat -tiedostosta käynnistettäessä + + Information Tietoa + Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) + Kelvoton määrä argumentille -paytxfee=<amount>: '%s' (pitää olla vähintään %s) + + + Invalid netmask specified in -whitelist: '%s' + Kelvoton verkkopeite määritelty argumentissa -whitelist: '%s' + + Keep at most <n> unconnectable transactions in memory (default: %u) Pidä enimmillään <n> yhdistämiskelvotonta rahansiirtoa muistissa (oletus: %u) + Need to specify a port with -whitebind: '%s' + Pitää määritellä portti argumentilla -whitebind: '%s' + + Node relay options: Välityssolmukohdan asetukset: @@ -2003,6 +2252,10 @@ Kuinka läpikäyvä lohkojen -checkblocks -todennus on (0-4, oletus: %u) + Output debugging information (default: %u, supplying <category> is optional) + Tulosta debuggaustieto (oletus: %u, annettu <category> valinnainen) + + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Käytä erillistä SOCKS5-proxyä tavoittaaksesi vertaisia Tor-piilopalveluiden kautta (oletus: %s) @@ -2067,10 +2320,6 @@ Aseta avainaltaan kooksi <n> (oletus: %u) - Set minimum block size in bytes (default: %u) - Aseta pienin mahdollinen lohkokoko tavuina (oletus: %u) - - Set the number of threads to service RPC calls (default: %d) Aseta RPC-kutsujen palvelemiseen tarkoitettujen säikeiden lukumäärä (oletus: %d) diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts index 0b538d76642..30a9fa3c0c5 100644 --- a/src/qt/locale/bitcoin_fr.ts +++ b/src/qt/locale/bitcoin_fr.ts @@ -41,6 +41,77 @@ &Delete &Supprimer + + Choose the address to send coins to + Choisir l'adresse à laquelle envoyer des pièces + + + Choose the address to receive coins with + Choisir l'adresse avec laquelle recevoir des pîèces + + + C&hoose + C&hoisir + + + Sending addresses + Adresses d'envoi + + + Receiving addresses + Adresses de réception + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Voici vos adresses Bitcoin pour envoyer des paiements. Vérifiez toujours le montant et l'adresse du destinataire avant d'envoyer des pièces. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Voici vos adresses Bitcoin pour recevoir des paiements. Il est recommandé d'utiliser une nouvelle adresse de réception pour chaque transaction. + + + &Copy Address + &Copier l'adresse + + + Copy &Label + Copier l'é&tiquette + + + &Edit + &Modifier + + + Export Address List + Exporter la liste d'adresses + + + Comma separated file (*.csv) + Valeurs séparées par des virgules (*.csv) + + + Exporting Failed + Échec d'exportation + + + There was an error trying to save the address list to %1. Please try again. + Une erreur est survenue lors de l'enregistrement de la liste d'adresses vers %1. Veuillez ressayer plus tard. + + + + AddressTableModel + + Label + Étiquette + + + Address + Adresse + + + (no label) + (aucune étiquette) + AskPassphraseDialog @@ -60,6 +131,94 @@ Repeat new passphrase Répéter la phrase de passe + + 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>. + Saisissez la nouvelle phrase de passe du porte-monnaie.<br/>Veuillez utiliser une phrase de passe composée de <b>dix caractères aléatoires ou plus</b>, ou de <b>huit mots ou plus</b>. + + + Encrypt wallet + Chiffrer le porte-monnaie + + + This operation needs your wallet passphrase to unlock the wallet. + Cette opération nécessite votre phrase de passe pour déverrouiller le porte-monnaie. + + + Unlock wallet + Déverrouiller le porte-monnaie + + + This operation needs your wallet passphrase to decrypt the wallet. + Cette opération nécessite votre phrase de passe pour déchiffrer le porte-monnaie. + + + Decrypt wallet + Déchiffrer le porte-monnaie + + + Change passphrase + Changer la phrase de passe + + + Enter the old passphrase and new passphrase to the wallet. + Saisir l'ancienne puis la nouvelle phrase de passe du porte-monnaie. + + + Confirm wallet encryption + Confirmer le chiffrement du porte-monnaie + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Avertissement : si vous chiffrez votre porte-monnaie et perdez votre phrase de passe, vous <b>PERDREZ TOUS VOS BITCOINS</b> ! + + + Are you sure you wish to encrypt your wallet? + Voulez-vous vraiment chiffrer votre porte-monnaie ? + + + Wallet encrypted + Le porte-monnaie est chiffré + + + %1 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. + %1 va maintenant se fermer pour terminer le processus de chiffrement. Souvenez-vous que le chiffrement de votre porte-monnaie ne peut pas protéger entièrement vos bitcoins contre le vol par des logiciels malveillants qui infecteraient votre ordinateur. + + + 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. + IMPORTANT : toutes les sauvegardes précédentes du fichier de votre porte-monnaie devraient être remplacées par le fichier du porte-monnaie chiffré nouvellement généré. Pour des raisons de sécurité, les sauvegardes précédentes de votre fichier de porte-monnaie non chiffré deviendront inutilisables dès que vous commencerez à utiliser le nouveau porte-monnaie chiffré. + + + Wallet encryption failed + Échec de chiffrement du porte-monnaie + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Le chiffrement du porte-monnaie a échoué en raison d'une erreur interne. Votre porte-monnaie n'a pas été chiffré. + + + The supplied passphrases do not match. + Les phrases de passe saisies ne correspondent pas. + + + Wallet unlock failed + Échec de déverrouillage du porte-monnaie + + + The passphrase entered for the wallet decryption was incorrect. + La phrase de passe saisie pour déchiffrer le porte-monnaie était erronée. + + + Wallet decryption failed + Échec de déchiffrement du porte-monnaie + + + Wallet passphrase was successfully changed. + La phrase de passe du porte-monnaie a été modifiée avec succès. + + + Warning: The Caps Lock key is on! + Avertissement : la touche Verr. Maj. est activée ! + BanTableModel @@ -76,11 +235,11 @@ BitcoinGUI Sign &message... - &Signer le message... + Signer un &message... Synchronizing with network... - Synchronisation avec le réseau en cours… + Synchronisation avec le réseau… &Overview @@ -100,7 +259,7 @@ Browse transaction history - Parcourir l'historique des transactions + Parcourir l'historique transactionnel E&xit @@ -156,7 +315,7 @@ Open &URI... - Ouvrir un &URI... + Ouvrir une &URI... Reindexing blocks on disk... @@ -204,15 +363,15 @@ &Show / Hide - &Afficher / Cacher + &Afficher / cacher Show or hide the main Window - Afficher ou masquer la fenêtre principale + Afficher ou cacher la fenêtre principale Encrypt the private keys that belong to your wallet - Chiffrer les clefs privées de votre porte-monnaie + Chiffrer les clés privées qui appartiennent à votre porte-monnaie Sign messages with your Bitcoin addresses to prove you own them @@ -220,7 +379,7 @@ Verify messages to ensure they were signed with specified Bitcoin addresses - Vérifier les messages pour vous assurer qu'ils ont été signés avec les adresses Bitcoin spécifiées + Vérifier les messages pour s'assurer qu'ils ont été signés avec les adresses Bitcoin spécifiées &File @@ -228,7 +387,7 @@ &Settings - &Réglages + &Paramètres &Help @@ -240,7 +399,7 @@ Request payments (generates QR codes and bitcoin: URIs) - Demander des paiements (génère des codes QR et des URIs bitcoin:) + Demander des paiements (génère des codes QR et des URI bitcoin:) Show the list of used sending addresses and labels @@ -252,7 +411,7 @@ Open a bitcoin: URI or payment request - Ouvrir un URI bitcoin: ou une demande de paiement + Ouvrir une URI bitcoin: ou une demande de paiement &Command-line options @@ -300,7 +459,7 @@ %1 behind - %1 en retard + en retard de %1 Last received block was generated %1 ago. @@ -308,7 +467,7 @@ Transactions after this will not yet be visible. - Les transactions après ceci ne sont pas encore visibles. + Les transactions suivantes ne seront pas déjà visibles. Error @@ -336,7 +495,7 @@ Catching up... - Rattrapage en cours… + Rattrapage… Date: %1 @@ -425,7 +584,7 @@ (un)select all - Tout (dé)sélectionner + Tout (des)sélectionner Tree mode @@ -463,6 +622,150 @@ Priority Priorité + + Copy address + Copier l’adresse + + + Copy label + Copier l’étiquette + + + Copy amount + Copier le montant + + + Copy transaction ID + Copier l'ID de la transaction + + + Lock unspent + Verrouiller les transactions non dépensées + + + Unlock unspent + Déverrouiller les transactions non dépensées + + + Copy quantity + Copier la quantité + + + Copy fee + Copier les frais + + + Copy after fee + Copier après les frais + + + Copy bytes + Copier les octets + + + Copy priority + Copier la priorité + + + Copy dust + Copier la poussière + + + Copy change + Copier la monnaie + + + highest + la plus élevée + + + higher + plus élevée + + + high + élevée + + + medium-high + moyenne-élevée + + + medium + moyenne + + + low-medium + faible-moyenne + + + low + faible + + + lower + plus faible + + + lowest + la plus faible + + + (%1 locked) + (%1 verrouillée) + + + none + aucune + + + yes + oui + + + no + non + + + This label turns red if the transaction size is greater than 1000 bytes. + Cette étiquette devient rouge si la taille de la transaction dépasse 1 000 octets. + + + This means a fee of at least %1 per kB is required. + Cela signifie que des frais d'au moins %1 sont exigés par Ko. + + + Can vary +/- 1 byte per input. + Peut varier +/- 1 octet par entrée. + + + Transactions with higher priority are more likely to get included into a block. + Les transactions à priorité élevée on plus de chance d'être incluses dans un bloc. + + + This label turns red if the priority is smaller than "medium". + Cette étiquette devient rouge si la priorité est plus basse que « moyenne ». + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Cette étiquette devient rouge si un destinataire reçoit un montant inférieur au seuil actuel de poussière. + + + Can vary +/- %1 satoshi(s) per input. + Peut varier +/- %1 satoshi(s) par entrée. + + + (no label) + (aucune étiquette) + + + change from %1 (%2) + monnaie de %1 (%2) + + + (change) + (monnaie) + EditAddressDialog @@ -472,7 +775,7 @@ &Label - &Étiquette + É&tiquette The label associated with this address list entry @@ -480,12 +783,44 @@ The address associated with this address list entry. This can only be modified for sending addresses. - L'adresse associée à cette entrée de la liste d'adresses. Ceci ne peut être modifié que pour les adresses d'envoi. + L'adresse associée à cette entrée de la liste d'adresses. Cela ne peut être modifié que pour les adresses d'envoi. &Address &Adresse + + New receiving address + Nouvelle adresse de réception + + + New sending address + Nouvelle adresse d’envoi + + + Edit receiving address + Modifier l’adresse de réception + + + Edit sending address + Modifier l’adresse d'envoi + + + The entered address "%1" is not a valid Bitcoin address. + L'adresse saisie « %1 » n'est pas une adresse Bitcoin valide. + + + The entered address "%1" is already in the address book. + L’adresse saisie « %1 » est déjà présente dans le carnet d'adresses. + + + Could not unlock wallet. + Impossible de déverrouiller le porte-monnaie. + + + New key generation failed. + Échec de génération de la nouvelle clé. + FreespaceChecker @@ -499,7 +834,7 @@ Directory already exists. Add %1 if you intend to create a new directory here. - Le répertoire existe déjà. Ajoutez %1 si vous voulez créer un nouveau répertoire ici. + Le répertoire existe déjà. Ajouter %1 si vous comptez créer un nouveau répertoire ici. Path already exists, and is not a directory. @@ -605,18 +940,18 @@ (of %n GB needed) - (sur %n Go nécessaire)(sur %n Go nécessaires) + (sur %n Go requis)(sur %n Go requis) OpenURIDialog Open URI - Ouvrir un URI + Ouvrir une URI Open payment request from URI or file - Ouvrir une demande de paiement à partir d'un URI ou d'un fichier + Ouvrir une demande de paiement à partir d'une URI ou d'un fichier URI: @@ -626,6 +961,10 @@ Select payment request file Choisir le fichier de demande de paiement + + Select payment request file to open + Choisir le fichier de demande de paiement à ouvrir + OptionsDialog @@ -635,7 +974,7 @@ &Main - Réglages &principaux + &Principaux Automatically start %1 after logging in to the system. @@ -655,7 +994,7 @@ Number of script &verification threads - Nombre d'exétrons de &vérification de script + Nombre de fils de &vérification de script Accept connections from outside @@ -667,7 +1006,7 @@ IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) - Adresse IP du mandataire (par ex. IPv4 : 127.0.0.1 / IPv6 : ::1) + Adresse IP du mandataire (p. ex. IPv4 : 127.0.0.1 / IPv6 : ::1) 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. @@ -675,7 +1014,7 @@ 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 |. - URL de tiers (par ex. un explorateur de blocs) apparaissant dans l'onglet des transactions comme éléments du menu contextuel. %s dans l'URL est remplacé par le hachage de la transaction. Les URL multiples sont séparées par une barre verticale |. + URL de tiers (p. ex. un explorateur de blocs) apparaissant dans l'onglet des transactions comme éléments du menu contextuel. %s dans l'URL est remplacé par le hachage de la transaction. Les URL multiples sont séparées par une barre verticale |. Third party transaction URLs @@ -691,7 +1030,7 @@ &Reset Options - &Réinitialisation des options + &Réinitialiser les options &Network @@ -711,11 +1050,11 @@ Enable coin &control features - Activer les fonctions de &contrôle des pièces + Activer les fonctions de &contrôle des pièces 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. - Si vous désactivé la dépense de la monnaie non confirmée, la monnaie d'une transaction ne peut pas être utilisée tant que cette transaction n'a pas reçu au moins une confirmation. Ceci affecte aussi comment votre solde est calculé. + Si vous désactivé la dépense de la monnaie non confirmée, la monnaie d'une transaction ne peut pas être utilisée tant que cette transaction n'a pas reçu au moins une confirmation. Celai affecte aussi le calcul de votre solde. &Spend unconfirmed change @@ -723,7 +1062,7 @@ Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. - Ouvrir le port du client Bitcoin automatiquement sur le routeur. Ceci ne fonctionne que si votre routeur supporte l'UPnP et si la fonctionnalité est activée. + Ouvrir automatiquement le port du client Bitcoin sur le routeur. Cela ne fonctionne que si votre routeur prend en charge l'UPnP et si la fonction est activée. Map port using &UPnP @@ -739,7 +1078,7 @@ Proxy &IP: - &IP du serveur mandataire : + &IP du mandataire : &Port: @@ -747,7 +1086,7 @@ Port of the proxy (e.g. 9050) - Port du serveur mandataire (par ex. 9050) + Port du mandataire (p. ex. 9050) Used for reaching peers via: @@ -791,11 +1130,11 @@ Show only a tray icon after minimizing the window. - Afficher uniquement une icône système après minimisation. + N'afficher qu'une icône dans la zone de notification après minimisation. &Minimize to the tray instead of the taskbar - &Minimiser dans la barre système au lieu de la barre des tâches + &Minimiser dans la zone de notification au lieu de la barre des tâches M&inimize on close @@ -819,7 +1158,7 @@ Choose the default subdivision unit to show in the interface and when sending coins. - Choisissez la sous-unité par défaut pour l'affichage dans l'interface et lors de l'envoi de pièces. + Choisir la sous-unité par défaut d'affichage dans l'interface et lors d'envoi de pièces. Whether to show coin control features or not. @@ -847,7 +1186,7 @@ Client restart required to activate changes. - Le redémarrage du client est nécessaire pour activer les changements. + Le redémarrage du client est exigé pour activer les changements. Client will be shut down. Do you want to proceed? @@ -882,7 +1221,7 @@ Your current spendable balance - Votre solde actuel pouvant être dépensé + Votre solde actuel disponible Pending: @@ -890,7 +1229,7 @@ Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance - Total des transactions qui doivent encore être confirmées et qu'il n'est pas encore possible de dépenser + Total des transactions qui doivent encore être confirmées et qui ne sont pas prises en compte dans le solde disponible Immature: @@ -938,6 +1277,97 @@ + PaymentServer + + Payment request error + Erreur de demande de paiement + + + Cannot start bitcoin: click-to-pay handler + Impossible de démarrer le gestionnaire de cliquer-pour-payer bitcoin: + + + URI handling + Gestion des URI + + + Payment request fetch URL is invalid: %1 + L'URL de récupération de la demande de paiement est invalide : %1 + + + Invalid payment address %1 + Adresse de paiement invalide %1 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + L'URI ne peut pas être analysée ! Cela peut être causé par une adresse Bitcoin invalide ou par des paramètres d'URI mal formés. + + + Payment request file handling + Gestion des fichiers de demande de paiement + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + Le fichier de demande de paiement ne peut pas être lu ! Cela peut être causé par un fichier de demande de paiement invalide. + + + Payment request rejected + Demande de paiement rejetée + + + Payment request network doesn't match client network. + Le réseau de la demande de paiement ne correspond pas au réseau du client. + + + Payment request expired. + La demande de paiement a expiré + + + Payment request is not initialized. + La demande de paiement n'est pas initialisée. + + + Unverified payment requests to custom payment scripts are unsupported. + Les demandes de paiements non vérifiées vers des scripts de paiement personnalisés ne sont pas prises en charge. + + + Invalid payment request. + Demande de paiement invalide. + + + Requested payment amount of %1 is too small (considered dust). + Le paiement demandé d'un montant de %1 est trop faible (considéré comme de la poussière). + + + Refund from %1 + Remboursement de %1 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + La demande de paiement %1 est trop grande (%2 octets, %3 octets permis). + + + Error communicating with %1: %2 + Erreur de communication avec %1 : %2 + + + Payment request cannot be parsed! + La demande de paiement ne peut pas être analysée ! + + + Bad response from server %1 + Mauvaise réponse du serveur %1 + + + Network request error + Erreur de demande réseau + + + Payment acknowledged + Le paiement a été confirmé + + + PeerTableModel User Agent @@ -992,6 +1422,25 @@ + QRImageWidget + + &Save Image... + &Enregistrer l'image... + + + &Copy Image + &Copier l'image + + + Save QR Code + Enregistrer le code QR + + + PNG Image (*.png) + Image PNG (*.png) + + + RPCConsole N/A @@ -1107,7 +1556,7 @@ Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. - Ouvrir le journal de débogage de %1 depuis le répertoire de données actuel. Ceci peut prendre quelques secondes pour les journaux de grande taille. + Ouvrir le fichier journal de débogage de %1 à partir du répertoire de données actuel. Cela peut prendre quelques secondes pour les fichiers journaux de grande taille. Decrease font size @@ -1143,7 +1592,7 @@ The duration of a currently outstanding ping. - La durée d'un ping actuellement en cours. + La durée d'un ping en cours. Ping Wait @@ -1171,7 +1620,7 @@ &Clear - &Nettoyer + &Effacer Totals @@ -1187,11 +1636,11 @@ Debug log file - Journal de débogage + Fichier journal de débogage Clear console - Nettoyer la console + Effacer la console &Disconnect Node @@ -1227,7 +1676,7 @@ Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. - Utiliser les touches de curseur pour naviguer dans l'historique et <b>Ctrl-L</b> pour effacer l'écran. + Utiliser les touches de déplacement pour naviguer dans l'historique et <b>Ctrl-L</b> pour effacer l'écran. Type <b>help</b> for an overview of available commands. @@ -1298,7 +1747,7 @@ 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. - Réutilise une adresse de réception précédemment utilisée. Réutiliser une adresse pose des problèmes de sécurité et de vie privée. N'utilisez pas cette option sauf si vous générez à nouveau une demande de paiement déjà faite. + Réutiliser une adresse de réception utilisée précédemment. Réutiliser une adresse comporte des problèmes de sécurité et de confidentialité. À ne pas utiliser, sauf pour générer une demande de paiement faite au préalable. R&euse an existing receiving address (not recommended) @@ -1306,19 +1755,19 @@ 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. - Un message optionnel à joindre à la demande de paiement qui sera affiché à l'ouverture de celle-ci. Note : le message ne sera pas envoyé avec le paiement par le réseau Bitcoin. + Un message facultatif à joindre à la demande de paiement et qui sera affiché à l'ouverture de celle-ci. Note : le message ne sera pas envoyé avec le paiement par le réseau Bitcoin. An optional label to associate with the new receiving address. - Un étiquette optionnelle à associer à la nouvelle adresse de réception + Un étiquette facultative à associer à la nouvelle adresse de réception. Use this form to request payments. All fields are <b>optional</b>. - Utiliser ce formulaire pour demander des paiements. Tous les champs sont <b>optionnels</b>. + Utiliser ce formulaire pour demander des paiements. Tous les champs sont <b>facultatifs</b>. An optional amount to request. Leave this empty or zero to not request a specific amount. - Un montant optionnel à demander. Laisser ceci vide ou à zéro pour ne pas demander de montant spécifique. + Un montant facultatif à demander. Ne rien saisir ou un zéro pour ne pas demander de montant spécifique. Clear all fields of the form. @@ -1334,11 +1783,11 @@ &Request payment - &Demande de paiement + &Demander un paiement Show the selected request (does the same as double clicking an entry) - Afficher la demande choisie (identique à un double-clic sur une entrée) + Afficher la demande choisie (comme double-cliquer sur une entrée) Show @@ -1346,11 +1795,23 @@ Remove the selected entries from the list - Enlever les entrées sélectionnées de la liste + Retirer les entrées sélectionnées de la liste Remove - Enlever + Retirer + + + Copy label + Copier l’étiquette + + + Copy message + Copier le message + + + Copy amount + Copier le montant @@ -1369,42 +1830,109 @@ &Save Image... - &Sauvegarder l'image... + &Enregistrer l'image... - - - SendCoinsDialog - Send Coins - Envoyer des pièces + Request payment to %1 + Demande de paiement à %1 - Coin Control Features - Fonctions de contrôle des pièces + Payment information + Informations de paiement - Inputs... - Entrants... + URI + URI - automatically selected - choisi automatiquement + Address + Adresse - Insufficient funds! - Fonds insuffisants ! + Amount + Montant - Quantity: - Quantité : + Label + Étiquette - Bytes: - Octets : + Message + Message - Amount: - Montant : + Resulting URI too long, try to reduce the text for label / message. + L'URI résultante est trop longue. Essayez de réduire le texte de l'étiquette ou du message. + + + Error encoding URI into QR Code. + Erreur d'encodage de l'URI en code QR. + + + + RecentRequestsTableModel + + Date + Date + + + Label + Étiquette + + + Message + Message + + + (no label) + (aucune étiquette) + + + (no message) + (aucun message) + + + (no amount requested) + (aucun montant demandé) + + + Requested + Demandée + + + + SendCoinsDialog + + Send Coins + Envoyer des pièces + + + Coin Control Features + Fonctions de contrôle des pièces + + + Inputs... + Entrants... + + + automatically selected + choisi automatiquement + + + Insufficient funds! + Fonds insuffisants ! + + + Quantity: + Quantité : + + + Bytes: + Octets : + + + Amount: + Montant : Priority: @@ -1424,7 +1952,7 @@ If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address. - Si ceci est actif mais l'adresse de monnaie rendue est vide ou invalide, la monnaie sera envoyée vers une adresse nouvellement générée. + Si cette option est activée, et l'adresse de monnaie rendue est vide ou invalide, la monnaie sera envoyée vers une adresse nouvellement générée. Custom change address @@ -1460,7 +1988,7 @@ 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. - Il est correct de payer les frais minimum tant que le volume transactionnel est inférieur à l'espace dans les blocs. Mais soyez conscient que ceci pourrait résulter en une transaction n'étant jamais confirmée une fois qu'il y aura plus de transactions que le réseau ne pourra en traiter. + Il est correct de payer les frais minimum tant que le volume transactionnel est inférieur à l'espace dans les blocs. Mais soyez conscient que cela pourrait résulter en une transaction n'étant jamais confirmée une fois qu'il y aura plus de transactions que le réseau ne pourra en traiter. (read the tooltip) @@ -1476,7 +2004,7 @@ (Smart fee not initialized yet. This usually takes a few blocks...) - (Les frais intelligents ne sont pas encore initialisés. Ceci prend habituellement quelques blocs...) + (Les frais intelligents ne sont pas encore initialisés. Cela prend habituellement quelques blocs...) Confirmation time: @@ -1508,7 +2036,7 @@ Clear &All - &Tout nettoyer + &Tout effacer Balance: @@ -1522,6 +2050,114 @@ S&end E&nvoyer + + Copy quantity + Copier la quantité + + + Copy amount + Copier le montant + + + Copy fee + Copier les frais + + + Copy after fee + Copier après les frais + + + Copy bytes + Copier les octets + + + Copy priority + Copier la priorité + + + Copy dust + Copier la poussière + + + Copy change + Copier la monnaie + + + %1 to %2 + %1 à %2 + + + Are you sure you want to send? + Voulez-vous vraiment envoyer ? + + + added as transaction fee + ajoutés comme frais de transaction + + + Total Amount %1 + Montant total %1 + + + or + ou + + + Confirm send coins + Confirmer l’envoi de pièces + + + The recipient address is not valid. Please recheck. + L'adresse du destinataire est invalide. Veuillez la revérifier. + + + The amount to pay must be larger than 0. + Le montant à payer doit être supérieur à 0. + + + The amount exceeds your balance. + Le montant dépasse votre solde. + + + The total exceeds your balance when the %1 transaction fee is included. + Le montant dépasse votre solde lorsque les frais de transaction de %1 sont inclus. + + + Duplicate address found: addresses should only be used once each. + Adresse identique trouvée : chaque adresse ne devrait être utilisée qu'une fois. + + + Transaction creation failed! + Échec de création de la transaction ! + + + 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. + La transaction a été rejetée ! Cela peut arriver si certaines pièces de votre porte-monnaie étaient déjà dépensées, par exemple si vous avez utilisé une copie de wallet.dat et que des pièces ont été dépensées dans la copie sans être marquées comme telles ici. + + + A fee higher than %1 is considered an absurdly high fee. + Des frais supérieurs à %1 sont considérés comme ridiculement élevés. + + + Payment request expired. + La demande de paiement a expiré + + + Pay only the required fee of %1 + Payer seulement les frais exigés de %1 + + + Warning: Invalid Bitcoin address + Avertissement : adresse Bitcoin invalide + + + Warning: Unknown change address + Avertissement : adresse de monnaie rendue inconnue + + + (no label) + (aucune étiquette) + SendCoinsEntry @@ -1555,7 +2191,7 @@ Paste address from clipboard - Coller l'adresse depuis le presse-papiers + Coller l'adresse du presse-papiers Alt+P @@ -1563,7 +2199,7 @@ Remove this entry - Enlever cette entrée + Retirer cette entrée 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. @@ -1591,7 +2227,7 @@ 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. - Un message qui était joint à l'URI Bitcoin et qui sera stocké avec la transaction pour référence. Note : ce message ne sera pas envoyé par le réseau Bitcoin. + Un message qui était joint à l'URI bitcoin: et qui sera stocké avec la transaction pour référence. Note : ce message ne sera pas envoyé par le réseau Bitcoin. Pay To: @@ -1601,6 +2237,17 @@ Memo: Mémo : + + Enter a label for this address to add it to your address book + Saisir une étiquette pour cette adresse afin de l’ajouter à votre carnet d’adresses + + + + SendConfirmationDialog + + Yes + Oui + ShutdownWindow @@ -1617,7 +2264,7 @@ SignVerifyMessageDialog Signatures - Sign / Verify a Message - Signatures - Signer / Vérifier un message + Signatures - Signer / vérifier un message &Sign Message @@ -1625,7 +2272,7 @@ 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. - Vous pouvez signer des messages/accords avec vos adresses pour prouver que vous pouvez recevoir des bitcoins à ces dernières. Faites attention de ne rien signer de vague ou au hasard, car des attaques d'hameçonnage pourraient essayer de vous faire signer avec votre identité afin de l'usurper. Ne signez que des déclarations entièrement détaillées et avec lesquelles vous êtes d'accord. + Vous pouvez signer des messages ou des accords avec vos adresses pour prouver que vous pouvez recevoir des bitcoins à ces dernières. Faites attention de ne rien signer de vague ou au hasard, car des attaques d'hameçonnage pourraient essayer de vous faire signer avec votre identité afin de l'usurper. Ne signez que des déclarations entièrement détaillées et avec lesquelles vous êtes d'accord. The Bitcoin address to sign the message with @@ -1633,7 +2280,7 @@ Choose previously used address - Choisir une adresse précédemment utilisée + Choisir une adresse déjà utilisée Alt+A @@ -1641,7 +2288,7 @@ Paste address from clipboard - Coller une adresse depuis le presse-papiers + Coller une adresse du presse-papiers Alt+P @@ -1661,7 +2308,7 @@ Sign the message to prove you own this Bitcoin address - Signer le message pour prouver que vous détenez cette adresse Bitcoin + Signer le message afin de prouver que vous détenez cette adresse Bitcoin Sign &Message @@ -1673,7 +2320,7 @@ Clear &All - &Tout nettoyer + &Tout effacer &Verify Message @@ -1681,7 +2328,7 @@ 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! - Saisissez ci-dessous l'adresse de destinataire, le message (assurez-vous de copier exactement les retours à la ligne, les espaces, les tabulations, etc.) et la signature pour vérifier le message. Faites attention à ne pas déduire davantage de la signature que ce qui est contenu dans le message signé même, pour éviter d'être trompé par une attaque d'homme du milieu. Notez que ceci ne fait que prouver que le signataire reçoit l'adresse et ne peut pas prouver la provenance d'une transaction. + Saisir ci-dessous l'adresse du destinataire, le message (s'assurer de copier fidèlement les retours à la ligne, les espaces, les tabulations, etc.) et la signature pour vérifier le message. Faire attention à ne pas déduire davantage de la signature que ce qui est contenu dans le message signé même, pour éviter d'être trompé par une attaque d'homme du milieu. Prendre en compte que cela ne fait que prouver que le signataire reçoit l'adresse et ne peut pas prouver la provenance d'une transaction ! The Bitcoin address the message was signed with @@ -1689,7 +2336,7 @@ Verify the message to ensure it was signed with the specified Bitcoin address - Vérifier le message pour vous assurer qu'il a bien été signé par l'adresse Bitcoin spécifiée + Vérifier le message pour s'assurer qu'il a été signé avec l'adresse Bitcoin spécifiée Verify &Message @@ -1699,6 +2346,58 @@ Reset all verify message fields Réinitialiser tous les champs de vérification de message + + Click "Sign Message" to generate signature + Cliquez sur « Signer le message » pour générer la signature + + + The entered address is invalid. + L'adresse saisie est invalide. + + + Please check the address and try again. + Veuillez vérifier l'adresse et ressayer. + + + The entered address does not refer to a key. + L'adresse saisie ne fait pas référence à une clé. + + + Wallet unlock was cancelled. + Le déverrouillage du porte-monnaie a été annulé. + + + Private key for the entered address is not available. + La clé privée n'est pas disponible pour l'adresse saisie. + + + Message signing failed. + Échec de signature du message. + + + Message signed. + Le message a été signé. + + + The signature could not be decoded. + La signature n'a pu être décodée. + + + Please check the signature and try again. + Veuillez vérifier la signature et ressayer. + + + The signature did not match the message digest. + La signature ne correspond pas au condensé du message. + + + Message verification failed. + Échec de vérification du message. + + + Message verified. + Le message a été vérifié. + SplashScreen @@ -1715,11 +2414,456 @@ + TransactionDesc + + Open for %n more block(s) + Ouvert pour %n bloc de plusOuvert pour %n blocs de plus + + + Open until %1 + Ouvert jusqu'à %1 + + + conflicted with a transaction with %1 confirmations + est en conflit avec une transaction ayant %1 confirmations + + + %1/offline + %1/hors ligne + + + 0/unconfirmed, %1 + 0/non confirmées, %1 + + + in memory pool + dans la réserve de mémoire + + + not in memory pool + pas dans la réserve de mémoire + + + abandoned + abandonnée + + + %1/unconfirmed + %1/non confirmée + + + %1 confirmations + %1 confirmations + + + Status + État + + + , has not been successfully broadcast yet + , n’a pas encore été diffusée avec succès + + + , broadcast through %n node(s) + , diffusée à travers %n nœud, diffusée à travers %n nœuds + + + Date + Date + + + Source + Source + + + Generated + Générée + + + From + De + + + unknown + inconnue + + + To + À + + + own address + votre adresse + + + watch-only + juste-regarder + + + label + étiquette + + + Credit + Crédit + + + matures in %n more block(s) + arrive à maturité dans %n bloc de plusarrive à maturité dans %n blocs de plus + + + not accepted + refusée + + + Debit + Débit + + + Total debit + Débit total + + + Total credit + Crédit total + + + Transaction fee + Frais de transaction + + + Net amount + Montant net + + + Message + Message + + + Comment + Commentaire + + + Transaction ID + ID de la transaction + + + Output index + Index de sorties + + + Merchant + Marchand + + + 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. + Les pièces générées doivent mûrir pendant %1 blocs avant de pouvoir être dépensées. Lorsque ce bloc a été généré, il a été diffusé sur le réseau pour être ajouté à la chaîne de blocs. Si son intégration à la chaîne échoue, son état sera modifié en « refusée » et il ne sera pas possible de le dépenser. Cela peut arriver occasionnellement si un autre nœud génère un bloc à quelques secondes du vôtre. + + + Debug information + Informations de débogage + + + Transaction + Transaction + + + Inputs + Entrées + + + Amount + Montant + + + true + vrai + + + false + faux + + + TransactionDescDialog This pane shows a detailed description of the transaction Ce panneau affiche une description détaillée de la transaction + + Details for %1 + Détails de %1 + + + + TransactionTableModel + + Date + Date + + + Type + Type + + + Label + Étiquette + + + Open for %n more block(s) + Ouvert pour %n bloc de plusOuvert pour %n blocs de plus + + + Open until %1 + Ouvert jusqu'à %1 + + + Offline + Hors ligne + + + Unconfirmed + Non confirmée + + + Abandoned + Abandonnée + + + Confirming (%1 of %2 recommended confirmations) + Confirmation (%1 sur %2 confirmations recommandées) + + + Confirmed (%1 confirmations) + Confirmée (%1 confirmations) + + + Conflicted + En conflit + + + Immature (%1 confirmations, will be available after %2) + Immature (%1 confirmations, sera disponible après %2) + + + This block was not received by any other nodes and will probably not be accepted! + Ce bloc n’a été reçu par aucun autre nœud et ne sera probablement pas accepté ! + + + Generated but not accepted + Générée mais refusée + + + Received with + Reçue avec + + + Received from + Reçue de + + + Sent to + Envoyée à + + + Payment to yourself + Paiement à vous-même + + + Mined + Miné + + + watch-only + juste-regarder + + + (n/a) + (n.d) + + + (no label) + (aucune étiquette) + + + Transaction status. Hover over this field to show number of confirmations. + État de la transaction. Survoler ce champ avec la souris pour afficher le nombre de confirmations. + + + Date and time that the transaction was received. + Date et heure de réception de la transaction. + + + Type of transaction. + Type de transaction. + + + Whether or not a watch-only address is involved in this transaction. + Une adresse juste-regarder est-elle ou non impliquée dans cette transaction. + + + User-defined intent/purpose of the transaction. + Intention/but de la transaction défini par l'utilisateur. + + + Amount removed from or added to balance. + Le montant a été ajouté ou soustrait du solde. + + + + TransactionView + + All + Toutes + + + Today + Aujourd’hui + + + This week + Cette semaine + + + This month + Ce mois + + + Last month + Le mois dernier + + + This year + Cette année + + + Range... + Plage… + + + Received with + Reçue avec + + + Sent to + Envoyée à + + + To yourself + À vous-même + + + Mined + Miné + + + Other + Autres + + + Enter address or label to search + Saisir une adresse ou une étiquette à rechercher + + + Min amount + Montant min. + + + Abandon transaction + Abandonner la transaction + + + Copy address + Copier l’adresse + + + Copy label + Copier l’étiquette + + + Copy amount + Copier le montant + + + Copy transaction ID + Copier l'ID de la transaction + + + Copy raw transaction + Copier la transaction brute + + + Copy full transaction details + Copier tous les détails de la transaction + + + Edit label + Modifier l’étiquette + + + Show transaction details + Afficher les détails de la transaction + + + Export Transaction History + Exporter l'historique transactionnel + + + Comma separated file (*.csv) + Valeurs séparées par des virgules (*.csv) + + + Confirmed + Confirmée + + + Watch-only + Juste-regarder + + + Date + Date + + + Type + Type + + + Label + Étiquette + + + Address + Adresse + + + ID + ID + + + Exporting Failed + Échec d'exportation + + + There was an error trying to save the transaction history to %1. + Une erreur est survenue lors de l'enregistrement de l'historique transactionnel vers %1. + + + Exporting Successful + L'exportation est réussie + + + The transaction history was successfully saved to %1. + L'historique transactionnel a été enregistré avec succès vers %1. + + + Range: + Plage : + + + to + à + UnitDisplayStatusBarControl @@ -1729,6 +2873,55 @@ + WalletFrame + + No wallet has been loaded. + Aucun porte-monnaie n'a été chargé. + + + + WalletModel + + Send Coins + Envoyer des pièces + + + + WalletView + + &Export + &Exporter + + + Export the data in the current tab to a file + Exporter les données de l'onglet actuel vers un fichier + + + Backup Wallet + Sauvegarder le porte-monnaie + + + Wallet Data (*.dat) + Données du porte-monnaie (*.dat) + + + Backup Failed + Échec de la sauvegarde + + + There was an error trying to save the wallet data to %1. + Une erreur est survenue lors de l'enregistrement des données du porte-monnaie vers %1. + + + Backup Successful + La sauvegarde est réussie + + + The wallet data was successfully saved to %1. + Les données du porte-monnaie ont été enregistrées avec succès vers %1 + + + bitcoin-core Options: @@ -1748,7 +2941,7 @@ Accept command line and JSON-RPC commands - Accepter les commandes de JSON-RPC et de la ligne de commande + Accepter les commandes JSON-RPC et en ligne de commande If <category> is not supplied or if <category> = 1, output all debugging information. @@ -1812,7 +3005,7 @@ Bind to given address and always listen on it. Use [host]:port notation for IPv6 - Se lier à l'adresse donnée et toujours l'écouter. Utilisez la notation [host]:port pour l'IPv6 + Se lier à l'adresse donnée et toujours l'écouter. Utiliser la notation [host]:port pour l'IPv6 Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup @@ -1823,6 +3016,10 @@ Distribué sous la licence MIT d'utilisation d'un logiciel. Consultez le fichier joint COPYING ou <http://www.opensource.org/licenses/mit-license.php>. + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Octets équivalents par sigop dans les transactions pour relayer et miner (par défaut : %u) + + Error loading %s: You can't enable HD on a already existing non-HD wallet Erreur de chargement de %s : vous ne pouvez pas activer HD sur un porte-monnaie non HD existant @@ -1844,7 +3041,7 @@ Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) - Définir le nombre d'exétrons de vérification des scripts (%u à %d, 0 = auto, < 0 = laisser ce nombre de cœurs inutilisés, par défaut : %d) + Définir le nombre de fils de vérification des scripts (%u à %d, 0 = auto, < 0 = laisser ce nombre de cœurs inutilisés, par défaut : %d) 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 @@ -1852,7 +3049,7 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications - Ceci est une pré-version de test - l'utiliser à vos risques et périls - ne pas l'utiliser pour miner ou pour des applications marchandes + Ceci est une préversion de test - l'utiliser à vos risques - ne pas l'utiliser pour miner ou pour des applications marchandes Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain @@ -1860,7 +3057,7 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) - Utiliser l'UPnP pour mapper le port d'écoute (par défaut : 1 lors de l'écoute et pas de mandataire -proxy) + Utiliser l'UPnP pour mapper le port d'écoute (par défaut : 1 en écoute et sans -proxy) Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. @@ -1896,11 +3093,11 @@ Attempt to recover private keys from a corrupt wallet on startup - Tenter de récupérer les clefs privées d'un porte-monnaie corrompu lors du démarrage + Tenter de récupérer les clés privées d'un porte-monnaie corrompu lors du démarrage Block creation options: - Options de création de bloc : + Options de création de blocs : Cannot resolve -%s address: '%s' @@ -1924,7 +3121,7 @@ Corrupted block database detected - Base corrompue de données des blocs détectée + Une base de données de blocs corrompue a été détectée Debugging/Testing options: @@ -1936,7 +3133,7 @@ Do you want to rebuild the block database now? - Voulez-vous reconstruire la base de données des blocs maintenant ? + Voulez-vous reconstruire la base de données de blocs maintenant ? Enable publish hash block in <address> @@ -1956,23 +3153,23 @@ Error initializing block database - Erreur lors de l'initialisation de la base de données des blocs + Erreur d'initialisation de la base de données de blocs Error initializing wallet database environment %s! - Erreur lors de l'initialisation de l'environnement de la base de données du porte-monnaie %s ! + Erreur d'initialisation de l'environnement de la base de données du porte-monnaie %s ! Error loading %s - Erreur lors du chargement de %s + Erreur de chargement de %s Error loading %s: Wallet corrupted - Erreur lors du chargement de %s : porte-monnaie corrompu + Erreur de chargement de %s : porte-monnaie corrompu Error loading %s: Wallet requires newer version of %s - Erreur lors du chargement de %s : le porte-monnaie exige une version plus récente de %s + Erreur de chargement de %s : le porte-monnaie exige une version plus récente de %s Error loading %s: You can't disable HD on a already existing HD wallet @@ -1980,11 +3177,11 @@ Error loading block database - Erreur du chargement de la base de données des blocs + Erreur de chargement de la base de données de blocs Error opening block database - Erreur lors de l'ouverture de la base de données des blocs + Erreur d'ouverture de la base de données de blocs Error: Disk space is low! @@ -1992,7 +3189,7 @@ Failed to listen on any port. Use -listen=0 if you want this. - Échec de l'écoute sur un port quelconque. Utilisez -listen=0 si vous voulez ceci. + Échec d'écoute sur un port quelconque. Utiliser -listen=0 si vous le voulez. Importing... @@ -2000,7 +3197,7 @@ Incorrect or no genesis block found. Wrong datadir for network? - Bloc de genèse incorrect ou introuvable. Mauvais répertoire de données pour le réseau ? + Bloc de genèse incorrect ou introuvable. Mauvais datadir pour le réseau ? Invalid -onion address: '%s' @@ -2027,10 +3224,6 @@ Emplacement du fichier témoin auth (par défaut : data dir) - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Octets minimaux par sigop dans les transactions que nous relayons et minons (par défaut : %u) - - Not enough file descriptors available. Pas assez de descripteurs de fichiers proposés. @@ -2068,11 +3261,11 @@ Set database cache size in megabytes (%d to %d, default: %d) - Définir la taille du cache de la base de données en mégaoctets (%d to %d, default: %d) + Définir la taille du cache de la base de données en mégaoctets (%d à %d, default: %d) - Set maximum block cost (default: %d) - Définir le coût maximal de bloc (par défaut : %d) + Set maximum BIP141 block weight (default: %d) + Définir le poids maximal de bloc BIP141 (par défaut : %d) Set maximum block size in bytes (default: %d) @@ -2083,6 +3276,10 @@ Spécifiez le fichier de porte-monnaie (dans le répertoire de données) + Starting network threads... + Démarrage des processus réseau... + + The source code is available from %s. Le code source est disponible sur %s. @@ -2108,11 +3305,11 @@ Verifying blocks... - Vérification des blocs en cours... + Vérification des blocs... Verifying wallet... - Vérification du porte-monnaie en cours... + Vérification du porte-monnaie... Wallet %s resides outside data directory %s @@ -2152,7 +3349,7 @@ Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) - Exécuter une commande lorsqu'une alerte pertinente est reçue ou si nous voyons une bifurcation vraiment étendue (%s dans la commande est remplacé par le message) + Exécuter une commande lorsqu'une alerte pertinente est reçue, ou si nous voyons une bifurcation vraiment étendue (%s dans la commande est remplacé par le message) Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) @@ -2176,11 +3373,11 @@ Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u) - Aléer les authentifiants pour chaque connexion mandataire. Ceci active l'isolement de flux de Tor (par défaut : %u) + Aléer les authentifiants pour chaque connexion mandataire. Cela active l'isolement de flux de Tor (par défaut : %u) Set maximum size of high-priority/low-fee transactions in bytes (default: %d) - Définir la taille maximale en octets des transactions prioritaires/à frais modiques (par défaut : %d) + Définir la taille maximale en octets des transactions à priorité élevée et frais modiques (par défaut : %d) The transaction amount is too small to send after the fee has been deducted @@ -2192,7 +3389,7 @@ Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start - Utiliser une génération de clef hiérarchique déterministe (HD) après BIP32. N'a d'effet que lors de la création/premier lancement du porte-monnaie + Utiliser une génération de clé hiérarchique déterministe (HD) après BIP32. N'a d'effet que lors de la création ou du lancement intitial du porte-monnaie 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 @@ -2200,7 +3397,7 @@ You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain - Vous devez reconstruire la base de données en utilisant -reindex afin de revenir au mode sans élagage. Ceci retéléchargera complètement la chaîne de blocs. + Vous devez reconstruire la base de données en utilisant -reindex afin de revenir au mode sans élagage. Cela retéléchargera complètement la chaîne de blocs. (default: %u) @@ -2224,7 +3421,7 @@ Imports blocks from external blk000??.dat file on startup - Importe des blocs depuis un fichier blk000??.dat externe lors du démarrage + Importe des blocs à partir d'un fichier blk000??.dat externe lors du démarrage Information @@ -2264,7 +3461,7 @@ Send trace/debug info to console instead of debug.log file - Envoyer les informations de débogage/trace à la console au lieu du fichier debug.log + Envoyer les infos de débogage/trace à la console au lieu du fichier debug.log Send transactions as zero-fee transactions if possible (default: %u) @@ -2276,11 +3473,11 @@ Shrink debug.log file on client startup (default: 1 when no -debug) - Réduire le fichier debug.log lors du démarrage du client (par défaut : 1 lorsque -debug n'est pas présent) + Réduire le fichier debug.log lors du démarrage du client (par défaut : 1 sans -debug) Signing transaction failed - La signature de la transaction a échoué + Échec de signature de la transaction The transaction amount is too small to pay the fee @@ -2300,7 +3497,7 @@ Transaction amount too small - Montant de la transaction trop bas + Le montant de la transaction est trop bas Transaction amounts must be positive @@ -2312,7 +3509,7 @@ Transaction too large - Transaction trop volumineuse + La transaction est trop grosse Unable to bind to %s on this computer (bind returned error %s) @@ -2364,15 +3561,15 @@ (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) - (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) + (1 = conserver les métadonnées de transmission, p. ex. les informations du propriétaire du compte et de demande de paiement, 2 = abandonner les métadonnées de transmission) -maxtxfee is set very high! Fees this large could be paid on a single transaction. - -maxtxfee est défini très haut ! Des frais aussi élevés pourraient être payés en une seule transaction. + La valeur -maxtxfee est très élevée ! Des frais aussi élevés pourraient être payés en une seule transaction. -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. - -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. + La valeur -paytxfee est très élevée ! Il s'agit des frais de transaction que vous payerez si vous envoyez une transaction. Do not keep transactions in the mempool longer than <n> hours (default: %u) @@ -2396,7 +3593,7 @@ Output debugging information (default: %u, supplying <category> is optional) - Extraire les informations de débogage (par défaut : %u, fournir <category> est optionnel) + Extraire les informations de débogage (par défaut : %u, fournir <category> est facultatif) Support filtering of blocks and transaction with bloom filters (default: %u) @@ -2492,15 +3689,11 @@ Set key pool size to <n> (default: %u) - Définir la taille de la réserve de clefs à <n> (par défaut : %u) - - - Set minimum block size in bytes (default: %u) - Définir la taille de bloc minimale en octets (par défaut : %u) + Définir la taille de la réserve de clés à <n> (par défaut : %u) Set the number of threads to service RPC calls (default: %d) - Définir le nombre d'exétrons pour desservir les appels RPC (par défaut : %d) + Définir le nombre de fils pour les appels RPC (par défaut : %d) Specify configuration file (default: %s) @@ -2524,7 +3717,7 @@ Unknown network specified in -onlynet: '%s' - Réseau inconnu spécifié sur -onlynet : « %s » + Réseau inconnu spécifié dans -onlynet : « %s » Insufficient funds diff --git a/src/qt/locale/bitcoin_fr_CA.ts b/src/qt/locale/bitcoin_fr_CA.ts index fca1e62883d..e576f8d74c1 100644 --- a/src/qt/locale/bitcoin_fr_CA.ts +++ b/src/qt/locale/bitcoin_fr_CA.ts @@ -13,7 +13,10 @@ &Delete &Supprimer - + + + AddressTableModel + AskPassphraseDialog @@ -28,7 +31,7 @@ Repeat new passphrase Répéter Mot de Passe - + BanTableModel @@ -52,7 +55,7 @@ &Address Addresse - + FreespaceChecker @@ -76,12 +79,18 @@ OverviewPage + PaymentServer + + PeerTableModel QObject + QRImageWidget + + RPCConsole @@ -91,12 +100,18 @@ ReceiveRequestDialog + RecentRequestsTableModel + + SendCoinsDialog SendCoinsEntry + SendConfirmationDialog + + ShutdownWindow @@ -109,12 +124,30 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core \ No newline at end of file diff --git a/src/qt/locale/bitcoin_fr_FR.ts b/src/qt/locale/bitcoin_fr_FR.ts index a6f6ac4fd10..3fa055de2d5 100644 --- a/src/qt/locale/bitcoin_fr_FR.ts +++ b/src/qt/locale/bitcoin_fr_FR.ts @@ -41,7 +41,10 @@ &Delete &Supprimer - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Répétez la phrase de passe - + BanTableModel @@ -443,7 +446,7 @@ Priority Priorité - + EditAddressDialog @@ -458,7 +461,7 @@ &Address &Adresse - + FreespaceChecker @@ -566,7 +569,7 @@ Select payment request file Sélectionner un fichier de demande de paiement - + OptionsDialog @@ -754,6 +757,9 @@ + PaymentServer + + PeerTableModel User Agent @@ -808,6 +814,9 @@ + QRImageWidget + + RPCConsole N/A @@ -1064,7 +1073,7 @@ Remove Retirer - + ReceiveRequestDialog @@ -1083,7 +1092,10 @@ &Save Image... &Sauvegarder image - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1241,7 +1253,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1311,16 +1326,34 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Ce panneau affiche une description détaillée de la transaction - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_gl.ts b/src/qt/locale/bitcoin_gl.ts index 9aa7b550964..3308c24015c 100644 --- a/src/qt/locale/bitcoin_gl.ts +++ b/src/qt/locale/bitcoin_gl.ts @@ -37,7 +37,10 @@ &Delete &Borrar - + + + AddressTableModel + AskPassphraseDialog @@ -56,7 +59,7 @@ Repeat new passphrase Repite novo contrasinal - + BanTableModel @@ -333,7 +336,7 @@ Priority Prioridade - + EditAddressDialog @@ -356,7 +359,7 @@ &Address &Dirección - + FreespaceChecker @@ -436,7 +439,7 @@ Select payment request file Seleccionar ficheiro de solicitude de pago - + OptionsDialog @@ -572,6 +575,9 @@ + PaymentServer + + PeerTableModel @@ -594,6 +600,9 @@ + QRImageWidget + + RPCConsole N/A @@ -749,7 +758,10 @@ &Save Image... &Gardar Imaxe... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -816,7 +828,7 @@ S&end &Enviar - + SendCoinsEntry @@ -871,7 +883,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -945,7 +960,7 @@ Reset all verify message fields Restaurar todos os campos de verificación de mensaxe - + SplashScreen @@ -961,16 +976,34 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Este panel amosa unha descripción detallada da transacción - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_he.ts b/src/qt/locale/bitcoin_he.ts index 4a293c1c3f2..394cc317365 100644 --- a/src/qt/locale/bitcoin_he.ts +++ b/src/qt/locale/bitcoin_he.ts @@ -41,6 +41,69 @@ &Delete מ&חיקה + + Choose the address to send coins to + בחר את הכתובת אליה תרצה לשלוח את המטבעות + + + Choose the address to receive coins with + בחר את הכתובת בה תקבל את המטבעות + + + C&hoose + בחר + + + Sending addresses + כתובת לשליחה + + + Receiving addresses + מקבל כתובות + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + אלה הם כתובות הביטקוין שלך לשליחת תשלומים. חשוב לבדוק את הכמות של הכתובות המקבלות לפני שליחת מטבעות + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + אלה הן כתובות הביטקוין שלך לקבלת תשלומים. מומלץ להשתמש בכתובת חדשה לכל העברה. + + + &Copy Address + &העתק כתובת + + + Copy &Label + העתק &תוית + + + &Edit + &ערוך + + + Exporting Failed + יצוא נכשל + + + There was an error trying to save the address list to %1. Please try again. + אירעה שגיאה בעת הניסיון לשמור את רשימת הכתובת אל %1. נא לנסות שוב. + + + + AddressTableModel + + Label + תוית + + + Address + כתובת + + + (no label) + (ללא תוית) + AskPassphraseDialog @@ -60,7 +123,7 @@ Repeat new passphrase נא לחזור על מילת הצופן החדשה - + BanTableModel @@ -389,7 +452,11 @@ Priority עדיפות - + + (no label) + (ללא תוית) + + EditAddressDialog @@ -412,7 +479,7 @@ &Address &כתובת - + FreespaceChecker @@ -516,7 +583,7 @@ Select payment request file בחירת קובץ בקשת תשלום - + OptionsDialog @@ -776,6 +843,9 @@ + PaymentServer + + PeerTableModel User Agent @@ -826,6 +896,9 @@ + QRImageWidget + + RPCConsole N/A @@ -1150,7 +1223,7 @@ Remove הסרה - + ReceiveRequestDialog @@ -1169,7 +1242,26 @@ &Save Image... &שמירת תמונה… - + + Address + כתובת + + + Label + תוית + + + + RecentRequestsTableModel + + Label + תוית + + + (no label) + (ללא תוית) + + SendCoinsDialog @@ -1300,6 +1392,10 @@ S&end &שליחה + + (no label) + (ללא תוית) + SendCoinsEntry @@ -1367,7 +1463,10 @@ Memo: תזכורת: - + + + SendConfirmationDialog + ShutdownWindow @@ -1453,7 +1552,7 @@ Reset all verify message fields איפוס כל שדות אימות ההודעה - + SplashScreen @@ -1469,12 +1568,41 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction חלונית זו מציגה תיאור מפורט של ההעברה - + + + TransactionTableModel + + Label + תוית + + + (no label) + (ללא תוית) + + + + TransactionView + + Label + תוית + + + Address + כתובת + + + Exporting Failed + יצוא נכשל + + UnitDisplayStatusBarControl @@ -1483,6 +1611,15 @@ + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_hi_IN.ts b/src/qt/locale/bitcoin_hi_IN.ts index 86c53b4ce3d..1cb5cf17a46 100644 --- a/src/qt/locale/bitcoin_hi_IN.ts +++ b/src/qt/locale/bitcoin_hi_IN.ts @@ -13,7 +13,10 @@ &Delete &मिटाए !! - + + + AddressTableModel + AskPassphraseDialog @@ -28,7 +31,7 @@ Repeat new passphrase दोबारा नया पहचान शब्द/अक्षर डालिए ! - + BanTableModel @@ -169,7 +172,7 @@ &Address &पता - + FreespaceChecker @@ -221,6 +224,9 @@ + PaymentServer + + PeerTableModel @@ -236,6 +242,9 @@ + QRImageWidget + + RPCConsole N/A @@ -266,6 +275,9 @@ + RecentRequestsTableModel + + SendCoinsDialog Send Coins @@ -320,6 +332,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -352,16 +367,34 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction ये खिड़की आपको लेन-देन का विस्तृत विवरण देगी ! - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_hr.ts b/src/qt/locale/bitcoin_hr.ts index f5accfb0b8f..f770cf14667 100644 --- a/src/qt/locale/bitcoin_hr.ts +++ b/src/qt/locale/bitcoin_hr.ts @@ -41,7 +41,34 @@ &Delete Iz&briši - + + Choose the address to send coins to + Odaberi adresu na koju šalješ novac + + + Choose the address to receive coins with + Odaberi adresu na koju primaš novac + + + C&hoose + &Odaberi + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Ovo su vaše Bitcoin adrese za slanje novca. Uvijek provjerite iznos i adresu primatelja prije slanja novca. + + + &Copy Address + &Kopiraj adresu + + + Exporting Failed + Izvoz neuspješan + + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +87,7 @@ Repeat new passphrase Ponovite novu lozinku - + BanTableModel @@ -411,7 +438,7 @@ Priority Prioriteta - + EditAddressDialog @@ -434,7 +461,7 @@ &Address &Adresa - + FreespaceChecker @@ -502,7 +529,7 @@ Select payment request file Izaberi datoteku zahtjeva za plaćanje - + OptionsDialog @@ -642,6 +669,9 @@ + PaymentServer + + PeerTableModel @@ -656,6 +686,9 @@ + QRImageWidget + + RPCConsole N/A @@ -791,7 +824,10 @@ &Save Image... &Spremi sliku... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -862,7 +898,7 @@ S&end &Pošalji - + SendCoinsEntry @@ -899,6 +935,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -955,16 +994,38 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Ovaj prozor prikazuje detaljni opis transakcije - + + + TransactionTableModel + + + TransactionView + + Exporting Failed + Izvoz neuspješan + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_hu.ts b/src/qt/locale/bitcoin_hu.ts index 9eb0cf76c43..e5e0d10597a 100644 --- a/src/qt/locale/bitcoin_hu.ts +++ b/src/qt/locale/bitcoin_hu.ts @@ -41,7 +41,10 @@ &Delete &Törlés - + + + AddressTableModel + AskPassphraseDialog @@ -60,10 +63,18 @@ Repeat new passphrase Új jelszó újra - + BanTableModel - + + IP/Netmask + IP-cím/maszk + + + Banned Until + Kitiltás vége + + BitcoinGUI @@ -431,7 +442,7 @@ Priority Prioritás - + EditAddressDialog @@ -454,7 +465,7 @@ &Address &Cím - + FreespaceChecker @@ -542,7 +553,7 @@ Select payment request file Fizetési kérelmi fájl kiválasztása - + OptionsDialog @@ -754,6 +765,9 @@ + PaymentServer + + PeerTableModel User Agent @@ -804,6 +818,9 @@ + QRImageWidget + + RPCConsole N/A @@ -870,6 +887,10 @@ &Peerek + Banned peers + Kitiltott felek + + Select a peer to view detailed information. Peer kijelölése a részletes információkért @@ -942,6 +963,10 @@ Konzol törlése + Ban Node for + Kitiltás oka + + 1 &hour 1 &óra @@ -958,6 +983,10 @@ 1 &év + &Unban Node + Kitiltás &feloldása + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Navigálhat a fel és le nyilakkal, és <b>Ctrl-L</b> -vel törölheti a képernyőt. @@ -1052,7 +1081,7 @@ Remove Eltávolítás - + ReceiveRequestDialog @@ -1071,7 +1100,10 @@ &Save Image... &Kép mentése - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1182,7 +1214,7 @@ S&end &Küldés - + SendCoinsEntry @@ -1229,7 +1261,10 @@ Memo: Jegyzet: - + + + SendConfirmationDialog + ShutdownWindow @@ -1311,16 +1346,34 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Ez a mező a tranzakció részleteit mutatja - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: @@ -1363,6 +1416,10 @@ Parancs, amit akkor hajt végre, amikor egy tárca-tranzakció megváltozik (%s a parancsban lecserélődik a blokk TxID-re) + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + UPnP használata porttovábbításra (alapértelmezett: 1, amikor kiszolgál és nem használt a -proxy) + + Connect only to the specified node(s) Csatlakozás csak a megadott csomóponthoz @@ -1407,6 +1464,10 @@ Helytelen vagy nemlétező genézis blokk. Helytelen hálózati adatkönyvtár? + Loading banlist... + Tiltólista betöltése... + + Not enough file descriptors available. Nincs elég fájlleíró. @@ -1423,6 +1484,18 @@ Tárca beállítások: + Discover own IP addresses (default: 1 when listening and no -externalip or -proxy) + Saját IP-cím felfedezése (alapértelmezett: 1, amikor kiszolgál és nem használt a -externalip) + + + 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 + A fehérlistán szereplő felek nem lesznek automatikusan kitiltva és a tranzakcióik is mindig továbbítva lesznek, akkor is ha már a megerősítésre váró listán (mempool) vannak. Hasznos például összekötő csomópontokon (gateway). + + + (default: %u) + (alapértelmezett: %u) + + Error reading from database, shutting down. Hiba az adatbázis olvasásakor, leállítás @@ -1481,6 +1554,14 @@ Címek betöltése... + (default: %s) + (alapértelmezett: %s) + + + Include IP addresses in debug output (default: %u) + IP-címek megjelenítése a naplóban (alapértelmezett: %u) + + Invalid -proxy address: '%s' Érvénytelen -proxy cím: '%s' diff --git a/src/qt/locale/bitcoin_id_ID.ts b/src/qt/locale/bitcoin_id_ID.ts index feb6f690c45..f47ed16baaa 100644 --- a/src/qt/locale/bitcoin_id_ID.ts +++ b/src/qt/locale/bitcoin_id_ID.ts @@ -41,7 +41,10 @@ &Delete &Hapus - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Ulangi kata kunci baru - + BanTableModel @@ -435,7 +438,7 @@ Priority Prioritas - + EditAddressDialog @@ -458,7 +461,7 @@ &Address &Alamat - + FreespaceChecker @@ -578,7 +581,7 @@ Select payment request file Pilih data permintaan pembayaran - + OptionsDialog @@ -822,6 +825,9 @@ + PaymentServer + + PeerTableModel User Agent @@ -852,6 +858,9 @@ + QRImageWidget + + RPCConsole N/A @@ -1070,7 +1079,7 @@ Remove Menghapus - + ReceiveRequestDialog @@ -1089,7 +1098,10 @@ &Save Image... &Simpan Gambaran... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1200,7 +1212,7 @@ S&end K&irim - + SendCoinsEntry @@ -1255,7 +1267,10 @@ Memo: Catatan Peringatan: - + + + SendConfirmationDialog + ShutdownWindow @@ -1329,7 +1344,7 @@ Reset all verify message fields Hapus semua bidang verifikasi pesan - + SplashScreen @@ -1345,16 +1360,34 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Jendela ini menampilkan deskripsi rinci dari transaksi tersebut - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_it.ts b/src/qt/locale/bitcoin_it.ts index 55bc9c3c824..26615ecd206 100644 --- a/src/qt/locale/bitcoin_it.ts +++ b/src/qt/locale/bitcoin_it.ts @@ -3,7 +3,7 @@ AddressBookPage Right-click to edit address or label - Fare clic con il tasto destro del mouse per modificare l'indirizzo o l'etichetta + Fare clic con il tasto destro del mouse per modificare l'indirizzo o l'etichettadefault Create a new address @@ -41,7 +41,10 @@ &Delete &Elimina - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Ripeti la nuova passphrase - + BanTableModel @@ -115,6 +118,10 @@ &Informazioni su %1 + Show information about %1 + Mostra informazioni su %1 + + About &Qt Informazioni su &Qt @@ -127,6 +134,10 @@ &Opzioni... + Modify configuration options for %1 + Modifica le opzioni di configurazione per %1 + + &Encrypt Wallet... &Cifra il portamonete... @@ -255,6 +266,14 @@ %n connessione attiva alla rete Bitcoin%n connessioni alla rete Bitcoin attive + Indexing blocks on disk... + Indicizzando i blocchi su disco... + + + Processing blocks on disk... + Processando i blocchi su disco... + + No block source available... Nessuna fonte di blocchi disponibile... @@ -311,6 +330,14 @@ Aggiornato + Show the %1 help message to get a list with possible Bitcoin command-line options + Mostra il messaggio di aiuto di %1 per ottenere una lista di opzioni di comando per Bitcoin + + + %1 client + %1 client + + Catching up... In aggiornamento... @@ -439,7 +466,7 @@ Priority Priorità - + EditAddressDialog @@ -462,7 +489,7 @@ &Address &Indirizzo - + FreespaceChecker @@ -497,6 +524,10 @@ (%1-bit) + About %1 + Informazioni %1 + + Command-line options Opzioni della riga di comando @@ -532,7 +563,11 @@ Show splash screen on startup (default: %u) Mostra schermata iniziale all'avvio (default: %u) - + + Reset all settings changed in the GUI + Reimposta tutti i campi dell'interfaccia grafica + + Intro @@ -540,6 +575,18 @@ Benvenuto + Welcome to %1. + Benvenuto su %1. + + + As this is the first time the program is launched, you can choose where %1 will store its data. + Dato che questa è la prima volta che il programma viene lanciato, puoi scegliere dove %1 salverà i suoi dati. + + + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 scaricherà e salverà una copia della Blockchain di Bitcoin. Saranno salvati almeno %2GB di dati in questo percorso e continueranno ad aumentare col tempo. Anche il portafoglio verrà salvato in questo percorso. + + Use the default data directory Usa la cartella dati predefinita @@ -582,7 +629,7 @@ Select payment request file Seleziona il file di richiesta di pagamento - + OptionsDialog @@ -594,6 +641,14 @@ &Principale + Automatically start %1 after logging in to the system. + Avvia automaticamente %1 una volta effettuato l'accesso al sistema. + + + &Start %1 on system login + &Start %1 all'accesso al sistema + + Size of &database cache Dimensione della cache del &database. @@ -731,6 +786,10 @@ Per specificare più URL separarli con una barra verticale "|". &Finestra + Hide tray icon + Nascondi l'icona della barra applicazioni + + Show only a tray icon after minimizing the window. Mostra solo nella tray bar quando si riduce ad icona. @@ -751,6 +810,10 @@ Per specificare più URL separarli con una barra verticale "|". &Lingua Interfaccia Utente: + The user interface language can be set here. This setting will take effect after restarting %1. + La lingua dell'interfaccia utente può essere impostata qui. L'impostazione avrà effetto dopo il riavvio %1. + + &Unit to show amounts in: &Unità di misura con cui visualizzare gli importi: @@ -875,6 +938,9 @@ Per specificare più URL separarli con una barra verticale "|". + PaymentServer + + PeerTableModel User Agent @@ -929,6 +995,9 @@ Per specificare più URL separarli con una barra verticale "|". + QRImageWidget + + RPCConsole N/A @@ -955,6 +1024,10 @@ Per specificare più URL separarli con una barra verticale "|". Versione BerkeleyDB in uso + Datadir + Datadir + + Startup time Ora di avvio @@ -1039,6 +1112,18 @@ Per specificare più URL separarli con una barra verticale "|". User Agent + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + Apri il file log del debug di %1 dalla cartella dati attuale. Può richiedere alcuni secondi per file di log di grandi dimensioni. + + + Decrease font size + Riduci dimensioni font. + + + Increase font size + Aumenta dimensioni font + + Services Servizi @@ -1143,6 +1228,10 @@ Per specificare più URL separarli con una barra verticale "|". &Elimina Ban Nodo + Welcome to the %1 RPC console. + Benvenuto nella console RPC di %1. + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Usa le frecce direzionali per scorrere la cronologia, e <b>Ctrl-L</b> per cancellarla. @@ -1269,7 +1358,7 @@ Per specificare più URL separarli con una barra verticale "|". Remove Rimuovi - + ReceiveRequestDialog @@ -1288,7 +1377,10 @@ Per specificare più URL separarli con una barra verticale "|". &Save Image... &Salva Immagine... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1439,7 +1531,7 @@ Per specificare più URL separarli con una barra verticale "|". S&end &Invia - + SendCoinsEntry @@ -1518,10 +1610,17 @@ Per specificare più URL separarli con una barra verticale "|". Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow + %1 is shutting down... + Arresto di %1 in corso... + + Do not shut down the computer until this window disappears. Non spegnere il computer fino a quando questa finestra non si sarà chiusa. @@ -1612,7 +1711,7 @@ Per specificare più URL separarli con una barra verticale "|". Reset all verify message fields Reimposta tutti i campi della verifica messaggio - + SplashScreen @@ -1628,12 +1727,21 @@ Per specificare più URL separarli con una barra verticale "|". + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Questo pannello mostra una descrizione dettagliata della transazione - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1642,6 +1750,15 @@ Per specificare più URL separarli con una barra verticale "|". + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: @@ -1712,6 +1829,18 @@ Per specificare più URL separarli con una barra verticale "|". Bitcoin Core + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee è impostato su un valore molto elevato! Questa è la commissione che potresti pagare quando la stima della commissione non è disponibile. + + + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + Un importo (in %s/kB) che sarà utilizzato quando la stima delle commissioni non ha abbastanza dati (default: %s) + + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Accetta le transazioni trasmesse ricevute da peers in whitelist anche se non si stanno trasmettendo transazioni (default: %d) + + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Associa all'indirizzo indicato e resta permanentemente in ascolto su di esso. Usa la notazione [host]:porta per l'IPv6 @@ -1724,10 +1853,38 @@ Per specificare più URL separarli con una barra verticale "|". Distribuito secondo la licenza software MIT, vedi il file COPYING incluso oppure <http://www.opensource.org/licenses/mit-license.php>. + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Byte equivalenti per ottimizzazione segnale dedicati a ritrasmissione ed estrazione (default: %u) + + + Error loading %s: You can't enable HD on a already existing non-HD wallet + Errore caricamento %s: Non puoi abilitare HD in un portafoglio non-HD già esistente + + + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Errore lettura %s! Tutte le chiavi sono state lette correttamente, ma i dati delle transazioni o della rubrica potrebbero essere mancanti o non corretti. + + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Esegue un comando quando lo stato di una transazione del portamonete cambia (%s in cmd è sostituito da TxID) + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + Regolazione della massima differenza media di tempo dei peer consentita. L'impostazione dell'orario locale può essere impostata in avanti o indietro di questa quantità. (default %u secondi) + + + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + Totale massimo di commissioni (in %s) da usare in una transazione singola o di gruppo del wallet; valori troppo bassi possono abortire grandi transazioni (default: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + Per favore controllate che la data del computer e l'ora siano corrette! Se il vostro orologio è sbagliato %s non funzionerà correttamente. + + + Please contribute if you find %s useful. Visit %s for further information about the software. + Per favore contribuite se ritenete %s utile. Visitate %s per maggiori informazioni riguardo il software. + + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Imposta il numero di thread per la verifica degli script (da %u a %d, 0 = automatico, <0 = lascia questo numero di core liberi, predefinito: %d) @@ -1740,6 +1897,10 @@ Per specificare più URL separarli con una barra verticale "|". Questa versione è una compilazione pre-rilascio - usala a tuo rischio - non utilizzarla per la generazione o per applicazioni di commercio + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + Impossibile riportare il database ad un livello pre-fork. Dovrai riscaricare tutta la blockchain + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) Utilizza UPnP per mappare la porta in ascolto (default: 1 quando in ascolto e -proxy non è specificato) @@ -1756,6 +1917,14 @@ Per specificare più URL separarli con una barra verticale "|". Inserisce in whitelist i peer che si connettono da un dato indirizzo IP o netmask. Può essere specificato più volte. + You need to rebuild the database using -reindex-chainstate to change -txindex + È necessario ricostruire il database usando -reindex per cambiare -txindex + + + %s corrupt, salvage failed + %s corrotto, recupero fallito + + -maxmempool must be at least %d MB -maxmempool deve essere almeno %d MB @@ -1764,10 +1933,26 @@ Per specificare più URL separarli con una barra verticale "|". Valori possibili per <category>: + Append comment to the user agent string + Aggiungi commento alla stringa dell'applicazione utente + + + Attempt to recover private keys from a corrupt wallet on startup + Prova a recuperare le chiavi private da un portafoglio corrotto all'avvio + + Block creation options: Opzioni creazione blocco: + Cannot resolve -%s address: '%s' + Impossobile risolvere l'indirizzo -%s: '%s' + + + Change index out of range + Cambio indice fuori paramentro + + Connect only to the specified node(s) Connessione ai soli nodi specificati @@ -1776,6 +1961,10 @@ Per specificare più URL separarli con una barra verticale "|". Opzioni di connessione: + Copyright (C) %i-%i + Copyright (C) %i-%i + + Corrupted block database detected Rilevato database blocchi corrotto @@ -1808,6 +1997,10 @@ Per specificare più URL separarli con una barra verticale "|". Abilita pubblicazione transazione raw in <address> + Enable transaction replacement in the memory pool (default: %u) + Abilita la sostituzione della transazione nel pool della memoria (default: %u) + + Error initializing block database Errore durante l'inizializzazione del database dei blocchi @@ -1816,6 +2009,22 @@ Per specificare più URL separarli con una barra verticale "|". Errore durante l'inizializzazione dell'ambiente del database del portamonete %s! + Error loading %s + Errore caricamento %s + + + Error loading %s: Wallet corrupted + Errore caricamento %s: Portafoglio corrotto + + + Error loading %s: Wallet requires newer version of %s + Errore caricamento %s: il Portafoglio richiede una versione aggiornata di %s + + + Error loading %s: You can't disable HD on a already existing HD wallet + Errore caricamento %s: Non puoi disabilitare HD in un portafoglio HD già esistente + + Error loading block database Errore durante il caricamento del database blocchi @@ -1840,14 +2049,34 @@ Per specificare più URL separarli con una barra verticale "|". Blocco genesi non corretto o non trovato. È possibile che la cartella dati appartenga ad un'altra rete. + Initialization sanity check failed. %s is shutting down. + Test di integrità iniziale fallito. %s si arresterà. + + Invalid -onion address: '%s' Indirizzo -onion non valido: '%s' + Invalid amount for -%s=<amount>: '%s' + Importo non valido per -%s=<amount>: '%s' + + + Invalid amount for -fallbackfee=<amount>: '%s' + Importo non valido per -fallbackfee=<amount>: '%s' + + Keep the transaction memory pool below <n> megabytes (default: %u) Mantieni la memory pool delle transazioni al di sotto di <n> megabytes (default: %u) + Loading banlist... + Caricamento bloccati... + + + Location of the auth cookie (default: data dir) + Posizione del cookie di aiutorizzazione (default: data dir) + + Not enough file descriptors available. Non ci sono abbastanza descrittori di file disponibili. @@ -1856,6 +2085,14 @@ Per specificare più URL separarli con una barra verticale "|". Connessione ai soli nodi appartenenti alla rete <net> (ipv4, ipv6 o Tor) + Print this help message and exit + Mostra questo messaggio di aiuto ed esci + + + Print version and exit + Mostra la versione ed esci + + Prune cannot be configured with a negative value. La modalità prune non può essere configurata con un valore negativo. @@ -1864,10 +2101,26 @@ Per specificare più URL separarli con una barra verticale "|". La modalità prune è incompatibile con l'opzione -txindex. + Rebuild chain state and block index from the blk*.dat files on disk + Ricostruisci lo stato della catena e l'indice dei blocchi partendo dai file blk*.dat presenti sul disco + + + Rebuild chain state from the currently indexed blocks + Ricrea l'indice della catena dei blocchi partendo da quelli già indicizzati + + + Rewinding blocks... + Verifica blocchi... + + Set database cache size in megabytes (%d to %d, default: %d) Imposta la dimensione della cache del database in megabyte (%d a %d, predefinito: %d) + Set maximum BIP141 block weight (default: %d) + Imposta la dimensione massima del blocco BIP141 (default: %d) + + Set maximum block size in bytes (default: %d) Imposta la dimensione massima del blocco in byte (predefinito: %d) @@ -1876,6 +2129,14 @@ Per specificare più URL separarli con una barra verticale "|". Specifica il file del portamonete (all'interno della cartella dati) + The source code is available from %s. + Il codice sorgente è disponibile in %s + + + Unable to bind to %s on this computer. %s is probably already running. + Impossibile collegarsi a %s su questo computer. Probabilmente %s è già in esecuzione. + + Unsupported argument -benchmark ignored, use -debug=bench. Ignorata opzione -benchmark non supportata, utilizzare -debug=bench. @@ -1908,6 +2169,14 @@ Per specificare più URL separarli con una barra verticale "|". Il portamonete %s si trova al di fuori dalla cartella dati %s + Wallet debugging/testing options: + Opzioni di Debug/Test del portafoglio: + + + Wallet needed to be rewritten: restart %s to complete + Il portamonete necessita di essere riscritto: riavviare %s per completare + + Wallet options: Opzioni portamonete: @@ -1976,6 +2245,10 @@ Per specificare più URL separarli con una barra verticale "|". Questo prodotto include software sviluppato dal progetto OpenSSL per l'uso del Toolkit OpenSSL <https://www.openssl.org/>, software crittografico scritto da Eric Young e software UPnP scritto da Thomas Bernard. + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + Usa la generazione gerarchica deterministica (HD) della chiave dopo BIP32. Valido solamente durante la creazione del portafoglio o al primo avvio + + 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 I peer inclusi in whitelist non possono subire ban per DoS e le loro transazioni saranno sempre trasmesse, anche nel caso in cui si trovino già nel mempool. Ciò è utile ad es. per i gateway @@ -2112,6 +2385,10 @@ Per specificare più URL separarli con una barra verticale "|". Attenzione + Warning: unknown new rules activated (versionbit %i) + Attenzione: nuove regole non conosciute attivate (versionbit %i) + + Whether to operate in a blocks only mode (default: %u) Imposta se operare in modalità solo blocchi (default: %u) @@ -2192,6 +2469,10 @@ Per specificare più URL separarli con una barra verticale "|". Argomento -socks non supportato. Non è più possibile impostare la versione SOCKS, solamente i proxy SOCKS5 sono supportati. + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Argomento non supportato -whitelistalwaysrelay è stato ignorato, utilizzare -whitelistrelay e/o -whitelistforcerelay. + + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Usa un proxy SOCKS5 a parte per raggiungere i peer attraverso gli hidden services di Tor (predefinito: %s) @@ -2200,6 +2481,14 @@ Per specificare più URL separarli con una barra verticale "|". Username e hash password per connessioni JSON-RPC. Il campo <userpw> utilizza il formato: <USERNAME>:<SALT>$<HASH>. Uno script python standard è incluso in share/rpcuser. Questa opzione può essere specificata più volte + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Attenzione: si stanno minando versioni sconocsiute di blocchi! E' possibile che siano attive regole sconosciute + + + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + Attenzione: file del Portafoglio corrotto, dati recuperati! %s originale salvato come %s in %s; se il saldo o le transazioni non sono corrette effettua un ripristino da un backup. + + (default: %s) (predefinito: %s) @@ -2260,10 +2549,6 @@ Per specificare più URL separarli con una barra verticale "|". Imposta la dimensione del pool di chiavi a <n> (predefinito: %u) - Set minimum block size in bytes (default: %u) - Imposta la dimensione minima del blocco in byte (predefinito: %u) - - Set the number of threads to service RPC calls (default: %d) Imposta il numero di thread destinati a rispondere alle chiamate RPC (predefinito %d) diff --git a/src/qt/locale/bitcoin_it_IT.ts b/src/qt/locale/bitcoin_it_IT.ts index f89f4bdc48d..c36ae2e488e 100644 --- a/src/qt/locale/bitcoin_it_IT.ts +++ b/src/qt/locale/bitcoin_it_IT.ts @@ -41,7 +41,10 @@ &Delete Cancella - + + + AddressTableModel + AskPassphraseDialog @@ -56,10 +59,18 @@ Repeat new passphrase Ripeti nuova passphrase + + Warning: The Caps Lock key is on! + Attenzione: Il tasto blocco delle maiuscole è attivo! + BanTableModel + IP/Netmask + IP/Netmask + + Banned Until bannato fino @@ -96,13 +107,23 @@ OverviewPage + PaymentServer + + PeerTableModel QObject + QRImageWidget + + RPCConsole + + Ban Node for + Nodo bannato per + ReceiveCoinsDialog @@ -111,12 +132,18 @@ ReceiveRequestDialog + RecentRequestsTableModel + + SendCoinsDialog SendCoinsEntry + SendConfirmationDialog + + ShutdownWindow @@ -129,12 +156,30 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core \ No newline at end of file diff --git a/src/qt/locale/bitcoin_ja.ts b/src/qt/locale/bitcoin_ja.ts index 4948cc30675..3ca1f3e4f3a 100644 --- a/src/qt/locale/bitcoin_ja.ts +++ b/src/qt/locale/bitcoin_ja.ts @@ -41,6 +41,77 @@ &Delete 削除(&D) + + Choose the address to send coins to + 先のアドレスを選択 + + + Choose the address to receive coins with + 支払いを受け取るアドレスを指定する + + + C&hoose + 選択 (&C) + + + Sending addresses + 送金用 + + + Receiving addresses + 受け取りアドレス + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + これらは支払いを送信するためのあなたの Bitcoin アドレスです。コインを送信する前に、常に額と受信アドレスを確認してください。 + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + これらは支払いを受け取るためのビットコインアドレスです。トランザクションごとに新しい受け取り用アドレスを作成することが推奨されます。 + + + &Copy Address + アドレスをコピー (&C) + + + Copy &Label + ラベルをコピー (&L) + + + &Edit + 編集 (&E) + + + Export Address List + アドレス帳をエクスポート + + + Comma separated file (*.csv) + テキスト CSV (*.csv) + + + Exporting Failed + エクスポートに失敗しました + + + There was an error trying to save the address list to %1. Please try again. + トランザクション履歴を %1 へ保存する際にエラーが発生しました。再試行してください。 + + + + AddressTableModel + + Label + ラベル + + + Address + アドレス + + + (no label) + (ラベル無し) + AskPassphraseDialog @@ -60,6 +131,94 @@ Repeat new passphrase 新しいパスフレーズをもう一度 + + 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>. + ウォレットの新しいパスフレーズを入力してください。<br/><b>10文字以上のランダムな文字</b>で構成されたものか、<b>8単語以上の単語</b>で構成されたパスフレーズを使用してください。 + + + Encrypt wallet + ウォレットを暗号化する + + + This operation needs your wallet passphrase to unlock the wallet. + この操作はウォレットをアンロックするためにパスフレーズが必要です。 + + + Unlock wallet + ウォレットをアンロックする + + + This operation needs your wallet passphrase to decrypt the wallet. + この操作はウォレットの暗号化解除のためにパスフレーズが必要です。 + + + Decrypt wallet + ウォレットの暗号化を解除する + + + Change passphrase + パスフレーズの変更 + + + Enter the old passphrase and new passphrase to the wallet. + ウォレットの古いパスフレーズおよび新しいパスフレーズを入力してください。 + + + Confirm wallet encryption + ウォレットの暗号化を確認する + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + 警告: もしもあなたのウォレットを暗号化してパスフレーズを失ってしまったなら、<b>あなたの Bitcoin はすべて失われます</b>! + + + Are you sure you wish to encrypt your wallet? + 本当にウォレットを暗号化しますか? + + + Wallet encrypted + ウォレットは暗号化されました + + + %1 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. + 暗号化処理を完了させるため %1 をいますぐ終了します。ウォレットの暗号化では、コンピュータに感染したマルウェアなどによるビットコインの盗難から完全に守ることはできないことにご注意ください。 + + + 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. + 重要: 過去のウォレット ファイルのバックアップは、暗号化された新しいウォレット ファイルに取り替える必要があります。セキュリティ上の理由により、暗号化された新しいウォレットを使い始めると、暗号化されていないウォレット ファイルのバックアップはすぐに使えなくなります。 + + + Wallet encryption failed + ウォレットの暗号化に失敗しました + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + 内部エラーによりウォレットの暗号化が失敗しました。ウォレットは暗号化されませんでした。 + + + The supplied passphrases do not match. + パスフレーズが同じではありません。 + + + Wallet unlock failed + ウォレットのアンロックに失敗しました + + + The passphrase entered for the wallet decryption was incorrect. + ウォレットの暗号化解除のパスフレーズが正しくありません。 + + + Wallet decryption failed + ウォレットの暗号化解除に失敗しました + + + Wallet passphrase was successfully changed. + ウォレットのパスフレーズの変更が成功しました。 + + + Warning: The Caps Lock key is on! + 警告: Caps Lock キーがオンになっています! + BanTableModel @@ -463,6 +622,150 @@ Priority 優先度 + + Copy address + アドレスをコピーする + + + Copy label + ラベルをコピーする + + + Copy amount + 総額のコピー + + + Copy transaction ID + 取引 ID をコピー + + + Lock unspent + 未使用トランザクションをロックする + + + Unlock unspent + 未使用トランザクションをアンロックする + + + Copy quantity + 数量をコピーする + + + Copy fee + 手数料をコピーする + + + Copy after fee + 手数料差引後の値をコピーする + + + Copy bytes + バイト数をコピーする + + + Copy priority + 優先度をコピーする + + + Copy dust + ダストをコピーする + + + Copy change + 釣り銭をコピー + + + highest + 最高 + + + higher + 非常に高 + + + high + + + + medium-high + 中〜高 + + + medium + + + + low-medium + 低〜中 + + + low + + + + lower + 非常に低 + + + lowest + 最低 + + + (%1 locked) + (%1 がロック済み) + + + none + なし + + + yes + はい + + + no + いいえ + + + This label turns red if the transaction size is greater than 1000 bytes. + トランザクションのサイズが1000バイトを超える場合にはこのラベルは赤色になります。 + + + This means a fee of at least %1 per kB is required. + これは少なくとも1kBあたり %1 の手数料が必要であることを意味します。 + + + Can vary +/- 1 byte per input. + ひとつの入力につき1バイト程度ずれることがあります。 + + + Transactions with higher priority are more likely to get included into a block. + より高い優先度を持つトランザクションの方がブロックに取り込まれやすくなります。 + + + This label turns red if the priority is smaller than "medium". + 優先度が「中」未満の場合、このラベルは赤色になります。 + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + 少なくともひとつの受取額が現在のダスト閾値を下回る場合にはこのラベルは赤くなります。 + + + Can vary +/- %1 satoshi(s) per input. + ひとつの入力につき %1 satoshi 前後ずれることがあります。 + + + (no label) + (ラベル無し) + + + change from %1 (%2) + %1 (%2) からのおつり + + + (change) + (おつり) + EditAddressDialog @@ -486,6 +789,38 @@ &Address アドレス帳 (&A) + + New receiving address + 新しい受信アドレス + + + New sending address + 新しい送信アドレス + + + Edit receiving address + 入金アドレスを編集 + + + Edit sending address + 送信アドレスを編集 + + + The entered address "%1" is not a valid Bitcoin address. + 入力されたアドレス "%1" は無効な Bitcoin アドレスです。 + + + The entered address "%1" is already in the address book. + 入力されたアドレス "%1" は既にアドレス帳にあります。 + + + Could not unlock wallet. + ウォレットをアンロックできませんでした。 + + + New key generation failed. + 新しいキーの生成に失敗しました。 + FreespaceChecker @@ -626,6 +961,10 @@ Select payment request file 支払いリクエストファイルを選択してください + + Select payment request file to open + 開きたい支払いリクエストファイルを選択してください + OptionsDialog @@ -938,6 +1277,97 @@ + PaymentServer + + Payment request error + 支払いのリクエストのエラーです + + + Cannot start bitcoin: click-to-pay handler + Bitcoin を起動できません: click-to-pay handler + + + URI handling + URI の操作 + + + Payment request fetch URL is invalid: %1 + 支払い要求の取得先URLが無効です: %1 + + + Invalid payment address %1 + 支払いのアドレス「%1」は無効です + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + URI を解析できません! これは無効な Bitcoin アドレスあるいや不正な形式の URI パラメーターによって引き起こされる場合があります。 + + + Payment request file handling + 支払いリクエストファイルを処理しています + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + 支払いリクエストファイルを読み込めませんでした!無効な支払いリクエストファイルにより引き起こされた可能性があります。 + + + Payment request rejected + 支払い要求は拒否されました + + + Payment request network doesn't match client network. + 支払いリクエストのネットワークは現在のクライアントのネットワークに一致しません。 + + + Payment request expired. + 支払いリクエストの期限が切れました。 + + + Payment request is not initialized. + 支払いリクエストは開始されていません。 + + + Unverified payment requests to custom payment scripts are unsupported. + カスタム支払いスクリプトに対する、検証されていない支払いリクエストはサポートされていません。 + + + Invalid payment request. + 無効な支払いリクエスト。 + + + Requested payment amount of %1 is too small (considered dust). + 要求された支払額 %1 は少なすぎます (ダストとみなされてしまいます)。 + + + Refund from %1 + %1 からの返金 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + 支払リクエスト %1 は大きすぎます(%2バイトですが、%3バイトまでが許されています)。 + + + Error communicating with %1: %2 + %1: %2とコミュニケーション・エラーです + + + Payment request cannot be parsed! + 支払リクエストを読み込めませんでした! + + + Bad response from server %1 + サーバーの返事は無効 %1 + + + Network request error + ネットワーク・リクエストのエラーです + + + Payment acknowledged + 支払いは確認しました + + + PeerTableModel User Agent @@ -992,6 +1422,25 @@ + QRImageWidget + + &Save Image... + 画像を保存(&S) + + + &Copy Image + 画像をコピー(&C) + + + Save QR Code + QR コードの保存 + + + PNG Image (*.png) + PNG画像ファイル(*.png) + + + RPCConsole N/A @@ -1352,6 +1801,18 @@ Remove 削除 + + Copy label + ラベルをコピーする + + + Copy message + メッセージをコピーする + + + Copy amount + 総額のコピー + ReceiveRequestDialog @@ -1371,35 +1832,102 @@ &Save Image... 画像を保存(&S) - - - SendCoinsDialog - Send Coins - コインを送る + Request payment to %1 + %1 への支払いリクエストを行う - Coin Control Features - コインコントロール機能 + Payment information + 支払い情報 - Inputs... - 入力... + URI + URI - automatically selected - 自動選択 + Address + アドレス - Insufficient funds! - 残高不足です! + Amount + 総額 - Quantity: - 数量: + Label + ラベル - Bytes: + Message + メッセージ + + + Resulting URI too long, try to reduce the text for label / message. + URI が長くなり過ぎます。ラベルやメッセージのテキストを短くしてください。 + + + Error encoding URI into QR Code. + QR コード用の URI エンコードでエラー。 + + + + RecentRequestsTableModel + + Date + 日付 + + + Label + ラベル + + + Message + メッセージ + + + (no label) + (ラベル無し) + + + (no message) + (メッセージなし) + + + (no amount requested) + (金額指定なし) + + + Requested + 要求 + + + + SendCoinsDialog + + Send Coins + コインを送る + + + Coin Control Features + コインコントロール機能 + + + Inputs... + 入力... + + + automatically selected + 自動選択 + + + Insufficient funds! + 残高不足です! + + + Quantity: + 数量: + + + Bytes: バイト: @@ -1522,6 +2050,114 @@ S&end 送金 (&E) + + Copy quantity + 数量をコピーする + + + Copy amount + 総額のコピー + + + Copy fee + 手数料をコピーする + + + Copy after fee + 手数料差引後の値をコピーする + + + Copy bytes + バイト数をコピーする + + + Copy priority + 優先度をコピーする + + + Copy dust + ダストをコピーする + + + Copy change + 釣り銭をコピー + + + %1 to %2 + %1 から %2 + + + Are you sure you want to send? + 送ってよろしいですか? + + + added as transaction fee + 取引手数料として追加された + + + Total Amount %1 + 合計: %1 + + + or + または + + + Confirm send coins + コインを送る確認 + + + The recipient address is not valid. Please recheck. + 受取アドレスが不正です。再チェックしてください。 + + + The amount to pay must be larger than 0. + 支払額は0より大きくないといけません。 + + + The amount exceeds your balance. + 額が残高を超えています。 + + + The total exceeds your balance when the %1 transaction fee is included. + %1 の取引手数料を含めると額が残高を超えています。 + + + Duplicate address found: addresses should only be used once each. + 重複したアドレスが見つかりました: アドレスはそれぞれ一度のみ使用することができます。 + + + Transaction creation failed! + トラザクションの作成に失敗しました! + + + 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. + トランザクションは拒否されました。wallet.dat のコピーを使い、そしてコピーしたウォレットからコインを使用したことがマークされなかったときなど、ウォレットのいくつかのコインがすでに使用されている場合に、このエラーは起こるかもしれません。 + + + A fee higher than %1 is considered an absurdly high fee. + %1 よりも高い手数料の場合、手数料が高すぎると判断されます。 + + + Payment request expired. + 支払いリクエストの期限が切れました。 + + + Pay only the required fee of %1 + 要求手数料 %1 のみを支払う + + + Warning: Invalid Bitcoin address + 警告:無効なBitcoinアドレスです + + + Warning: Unknown change address + 警告:未知のおつりアドレスです + + + (no label) + (ラベル無し) + SendCoinsEntry @@ -1601,6 +2237,17 @@ Memo: メモ: + + Enter a label for this address to add it to your address book + アドレス帳に追加するには、このアドレスのラベルを入力します + + + + SendConfirmationDialog + + Yes + はい + ShutdownWindow @@ -1699,6 +2346,58 @@ Reset all verify message fields 入力項目の内容をすべて消去します + + Click "Sign Message" to generate signature + 署名を作成するには"メッセージの署名"をクリック + + + The entered address is invalid. + 不正なアドレスが入力されました。 + + + Please check the address and try again. + アドレスを確かめてからもう一度試してください。 + + + The entered address does not refer to a key. + 入力されたアドレスに関連するキーがありません。 + + + Wallet unlock was cancelled. + ウォレットのアンロックはキャンセルされました。 + + + Private key for the entered address is not available. + 入力されたアドレスのプライベート キーが無効です。 + + + Message signing failed. + メッセージの署名に失敗しました。 + + + Message signed. + メッセージに署名しました。 + + + The signature could not be decoded. + 署名がデコードできません。 + + + Please check the signature and try again. + 署名を確認してからもう一度試してください。 + + + The signature did not match the message digest. + 署名はメッセージ ダイジェストと一致しませんでした。 + + + Message verification failed. + メッセージの検証に失敗しました。 + + + Message verified. + メッセージは検証されました。 + SplashScreen @@ -1715,11 +2414,456 @@ + TransactionDesc + + Open for %n more block(s) + %n 以上のブロックを開く + + + Open until %1 + ユニット %1 を開く + + + conflicted with a transaction with %1 confirmations + %1 検証のトランザクションと衝突 + + + %1/offline + %1/オフライン + + + 0/unconfirmed, %1 + 0/未検証, %1 + + + in memory pool + メモリプール内 + + + not in memory pool + メモリプール外 + + + abandoned + 中止 + + + %1/unconfirmed + %1/未検証 + + + %1 confirmations + %1 確認 + + + Status + ステータス + + + , has not been successfully broadcast yet + まだブロードキャストが成功していません + + + , broadcast through %n node(s) + %n ノードにブロードキャスト + + + Date + 日付 + + + Source + ソース + + + Generated + 生成された + + + From + 送信 + + + unknown + 未確認 + + + To + 受信 + + + own address + 自分のアドレス + + + watch-only + 監視限定 + + + label + ラベル + + + Credit + クレジット + + + matures in %n more block(s) + %n 以上のブロックが満期 + + + not accepted + 承認されなかった + + + Debit + 引き落とし額 + + + Total debit + 総出金額 + + + Total credit + 総入金額 + + + Transaction fee + 取引手数料 + + + Net amount + 正味金額 + + + Message + メッセージ + + + Comment + コメント + + + Transaction ID + 取引 ID + + + Output index + 出力インデックス + + + Merchant + 商人 + + + 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. + 生成されたコインは使う前に%1のブロックを完成させる必要があります。あなたが生成した時、このブロックはブロック チェーンに追加されるネットワークにブロードキャストされました。チェーンに追加されるのが失敗した場合、状態が"不承認"に変更されて使えなくなるでしょう。これは、別のノードがあなたの数秒前にブロックを生成する場合に時々起こるかもしれません。 + + + Debug information + デバッグ情報 + + + Transaction + 取引 + + + Inputs + 入力 + + + Amount + 総額 + + + true + 正しい + + + false + 正しくない + + + TransactionDescDialog This pane shows a detailed description of the transaction ここでは取引の詳細を表示しています + + Details for %1 + %1 の詳細 + + + + TransactionTableModel + + Date + 日付 + + + Type + タイプ + + + Label + ラベル + + + Open for %n more block(s) + %n 以上のブロックを開く + + + Open until %1 + ユニット %1 を開く + + + Offline + オフライン + + + Unconfirmed + 未検証 + + + Abandoned + 中止 + + + Confirming (%1 of %2 recommended confirmations) + 検証中(%2の推奨検証数のうち、%1検証が完了) + + + Confirmed (%1 confirmations) + 検証されました (%1 検証済み) + + + Conflicted + 衝突 + + + Immature (%1 confirmations, will be available after %2) + 未成熟(%1検証。%2検証完了後に使用可能となります) + + + This block was not received by any other nodes and will probably not be accepted! + このブロックは他のどのノードによっても受け取られないで、多分受け入れられないでしょう! + + + Generated but not accepted + 生成されましたが承認されませんでした + + + Received with + 送り主 + + + Received from + 送り主 + + + Sent to + 送り先 + + + Payment to yourself + 自分自身への支払い + + + Mined + 発掘した + + + watch-only + 監視限定 + + + (n/a) + (n/a) + + + (no label) + (ラベル無し) + + + Transaction status. Hover over this field to show number of confirmations. + 取引の状況。このフィールドの上にカーソルを置くと検証の数を表示します。 + + + Date and time that the transaction was received. + 取引を受信した日時。 + + + Type of transaction. + 取引の種類。 + + + Whether or not a watch-only address is involved in this transaction. + 監視限定アドレスがこのトランザクションに含まれているかどうか + + + User-defined intent/purpose of the transaction. + ユーザ定義のトランザクションの意図や目的。 + + + Amount removed from or added to balance. + 残高に追加または削除された総額。 + + + + TransactionView + + All + すべて + + + Today + 今日 + + + This week + 今週 + + + This month + 今月 + + + Last month + 先月 + + + This year + 今年 + + + Range... + 期間... + + + Received with + 送り主 + + + Sent to + 送り先 + + + To yourself + 自分自身 + + + Mined + 発掘した + + + Other + その他 + + + Enter address or label to search + 検索するアドレスまたはラベルを入力 + + + Min amount + 最小の額 + + + Abandon transaction + 取引の中止 + + + Copy address + アドレスをコピーする + + + Copy label + ラベルをコピーする + + + Copy amount + 総額のコピー + + + Copy transaction ID + 取引 ID をコピー + + + Copy raw transaction + 生トランザクションをコピー + + + Copy full transaction details + トランザクションの詳細すべてをコピー + + + Edit label + ラベルの編集 + + + Show transaction details + 取引の詳細を表示 + + + Export Transaction History + トランザクション履歴をエクスポートする + + + Comma separated file (*.csv) + テキスト CSV (*.csv) + + + Confirmed + 検証済み + + + Watch-only + 監視限定 + + + Date + 日付 + + + Type + タイプ + + + Label + ラベル + + + Address + アドレス + + + ID + ID + + + Exporting Failed + エクスポートに失敗しました + + + There was an error trying to save the transaction history to %1. + トランザクション履歴を %1 へ保存する際にエラーが発生しました。 + + + Exporting Successful + エクスポートに成功しました + + + The transaction history was successfully saved to %1. + トランザクション履歴は正常に%1に保存されました。 + + + Range: + 期間: + + + to + から + UnitDisplayStatusBarControl @@ -1729,6 +2873,55 @@ + WalletFrame + + No wallet has been loaded. + ウォレットがロードされていません + + + + WalletModel + + Send Coins + コインを送る + + + + WalletView + + &Export + エクスポート (&E) + + + Export the data in the current tab to a file + ファイルに現在のタブのデータをエクスポート + + + Backup Wallet + ウォレットのバックアップ + + + Wallet Data (*.dat) + ウォレット データ (*.dat) + + + Backup Failed + バックアップに失敗しました + + + There was an error trying to save the wallet data to %1. + ウォレットデータを%1へ保存する際にエラーが発生しました。 + + + Backup Successful + バックアップ成功 + + + The wallet data was successfully saved to %1. + ウォレット データは正常に%1に保存されました。 + + + bitcoin-core Options: @@ -1831,6 +3024,10 @@ MITソフトウェアライセンスのもとで配布されています。付属のCOPYINGファイルまたは<http://www.opensource.org/licenses/mit-license.php>を参照してください。 + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + 中継や採掘を行う際のトランザクション内の、sigopあたりバイト数の相当量 (初期値: %u) + + Error loading %s: You can't enable HD on a already existing non-HD wallet %s の読み込みエラー: 非HDウォレットが既に存在するため、HDウォレットを有効化できません @@ -1843,10 +3040,6 @@ ウォレットの取引を変更する際にコマンドを実行 (cmd の %s は TxID に置換される) - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - ホワイトリストのピアから受け取ったトランザクションに関しては、たとえローカルの中継ポリシーに違反しているとしても中継を行うようにする (デフォルト: %d) - - Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) 時間オフセット調整値のピア中央値に対する最大の許容値。ローカル時間の見込み値は、接続するピアにより前方ないし後方へ影響されます。(初期値: %u 秒) @@ -2056,10 +3249,6 @@ 認証クッキーの場所 (デフォルト: ) - Minimum bytes per sigop in transactions we relay and mine (default: %u) - 中継や採掘を行ってもよい、sigopあたりの最小バイト数 (デフォルト: %u) - - Not enough file descriptors available. 使用可能なファイルディスクリプタが不足しています。 @@ -2100,8 +3289,8 @@ データベースのキャッシュサイズをメガバイトで設定 (%dから%d。初期値: %d) - Set maximum block cost (default: %d) - 最大ブロックコストを設定 (初期値: %d) + Set maximum BIP141 block weight (default: %d) + BIP141ブロック重みの最大値を設定 (初期値: %d) Set maximum block size in bytes (default: %d) @@ -2112,6 +3301,10 @@ ウォレットのファイルを指定 (データ・ディレクトリの中に) + Starting network threads... + ネットワークのスレッドを起動しています... + + The source code is available from %s. ソースコードは %s より入手可能です。 @@ -2196,6 +3389,10 @@ トランザクションの中継、採掘および作成の際には、この値未満の手数料 (%s/kB単位) はゼロであるとみなす (デフォルト: %s) + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + ホワイトリストのピアから受け取ったトランザクションに関しては、たとえローカルの中継ポリシーに違反しているとしても中継を行うようにする (デフォルト: %d) + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) paytxfee が設定されていなかった場合、平均して n ブロック以内にトランザクションが検証され始めるのに十分な手数料を含める (初期値: %u) @@ -2532,10 +3729,6 @@ key pool のサイズを <n> (初期値: %u) にセット - Set minimum block size in bytes (default: %u) - 最小ブロックサイズをバイトで設定 (初期値: %u) - - Set the number of threads to service RPC calls (default: %d) RPC サービスのスレッド数を設定 (初期値: %d) diff --git a/src/qt/locale/bitcoin_ka.ts b/src/qt/locale/bitcoin_ka.ts index 80508be8eeb..b2b9a58e568 100644 --- a/src/qt/locale/bitcoin_ka.ts +++ b/src/qt/locale/bitcoin_ka.ts @@ -37,7 +37,10 @@ &Delete &წაშლა - + + + AddressTableModel + AskPassphraseDialog @@ -56,7 +59,7 @@ Repeat new passphrase გაიმეორეთ ახალი ფრაზა-პაროლი - + BanTableModel @@ -353,7 +356,7 @@ Priority პრიორიტეტი - + EditAddressDialog @@ -376,7 +379,7 @@ &Address მის&ამართი - + FreespaceChecker @@ -456,7 +459,7 @@ Select payment request file გადახდის მოთხოვნის ფაილის არჩევა - + OptionsDialog @@ -640,6 +643,9 @@ + PaymentServer + + PeerTableModel @@ -662,6 +668,9 @@ + QRImageWidget + + RPCConsole N/A @@ -842,7 +851,7 @@ Remove წაშლა - + ReceiveRequestDialog @@ -861,7 +870,10 @@ &Save Image... გამო&სახულების შენახვა... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -952,7 +964,7 @@ S&end გაგ&ზავნა - + SendCoinsEntry @@ -1011,7 +1023,10 @@ Memo: შენიშვნა: - + + + SendConfirmationDialog + ShutdownWindow @@ -1089,7 +1104,7 @@ Reset all verify message fields ვერიფიკაციის ყველა ველის წაშლა - + SplashScreen @@ -1105,16 +1120,34 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction ტრანსაქციის დაწვრილებითი აღწერილობა - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_kk_KZ.ts b/src/qt/locale/bitcoin_kk_KZ.ts index ff02521264f..28c9949589a 100644 --- a/src/qt/locale/bitcoin_kk_KZ.ts +++ b/src/qt/locale/bitcoin_kk_KZ.ts @@ -25,7 +25,10 @@ &Delete Жою - + + + AddressTableModel + AskPassphraseDialog @@ -40,7 +43,7 @@ Repeat new passphrase Жаңа құпия сөзді қайта енгізу - + BanTableModel @@ -173,7 +176,7 @@ Priority Басымдық - + EditAddressDialog @@ -184,7 +187,7 @@ &Address Адрес - + FreespaceChecker @@ -212,6 +215,9 @@ OverviewPage + PaymentServer + + PeerTableModel @@ -222,6 +228,9 @@ + QRImageWidget + + RPCConsole &Information @@ -239,6 +248,9 @@ ReceiveRequestDialog + RecentRequestsTableModel + + SendCoinsDialog Amount: @@ -269,6 +281,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -281,12 +296,30 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Information diff --git a/src/qt/locale/bitcoin_ko_KR.ts b/src/qt/locale/bitcoin_ko_KR.ts index 012632c0e0a..399322d4516 100644 --- a/src/qt/locale/bitcoin_ko_KR.ts +++ b/src/qt/locale/bitcoin_ko_KR.ts @@ -41,7 +41,22 @@ &Delete 삭제(&D) - + + C&hoose + 선택 (&H) + + + &Edit + 편집 (&E) + + + + AddressTableModel + + Address + 주소 + + AskPassphraseDialog @@ -60,7 +75,7 @@ Repeat new passphrase 새로운 암호 재확인 - + BanTableModel @@ -111,6 +126,14 @@ 어플리케이션 종료 + &About %1 + %1 정보(&A) + + + Show information about %1 + %1 정보를 표시합니다 + + About &Qt &Qt 정보 @@ -123,6 +146,10 @@ 옵션(&O) + Modify configuration options for %1 + %1 설정 옵션 수정 + + &Encrypt Wallet... 지갑 암호화(&E)... @@ -251,6 +278,14 @@ 비트코인 네트워크에 %n개의 연결이 활성화되어 있습니다. + Indexing blocks on disk... + 디스크에서 블록 색인중... + + + Processing blocks on disk... + 디스크에서 블록 처리중... + + No block source available... 사용 가능한 블록이 없습니다... @@ -307,6 +342,14 @@ 현재까지 + Show the %1 help message to get a list with possible Bitcoin command-line options + 사용할 수 있는 비트코인 명령줄 옵션 목록을 가져오기 위해 %1 도움말 메시지를 표시합니다. + + + %1 client + %1 클라이언트 + + Catching up... 블록 따라잡기... @@ -435,7 +478,11 @@ Priority 우선순위 - + + Copy address + 주소 복사 + + EditAddressDialog @@ -458,7 +505,7 @@ &Address 주소(&A) - + FreespaceChecker @@ -493,6 +540,10 @@ (%1-비트) + About %1 + %1 정보(&A) + + Command-line options 명령줄 옵션 @@ -528,7 +579,11 @@ Show splash screen on startup (default: %u) 실행시 시작화면 보기 (기본값: %u) - + + Reset all settings changed in the GUI + GUI를 통해 수정된 모든 설정을 초기화 + + Intro @@ -536,6 +591,18 @@ 환영합니다 + Welcome to %1. + %1에 오신것을 환영합니다. + + + As this is the first time the program is launched, you can choose where %1 will store its data. + 프로그램이 처음으로 실행되고 있습니다. %1가 어디에 데이터를 저장할지 선택할 수 있습니다. + + + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1가 블럭체인의 복사본을 다운로드 저장합니다. 적어도 %2GB의 데이터가 이 폴더에 저장되며 시간이 경과할수록 점차 증가합니다. 그리고 지갑 또한 이 폴더에 저장됩니다. + + Use the default data directory 기본 데이터 폴더를 사용하기 @@ -578,7 +645,7 @@ Select payment request file 지불 요청 파일을 선택하세요 - + OptionsDialog @@ -590,6 +657,14 @@ 메인(&M) + Automatically start %1 after logging in to the system. + 시스템 로그인후에 %1을 자동으로 시작합니다. + + + &Start %1 on system login + 시스템 로그인시 %1 시작(&S) + + Size of &database cache 데이터베이스 캐시 크기(&D) @@ -691,7 +766,7 @@ Port of the proxy (e.g. 9050) - 프록시의 포트번호입니다(예: 9050) + 프록시의 포트번호입니다 (예: 9050) Used for reaching peers via: @@ -726,6 +801,14 @@ 창(&W) + &Hide the icon from the system tray. + 시스템 트레이 로 부터 아이콘 숨기기(&H) + + + Hide tray icon + 트레이 아이콘 숨기기 + + Show only a tray icon after minimizing the window. 창을 최소화 하면 트레이에 아이콘만 표시합니다. @@ -746,6 +829,10 @@ 사용자 인터페이스 언어(&L): + The user interface language can be set here. This setting will take effect after restarting %1. + 사용자 인터페이스 언어를 여기서 설정할 수 있습니다. 이 설정은 %1을 다시 시작할때 적용됩니다. + + &Unit to show amounts in: 거래액을 표시할 단위(&U): @@ -870,6 +957,9 @@ + PaymentServer + + PeerTableModel User Agent @@ -924,6 +1014,9 @@ + QRImageWidget + + RPCConsole N/A @@ -950,6 +1043,10 @@ 사용 중인 BerkeleyDB 버전 + Datadir + 데이터 폴더 + + Startup time 시작 시간 @@ -1034,6 +1131,18 @@ 유저 에이전트 + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + %1 디버그 로그파일을 현재 데이터 폴더에서 엽니다. 용량이 큰 로그 파일들은 몇 초가 걸릴 수 있습니다. + + + Decrease font size + 글자 크기 축소 + + + Increase font size + 글자 크기 확대 + + Services 서비스 @@ -1138,6 +1247,10 @@ 노드 추방 취소(&U) + Welcome to the %1 RPC console. + %1 RPC 콘솔에 오신걸 환영합니다 + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. 기록을 찾아보려면 위 아래 화살표 키를, 화면을 지우려면 <b>Ctrl-L</b>키를 사용하십시오. @@ -1264,7 +1377,7 @@ Remove 삭제 - + ReceiveRequestDialog @@ -1283,7 +1396,14 @@ &Save Image... 이미지 저장(&S)... - + + Address + 주소 + + + + RecentRequestsTableModel + SendCoinsDialog @@ -1434,7 +1554,7 @@ S&end 보내기(&E) - + SendCoinsEntry @@ -1443,11 +1563,11 @@ Pay &To: - 송금할 대상(&T) : + 송금할 대상(&T): &Label: - 라벨(&L) + 라벨(&L): Choose previously used address @@ -1507,16 +1627,23 @@ Pay To: - 송금할 대상 : + 송금할 대상: Memo: 메모: - + + + SendConfirmationDialog + ShutdownWindow + %1 is shutting down... + %1이 종료 중입니다... + + Do not shut down the computer until this window disappears. 창이 사라지기 전까지 컴퓨터를 끄지마시오. @@ -1607,7 +1734,7 @@ Reset all verify message fields 모든 검증 메시지 필드 재설정 - + SplashScreen @@ -1623,12 +1750,29 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction 이 창은 거래의 세부내역을 보여줍니다 - + + + TransactionTableModel + + + TransactionView + + Copy address + 주소 복사 + + + Address + 주소 + + UnitDisplayStatusBarControl @@ -1637,6 +1781,15 @@ + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: @@ -1707,6 +1860,10 @@ 비트코인 코어 + The %s developers + %s 코어 개발자 + + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. -fallbackfee은 너무 높습니다! 이것은 수수료 예측을 이용할 수 없을 때 지불되는 트랜잭션 수수료입니다. @@ -1723,6 +1880,10 @@ 선택된 주소로 고정하며 항상 리슨(Listen)합니다. IPv6 프로토콜인 경우 [host]:port 방식의 명령어 표기법을 사용합니다. + Cannot obtain a lock on data directory %s. %s is probably already running. + %s 데이터 디렉토리에 락을 걸 수 없었습니다. %s가 이미 실행 중인 것으로 보입니다. + + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup 시작시 모든 지갑 트랜잭션을 삭제하고 -rescan을 통하여 블록체인만 복구합니다. @@ -1731,12 +1892,28 @@ MIT 소프트웨어 라이센스에 따라 배포됩니다. 동봉된 파일 혹은 <http://www.opensource.org/licenses/mit-license.php>를 참조하세요. + Error loading %s: You can't enable HD on a already existing non-HD wallet + %s 불러오기 오류: 비-HD 지갑이 존재하는 상태에서 HD 지갑을 활성화 할 수 없습니다 + + + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + %s 불러오기 오류: 주소 키는 모두 정확하게 로드되었으나 거래 데이터와 주소록 필드에서 누락이나 오류가 존재할 수 있습니다. + + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) 지갑 거래가 바뀌면 명령을 실행합니다.(%s 안의 명령어가 TxID로 바뀝니다) - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - 피어들이 로컬 중계 정책을 위반하더라도 화이트 리스트에 포함된 피어인경우 강제로 중계하기 (기본값: %d) + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + 하나의 지갑 트랜잭션에서의 총 수수료(%s)의 최대치; 너무 낮게 설정하면 큰 트랜잭션이 중지 됩니다 (기본값: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + 컴퓨터의 날짜와 시간이 올바른지 확인하십시오! 시간이 잘못되면 %s은 제대로 동작하지 않습니다. + + + Please contribute if you find %s useful. Visit %s for further information about the software. + %s가 유용하다고 생각한다면 프로젝트에 공헌해주세요. 이 소프트웨어에 대한 보다 자세한 정보는 %s를 방문해주십시오. Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) @@ -1751,6 +1928,10 @@ 이 빌드 버전은 정식 출시 전 테스트의 목적이며, 예기치 않은 위험과 오류가 발생할 수 있습니다. 채굴과 상점용 소프트웨어로 사용하는 것을 권하지 않습니다. + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + 데이터베이스를 포크 전 상태로 돌리지 못했습니다. 블록체인을 다시 다운로드 해주십시오. + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) 리슨(Listen) 포트를 할당하기 위해 UPnP 사용 (기본값: 열려있거나 -proxy 옵션을 사용하지 않을 시 1) @@ -1767,6 +1948,14 @@ 설정된 넷마스크 혹은 IP 주소로 화이트리스트에 포함된 피어에 접속합니다. 이 설정은 복수로 지정 할 수 있습니다. + You need to rebuild the database using -reindex-chainstate to change -txindex + -txindex를 바꾸기 위해서는 -reindex-chainstate를 사용해서 데이터베이스를 재구성해야 합니다. + + + %s corrupt, salvage failed + %s 손상되었고 복구가 실패하였습니다 + + -maxmempool must be at least %d MB -maxmempool은 최소한 %d MB가 필요합니다 @@ -1779,10 +1968,18 @@ 사용자 에이전트 문자열에 코멘트 첨부 + Attempt to recover private keys from a corrupt wallet on startup + 시작시 망가진 wallet.dat에서 개인키 복원을 시도합니다 + + Block creation options: 블록 생성 옵션: + Cannot resolve -%s address: '%s' + %s 주소를 확인할 수 없습니다: '%s' + + Connect only to the specified node(s) 지정된 노드에만 연결하기 @@ -1791,6 +1988,10 @@ 연결 설정 : + Copyright (C) %i-%i + Copyright (C) %i-%i + + Corrupted block database detected 손상된 블록 데이터베이스가 감지되었습니다 @@ -1835,6 +2036,22 @@ 지갑 데이터베이스 환경 초기화하는데 오류 %s + Error loading %s + %s 불러오기 오류 + + + Error loading %s: Wallet corrupted + %s 불러오기 오류: 지갑 오류 + + + Error loading %s: Wallet requires newer version of %s + %s 불러오기 에러: 지갑은 새 버전의 %s이 필요합니다 + + + Error loading %s: You can't disable HD on a already existing HD wallet + %s 불러오기 오류: 이미 HD 지갑이 존재하는 상태에서 HD 지갑을 비활성화 할 수 없습니다 + + Error loading block database 블록 데이터베이스를 불러오는데 오류 @@ -1859,10 +2076,18 @@ 올바르지 않거나 생성된 블록을 찾을 수 없습니다. 잘못된 네트워크 자료 디렉토리? + Initialization sanity check failed. %s is shutting down. + 무결성 확인 초기화가 실패했습니다. %s가 종료됩니다. + + Invalid -onion address: '%s' 잘못된 -onion 주소입니다: '%s' + Invalid amount for -%s=<amount>: '%s' + 유효하지 않은 금액 -%s=<amount>: '%s' + + Invalid amount for -fallbackfee=<amount>: '%s' 유효하지 않은 금액 -fallbackfee=<amount>: '%s' @@ -1871,12 +2096,12 @@ 트랜잭션 메모리 풀의 용량을 <n>메가바이트 아래로 유지하기 (기본값: %u) - Location of the auth cookie (default: data dir) - 인증 쿠키의 위치 (기본값: data dir) + Loading banlist... + 추방리스트를 불러오는 중... - Minimum bytes per sigop in transactions we relay and mine (default: %u) - 중계 및 채굴을 할 때 트랜잭션에서의 sigop 당 데이터의 최소 크기 (기본값: %u) + Location of the auth cookie (default: data dir) + 인증 쿠키의 위치 (기본값: data dir) Not enough file descriptors available. @@ -1887,6 +2112,10 @@ 오직 <net> 네트워크로 로만 접속 (IPv4, IPv6 혹은 onion) + Print this help message and exit + 도움말 메시지 출력 후 종료 + + Print version and exit 버전 출력후 종료 @@ -1899,6 +2128,18 @@ 블록 축소 모드는 -txindex와 호환되지 않습니다. + Rebuild chain state and block index from the blk*.dat files on disk + 현재의 blk*.dat 파일들로부터 블록체인 색인을 재구성합니다. + + + Rebuild chain state from the currently indexed blocks + 현재 색인 된 블록들로부터 블록체인을 재구성합니다. + + + Rewinding blocks... + 블록 되감는중... + + Set database cache size in megabytes (%d to %d, default: %d) 데이터베이스 케시 크기를 메가바이트로 설정(%d 부터 %d, 기본값: %d) @@ -1911,6 +2152,14 @@ 데이터 폴더 안에 지갑 파일을 선택하세요. + The source code is available from %s. + 소스코드는 %s 에서 확인하실 수 있습니다. + + + Unable to bind to %s on this computer. %s is probably already running. + 이 컴퓨터의 %s에 바인딩 할 수 없습니다. 아마도 %s이 실행중인 것 같습니다. + + Unsupported argument -benchmark ignored, use -debug=bench. 지원하지 않는 인수 -benchmark 은 무시됩니다, -debug=bench 형태로 사용하세요. @@ -1947,6 +2196,10 @@ 지갑 디버깅/테스트 옵션: + Wallet needed to be rewritten: restart %s to complete + 지갑을 새로 써야 합니다: 완성하기 위하여 %s을 다시 시작하십시오. + + Wallet options: 지갑 옵션: @@ -2247,6 +2500,10 @@ 경고: 알려지지 않은 버전의 블록이 채굴되었습니다. 알려지지 않은 규칙이 적용되었을 가능성이 있습니다. + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + 경고 : 지갑파일이 손상되어 데이터가 복구되었습니다. 원래의 %s 파일은 %s 후에 %s 이름으로 저장됩니다. 잔액과 거래 내역이 정확하지 않다면 백업 파일로 부터 복원해야 합니다. + + Always query for peer addresses via DNS lookup (default: %u) DNS lookup을 통해 항상 피어주소에 대한 쿼리 보내기 (기본값: %u) diff --git a/src/qt/locale/bitcoin_ku_IQ.ts b/src/qt/locale/bitcoin_ku_IQ.ts index da5e41a3583..80fa68289b2 100644 --- a/src/qt/locale/bitcoin_ku_IQ.ts +++ b/src/qt/locale/bitcoin_ku_IQ.ts @@ -25,7 +25,14 @@ &Delete &سڕینەوە - + + + AddressTableModel + + Address + ناوونیشان + + AskPassphraseDialog @@ -89,7 +96,23 @@ Priority لەپێشی - + + high + بەرز + + + low + نزم + + + yes + بەڵێ + + + no + نەخێر + + EditAddressDialog @@ -136,6 +159,9 @@ + PaymentServer + + PeerTableModel @@ -146,20 +172,39 @@ + QRImageWidget + + RPCConsole &Information &زانیاری + General + گشتی + + + Network + تۆڕ + + Name ناو + Sent + نێدرا + + Version وەشان + Services + خزمەتگوزاریەکان + + &Open &کردنەوە @@ -172,6 +217,34 @@ گشتییەکان + In: + لە ناو + + + Out: + لەدەرەوە + + + 1 &hour + 1&سات + + + 1 &day + 1&ڕۆژ + + + 1 &week + 1&هەفتە + + + 1 &year + 1&ساڵ + + + never + هەرگیز + + Yes بەڵێ @@ -202,9 +275,16 @@ Remove سڕینەوە - + ReceiveRequestDialog + + Address + ناوونیشان + + + + RecentRequestsTableModel SendCoinsDialog @@ -233,6 +313,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -245,12 +328,34 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + Address + ناوونیشان + + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_ky.ts b/src/qt/locale/bitcoin_ky.ts index 14cb9c20201..b9be5f8ec65 100644 --- a/src/qt/locale/bitcoin_ky.ts +++ b/src/qt/locale/bitcoin_ky.ts @@ -9,7 +9,10 @@ &Delete Ө&чүрүү - + + + AddressTableModel + AskPassphraseDialog @@ -72,7 +75,7 @@ &Address &Дарек - + FreespaceChecker @@ -136,12 +139,18 @@ OverviewPage + PaymentServer + + PeerTableModel QObject + QRImageWidget + + RPCConsole &Information @@ -183,6 +192,9 @@ ReceiveRequestDialog + RecentRequestsTableModel + + SendCoinsDialog Clear &All @@ -192,7 +204,7 @@ S&end &Жөнөтүү - + SendCoinsEntry @@ -205,6 +217,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -225,12 +240,30 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Information diff --git a/src/qt/locale/bitcoin_la.ts b/src/qt/locale/bitcoin_la.ts index dc532fe0119..4fff8c6536a 100644 --- a/src/qt/locale/bitcoin_la.ts +++ b/src/qt/locale/bitcoin_la.ts @@ -25,7 +25,10 @@ &Delete &Dele - + + + AddressTableModel + AskPassphraseDialog @@ -44,7 +47,7 @@ Repeat new passphrase Itera novam tesseram - + BanTableModel @@ -276,7 +279,7 @@ &Address &Inscriptio - + FreespaceChecker @@ -428,6 +431,9 @@ + PaymentServer + + PeerTableModel @@ -442,6 +448,9 @@ + QRImageWidget + + RPCConsole N/A @@ -531,6 +540,9 @@ + RecentRequestsTableModel + + SendCoinsDialog Send Coins @@ -572,7 +584,7 @@ S&end &Mitte - + SendCoinsEntry @@ -609,6 +621,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -677,7 +692,7 @@ Reset all verify message fields Reconstitue omnes campos verificandi nuntii - + SplashScreen @@ -689,16 +704,34 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Haec tabula monstrat descriptionem verbosam transactionis - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_lt.ts b/src/qt/locale/bitcoin_lt.ts index 1f6cda1f52b..3ed8e2ca312 100644 --- a/src/qt/locale/bitcoin_lt.ts +++ b/src/qt/locale/bitcoin_lt.ts @@ -41,7 +41,10 @@ &Delete &Trinti - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Pakartokite naują slaptafrazę - + BanTableModel @@ -325,7 +328,7 @@ Priority Pirmumas - + EditAddressDialog @@ -340,7 +343,7 @@ &Address &Adresas - + FreespaceChecker @@ -540,6 +543,9 @@ + PaymentServer + + PeerTableModel @@ -562,6 +568,9 @@ + QRImageWidget + + RPCConsole N/A @@ -703,6 +712,9 @@ + RecentRequestsTableModel + + SendCoinsDialog Send Coins @@ -768,7 +780,7 @@ S&end &Siųsti - + SendCoinsEntry @@ -805,6 +817,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -869,16 +884,34 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Šis langas sandorio detalų aprašymą - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_lv_LV.ts b/src/qt/locale/bitcoin_lv_LV.ts index 38333531e48..ab528229c42 100644 --- a/src/qt/locale/bitcoin_lv_LV.ts +++ b/src/qt/locale/bitcoin_lv_LV.ts @@ -37,7 +37,10 @@ &Delete &Dzēst - + + + AddressTableModel + AskPassphraseDialog @@ -56,7 +59,7 @@ Repeat new passphrase Jaunā parole vēlreiz - + BanTableModel @@ -341,7 +344,7 @@ Priority Prioritāte - + EditAddressDialog @@ -356,7 +359,7 @@ &Address &Adrese - + FreespaceChecker @@ -436,7 +439,7 @@ Select payment request file Izvēlies maksājuma pieprasījuma datni - + OptionsDialog @@ -628,6 +631,9 @@ + PaymentServer + + PeerTableModel @@ -650,6 +656,9 @@ + QRImageWidget + + RPCConsole N/A @@ -810,7 +819,7 @@ Remove Noņemt - + ReceiveRequestDialog @@ -829,7 +838,10 @@ &Save Image... &Saglabāt Attēlu... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -916,7 +928,7 @@ S&end &Sūtīt - + SendCoinsEntry @@ -967,7 +979,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1041,7 +1056,7 @@ Reset all verify message fields Atiestatīt visus laukus - + SplashScreen @@ -1057,16 +1072,34 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Šis panelis parāda transakcijas detaļas - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_mk_MK.ts b/src/qt/locale/bitcoin_mk_MK.ts index b696111a537..dd1ce4d0894 100644 --- a/src/qt/locale/bitcoin_mk_MK.ts +++ b/src/qt/locale/bitcoin_mk_MK.ts @@ -41,7 +41,10 @@ &Delete &Избриши - + + + AddressTableModel + AskPassphraseDialog @@ -56,7 +59,7 @@ Repeat new passphrase Повторете ја новата тајна фраза - + BanTableModel @@ -287,7 +290,7 @@ Priority Приоритет - + EditAddressDialog @@ -302,7 +305,7 @@ &Address &Адреса - + FreespaceChecker @@ -382,6 +385,9 @@ + PaymentServer + + PeerTableModel @@ -412,6 +418,9 @@ + QRImageWidget + + RPCConsole Network @@ -495,7 +504,10 @@ &Save Image... &Сними Слика... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -543,6 +555,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -555,12 +570,30 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_mn.ts b/src/qt/locale/bitcoin_mn.ts index d9ef0d127b8..70b1b470d63 100644 --- a/src/qt/locale/bitcoin_mn.ts +++ b/src/qt/locale/bitcoin_mn.ts @@ -37,7 +37,10 @@ &Delete &Устгах - + + + AddressTableModel + AskPassphraseDialog @@ -52,7 +55,7 @@ Repeat new passphrase Шинэ нууц үгийг давтана уу - + BanTableModel @@ -212,7 +215,7 @@ &Address &Хаяг - + FreespaceChecker @@ -276,6 +279,9 @@ + PaymentServer + + PeerTableModel @@ -290,6 +296,9 @@ + QRImageWidget + + RPCConsole N/A @@ -370,7 +379,7 @@ Remove Устгах - + ReceiveRequestDialog @@ -379,6 +388,9 @@ + RecentRequestsTableModel + + SendCoinsDialog Send Coins @@ -424,7 +436,7 @@ S&end Яв&уул - + SendCoinsEntry @@ -461,6 +473,9 @@ + SendConfirmationDialog + + ShutdownWindow Do not shut down the computer until this window disappears. @@ -493,16 +508,34 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Гүйлгээний дэлгэрэнгүйг энэ бичил цонх харуулж байна - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_ms_MY.ts b/src/qt/locale/bitcoin_ms_MY.ts index acfb38e418c..d680a501308 100644 --- a/src/qt/locale/bitcoin_ms_MY.ts +++ b/src/qt/locale/bitcoin_ms_MY.ts @@ -34,7 +34,10 @@ Alihkan fail data ke dalam tab semasa &Delete &Padam - + + + AddressTableModel + AskPassphraseDialog @@ -61,7 +64,7 @@ Alihkan fail data ke dalam tab semasa &Address Alamat - + FreespaceChecker @@ -81,12 +84,18 @@ Alihkan fail data ke dalam tab semasa OverviewPage + PaymentServer + + PeerTableModel QObject + QRImageWidget + + RPCConsole @@ -100,6 +109,9 @@ Alihkan fail data ke dalam tab semasa + RecentRequestsTableModel + + SendCoinsDialog Balance: @@ -110,6 +122,9 @@ Alihkan fail data ke dalam tab semasa SendCoinsEntry + SendConfirmationDialog + + ShutdownWindow @@ -122,12 +137,30 @@ Alihkan fail data ke dalam tab semasa TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core \ No newline at end of file diff --git a/src/qt/locale/bitcoin_nb.ts b/src/qt/locale/bitcoin_nb.ts index 4538fd6e1e8..7ae530335d6 100644 --- a/src/qt/locale/bitcoin_nb.ts +++ b/src/qt/locale/bitcoin_nb.ts @@ -41,7 +41,10 @@ &Delete &Slett - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Gjenta ny adgangsfrase - + BanTableModel @@ -115,6 +118,10 @@ &Om %1 + Show information about %1 + Vis informasjon om %1 + + About &Qt Om &Qt @@ -127,6 +134,10 @@ &Innstillinger... + Modify configuration options for %1 + Endre innstilinger for %1 + + &Encrypt Wallet... &Krypter Lommebok... @@ -311,6 +322,10 @@ Oppdatert + %1 client + %1 klient + + Catching up... Laster ned... @@ -439,7 +454,7 @@ Priority Prioritet - + EditAddressDialog @@ -462,7 +477,7 @@ &Address &Adresse - + FreespaceChecker @@ -497,6 +512,10 @@ (%1-bit) + About %1 + Om %1 + + Command-line options Kommandolinjevalg @@ -540,6 +559,10 @@ Velkommen + Welcome to %1. + Velkommen til %1. + + Use the default data directory Bruk standard datamappe @@ -582,7 +605,7 @@ Select payment request file Velg fil for betalingsetterspørring - + OptionsDialog @@ -730,6 +753,10 @@ &Vindu + Hide tray icon + Skjul søppel ikon + + Show only a tray icon after minimizing the window. Vis kun ikon i systemkurv etter minimering av vinduet. @@ -874,6 +901,9 @@ + PaymentServer + + PeerTableModel User Agent @@ -928,6 +958,9 @@ + QRImageWidget + + RPCConsole N/A @@ -1038,6 +1071,14 @@ Brukeragent + Decrease font size + Forminsk font størrelsen + + + Increase font size + Forstørr font størrelse + + Services Tjenester @@ -1268,7 +1309,7 @@ Remove Fjern - + ReceiveRequestDialog @@ -1287,7 +1328,10 @@ &Save Image... &Lagre Bilde... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1438,7 +1482,7 @@ S&end S&end - + SendCoinsEntry @@ -1517,7 +1561,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1611,7 +1658,7 @@ Reset all verify message fields Tilbakestill alle felter for meldingsverifikasjon - + SplashScreen @@ -1627,12 +1674,21 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Her vises en detaljert beskrivelse av transaksjonen - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1641,6 +1697,15 @@ + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: @@ -1815,6 +1880,10 @@ Feil under oppstart av lommeboken sitt databasemiljø %s! + Error loading %s + Feil ved lasting av %s + + Error loading block database Feil ved lasting av blokkdatabase @@ -1855,6 +1924,14 @@ Bare koble til noder i nettverket <net> (IPv4, IPv6 eller onion) + Print this help message and exit + Skriv ut denne hjelpemeldingen og avslutt + + + Print version and exit + Skriv ut denne versjonen og avslutt + + Prune cannot be configured with a negative value. Beskjæringsmodus kan ikke konfigureres med en negativ verdi. @@ -1875,6 +1952,10 @@ Angi lommebokfil (inne i datamappe) + The source code is available from %s. + Kildekoden er tilgjengelig fra %s. + + Unsupported argument -benchmark ignored, use -debug=bench. Ustøttet argument -benchmark ble ignorert, bruk -debug=bench. @@ -2259,10 +2340,6 @@ Angi størrelse på nøkkel-lager til <n> (standardverdi: %u) - Set minimum block size in bytes (default: %u) - Sett minimum blokkstørrelse i bytes (standardverdi: %u) - - Set the number of threads to service RPC calls (default: %d) Sett antall tråder til betjening av RPC-kall (standardverdi: %d) diff --git a/src/qt/locale/bitcoin_ne.ts b/src/qt/locale/bitcoin_ne.ts new file mode 100644 index 00000000000..0cffd96f98d --- /dev/null +++ b/src/qt/locale/bitcoin_ne.ts @@ -0,0 +1,581 @@ + + + AddressBookPage + + Right-click to edit address or label + ठेगाना वा लेबल सम्पादन गर्न दायाँ-क्लिक गर्नुहोस् + + + Create a new address + नयाँ ठेगाना सिर्जना गर्नुहोस् + + + &New + &amp;नयाँ + + + Copy the currently selected address to the system clipboard + भर्खरै चयन गरेको ठेगाना प्रणाली क्लिपबोर्डमा कपी गर्नुहोस् + + + &Copy + &amp;कपी गर्नुहोस् + + + C&lose + बन्द गर्नुहोस् + + + Delete the currently selected address from the list + भर्खरै चयन गरेको ठेगाना सूचीबाट मेटाउनुहोस् + + + Export the data in the current tab to a file + वर्तमान ट्याबको डाटालाई फाइलमा निर्यात गर्नुहोस् + + + &Export + &amp;निर्यात गर्नुहोस् + + + &Delete + &amp;मेटाउनुहोस् + + + + AddressTableModel + + + AskPassphraseDialog + + Passphrase Dialog + पासफ्रेज संवाद + + + Enter passphrase + पासफ्रेज प्रवेश गर्नुहोस् + + + New passphrase + नयाँ पासफ्रेज + + + Repeat new passphrase + नयाँ पासफ्रेज दोहोर्याउनुहोस् + + + + BanTableModel + + IP/Netmask + IP/नेटमास्क + + + Banned Until + प्रतिबन्धित समय + + + + BitcoinGUI + + Sign &message... + सन्देशमा &amp;हस्ताक्षर गर्नुहोस्... + + + Synchronizing with network... + नेटवर्कमा समिकरण हुँदै... + + + &Overview + शारांश + + + Node + नोड + + + Show general overview of wallet + वालेटको साधारण शारांश देखाउनुहोस् + + + &Transactions + &amp;कारोबार + + + Browse transaction history + कारोबारको इतिहास हेर्नुहोस् + + + E&xit + बाहिर निस्कनुहोस् + + + Quit application + एप्लिकेसन बन्द गर्नुहोस् + + + &About %1 + &amp;बारेमा %1 + + + Show information about %1 + %1 को बारेमा सूचना देखाउनुहोस् + + + About &Qt + &amp;Qt + + + Show information about Qt + Qt को बारेमा सूचना देखाउनुहोस् + + + &Options... + &amp;विकल्प... + + + Modify configuration options for %1 + %1 का लागि कन्फिगुरेसनको विकल्प परिमार्जन गर्नुहोस + + + &Encrypt Wallet... + &amp;वालेटलाई इन्क्रिप्ट गर्नुहोस्... + + + &Backup Wallet... + &amp;वालेटलाई ब्याकअप गर्नुहोस्... + + + &Change Passphrase... + &amp;पासफ्रेज परिवर्तन गर्नुहोस्... + + + &Sending addresses... + &amp;पठाउने ठेगानाहरू... + + + &Receiving addresses... + &amp;प्राप्त गर्ने ठेगानाहरू... + + + Open &URI... + URI &amp;खोल्नुहोस्... + + + Reindexing blocks on disk... + डिस्कमा ब्लकलाई पुनः सूचीकरण गरिँदै... + + + Send coins to a Bitcoin address + बिटकोइन ठेगानामा सिक्का पठाउनुहोस् + + + Backup wallet to another location + वालेटलाई अर्को ठेगानामा ब्याकअप गर्नुहोस् + + + Change the passphrase used for wallet encryption + वालेट इन्क्रिप्सनमा प्रयोग हुने इन्क्रिप्सन पासफ्रेज परिवर्तन गर्नुहोस् + + + &Debug window + &amp;डिबग विन्डो + + + Open debugging and diagnostic console + डिबगिङ र डायाग्नोस्टिक कन्सोल खोल्नुहोस् + + + + CoinControlDialog + + Amount + रकम + + + + EditAddressDialog + + + FreespaceChecker + + + HelpMessageDialog + + + Intro + + + OpenURIDialog + + + OptionsDialog + + + OverviewPage + + 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. + देखाइएको सूचना पूरानो हुन सक्छ । कनेक्सन स्थापित भएपछि, तपाईंको वालेट बिटकोइन नेटवर्कमा स्वचालित रूपमा समिकरण हुन्छ , तर यो प्रक्रिया अहिले सम्म पूरा भएको छैन । + + + Watch-only: + हेर्ने-मात्र: + + + Available: + उपलब्ध: + + + Your current spendable balance + तपाईंको खर्च गर्न मिल्ने ब्यालेन्स + + + Pending: + विचाराधिन: + + + Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance + अझै पुष्टि हुन बाँकी र खर्च गर्न मिल्ने ब्यालेन्समा गणना गर्न नमिल्ने जम्मा कारोबार + + + Immature: + अपरिपक्व: + + + Mined balance that has not yet matured + अझै परिपक्व नभएको खनन गरिएको ब्यालेन्स + + + Balances + ब्यालेन्स + + + Mined balance in watch-only addresses that has not yet matured + अहिलेसम्म परिपक्व नभएको खनन गरिएको, हेर्ने-मात्र ठेगानामा रहेको ब्यालेन्स + + + Current total balance in watch-only addresses + हेर्ने-मात्र ठेगानामा रहेको हालको जम्मा ब्यालेन्स + + + + PaymentServer + + + PeerTableModel + + User Agent + प्रयोगकर्ता एजेन्ट + + + Node/Service + नोड/सेव + + + Ping Time + पिङ समय + + + + QObject + + Amount + रकम + + + + QRImageWidget + + + RPCConsole + + User Agent + प्रयोगकर्ता एजेन्ट + + + Ping Time + पिङ समय + + + + ReceiveCoinsDialog + + + ReceiveRequestDialog + + + RecentRequestsTableModel + + + SendCoinsDialog + + + SendCoinsEntry + + 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. + पठाइँदै गरेको रकमबाट शुल्क कटौती गरिनेछ । प्राप्तकर्ताले तपाईंले रकम क्षेत्रमा प्रवेष गरेको भन्दा थोरै बिटकोइन प्राप्त गर्ने छन् । धेरै प्राप्तकर्ता चयन गरिएको छ भने समान रूपमा शुल्क विभाजित गरिनेछ । + + + 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. + बिटकोइनमा संलग्न गरिएको सन्देश: तपाईंको मध्यस्थको लागि कारोबारको साथमा भण्डारण गरिने URI । नोट: यो सन्देश बिटकोइन नेटवर्क मार्फत पठाइने छैन । + + + + SendConfirmationDialog + + + ShutdownWindow + + + SignVerifyMessageDialog + + 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. + आफ्नो ठेगानामा पठाइएको बिटकोइन प्राप्त गर्न सकिन्छ भनेर प्रमाणित गर्न तपाईंले ती ठेगानाले सन्देश/सम्झौताहरूमा हस्ताक्षर गर्न सक्नुहुन्छ । फिसिङ आक्रमणले तपाईंलाई छक्याएर अरूका लागि तपाईंको परिचयमा हस्ताक्षर गराउने प्रयास गर्न सक्ने भएकाले अस्पष्ट वा जथाभावीमा हस्ताक्षर गर्दा ध्यान दिनुहोस् । आफू सहमत भएको पूर्ण विस्तृत-कथनमा मात्र हस्ताक्षर गर्नुहोस् । + + + + SplashScreen + + + TrafficGraphWidget + + + TransactionDesc + + + TransactionDescDialog + + + TransactionTableModel + + + TransactionView + + + UnitDisplayStatusBarControl + + + WalletFrame + + + WalletModel + + + WalletView + + + 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 + ब्लक डाटाबेसमा भविष्यबाट आए जस्तो देखिने एउटा ब्लक हुन्छ । तपाईंको कम्प्युटरको मिति र समय गलत तरिकाले सेट गरिएकाले यस्तो हुन सक्छ । तपाईं आफ्नो कम्प्युटरको मिति र समय सही छ भनेर पक्का हुनुहुन्छ भने मात्र ब्लक डाटाबेस पुनर्निर्माण गर्नुहोस् । + + + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications + यो जारी गर्नु पूर्वको परीक्षण संस्करण हो - आफ्नै जोखिममा प्रयोग गर्नुहोस् - खनन वा व्यापारीक प्रयोगको लागि प्रयोग नगर्नुहोस + + + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + प्रि-फर्क अवस्थामा डाटाबेस रिवाइन्ड गर्न सकिएन । तपाईंले फेरि ब्लकचेन डाउनलोड गर्नु पर्ने हुन्छ + + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + UPnP प्रयोग गरेर सुन्ने पोर्टलाई म्याप गर्नुहोस् (सुन्दा र -प्रोक्सी नहुँदा डिफल्ट: 1) + + + Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. + चेतावनी: नेटवर्क पूरै तरिकाले सहमत छैन जस्तो देखिन्छ! केही खननकर्ताहरूले समस्या भोगिरहेका छन् जस्तो देखिन्छ । + + + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. + चेतावनी: हामी हाम्रा सहकर्मीहरूसँग पूर्णतया सहमत छैनौं जस्तो देखिन्छ! तपाईंले अपग्रेड गर्नु पर्ने हुनसक्छ वा अरू नोडहरूले अपग्रेड गर्नु पर्ने हुनसक्छ । + + + Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. + दिइएको नेटमास्क वा ठेगानाबाट कनेक्ट भइरहेका श्वेतसूचीका सहकर्मी । + + + You need to rebuild the database using -reindex-chainstate to change -txindex + तपाईंले -चेनस्टेट-पुनः सूचकांकबाट -txindex परिवर्तन प्रयोग गरेर डाटाबेस पुनर्निर्माण गर्नु आवश्यक छ + + + %s corrupt, salvage failed + %s मा क्षति, बचाव विफल भयो + + + -maxmempool must be at least %d MB + -maxmempool कम्तिमा %d MB को हुनुपर्छ । + + + <category> can be: + &lt;वर्ग&gt; निम्न आकारको हुनसक्छ: + + + Append comment to the user agent string + प्रयोगकर्ता एजेन्ट स्ट्रिङमा टिप्पणी जोड्नुहोस् + + + Attempt to recover private keys from a corrupt wallet on startup + स्टार्टअपमा क्षति पूगेको वालेटबाट निजी की प्राप्त गर्न प्रयास गर्नुहोस् + + + Block creation options: + ब्लक सिर्जनाको बिकल्प: + + + Cannot resolve -%s address: '%s' + -%s ठेगाना: &apos;%s&apos; निश्चय गर्न सकिँदैन + + + Change index out of range + सूचकांक परिवर्तन सीमा भन्दा बाहर + + + Connect only to the specified node(s) + उल्लेख गरिएको नोड (हरू) मात्र कनेक्ट गर्नुहोस + + + Connection options: + कनेक्सनको विकल्प: + + + Copyright (C) %i-%i + सर्वाधिकार (C) %i-%i + + + Corrupted block database detected + क्षति पुगेको ब्लक डाटाबेस फेला पर + + + Debugging/Testing options: + डिबगिङ/परीक्षणका विकल्पहरू: + + + Do not load the wallet and disable wallet RPC calls + वालेट लोड नगर्नुहोस् र वालेट RPC कलहरू अक्षम गर्नुहोस् + + + Do you want to rebuild the block database now? + तपाईं अहिले ब्लक डेटाबेस पुनर्निर्माण गर्न चाहनुहुन्छ ? + + + Unable to bind to %s on this computer. %s is probably already running. + यो कम्प्युटरको %s मा बाँध्न सकिएन । %s सम्भवित रूपमा पहिलैबाट चलिरहेको छ । + + + Unsupported argument -benchmark ignored, use -debug=bench. + असमर्थित तर्क -बेन्चमार्कलाई बेवास्ता गरियो, -डिबग=बेन्च प्रयोग गर्नुहोस् । + + + Unsupported argument -debugnet ignored, use -debug=net. + असमर्थित तर्क -डिबगनेटलाई बेवास्ता गरियो, -डिबग=नेट प्रयोग गर्नुहोस् । + + + Unsupported argument -tor found, use -onion. + असमर्थित तर्क -टोर फेला पर्यो, -ओनियन प्रयोग गर्नुहोस् । + + + Use UPnP to map the listening port (default: %u) + UPnP प्रयोग गरेर सुन्ने पोर्ट म्याप गर्नुहोस् (डिफल्ट: %u) + + + Verifying blocks... + ब्लक प्रमाणित गरिँदै... + + + Verifying wallet... + वालेट प्रमाणित गरिँदै... + + + Wallet %s resides outside data directory %s + वालेट %s डाटा निर्देशिका %s बाहिरमा बस्छ + + + Wallet debugging/testing options: + वालेट डिबगिङ/परीक्षणका विकल्पहरू: + + + Wallet needed to be rewritten: restart %s to complete + वालेट फेरि लेख्नु आवश्यक छ: पूरा गर्न %s लाई पुन: सुरु गर्नुहोस् + + + Wallet options: + वालेटका विकल्पहरू: + + + 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 + निर्दिष्ट गरिएको स्रोतबाट आएको JSON-RPC कनेक्सनलाई अनुमति दिनुहोस् । एकल IP (e.g. 1.2.3.4), नेटवर्क/नेटमास्क (उदाहरण 1.2.3.4/255.255.255.0) वा नेटवर्क/CIDR (उदाहरण 1.2.3.4/24) &lt;ip&gt; का लागि मान्य छन् । यो विकल्पलाई धेरै पटक निर्दिष्ट गर्न सकिन्छ + + + Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6 + दिइएको ठेगानामा बाँध्नुहोस् र यसमा कनेक्ट गर्ने सहकर्मीलाई श्वेतसूचीमा राख्नुहोस् । IPv6 लागि [होस्ट]:पोर्ट संकेतन प्रयोग गर्नुहोस् + + + 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) + JSON-RPC कनेक्सन सुन्नको लागि दिइएको ठेगानामा बाँध्नुहोस् । IPv6 लागि [होस्ट]:पोर्ट संकेतन प्रयोग गर्नुहोस् । यो विकल्पलाई धेरै पटक निर्दिष्ट गर्न सकिन्छ (डिफल्ट: सबै इन्टरफेसमा बाँध्नुहोस्) + + + Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) + umask 077 को सट्टामा प्रणालीको डिफल्ट अनुमतिको साथमा नयाँ फाइलहरू सिर्जना गर्नुहोस् । (असक्षम गरिएको वालेट कार्यक्षमतामा मात्र प्रभावकारी हुने) + + + Discover own IP addresses (default: 1 when listening and no -externalip or -proxy) + आफ्नै IP ठेगाना पत्ता लगाउनुहोस् (सुन्दा र -बाहिरीआइपी वा -प्रोक्सी नहुँदा डिफल्ट: 1 ) + + + Error: Listening for incoming connections failed (listen returned error %s) + त्रुटि: आगमन कनेक्सनमा सुन्ने कार्य असफल भयो (सुन्ने कार्यले त्रुटि %s फर्कायो) + + + Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) + सान्दर्भिक चेतावनी प्राप्त गर्दा आदेश कार्यान्वयन गर्नुहोस् नभए धेरै लामो फोर्क देखा पर्न सक्छ । (cmd को %s लाई सन्देशले प्रतिस्थापन गर्छ) + + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + रिले, खनन वा कारोबारको सिर्जनाको लागि यो भन्दा कम शुल्क (%s/kB मा) लाई शून्य शुल्कको रूपमा लिइन्छ । (डिफल्ट: %s) + + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) + paytxfee सेट गरिएको छैन भने, औसतमा n ब्लक भित्र कारोबार पुष्टिकरण सुरु होस् भन्नका लागि पर्याप्त शुल्क समावेश गर्नुहोस् (डिफल्ट: %u) + + + Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) + maxtxfee=&lt;रकम&gt;: का लागि अमान्य रकम &apos;%s&apos; (कारोबारलाई अड्कन नदिन अनिवार्य रूपमा कम्तिमा %s को न्यूनतम रिले शुल्क हुनु पर्छ) + + + Maximum size of data in data carrier transactions we relay and mine (default: %u) + हामीले रिले र खनन गर्ने डाटा वाहक कारोबारको डाटाको अधिकतम आकार (डिफल्ट: %u) + + + Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect) + यदि ठेगाना कम भएमा, DNS लुकअप मार्फत सहकर्मी ठेगानाको जाँच गर्नुहोस (डिफल्ट: 1 सिवाय -कनेक्ट) + + + Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u) + हरेक प्रोक्सी कनेक्सनका लागि क्रेडिन्सियल अनियमित बनाउनुहोस् । यसले टोर स्ट्रिमको अलगावलाई सक्षम पार्छ (डिफल्ट: %u) + + + Set maximum size of high-priority/low-fee transactions in bytes (default: %d) + बाइटमा उच्च-प्राथमिकता/कम शुल्कको कारोबारको अधिकतम आकार सेट गर्नुहोस् (डिफल्ट: %d) + + + The transaction amount is too small to send after the fee has been deducted + कारोबार रकम शुल्क कटौती गरेपछि पठाउँदा धेरै नै सानो हुन्छ + + + 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. + यो उत्पादन ले OpenSSL टुलकिट <https://www.openssl.org/> को प्रयोगको लागि OpenSSL परियोजनाले विकास गरेको सफ्टवेयर, एरिक यंग द्वारा लिखित क्रिप्टोग्राफिक सफ्टवेयर र थमस बर्नार्डद्वारा लिखित UPnP सफ्टवेयरलाई समावेश गर्छ । + + + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + BIP32 पछि पदानुक्रमित निर्धारक की सिर्जना (HD) प्रयोग गर्नुहोस् ।. केवल वालेट सिर्जना/पहिलो सुरुवातको समयमा प्रभाव पार्छ + + + 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 + श्वेतसूचीका सहकर्मी पहिलैबाट मेमपूल, उपयोगीमा भए पनि उनीहरूलाई DoS banned गर्न सकिँदैन र उनीहरूको कारोबार सधैं रिले हुन्छ, उदाहरण, गेटवेको लाग + + + You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain + तपाईंले काटछाँट नगरेको मोडमा जान पुनः सूचकांक प्रयोग गरेर डाटाबेस पुनर्निर्माण गर्नु पर्ने हुन्छ । यसले सम्पूर्ण ब्लकचेनलाई फेरि डाउनलोड गर्नेछ + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_nl.ts b/src/qt/locale/bitcoin_nl.ts index 781c5a8fd66..272714fc7b5 100644 --- a/src/qt/locale/bitcoin_nl.ts +++ b/src/qt/locale/bitcoin_nl.ts @@ -41,6 +41,77 @@ &Delete &Verwijder + + Choose the address to send coins to + Kies het adres om munten naar te versturen + + + Choose the address to receive coins with + Kies het adres om munten op te ontvangen + + + C&hoose + K&iezen + + + Sending addresses + Verzendadressen + + + Receiving addresses + Ontvangstadressen + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Dit zijn uw Bitcoinadressen om betalingen mee te verzenden. Controleer altijd het bedrag en het ontvangstadres voordat u uw bitcoins verzendt. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Dit zijn uw Bitcoin-adressen waarmee u betalingen kunt ontvangen. We raden u aan om een nieuw ontvangstadres voor elke transactie te gebruiken. + + + &Copy Address + &Kopiëer Adres + + + Copy &Label + Kopieer &Label + + + &Edit + &Bewerk + + + Export Address List + Exporteer adreslijst + + + Comma separated file (*.csv) + Kommagescheiden bestand (*.csv) + + + Exporting Failed + Export mislukt + + + There was an error trying to save the address list to %1. Please try again. + Een fout is opgetreden tijdens het opslaan van deze adreslijst naar %1. Probeer het nogmaals. + + + + AddressTableModel + + Label + Label + + + Address + Adres + + + (no label) + (geen label) + AskPassphraseDialog @@ -60,6 +131,94 @@ Repeat new passphrase Herhaal nieuw wachtwoord + + 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>. + Voer een nieuw wachtwoord in voor uw portemonnee.<br/>Gebruik een wachtwoord van <b>tien of meer willekeurige karakters</b>, of <b>acht of meer woorden</b>. + + + Encrypt wallet + Versleutel portemonnee + + + This operation needs your wallet passphrase to unlock the wallet. + Deze operatie vereist uw portemonneewachtwoord om de portemonnee te openen. + + + Unlock wallet + Open portemonnee + + + This operation needs your wallet passphrase to decrypt the wallet. + Deze operatie vereist uw portemonneewachtwoord om de portemonnee te ontsleutelen + + + Decrypt wallet + Ontsleutel portemonnee + + + Change passphrase + Wijzig wachtwoord + + + Enter the old passphrase and new passphrase to the wallet. + Voer het oude en nieuwe wachtwoord in voor uw portemonnee. + + + Confirm wallet encryption + Bevestig versleuteling van de portemonnee + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Waarschuwing: Als u uw portemonnee versleutelt en uw wachtwoord vergeet, zult u <b>AL UW BITCOINS VERLIEZEN</b>! + + + Are you sure you wish to encrypt your wallet? + Weet u zeker dat u uw portemonnee wilt versleutelen? + + + Wallet encrypted + Portemonnee versleuteld + + + %1 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. + %1 zal nu afsluiten om het versleutelingsproces te voltooien. Onthoud dat het versleutelen van uw portemonnee u niet volledig kan beschermen: Malware kan uw computer infecteren en uw bitcoins stelen. + + + 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. + BELANGRIJK: Elke eerder gemaakte backup van uw portemonneebestand dient u te vervangen door het nieuw gegenereerde, versleutelde portemonneebestand. Om veiligheidsredenen zullen eerdere backups van het niet-versleutelde portemonneebestand onbruikbaar worden zodra u uw nieuwe, versleutelde, portemonnee begint te gebruiken. + + + Wallet encryption failed + Portemonneeversleuteling mislukt + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Portemonneeversleuteling mislukt door een interne fout. Uw portemonnee is niet versleuteld. + + + The supplied passphrases do not match. + De opgegeven wachtwoorden komen niet overeen + + + Wallet unlock failed + Portemonnee openen mislukt + + + The passphrase entered for the wallet decryption was incorrect. + Het opgegeven wachtwoord voor de portemonnee-ontsleuteling is niet correct. + + + Wallet decryption failed + Portemonnee-ontsleuteling mislukt + + + Wallet passphrase was successfully changed. + Portemonneewachtwoord is met succes gewijzigd. + + + Warning: The Caps Lock key is on! + Waarschuwing: De Caps-Lock-toets staat aan! + BanTableModel @@ -463,6 +622,150 @@ Priority Prioriteit + + Copy address + Kopieer adres + + + Copy label + Kopieer label + + + Copy amount + Kopieer bedrag + + + Copy transaction ID + Kopieer transactie-ID + + + Lock unspent + Blokeer ongebruikte + + + Unlock unspent + Deblokkeer ongebruikte + + + Copy quantity + Kopieer aantal + + + Copy fee + Kopieer vergoeding + + + Copy after fee + Kopieer na vergoeding + + + Copy bytes + Kopieer bytes + + + Copy priority + Kopieer prioriteit + + + Copy dust + Kopieër stof + + + Copy change + Kopieer wijziging + + + highest + hoogste + + + higher + hoger + + + high + hoog + + + medium-high + gemiddeld hoog + + + medium + gemiddeld + + + low-medium + laag gemiddeld + + + low + laag + + + lower + lager + + + lowest + laagste + + + (%1 locked) + (%1 geblokkeerd) + + + none + geen + + + yes + ja + + + no + nee + + + This label turns red if the transaction size is greater than 1000 bytes. + Dit label wordt rood als de transactie groter is dan 1000 bytes. + + + This means a fee of at least %1 per kB is required. + Dit betekent dat een vergoeding van minimaal %1 per kB nodig is. + + + Can vary +/- 1 byte per input. + Kan +/- 1 byte per invoer variëren. + + + Transactions with higher priority are more likely to get included into a block. + Transacties met een hogere prioriteit zullen eerder in een blok gezet worden. + + + This label turns red if the priority is smaller than "medium". + Dit label wordt rood als de prioriteit lager is dan "gemiddeld". + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Dit label wordt rood, als een ontvanger een bedrag van minder dan de huidige dust-drempel gekregen heeft. + + + Can vary +/- %1 satoshi(s) per input. + Kan per input +/- %1 satoshi(s) variëren. + + + (no label) + (geen label) + + + change from %1 (%2) + wijzig van %1 (%2) + + + (change) + (wijzig) + EditAddressDialog @@ -486,6 +789,38 @@ &Address &Adres + + New receiving address + Nieuw ontvangstadres + + + New sending address + Nieuw verzendadres + + + Edit receiving address + Bewerk ontvangstadres + + + Edit sending address + Bewerk verzendadres + + + The entered address "%1" is not a valid Bitcoin address. + Het opgegeven adres "%1" is een ongeldig Bitcoinadres. + + + The entered address "%1" is already in the address book. + Het opgegeven adres "%1" bestaat al in uw adresboek. + + + Could not unlock wallet. + Kon de portemonnee niet openen. + + + New key generation failed. + Genereren nieuwe sleutel mislukt. + FreespaceChecker @@ -626,6 +961,10 @@ Select payment request file Selecteer betalingsverzoek bestand + + Select payment request file to open + Selecteer betalingsverzoekbestand om te openen + OptionsDialog @@ -938,6 +1277,97 @@ + PaymentServer + + Payment request error + Fout bij betalingsverzoek + + + Cannot start bitcoin: click-to-pay handler + Kan bitcoin niet starten: click-to-pay handler + + + URI handling + URI-behandeling + + + Payment request fetch URL is invalid: %1 + URL om betalingsverzoek te verkrijgen is ongeldig: %1 + + + Invalid payment address %1 + Ongeldig betalingsadres %1 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + URI kan niet verwerkt worden! Dit kan het gevolg zijn van een ongeldig Bitcoin adres of misvormde URI parameters. + + + Payment request file handling + Betalingsverzoek bestandsafhandeling + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + Betalingsverzoekbestand kan niet gelezen of verwerkt worden! Dit kan veroorzaakt worden door een ongeldig betalingsverzoekbestand. + + + Payment request rejected + Betalingsverzoek geweigerd + + + Payment request network doesn't match client network. + Betalingsaanvraagnetwerk komt niet overeen met klantennetwerk. + + + Payment request expired. + Betalingsverzoek verlopen. + + + Payment request is not initialized. + Betalingsaanvraag is niet geïnitialiseerd. + + + Unverified payment requests to custom payment scripts are unsupported. + Niet-geverifieerde betalingsverzoeken naar aangepaste betalingsscripts worden niet ondersteund. + + + Invalid payment request. + Ongeldig betalingsverzoek. + + + Requested payment amount of %1 is too small (considered dust). + Het gevraagde betalingsbedrag van %1 is te weinig (beschouwd als stof). + + + Refund from %1 + Restitutie van %1 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + Betalingsverzoek %1 is te groot (%2 bytes, toegestaan ​​%3 bytes). + + + Error communicating with %1: %2 + Fout bij communiceren met %1: %2 + + + Payment request cannot be parsed! + Betalingsverzoek kan niet worden verwerkt! + + + Bad response from server %1 + Ongeldige respons van server %1 + + + Network request error + Fout bij netwerkverzoek + + + Payment acknowledged + Betaling bevestigd + + + PeerTableModel User Agent @@ -992,6 +1422,25 @@ + QRImageWidget + + &Save Image... + &Sla afbeelding op... + + + &Copy Image + &Afbeelding kopiëren + + + Save QR Code + Sla QR-code op + + + PNG Image (*.png) + PNG afbeelding (*.png) + + + RPCConsole N/A @@ -1352,6 +1801,18 @@ Remove Verwijder + + Copy label + Kopieer label + + + Copy message + Kopieer bericht + + + Copy amount + Kopieer bedrag + ReceiveRequestDialog @@ -1371,39 +1832,106 @@ &Save Image... &Sla afbeelding op... - - - SendCoinsDialog - Send Coins - Verstuurde munten + Request payment to %1 + Betalingsverzoek tot %1 - Coin Control Features - Coin controle opties + Payment information + Betalingsinformatie - Inputs... - Invoer... + URI + URI - automatically selected - automatisch geselecteerd + Address + Adres - Insufficient funds! - Onvoldoende fonds! + Amount + Bedrag - Quantity: - Kwantiteit + Label + Label - Bytes: - Bytes: + Message + Bericht - Amount: + Resulting URI too long, try to reduce the text for label / message. + Resulterende URI te lang, probeer de tekst korter te maken voor het label/bericht. + + + Error encoding URI into QR Code. + Fout tijdens encoderen URI in QR-code + + + + RecentRequestsTableModel + + Date + Datum + + + Label + Label + + + Message + Bericht + + + (no label) + (geen label) + + + (no message) + (geen bericht) + + + (no amount requested) + (geen bedrag aangevraagd) + + + Requested + Verzoek ingediend + + + + SendCoinsDialog + + Send Coins + Verstuurde munten + + + Coin Control Features + Coin controle opties + + + Inputs... + Invoer... + + + automatically selected + automatisch geselecteerd + + + Insufficient funds! + Onvoldoende fonds! + + + Quantity: + Kwantiteit + + + Bytes: + Bytes: + + + Amount: Bedrag: @@ -1522,6 +2050,110 @@ S&end V&erstuur + + Copy quantity + Kopieer aantal + + + Copy amount + Kopieer bedrag + + + Copy fee + Kopieer vergoeding + + + Copy after fee + Kopieer na vergoeding + + + Copy bytes + Kopieer bytes + + + Copy priority + Kopieer prioriteit + + + Copy dust + Kopieër stof + + + Copy change + Kopieer wijziging + + + %1 to %2 + %1 tot %2 + + + Are you sure you want to send? + Weet u zeker dat u wilt verzenden? + + + added as transaction fee + toegevoegd als transactiekosten + + + Total Amount %1 + Totaalbedrag %1 + + + or + of + + + Confirm send coins + Bevestig versturen munten + + + The recipient address is not valid. Please recheck. + Het adres van de ontvanger is niet geldig. Gelieve opnieuw te controleren. + + + The amount to pay must be larger than 0. + Het ingevoerde bedrag moet groter zijn dan 0. + + + The amount exceeds your balance. + Het bedrag is hoger dan uw huidige saldo. + + + The total exceeds your balance when the %1 transaction fee is included. + Het totaal overschrijdt uw huidige saldo wanneer de %1 transactiekosten worden meegerekend. + + + Duplicate address found: addresses should only be used once each. + Dubbel adres gevonden: adressen mogen maar één keer worden gebruikt worden. + + + Transaction creation failed! + Transactiecreatie mislukt + + + 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. + 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. + + + Payment request expired. + Betalingsverzoek verlopen. + + + Pay only the required fee of %1 + Betaal alleen de verplichte transactiekosten van %1 + + + Warning: Invalid Bitcoin address + Waarschuwing: Ongeldig Bitcoinadres + + + Warning: Unknown change address + Waarschuwing: Onbekend wisselgeldadres + + + (no label) + (geen label) + SendCoinsEntry @@ -1601,6 +2233,17 @@ Memo: Memo: + + Enter a label for this address to add it to your address book + Vul een label in voor dit adres om het toe te voegen aan uw adresboek + + + + SendConfirmationDialog + + Yes + Ja + ShutdownWindow @@ -1699,6 +2342,58 @@ Reset all verify message fields Verwijder alles in de invulvelden + + Click "Sign Message" to generate signature + Klik op "Onderteken Bericht" om de handtekening te genereren + + + The entered address is invalid. + Het opgegeven adres is ongeldig. + + + Please check the address and try again. + Controleer het adres en probeer het opnieuw. + + + The entered address does not refer to a key. + Het opgegeven adres verwijst niet naar een sleutel. + + + Wallet unlock was cancelled. + Portemonnee-ontsleuteling is geannuleerd. + + + Private key for the entered address is not available. + Geheime sleutel voor het ingevoerde adres is niet beschikbaar. + + + Message signing failed. + Ondertekenen van het bericht is mislukt. + + + Message signed. + Bericht ondertekend. + + + The signature could not be decoded. + De handtekening kon niet worden gedecodeerd. + + + Please check the signature and try again. + Controleer de handtekening en probeer het opnieuw. + + + The signature did not match the message digest. + De handtekening hoort niet bij het bericht. + + + Message verification failed. + Berichtverificatie mislukt. + + + Message verified. + Bericht geverifiëerd. + SplashScreen @@ -1715,11 +2410,456 @@ + TransactionDesc + + Open for %n more block(s) + Open voor nog %n blok(ken)Open voor nog %n blok(ken) + + + Open until %1 + Open tot %1 + + + conflicted with a transaction with %1 confirmations + geconflicteerd met een transactie met %1 confirmaties + + + %1/offline + %1/offline + + + 0/unconfirmed, %1 + 0/onbevestigd, %1 + + + in memory pool + in geheugenpoel + + + not in memory pool + niet in geheugenpoel + + + abandoned + opgegeven + + + %1/unconfirmed + %1/onbevestigd + + + %1 confirmations + %1 bevestigingen + + + Status + Status + + + , has not been successfully broadcast yet + , is nog niet met succes uitgezonden + + + , broadcast through %n node(s) + , uitgezonden naar %n node(s), uitgezonden naar %n node(s) + + + Date + Datum + + + Source + Bron + + + Generated + Gegenereerd + + + From + Van + + + unknown + onbekend + + + To + Aan + + + own address + eigen adres + + + watch-only + alleen-bekijkbaar + + + label + label + + + Credit + Credit + + + matures in %n more block(s) + komt beschikbaar na %n nieuwe blokkenkomt beschikbaar na %n nieuwe blokken + + + not accepted + niet geaccepteerd + + + Debit + Debet + + + Total debit + Totaal debit + + + Total credit + Totaal credit + + + Transaction fee + Transactiekosten + + + Net amount + Netto bedrag + + + Message + Bericht + + + Comment + Opmerking + + + Transaction ID + Transactie-ID + + + Output index + Output index + + + Merchant + Handelaar + + + 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. + Gegenereerde munten moeten %1 blokken rijpen voordat ze kunnen worden besteed. Toen dit blok gegenereerd werd, werd het uitgezonden naar het netwerk om aan de blokketen toegevoegd te worden. Als het niet lukt om in de keten toegevoegd te worden, zal de status te veranderen naar "niet geaccepteerd" en zal het niet besteedbaar zijn. Dit kan soms gebeuren als een ander knooppunt een blok genereert binnen een paar seconden na die van u. + + + Debug information + Debug-informatie + + + Transaction + Transactie + + + Inputs + Inputs + + + Amount + Bedrag + + + true + waar + + + false + onwaar + + + TransactionDescDialog This pane shows a detailed description of the transaction Dit venster laat een uitgebreide beschrijving van de transactie zien + + Details for %1 + Details voor %1 + + + + TransactionTableModel + + Date + Datum + + + Type + Type + + + Label + Label + + + Open for %n more block(s) + Open voor nog %n blok(ken)Open voor nog %n blok(ken) + + + Open until %1 + Open tot %1 + + + Offline + Offline + + + Unconfirmed + Onbevestigd + + + Abandoned + Opgegeven + + + Confirming (%1 of %2 recommended confirmations) + Bevestigen (%1 van %2 aanbevolen bevestigingen) + + + Confirmed (%1 confirmations) + Bevestigd (%1 bevestigingen) + + + Conflicted + Conflicterend + + + Immature (%1 confirmations, will be available after %2) + Niet beschikbaar (%1 bevestigingen, zal beschikbaar zijn na %2) + + + This block was not received by any other nodes and will probably not be accepted! + Dit blok is niet ontvangen bij andere nodes en zal waarschijnlijk niet worden geaccepteerd! + + + Generated but not accepted + Gegenereerd maar niet geaccepteerd + + + Received with + Ontvangen met + + + Received from + Ontvangen van + + + Sent to + Verzonden aan + + + Payment to yourself + Betaling aan uzelf + + + Mined + Gedolven + + + watch-only + alleen-bekijkbaar + + + (n/a) + (nvt) + + + (no label) + (geen label) + + + Transaction status. Hover over this field to show number of confirmations. + Transactiestatus. Houd de cursor boven dit veld om het aantal bevestigingen te laten zien. + + + Date and time that the transaction was received. + Datum en tijd waarop deze transactie is ontvangen. + + + Type of transaction. + Type transactie. + + + Whether or not a watch-only address is involved in this transaction. + Of er een alleen-bekijken-adres is betrokken bij deze transactie. + + + User-defined intent/purpose of the transaction. + Door gebruiker gedefinieerde intentie/doel van de transactie. + + + Amount removed from or added to balance. + Bedrag verwijderd van of toegevoegd aan saldo. + + + + TransactionView + + All + Alles + + + Today + Vandaag + + + This week + Deze week + + + This month + Deze maand + + + Last month + Vorige maand + + + This year + Dit jaar + + + Range... + Bereik... + + + Received with + Ontvangen met + + + Sent to + Verzonden aan + + + To yourself + Aan uzelf + + + Mined + Gedolven + + + Other + Anders + + + Enter address or label to search + Vul adres of label in om te zoeken + + + Min amount + Min. bedrag + + + Abandon transaction + Doe afstand van transactie + + + Copy address + Kopieer adres + + + Copy label + Kopieer label + + + Copy amount + Kopieer bedrag + + + Copy transaction ID + Kopieer transactie-ID + + + Copy raw transaction + Kopieer ruwe transactie + + + Copy full transaction details + Kopieer volledige transactiedetials + + + Edit label + Bewerk label + + + Show transaction details + Toon transactiedetails + + + Export Transaction History + Exporteer transactiegeschiedenis + + + Comma separated file (*.csv) + Kommagescheiden bestand (*.csv) + + + Confirmed + Bevestigd + + + Watch-only + Alleen-bekijkbaar + + + Date + Datum + + + Type + Type + + + Label + Label + + + Address + Adres + + + ID + ID + + + Exporting Failed + Export mislukt + + + There was an error trying to save the transaction history to %1. + Er is een fout opgetreden bij het opslaan van de transactiegeschiedenis naar %1. + + + Exporting Successful + Export succesvol + + + The transaction history was successfully saved to %1. + De transactiegeschiedenis was succesvol bewaard in %1. + + + Range: + Bereik: + + + to + naar + UnitDisplayStatusBarControl @@ -1729,6 +2869,55 @@ + WalletFrame + + No wallet has been loaded. + Er is geen portemonnee geladen. + + + + WalletModel + + Send Coins + Verstuur munten + + + + WalletView + + &Export + &Exporteer + + + Export the data in the current tab to a file + Exporteer de data in de huidige tab naar een bestand + + + Backup Wallet + Portemonnee backuppen + + + Wallet Data (*.dat) + Portemonneedata (*.dat) + + + Backup Failed + Backup mislukt + + + There was an error trying to save the wallet data to %1. + Er is een fout opgetreden bij het wegschrijven van de portemonneedata naar %1. + + + Backup Successful + Backup succesvol + + + The wallet data was successfully saved to %1. + De portemonneedata is succesvol opgeslagen in %1. + + + bitcoin-core Options: @@ -1827,6 +3016,14 @@ Uitgegeven onder de MIT-softwarelicentie, zie het bijgevoegde bestand COPYING of <http://www.opensource.org/licenses/mit-license.php>. + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Equivalent byter per sigop in transactions voor doorsturen en mijnen (standaard: %u) + + + Error loading %s: You can't enable HD on a already existing non-HD wallet + Fout bij het laden van %s: Je kan HD niet activeren voor een reeds bestaande niet-HD portemonnee + + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. Waarschuwing: Fout bij het lezen van %s! Alle sleutels zijn in goede orde uitgelezen, maar transactiedata of adresboeklemma's zouden kunnen ontbreken of fouten bevatten. @@ -1835,10 +3032,6 @@ Voer opdracht uit zodra een portemonneetransactie verandert (%s in cmd wordt vervangen door TxID) - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Forceer het doorsturen van transacties van goedgekeurde peers, zelfs wanneer deze niet voldoen aan de lokale doorstuur regels (standaard: %d) - - Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) Maximum toegestane peer tijd compensatie. Lokaal perspectief van tijd mag worden beinvloed door peers die met deze hoeveelheid voor of achter lopen. (standaard: %u seconden) @@ -1851,6 +3044,10 @@ Waarschuwing: Controleer dat de datum en tijd van uw computer correct zijn ingesteld! Bij een onjuist ingestelde klok zal %s niet goed werken. + Please contribute if you find %s useful. Visit %s for further information about the software. + Gelieve bij te dragen als je %s nuttig vindt. Bezoek %s voor meer informatie over de software. + + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Kies het aantal scriptverificatie processen (%u tot %d, 0 = auto, <0 = laat dit aantal kernen vrij, standaard: %d) @@ -1860,7 +3057,11 @@ This is a pre-release test build - use at your own risk - do not use for mining or merchant applications - Dit is een prerelease testversie – gebruik op eigen risico! Gebruik deze niet voor het delven van munten of handelsdoeleinden + Dit is een prerelease testversie – gebruik op eigen risico! Gebruik deze niet voor mijnen of handelsdoeleinden + + + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + Niet mogelijk om de databank terug te draaien naar een staat voor de vork. Je zal je blokketen opnieuw moeten downloaden Use UPnP to map the listening port (default: 1 when listening and no -proxy) @@ -1979,6 +3180,10 @@ Fout bij laden %s: Portemonnee vereist een nieuwere versie van %s + Error loading %s: You can't disable HD on a already existing HD wallet + Fout bij het laden van %s: Je kan HD niet deactiveren voor een reeds bestaande HD portemonnee + + Error loading block database Fout bij het laden van blokkendatabase @@ -2031,10 +3236,6 @@ Locatie van de auth cookie (standaard: data dir) - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Minimum aantal bytes dat er per sigop in een transactie gerelayed en gemined worden (standaard: %u) - - Not enough file descriptors available. Niet genoeg file descriptors beschikbaar. @@ -2067,10 +3268,18 @@ Herbouw ketenstaat vanuit de huidige geindexeerde blokken + Rewinding blocks... + Blokken aan het terugdraaien... + + Set database cache size in megabytes (%d to %d, default: %d) Zet database cache grootte in megabytes (%d tot %d, standaard: %d) + Set maximum BIP141 block weight (default: %d) + Zet het BIP141 maximum gewicht van een blok (standaard: %d) + + Set maximum block size in bytes (default: %d) Stel maximum blokgrootte in in bytes (standaard: %d) @@ -2079,6 +3288,14 @@ Specificeer het portemonnee bestand (vanuit de gegevensmap) + Starting network threads... + Netwerkthread starten... + + + The source code is available from %s. + De broncode is beschikbaar van %s. + + Unable to bind to %s on this computer. %s is probably already running. Niet in staat om %s te verbinden op deze computer. %s draait waarschijnlijk al. @@ -2159,6 +3376,10 @@ Transactiekosten (in %s/kB) kleiner dan dit worden beschouw dat geen transactiekosten in rekening worden gebracht voor doorgeven, mijnen en transactiecreatie (standaard: %s) + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + Forceer het doorsturen van transacties van goedgekeurde peers, zelfs wanneer deze niet voldoen aan de lokale doorstuurregels (standaard: %d) + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Als paytxfee niet is ingesteld, voeg voldoende transactiekosten toe zodat transacties starten met bevestigingen binnen in n blokken (standaard: %u) @@ -2191,12 +3412,16 @@ 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. + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + Gebruik hiërarchische deterministische sleutelgeneratie (HD) na BIP32. Dit heeft enkel effect bij het aanmaken van portemonnees of het eerste gebruik + + 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 Goedgekeurde peers kunnen niet ge-DoS-banned worden en hun transacties worden altijd doorgegeven, zelfs als ze reeds in de mempool aanwezig zijn, nuttig voor bijv. een gateway You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain - U moet de database herbouwen met -reindex om terug te gaan naar de ongesnoeide modus. Dit zal de gehele blokkketen opnieuw downloaden. + U moet de database herbouwen met -reindex om terug te gaan naar de ongesnoeide modus. Dit zal de gehele blokketen opnieuw downloaden. (default: %u) @@ -2491,10 +3716,6 @@ Stel sleutelpoelgrootte in op <n> (standaard: %u) - Set minimum block size in bytes (default: %u) - Stel minimum blokgrootte in in bytes (standaard: %u) - - Set the number of threads to service RPC calls (default: %d) Stel het aantal threads in om RPC-aanvragen mee te bedienen (standaard: %d) diff --git a/src/qt/locale/bitcoin_pam.ts b/src/qt/locale/bitcoin_pam.ts index 53515433384..674c1b1d9db 100644 --- a/src/qt/locale/bitcoin_pam.ts +++ b/src/qt/locale/bitcoin_pam.ts @@ -33,7 +33,10 @@ &Delete &Ilako - + + + AddressTableModel + AskPassphraseDialog @@ -52,7 +55,7 @@ Repeat new passphrase Pasibayuan ya ing bayung passphrase - + BanTableModel @@ -256,7 +259,7 @@ &Address &Address - + FreespaceChecker @@ -412,6 +415,9 @@ + PaymentServer + + PeerTableModel @@ -426,6 +432,9 @@ + QRImageWidget + + RPCConsole N/A @@ -511,6 +520,9 @@ + RecentRequestsTableModel + + SendCoinsDialog Send Coins @@ -552,7 +564,7 @@ S&end Ipadala - + SendCoinsEntry @@ -589,6 +601,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -657,7 +672,7 @@ Reset all verify message fields Ibalik king dati reng ngan fields na ning pamag beripikang mensayi - + SplashScreen @@ -669,16 +684,34 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Ining pane a ini magpakit yang detalyadung description ning transaksion - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_pl.ts b/src/qt/locale/bitcoin_pl.ts index 09f748b83cb..deb6c37c7dd 100644 --- a/src/qt/locale/bitcoin_pl.ts +++ b/src/qt/locale/bitcoin_pl.ts @@ -41,7 +41,58 @@ &Delete &Usuń - + + Sending addresses + Adresy wysyłania + + + Receiving addresses + Adresy odbioru + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Tutaj znajdują się adresy Bitcoin na które wysyłasz płatności. Zawsze sprawdzaj ilość i adres odbiorcy przed wysyłką monet. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + To są twoje adresy Bitcoin do odbierania płatności. Zaleca się używanie nowych adresów odbiorczych dla każdej transakcji. + + + &Copy Address + &Kopiuj adres + + + Copy &Label + Kopiuj &Etykietę + + + &Edit + &Edytuj + + + Export Address List + Eksportuj listę adresów + + + Comma separated file (*.csv) + Plik *.CSV (dane rozdzielane przecinkami) + + + Exporting Failed + Eksportowanie nie powiodło się + + + + AddressTableModel + + Label + Etykieta + + + Address + Adres + + AskPassphraseDialog @@ -60,7 +111,51 @@ Repeat new passphrase Powtórz nowe hasło - + + Encrypt wallet + Zaszyfruj portfel + + + Unlock wallet + Odblokuj portfel + + + Decrypt wallet + Odszyfruj portfel + + + Change passphrase + Zmień hasło + + + Enter the old passphrase and new passphrase to the wallet. + Podaj stare i nowe hasło do portfela. + + + Confirm wallet encryption + Potwierdź szyfrowanie portfela + + + Wallet encrypted + Portfel zaszyfrowany + + + Wallet encryption failed + Szyfrowanie portfela nie powiodło się + + + Wallet unlock failed + Odblokowanie portfela nie powiodło się + + + The passphrase entered for the wallet decryption was incorrect. + Wprowadzone hasło do odszyfrowania portfela jest niepoprawne. + + + Wallet decryption failed + Odszyfrowanie portfela nie powiodło się + + BanTableModel @@ -463,7 +558,87 @@ Priority Priorytet - + + Copy address + Kopiuj adres + + + Copy label + Kopiuj etykietę + + + Copy amount + Kopiuj kwotę + + + Copy transaction ID + Skopiuj ID transakcji + + + Lock unspent + Zablokuj niewydane + + + Unlock unspent + Odblokuj niewydane + + + Copy quantity + Skopiuj ilość + + + Copy fee + Skopiuj prowizję + + + Copy after fee + Skopiuj ilość po opłacie + + + highest + najwyższy + + + higher + wyższy + + + high + wysoki + + + medium-high + średnio wysoki + + + medium + średni + + + low-medium + średnio niski + + + low + niski + + + lower + niższy + + + lowest + najniższy + + + yes + tak + + + no + nie + + EditAddressDialog @@ -486,7 +661,7 @@ &Address &Adres - + FreespaceChecker @@ -626,7 +801,7 @@ Select payment request file Otwórz żądanie zapłaty z pliku - + OptionsDialog @@ -938,6 +1113,9 @@ + PaymentServer + + PeerTableModel User Agent @@ -992,6 +1170,9 @@ + QRImageWidget + + RPCConsole N/A @@ -1142,6 +1323,10 @@ Czas odpowiedzi + The duration of a currently outstanding ping. + Czas trwania nadmiarowego pingu + + Ping Wait Czas odpowiedzi @@ -1348,6 +1533,14 @@ Remove Usuń + + Copy label + Kopiuj etykietę + + + Copy amount + Kopiuj kwotę + ReceiveRequestDialog @@ -1367,7 +1560,22 @@ &Save Image... &Zapisz obraz... - + + Address + Adres + + + Label + Etykieta + + + + RecentRequestsTableModel + + Label + Etykieta + + SendCoinsDialog @@ -1518,7 +1726,23 @@ S&end Wy&syłka - + + Copy quantity + Skopiuj ilość + + + Copy amount + Kopiuj kwotę + + + Copy fee + Skopiuj prowizję + + + Copy after fee + Skopiuj ilość po opłacie + + SendCoinsEntry @@ -1597,7 +1821,10 @@ Memo: Notatka: - + + + SendConfirmationDialog + ShutdownWindow @@ -1696,7 +1923,7 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Reset all verify message fields Resetuje wszystkie pola weryfikacji wiadomości - + SplashScreen @@ -1712,12 +1939,57 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Ten panel pokazuje szczegółowy opis transakcji - + + + TransactionTableModel + + Label + Etykieta + + + + TransactionView + + Copy address + Kopiuj adres + + + Copy label + Kopiuj etykietę + + + Copy amount + Kopiuj kwotę + + + Copy transaction ID + Skopiuj ID transakcji + + + Comma separated file (*.csv) + Plik *.CSV (dane rozdzielane przecinkami) + + + Label + Etykieta + + + Address + Adres + + + Exporting Failed + Eksportowanie nie powiodło się + + UnitDisplayStatusBarControl @@ -1726,6 +1998,15 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: @@ -1756,6 +2037,18 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Przycinanie skonfigurowano poniżej minimalnych %d MiB. Proszę użyć wyższej liczby. + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Prune: ostatnia synchronizacja portfela jest za danymi. Muszisz -reindexować (pobrać cały ciąg bloków ponownie w przypadku przyciętego węzła) + + + 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) + Zredukuj wymaganą ilość miejsca na dysku poprzez usuwanie starych bloków. Ten tryb jest niekompatybilny z -txindex oraz -rescan. Ostrzeżenie: Wycofanie tego ustawienia wymaga ponownego pobrania całego łańcucha bloków. (domyślnie: 0 = wyłącz usuwanie bloków, >%u = docelowy rozmiar w MiB jaki wykorzystać na pliki z blokami) + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Ponowne skanowanie nie jest możliwe w trybie przycinania. Będzie trzeba użyć -reindex, co pobierze ponownie cały łańcuch bloków. + + Error: A fatal internal error occurred, see debug.log for details Błąd: Wystąpił fatalny błąd wewnętrzny, sprawdź szczegóły w debug.log @@ -1792,6 +2085,14 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw -fallbackfee ma ustawioną bardzo dużą wartość! Jest to prowizja za transakcje, którą możesz zapłacić gdy oszacowanie opłaty jest niemożliwe. + A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s) + Stawka prowizji (w %s/kB), która będzie użyta, gdy oszacowane dane o prowizjach nie będą wystarczające (domyślnie: %s) + + + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Skojarz z podanym adresem i nasłuchuj na nim. Użyj formatu [host]:port dla IPv6 @@ -1816,10 +2117,6 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Wykonaj polecenie, kiedy transakcja portfela ulegnie zmianie (%s w poleceniu zostanie zastąpione przez TxID) - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Wymuś przekazywanie transakcji od osób z białej listy, nawet jeśli narusza to lokalną politykę przekazywania (default: %d) - - Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. Proszę sprawdzić czy data i czas na Twoim komputerze są poprawne! Jeżeli ustawienia zegara będą złe, %s nie będzie działał prawidłowo. @@ -1864,6 +2161,10 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw <category> mogą być: + Append comment to the user agent string + Dodaj komentarz do pola user agent + + Attempt to recover private keys from a corrupt wallet on startup Próbuj odzyskać klucze prywatne z uszkodzonego portfela podczas uruchamiania. @@ -1872,6 +2173,10 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Opcje tworzenia bloku: + Cannot resolve -%s address: '%s' + Nie można rozpoznać -%s adresu: '%s' + + Connect only to the specified node(s) Łącz się tylko do wskazanego węzła/węzłów @@ -1968,6 +2273,14 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Utrzymuj obszar pamięci dla transakcji poniżej <n> MB (default: %u) + Loading banlist... + Ładowanie listy zablokowanych... + + + Location of the auth cookie (default: data dir) + Lokalizacja autoryzacyjnego pliku cookie (domyślnie: ścieżka danych) + + Not enough file descriptors available. Brak wystarczającej liczby deskryptorów plików. @@ -2012,6 +2325,10 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Określ plik portfela (w obrębie folderu danych) + The source code is available from %s. + Kod źródłowy dostępny jest z %s. + + Unable to bind to %s on this computer. %s is probably already running. Nie można przywiązać do %s na tym komputerze. %s prawdopodobnie jest już uruchomiony. @@ -2212,6 +2529,10 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Hasło zabezpieczające portu kontrolnego Tora (domyślnie: puste) + Tor control port to use if onion listening enabled (default: %s) + Port kontrolny sieci Tor jeśli onion listening jest włączone (domyślnie: %s) + + Transaction amount too small Zbyt niska kwota transakcji @@ -2392,10 +2713,6 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw Ustaw rozmiar puli kluczy na <n> (domyślnie: %u) - Set minimum block size in bytes (default: %u) - Ustaw minimalny rozmiar bloku w bajtach (domyślnie: %u) - - Set the number of threads to service RPC calls (default: %d) Ustaw liczbę wątków do obsługi RPC (domyślnie: %d) diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts index ee48c673413..aeaf99f5073 100644 --- a/src/qt/locale/bitcoin_pt_BR.ts +++ b/src/qt/locale/bitcoin_pt_BR.ts @@ -23,7 +23,7 @@ C&lose - &Fechar + Fechar Delete the currently selected address from the list @@ -41,6 +41,77 @@ &Delete &Excluir + + Choose the address to send coins to + Escoha o endereço para enviar moedas + + + Choose the address to receive coins with + Escolha o enereço para receber moedas + + + C&hoose + Escol&ha + + + Sending addresses + Endereços de envio + + + Receiving addresses + Endereços de recebimento + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Estes são os seus endereços para enviar pagamentos. Sempre cheque a quantia e o endereço do destinatário antes de enviar moedas. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Estes são os seus endereços para receber pagamentos. É recomendado usar um novo para cada transação. + + + &Copy Address + &Copiar endereço + + + Copy &Label + Copiar rótu&lo + + + &Edit + &Editar + + + Export Address List + Exportar lista de endereços + + + Comma separated file (*.csv) + Comma separated file (*.csv) + + + Exporting Failed + Falha na exportação + + + There was an error trying to save the address list to %1. Please try again. + Erro ao salvar a lista de endereço para %1. Tente novamente. + + + + AddressTableModel + + Label + Rótuo + + + Address + Endereço + + + (no label) + (sem rótuo) + AskPassphraseDialog @@ -60,6 +131,90 @@ Repeat new passphrase Repita a nova frase de segurança + + 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>. + Insira a nova senha para a carteira.<br/>Favor usar uma senha com <b>dez ou mais caracteres aleatórios</b>, ou <b>oito ou mais palavras</b>. + + + Encrypt wallet + Criptografar carteira + + + This operation needs your wallet passphrase to unlock the wallet. + Esta operação precisa da sua senha para desbloquear a carteira. + + + Unlock wallet + Desbloquear carteira + + + This operation needs your wallet passphrase to decrypt the wallet. + Esta operação precisa da sua senha para descriptografar a carteira + + + Decrypt wallet + Descriptografar carteira + + + Change passphrase + Alterar senha + + + Enter the old passphrase and new passphrase to the wallet. + Insira a senha antiga e a nova para a carteira. + + + Confirm wallet encryption + Confirmar criptografia da carteira + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Aviso: Se você criptografar sua carteira e perder sua senha, você vai <b>PERDER TODOS OS SEUS BITCOINS</b>! + + + Are you sure you wish to encrypt your wallet? + Tem certeza que deseja criptografar a carteira? + + + Wallet encrypted + Carteira criptografada + + + 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. + IMPORTANTE: Qualquer backup prévio que você tenha feito da sua carteira deve ser substituído pelo novo e encriptado arquivo gerado. Por razões de segurança, qualquer backup do arquivo não criptografado se tornará inútil assim que você começar a usar uma nova carteira criptografada. + + + Wallet encryption failed + Falha ao criptografar carteira + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Falha na criptografia devido a um erro inerno. Sua carteira não foi criptografada. + + + The supplied passphrases do not match. + As senhas não conferem. + + + Wallet unlock failed + Falha ao desbloquear carteira + + + The passphrase entered for the wallet decryption was incorrect. + A senha inserida para descriptografar a carteira está incorreta. + + + Wallet decryption failed + Falha ao descriptografar a carteira + + + Wallet passphrase was successfully changed. + A senha da carteira foi alterada com êxito. + + + Warning: The Caps Lock key is on! + Aviso: Tecla Caps Lock ativa! + BanTableModel @@ -176,7 +331,7 @@ &Debug window - Janela de &Depuração + Janela de &depuração Open debugging and diagnostic console @@ -332,7 +487,7 @@ %1 client - cliente %1 + %1 Catching up... @@ -463,6 +618,150 @@ Priority Prioridade + + Copy address + Copiar endereço + + + Copy label + Copiar rótulo + + + Copy amount + Copiar quantia + + + Copy transaction ID + Copiar ID da transação + + + Lock unspent + Boquear saída + + + Unlock unspent + Desboquear saída + + + Copy quantity + Copiar quantia + + + Copy fee + Copiar taxa + + + Copy after fee + Copiar pós taxa + + + Copy bytes + Copiar bytes + + + Copy priority + Copiar prioridade + + + Copy dust + Copiar poeira + + + Copy change + Copiar troco + + + highest + mega alta + + + higher + super alta + + + high + alta + + + medium-high + média alta + + + medium + média + + + low-medium + média baixa + + + low + baixa + + + lower + super baixa + + + lowest + mega baixa + + + (%1 locked) + (%1 bloqueada) + + + none + nenhum + + + yes + sim + + + no + não + + + This label turns red if the transaction size is greater than 1000 bytes. + Este texto fica vermeho se o tamanho da transação for maior que 1 KiB. + + + This means a fee of at least %1 per kB is required. + Isso quer dizer que uma taxa de pelo menos %1 per KiB será necessária. + + + Can vary +/- 1 byte per input. + Pode variar +/- 1 byte por entrada + + + Transactions with higher priority are more likely to get included into a block. + Transações de alta prioridade são mais propensas a serem incluídas em um bloco. + + + This label turns red if the priority is smaller than "medium". + Este texto fica vermelho se a prioridade é menor que "medio". + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Este texto fica vermelho se qualquer destinatário receber uma quantidade menor que que o dust. + + + Can vary +/- %1 satoshi(s) per input. + Pode variar +/- %1 satoshi(s) por entrada + + + (no label) + (sem rótuo) + + + change from %1 (%2) + troco de %1 (%2) + + + (change) + (troco) + EditAddressDialog @@ -486,6 +785,38 @@ &Address &Endereço + + New receiving address + Novo endereço de recebimento + + + New sending address + Novo endereço de envio + + + Edit receiving address + Editar endereço de recebimento + + + Edit sending address + Editar endereço de envio + + + The entered address "%1" is not a valid Bitcoin address. + O endereço digitado "%1" não é um endereço válido. + + + The entered address "%1" is already in the address book. + O endereço digitado "%1" já se encontra no catálogo de endereços. + + + Could not unlock wallet. + Não foi possível desbloquear a carteira + + + New key generation failed. + Falha ao gerar chave + FreespaceChecker @@ -626,6 +957,10 @@ Select payment request file Selecione o arquivo de cobrança + + Select payment request file to open + Selecione o arquivo de cobrança para ser aberto + OptionsDialog @@ -643,7 +978,7 @@ &Start %1 on system login - $Iniciar %1 ao fazer login no sistema + &Iniciar %1 ao fazer login no sistema Size of &database cache @@ -938,6 +1273,97 @@ + PaymentServer + + Payment request error + Erro no pedido de pagamento + + + Cannot start bitcoin: click-to-pay handler + Não foi possível iniciar bitcoin: manipulador click-to-pay + + + URI handling + Manipulação de URI + + + Payment request fetch URL is invalid: %1 + URL de cobrança é inválida: %1 + + + Invalid payment address %1 + Endereço de pagamento %1 inválido + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + URI não pode ser analisado! Isto pode ser causado por um endereço inválido ou parâmetros URI informados incorretamente. + + + Payment request file handling + Manipulação de arquivo de cobrança + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + Arquivo de pedido de pagamento não pode ser lido! Isto pode ser causado por uma requisição de pagamento inválida. + + + Payment request rejected + Pedido de pagamento rejeitado + + + Payment request network doesn't match client network. + Rede do pedido de pagamento não corresponde rede do cliente. + + + Payment request expired. + Pedido de pagamento expirado + + + Payment request is not initialized. + Pedido de pagamento não inicializado + + + Unverified payment requests to custom payment scripts are unsupported. + Pedidos de pagamento não verificados para scripts de pagamento personalizados não são suportados. + + + Invalid payment request. + Pedido de pagamento inválido + + + Requested payment amount of %1 is too small (considered dust). + Valor do pagamento solicitado de %1 é muito pequeno (Considerado poeira). + + + Refund from %1 + Reembolso de %1 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + Pedido de pagamento %1 é muito grande (%2 bytes, permitido %3 bytes). + + + Error communicating with %1: %2 + Erro na comunicação com %1: %2 + + + Payment request cannot be parsed! + Pedido de pagamento não pode ser analisado! + + + Bad response from server %1 + Erro na resposta do servidor: %1 + + + Network request error + Erro de solicitação de rede + + + Payment acknowledged + Pagamento reconhecido + + + PeerTableModel User Agent @@ -992,6 +1418,25 @@ + QRImageWidget + + &Save Image... + &Savar imagem + + + &Copy Image + &Copiar imagem + + + Save QR Code + Salvar código QR + + + PNG Image (*.png) + Imagem PNG (*.png) + + + RPCConsole N/A @@ -1187,7 +1632,7 @@ Debug log file - Arquivo de log de Depuração + Arquivo de log de depuração Clear console @@ -1352,6 +1797,18 @@ Remove Remover + + Copy label + Copiar rótulo + + + Copy message + Copiar mensagem + + + Copy amount + Copiar quantia + ReceiveRequestDialog @@ -1371,44 +1828,111 @@ &Save Image... &Salvar Imagem... - - - SendCoinsDialog - Send Coins - Enviar moedas + Request payment to %1 + Pedido de pagamento para %1 - Coin Control Features - Opções de controle de moeda + Payment information + Informação do pagamento - Inputs... - Entradas... + URI + URI - automatically selected - automaticamente selecionado + Address + Endereço - Insufficient funds! - Saldo insuficiente! + Amount + Quantia - Quantity: - Quantidade: + Label + Rótuo - Bytes: - Bytes: + Message + Mensagem - Amount: - Quantia: + Resulting URI too long, try to reduce the text for label / message. + URI resultante muito longa. Tente reduzir o texto do rótulo ou da mensagem. - Priority: - Prioridade: + Error encoding URI into QR Code. + Erro ao codigicar o URI em código QR + + + + RecentRequestsTableModel + + Date + Data + + + Label + Rótuo + + + Message + Mensagem + + + (no label) + (sem rótuo) + + + (no message) + (sem mensagem) + + + (no amount requested) + (nenhuma quantia solicitada) + + + Requested + Solicitado + + + + SendCoinsDialog + + Send Coins + Enviar moedas + + + Coin Control Features + Opções de controle de moeda + + + Inputs... + Entradas... + + + automatically selected + automaticamente selecionado + + + Insufficient funds! + Saldo insuficiente! + + + Quantity: + Quantidade: + + + Bytes: + Bytes: + + + Amount: + Quantia: + + + Priority: + Prioridade: Fee: @@ -1522,6 +2046,118 @@ S&end Enviar + + Copy quantity + Copiar quantia + + + Copy amount + Copiar quantia + + + Copy fee + Copiar taxa + + + Copy after fee + Copiar pós taxa + + + Copy bytes + Copiar bytes + + + Copy priority + Copiar prioridade + + + Copy dust + Copiar poeira + + + Copy change + Copiar troco + + + %1 to %2 + %1 a %2 + + + Are you sure you want to send? + Tem certeza que deseja enviar? + + + added as transaction fee + adicionado como taxa da transação + + + Total Amount %1 + Quantia tota %1 + + + or + ou + + + Confirm send coins + Confirme o envio de moedas + + + The recipient address is not valid. Please recheck. + Endereço de envio inváido. Favor checar. + + + The amount to pay must be larger than 0. + A quantia à pagar deve ser maior que 0 + + + The amount exceeds your balance. + A quantia excede o seu saldo + + + The total exceeds your balance when the %1 transaction fee is included. + O total excede o seu saldo quando a taxa da transação %1 é incluída + + + Duplicate address found: addresses should only be used once each. + Endereço duplicado encontrado: Endereços devem ser usados somente uma vez cada. + + + Transaction creation failed! + Falha na criação da transação + + + 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. + A transação foi rejeitada! Isso pode acontecer se algumas moedas na sua carteira já foram gastas em outro local, por exemplo se você tiver uma cópia da carteira e as moedas tiverem sido gastas na cópia mas não marcados como gastas aqui ainda. + + + A fee higher than %1 is considered an absurdly high fee. + Uma taxa maior que %1 é considerada uma taxa absurdamente alta. + + + Payment request expired. + Pedido de pagamento expirado + + + Pay only the required fee of %1 + Pagar somente a taxa requerida de %1 + + + Estimated to begin confirmation within %n block(s). + Estimado a começar confirmação em %n bloco(s).Estimado começar confirmação em %n bloco(s). + + + Warning: Invalid Bitcoin address + Aviso: Endereço inválido + + + Warning: Unknown change address + Aviso: Endereço de troco inválido + + + (no label) + (sem rótuo) + SendCoinsEntry @@ -1567,7 +2203,7 @@ 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. - A taxa será deduzida da quantia sendo enviada. O destinatário receberá menos bitcoins do que você colocou no campo de quantidade. Se varios destinatários estão selecionados, a taxa é dividida igualmente. + A taxa será deduzida da quantia que está sendo enviada. O destinatário receberá menos bitcoins do que você colocou no campo de quantidade. Se vários destinatários estão selecionados, a taxa é dividida igualmente. S&ubtract fee from amount @@ -1601,6 +2237,17 @@ Memo: Memorizar: + + Enter a label for this address to add it to your address book + Digite um rótulo para este endereço para adicioná-lo ao catálogo de endereços + + + + SendConfirmationDialog + + Yes + Sim + ShutdownWindow @@ -1695,6 +2342,58 @@ Reset all verify message fields Limpar todos os campos de assinatura da mensagem + + Click "Sign Message" to generate signature + Clique em "Assinar mensagem" para gerar a assinatura + + + The entered address is invalid. + O endereço digitado é inválido + + + Please check the address and try again. + Favor checar o endereço e tente novamente + + + The entered address does not refer to a key. + O endereço fornecido não se refere a uma chave. + + + Wallet unlock was cancelled. + O desbloqueio da carteira foi cancelado + + + Private key for the entered address is not available. + A chave privada do endereço inserido não está disponível + + + Message signing failed. + Falha ao assinar mensagem + + + Message signed. + Mensagem assinada + + + The signature could not be decoded. + A assinatura não pode ser descodificada + + + Please check the signature and try again. + Favor checar a assinatura e tente novamente + + + The signature did not match the message digest. + A assinatura não corresponde a mensagem + + + Message verification failed. + Falha na verificação da mensagem + + + Message verified. + Mensagem verificada + SplashScreen @@ -1711,11 +2410,456 @@ + TransactionDesc + + Open for %n more block(s) + Aberto para mais %n bloco(s)Aberto para mais %n bloco(s) + + + Open until %1 + Aberto até %1 + + + conflicted with a transaction with %1 confirmations + conflitado com uma transação com %1 confirmações + + + %1/offline + %1/offline + + + 0/unconfirmed, %1 + 0/não confirmado, %1 + + + in memory pool + na memória + + + not in memory pool + não na memóra + + + abandoned + abandonado + + + %1/unconfirmed + %1/não confirmado + + + %1 confirmations + %1 confirmações + + + Status + Status + + + , has not been successfully broadcast yet + , ainda não foi propagada na rede com êxito. + + + , broadcast through %n node(s) + , propagada por %n nó(s), propagada por %n nó(s) + + + Date + Data + + + Source + Fonte + + + Generated + Gerado + + + From + De + + + unknown + desconhecido + + + To + Para + + + own address + próprio endereço + + + watch-only + monitorado + + + label + rótulo + + + Credit + Crédito + + + matures in %n more block(s) + amadurece em mais %n bloco(s)amadurece em mais %n bloco(s) + + + not accepted + não aceito + + + Debit + Débito + + + Total debit + Débito total + + + Total credit + Crédito total + + + Transaction fee + Taxa da transação + + + Net amount + Valor líquido + + + Message + Mensagem + + + Comment + Comentário + + + Transaction ID + ID da transação + + + Output index + Index da saída + + + Merchant + Mercador + + + 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. + Moedas recém minerados precisam aguardar %1 blocos antes de serem gastos. Quando o bloco foi gerado, ele foi disseminado pela rede para ser adicionado à blockchain. Se ele falhar em ser inserido na cadeia, seu estado será modificado para "não aceito" e ele não poderá ser gasto. Isso pode acontecer eventualmente quando blocos são gerados quase que simultaneamente. + + + Debug information + Depurar informação + + + Transaction + Transação + + + Inputs + Entradas + + + Amount + Quantia + + + true + verdadeiro + + + false + falso + + + TransactionDescDialog This pane shows a detailed description of the transaction Este painel mostra uma descrição detalhada da transação + + Details for %1 + Detalhes para %1 + + + + TransactionTableModel + + Date + Data + + + Type + Tipo + + + Label + Rótuo + + + Open for %n more block(s) + Aberto por mais %n bloco(s)Aberto por mais %n bloco(s) + + + Open until %1 + Aberto até %1 + + + Offline + Offline + + + Unconfirmed + Não confirmado + + + Abandoned + Abandonado + + + Confirming (%1 of %2 recommended confirmations) + Confirmando (%1 de %2 confirmações recomendadas) + + + Confirmed (%1 confirmations) + Confirmado (%1 confirmações) + + + Conflicted + Conflitado + + + Immature (%1 confirmations, will be available after %2) + Recém-criado (%1 confirmações, disponível somente após %2) + + + This block was not received by any other nodes and will probably not be accepted! + Este bloco não foi recebido por nenhum outro participante da rede e provavelmente não será aceito! + + + Generated but not accepted + Gerado mas não aceito + + + Received with + Recebido em + + + Received from + Recebido de + + + Sent to + Enviado para + + + Payment to yourself + Pagamento para você mesmo + + + Mined + Minerado + + + watch-only + monitorado + + + (n/a) + (n/a) + + + (no label) + (sem rótuo) + + + Transaction status. Hover over this field to show number of confirmations. + Status da transação. Passe o mouse sobre este campo para mostrar o número de confirmações. + + + Date and time that the transaction was received. + Data e hora em que a transação foi recebida. + + + Type of transaction. + Tipo de transação + + + Whether or not a watch-only address is involved in this transaction. + Mostrar ou não endereços monitorados na lista de transações. + + + User-defined intent/purpose of the transaction. + Intenção/Propósito definido pelo usuário para a transação + + + Amount removed from or added to balance. + Quantidade debitada ou creditada ao saldo. + + + + TransactionView + + All + Todos + + + Today + Hoje + + + This week + Essa semana + + + This month + Esse mês + + + Last month + Último mês + + + This year + Este ano + + + Range... + Intervalo... + + + Received with + Recebido em + + + Sent to + Enviado para + + + To yourself + Para você mesmo + + + Mined + Minerado + + + Other + Outro + + + Enter address or label to search + Procure um endereço ou rótulo + + + Min amount + Quantia mínima + + + Abandon transaction + Transação abandonada + + + Copy address + Copiar endereço + + + Copy label + Copiar rótulo + + + Copy amount + Copiar quantia + + + Copy transaction ID + Copiar ID da transação + + + Copy raw transaction + Copiar o raw da transação + + + Copy full transaction details + Copiar dados completos da transação + + + Edit label + Editar rótulo + + + Show transaction details + Mostrar detalhes da transação + + + Export Transaction History + Exportar histórico de transações + + + Comma separated file (*.csv) + Comma separated file (*.csv) + + + Confirmed + Confirmado + + + Watch-only + Monitorado + + + Date + Data + + + Type + Tipo + + + Label + Rótuo + + + Address + Endereço + + + ID + ID + + + Exporting Failed + Falha na exportação + + + There was an error trying to save the transaction history to %1. + Ocorreu um erro ao tentar salvar o histórico de transações em %1. + + + Exporting Successful + Exportação feita com êxito + + + The transaction history was successfully saved to %1. + O histórico de transação foi gravado com êxito em %1. + + + Range: + Intervalo: + + + to + para + UnitDisplayStatusBarControl @@ -1725,6 +2869,55 @@ + WalletFrame + + No wallet has been loaded. + Nenhuma carteira carregada + + + + WalletModel + + Send Coins + Enviar moedas + + + + WalletView + + &Export + &Exportar + + + Export the data in the current tab to a file + Exportar os dados da guia atual para um arquivo + + + Backup Wallet + Backup da carteira + + + Wallet Data (*.dat) + Dados da carteira (*.dat) + + + Backup Failed + Falha no backup + + + There was an error trying to save the wallet data to %1. + Ocorreu um erro ao tentar salvar os dados da carteira em %1. + + + Backup Successful + Êxito no backup + + + The wallet data was successfully saved to %1. + Os dados da carteira foram salvos com êxito em %1. + + + bitcoin-core Options: @@ -1752,19 +2945,19 @@ Prune configured below the minimum of %d MiB. Please use a higher number. - Corte configurado abaixo do nível mínimo de %d de MiB. Por favor use um número mais alto. + Prune configurado abaixo do mínimo de %d MiB. Por favor use um número mais alto. Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) - Corte: a ultima sincronização da carteira foi além do dado comprimido. Você precisa reindexar ( -reindex , faça o download de toda a blockchain novamente) + Prune: A ultima sincronização da carteira foi além do dado comprimido. Você precisa reindexar (fazer o download de toda a blockchain novamente) 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) - Reduza os requerimentos de armazenamento de dados (cortando) deletando blocos mais antigos. Esse modo é incompatível com -txindex e -rescan. Cuidado: Reverter essa configuração requer um novo download de toda a blockchain. (Padrão: 0 = desabilita o corte de blocos, >%u = tamanho alvo em MiB para o uso de blocos cortados) + Reduza o armazenamento de dados apagando os blocos mais antigos. Esse modo é incompatível com -txindex e -rescan. Cuidado: Reverter essa configuração requer um novo download de toda a blockchain. (Padrão: 0 = desabilitado, >%u = tamanho em MiB para o uso de blocos cortados) Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. - Rescans não são possíveis no modo de corte. Você precisa usar -reindex, que irá fazer o download de toda a blockchain novamente. + Rescans não são possíveis no modo prune. Você precisa usar -reindex, que irá fazer o download de toda a blockchain novamente. Error: A fatal internal error occurred, see debug.log for details @@ -1792,7 +2985,7 @@ Bitcoin Core - Bitcoin + Bitcoin Core -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. @@ -1823,6 +3016,10 @@ Distribuido sob a licença MIT software license. Veja os termos em <http://www.opensource.org/licenses/mit-license.php>. + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Número mínimo de bytes por assinatura em transações que transmitimos e mineramos (default: %u) + + Error loading %s: You can't enable HD on a already existing non-HD wallet Erro ao carregar %s. Não é permitido habilitar HD em carteiras não-HD pre existentes. @@ -1835,12 +3032,8 @@ Executa um comando quando uma transação da carteira mudar (%s no comando será substituído por TxID) - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Força a retransmissão de transações de pares da lista branca, mesmo quando violam a política local de retransmissão (default: %d) - - Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) - A mediana máxima permitida de peer time compensa o ajuste. Perspectiva local de horário pode ser influenciada por pares à frente ou atrás neste montante. (padrão: %u segundos) + A media máxima permitida de peer time compensa o ajuste. Perspectiva local de horário pode ser influenciada por pares à frente ou atrás neste montante. (padrão: %u segundos) Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) @@ -1867,6 +3060,10 @@ Este pode ser um build de teste pré-lançamento - use por sua conta e risco - não use para mineração ou aplicações de comércio. + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + Não foi possível reanalisar o banco de dados para o estado pre-fork. Você precisa rebaixar o blockchain + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) Use UPnP para mapear a porta escutada (padrão: 1 quando escutando e sem -proxy) @@ -1883,6 +3080,14 @@ Lista Branca pares de ligação da máscara de rede dado ou o endereço IP . Pode ser especificado várias vezes. + You need to rebuild the database using -reindex-chainstate to change -txindex + Você precisa reconstruir o banco de dados utilizando -reindex-chainstate para mudar -txindex + + + %s corrupt, salvage failed + %s corrompido, recuperação falhou + + -maxmempool must be at least %d MB -maxmempool deve ser pelo menos %d MB @@ -1903,6 +3108,14 @@ Opções de criação de blocos: + Cannot resolve -%s address: '%s' + Impossível resolver -%s endereço: '%s' + + + Change index out of range + Índice de mudança fora da faixa. + + Connect only to the specified node(s) Conectar apenas a cliente(s) específico(s) @@ -1911,6 +3124,10 @@ Opções de conexão: + Copyright (C) %i-%i + Copyright (C) %i-%i + + Corrupted block database detected Detectado Banco de dados de blocos corrompido @@ -1955,6 +3172,22 @@ Erro ao inicializar ambiente de banco de dados de carteira %s! + Error loading %s + Erro ao carregar %s + + + Error loading %s: Wallet corrupted + Erro ao carregar %s Carteira corrompida + + + Error loading %s: Wallet requires newer version of %s + Erro ao carregar %s A carteira requer a versão mais nova do %s + + + Error loading %s: You can't disable HD on a already existing HD wallet + Erro ao carregar %s: Você não pode desabilitar HD numa já existente carteira HD. + + Error loading block database Erro ao carregar banco de dados de blocos @@ -1979,10 +3212,18 @@ Bloco gênese incorreto ou não encontrado. Datadir errado para a rede? + Initialization sanity check failed. %s is shutting down. + O teste de integridade de inicialização falhou. O %s está sendo desligado. + + Invalid -onion address: '%s' Endereço -onion inválido: '%s' + Invalid amount for -%s=<amount>: '%s' + Valor inválido para -%s=<amount>: '%s' + + Invalid amount for -fallbackfee=<amount>: '%s' Valor inválido para -fallbackfee=<amount>: '%s' @@ -1991,12 +3232,12 @@ Mantenha a mempool de transações abaixo de <n> megabytes (padrão: %u) - Location of the auth cookie (default: data dir) - Localização do cookie de autenticação (padrão: diretório de dados) + Loading banlist... + Carregando lista de banidos... - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Número mínimo de bytes por sigop em transações que transmitimos e mineramos (default: %u) + Location of the auth cookie (default: data dir) + Localização do cookie de autenticação (padrão: diretório de dados) Not enough file descriptors available. @@ -2007,22 +3248,42 @@ Somente conectar a clientes na rede <net> (ipv4, ipv6 ou onion) + Print this help message and exit + Mostra essa mensagem de ajuda e sai + + Print version and exit - Mostra a versão e sai + Imprimir versão e sair Prune cannot be configured with a negative value. - O modo Prune não pode ser configurado com um valor negativo. + O modo prune não pode ser configurado com um valor negativo. Prune mode is incompatible with -txindex. - O modo Prune é incompatível com -txindex. + O modo prune é incompatível com -txindex. + + + Rebuild chain state and block index from the blk*.dat files on disk + Reconstruir índice de cadeia de bloco a partir dos arquivos blk*.dat no disco + + + Rebuild chain state from the currently indexed blocks + Reconstruir estado a partir dos blocos indexados + + + Rewinding blocks... + Reanalizando blocos... Set database cache size in megabytes (%d to %d, default: %d) Define o tamanho do cache do banco de dados em megabytes (%d para %d, padrão: %d) + Set maximum BIP141 block weight (default: %d) + Define a altura máxima BIP141 do bloco (padrão: %d) + + Set maximum block size in bytes (default: %d) Define o tamanho máximo de cada bloco em bytes (padrão: %d) @@ -2031,6 +3292,14 @@ Especifique o arquivo da carteira (dentro do diretório de dados) + Starting network threads... + Iniciando análise da rede... + + + The source code is available from %s. + O código fonte está disponível pelo %s + + Unsupported argument -benchmark ignored, use -debug=bench. Argumento não suportado -benchmark ignorado, use -debug=bench. @@ -2063,6 +3332,14 @@ Carteira %s reside fora do diretório de dados %s + Wallet debugging/testing options: + Opções de depuração/teste da Carteira + + + Wallet needed to be rewritten: restart %s to complete + A Carteira precisou ser reescrita: reinicie o %s para completar + + Wallet options: Opções da carteira: @@ -2099,12 +3376,16 @@ Comissões (em %s/kB) menores serão consideradas como zero para relaying, mineração e criação de transação (padrão %s) + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + Força a retransmissão de transações de pares da lista branca, mesmo quando violam a política local de retransmissão (default: %d) + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Se paytxfee não estiver definida, incluir comissão suficiente para que as transações comecem a ter confirmações em média dentro de N blocos (padrão %u) Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) - Valor inválido para -maxtxfee = <valor>: '%s'( precisa ser pelo menos a comissão mínima de %s para prevenir travamento de transações) + Valor inválido para -maxtxfee=<valor>: '%s' (precisa ser pelo menos a taxa mínima de %s para prevenir que a transação nunca seja confirmada) Maximum size of data in data carrier transactions we relay and mine (default: %u) @@ -2131,6 +3412,10 @@ Esse produto inclui software desenvolvido pelo Open SSL Project para uso na OpenSSL Toolkit <https://www.openssl.org> e software criptográfico escrito por Eric Young e software UPnP escrito por Thomas Bernard. + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + Usar carteira HD. Somente tem efeito na criação de uma nova carteira + + 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 Peers permitidos não podem ser banidos do DoS e suas transações sempre são transmitidas, até mesmo se eles já estão no pool de memória, útil, por exemplo, para um gateway @@ -2367,6 +3652,10 @@ Aviso: Versões de bloco desconhecidas sendo mineradas! É possível que regras estranhas estejam ativas + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + Atenção: Arquivo da carteira corrompido, dados recuperados! Original %s salvo como %s em %s; se seu saldo ou transações estiverem incorretos, você deve restaurar o backup. + + (default: %s) (padrão: %s) @@ -2427,10 +3716,6 @@ Defina o tamanho da chave para piscina<n> (padrão: %u) - Set minimum block size in bytes (default: %u) - Definir tamanho mínimo do bloco, em bytes (padrão: %u) - - Set the number of threads to service RPC calls (default: %d) Defina o número de threads para chamadas do serviço RPC (padrão: %d) @@ -2488,7 +3773,7 @@ Done loading - Carregamento terminado + Carregamento terminado! Error diff --git a/src/qt/locale/bitcoin_pt_PT.ts b/src/qt/locale/bitcoin_pt_PT.ts index eed262e010e..e4c5bef16dd 100644 --- a/src/qt/locale/bitcoin_pt_PT.ts +++ b/src/qt/locale/bitcoin_pt_PT.ts @@ -41,7 +41,18 @@ &Delete &Eliminar - + + Choose the address to send coins to + Escolhe qual o endereço para o qual enviar moedas + + + Choose the address to receive coins with + Escolhe qual o endereço para receber moedas + + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +71,7 @@ Repeat new passphrase Repita a nova frase de palavra-passe - + BanTableModel @@ -455,7 +466,7 @@ Priority Prioridade - + EditAddressDialog @@ -478,7 +489,7 @@ &Address E&ndereço - + FreespaceChecker @@ -606,7 +617,7 @@ Select payment request file Seleccione o ficheiro de pedido de pagamento - + OptionsDialog @@ -911,6 +922,9 @@ + PaymentServer + + PeerTableModel User Agent @@ -965,6 +979,9 @@ + QRImageWidget + + RPCConsole N/A @@ -1317,7 +1334,7 @@ Remove Remover - + ReceiveRequestDialog @@ -1336,7 +1353,10 @@ &Save Image... &Salvar Imagem... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1487,7 +1507,7 @@ S&end E&nviar - + SendCoinsEntry @@ -1566,7 +1586,10 @@ Memo: Memorando: - + + + SendConfirmationDialog + ShutdownWindow @@ -1664,7 +1687,7 @@ Reset all verify message fields Repor todos os campos de verificação de mensagem - + SplashScreen @@ -1680,12 +1703,21 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Esta janela mostra uma descrição detalhada da transação - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1694,6 +1726,15 @@ + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: @@ -1792,10 +1833,6 @@ Executar comando quando uma das transações na carteira mudar (no comando, %s é substituído pelo ID da Transação) - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Forçar retransmissão das transações a partir dos pares da lista branca, mesmo que estes violem a política de retransmissão local (predefinição: %d) - - Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) 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) @@ -1952,10 +1989,6 @@ Localização de cookie de autorização (predefinição: diretoria de dados) - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Mínimo de bytes por sigop nas transações que nós transmitimos e mine (predefinição: %u) - - Not enough file descriptors available. Os descritores de ficheiros disponíveis são insuficientes. @@ -2388,10 +2421,6 @@ Definir tamanho do banco de memória da chave para <n> (predefinição: %u) - Set minimum block size in bytes (default: %u) - Definir tamanho minímo de um bloco em bytes (por defeito: %u) - - Set the number of threads to service RPC calls (default: %d) Defina o número de processos para servir as chamadas RPC (por defeito: %d) diff --git a/src/qt/locale/bitcoin_ro.ts b/src/qt/locale/bitcoin_ro.ts index 270a4ba0629..d1f17e29c88 100644 --- a/src/qt/locale/bitcoin_ro.ts +++ b/src/qt/locale/bitcoin_ro.ts @@ -41,7 +41,10 @@ &Delete Șterge - + + + AddressTableModel + AskPassphraseDialog @@ -60,59 +63,651 @@ Repeat new passphrase Repetati noua parolă - + BanTableModel - + + IP/Netmask + IP/Netmask + + + Banned Until + Blocat până + + BitcoinGUI - + + Sign &message... + Semnează &mesajul... + + + Synchronizing with network... + Se sincronizează cu rețeaua + + + Node + Nod + + + Show general overview of wallet + Arată o prezentare generală a portofelului. + + + &Transactions + &Tranzacții + + + Browse transaction history + Navighează în istoricul tranzacțiilor + + + Quit application + Părăsește aplicația + + + About &Qt + Despre &Qt + + + Show information about Qt + Arată informații despre Qt + + + &Options... + &Opțiuni... + + + &Encrypt Wallet... + &Criptează portofelul... + + + &Backup Wallet... + &Backup portofel + + + &Change Passphrase... + &Schimbă parola... + + + &Sending addresses... + &Trimite adresele... + + + &Receiving addresses... + &Primește adresele... + + + Open &URI... + Deschide &URI... + + + Send coins to a Bitcoin address + Trimite monedele către o adresă Bitcoin + + + Backup wallet to another location + Fă o copie de rezervă a portofelului într-o altă locație + + + Change the passphrase used for wallet encryption + Schimbă parola folosită pentru criptarea portofelului + + + &Debug window + &Fereastra pentru depanare + + + Open debugging and diagnostic console + Pornește consola pentru depanare si diagnoză + + + &Verify message... + &Verifică mesajul... + + + Bitcoin + Bitcoin + + + Wallet + Portofel + + + &Send + &Trimite + + + &Receive + &Primește + + + &Show / Hide + &Arată/Ascunde + + + Show or hide the main Window + Arată sau ascunde fereastra principală + + + Encrypt the private keys that belong to your wallet + Criptează cheile private care aparțin portofelului tău. + + + Sign messages with your Bitcoin addresses to prove you own them + Semnează mesajele cu adresa ta de Bitcoin pentru a face dovada că îți aparțin. + + + Verify messages to ensure they were signed with specified Bitcoin addresses + Verifică mesajele cu scopul de a asigura faptul că au fost semnate cu adresa de Bitcoin specificată. + + + &File + &Fișier + + + &Settings + &Setări + + + &Help + &Ajutor + + + Request payments (generates QR codes and bitcoin: URIs) + Cerere plată (generează coduri QR și bitcoin: URIs) + + + Open a bitcoin: URI or payment request + Deschide un bitcoin: URI sau cerere de plată + + + %1 and %2 + %1 și %2 + + + %1 behind + %1 în urmă + + + Last received block was generated %1 ago. + Ultimul bloc primit a fost generat acum %1 + + + Error + Eroare + + + Warning + Atenționare + + + Information + Informație + + + Up to date + Actual + + + Date: %1 + + Data: %1 + + + Amount: %1 + + Cantitate: %1 + + + Type: %1 + + Tip: %1 + + + + Label: %1 + + Etichetă: %1 + + + + Address: %1 + + Adresa: %1 + + + + Sent transaction + Trimite tranzacția + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Portofelul este <b>criptat</b> și în prezent <b>deblocat</b> + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Portofelul este <b>criptat</b> și în prezent <b>blocat</b> + + CoinControlDialog + + Coin Selection + Selecția monedelor + + + Quantity: + Cantitatea: + + + Bytes: + Biți: + + + Amount: + Cantitate: + + + Priority: + Prioritate: + + + Fee: + Taxa: + + + After Fee: + După taxă: + + + Change: + Schimbă: + + + Tree mode + Mod arbore + + + List mode + Mod listă + + + Amount + Cantitate + + + Received with address + Primit cu adresa + + + Date + Data + + + Confirmations + Confirmări + + + Confirmed + Confirmat + + + Priority + Prioritate + EditAddressDialog + + Edit Address + Modifică adresa + + + &Address + &Adresa + FreespaceChecker + + name + Nume + + + Directory already exists. Add %1 if you intend to create a new directory here. + Directoriul există deja. Adaugă %1 dacă ai intenționat să creezi aici un directoriu nou. + HelpMessageDialog + + version + versiune + + + (%1-bit) + (%1-bit) + + + Start minimized + Pornește minimalizat + Intro + + Welcome + Bine ai venit! + + + Use the default data directory + Folosește directoriul pentru date din modul implicit. + + + Error + Eroare + + + %n GB of free space available + %n GB de spațiu liber disponibil%n GB de spațiu liber disponibil%n GB de spațiu liber disponibil + OpenURIDialog + + Open URI + Deschide URI + + + URI: + URI: + OptionsDialog + + Options + Opțiuni + + + MB + MB + + + Accept connections from outside + Acceptă conexiuni externe + + + Allow incoming connections + Acceptă conexiunea care sosește + + + IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) + Adresa IP a proxy-ului (ex. IPv4: 127.0.0.1 / IPv6: ::1) + + + &Reset Options + &Resetează opțiunile + + + &Network + &Rețea + + + Expert + Expert + + + Proxy &IP: + Proxy &IP: + + + &Port: + &Port: + + + Port of the proxy (e.g. 9050) + Portul pentru proxy (ex.: 9050) + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + &OK + &OK + + + &Cancel + &Anulează + + + default + inițial + + + none + fără + + + Confirm options reset + Confirmă resetarea opțiunilor + + + Client restart required to activate changes. + Repornirea clientului este necesară pentru ca schimbările să fie activate + + + Client will be shut down. Do you want to proceed? + Clientul va fi oprit. Dorești sa continui? + + + This change would require a client restart. + Această schimbare necesită repornirea clientului. + OverviewPage + + Available: + Disponibil: + + + Total: + Total: + + + Recent transactions + Tranzacții recente + + + + PaymentServer PeerTableModel QObject + + Amount + Cantitate + - RPCConsole + QRImageWidget + RPCConsole + + Client version + Versiunea clientului + + + &Information + &Informații + + + Debug window + Fereastra pentru depanare + + + General + General + + + Network + Rețea + + + Name + Nume + + + Number of connections + Numărul de conexiuni + + + Received + Primit + + + Sent + Trimis + + + Direction + Direcția + + + Version + Versiune + + + Connection Time + Durata conexiunii + + + &Open + &Deschide + + + &Console + &Consolă + + + 1 &hour + 1 &ore + + + 1 &day + 1 &zi + + + 1 &week + 1 &săptămână + + + 1 &year + 1 &an + + + %1 B + %1 B + + + %1 KB + %1 KB + + + %1 MB + %1 MB + + + %1 GB + %1 GB + + + Yes + Da + + + No + Nu + + + Unknown + Necunoscut + + + ReceiveCoinsDialog + + Show + Arată + + + Remove + Elimină + ReceiveRequestDialog + + &Save Image... + &Salvează imaginea... + + + + RecentRequestsTableModel SendCoinsDialog + + Quantity: + Cantitatea: + + + Bytes: + Biți: + + + Amount: + Cantitate: + + + Priority: + Prioritate: + + + Fee: + Taxa: + + + After Fee: + După taxă: + + + Change: + Schimbă: + SendCoinsEntry + SendConfirmationDialog + + ShutdownWindow @@ -125,12 +720,46 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl - bitcoin-core + WalletFrame + + WalletModel + + + WalletView + + + bitcoin-core + + Bitcoin Core + Bitcoin Core + + + Information + Informație + + + Warning + Atenționare + + + Error + Eroare + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_ro_RO.ts b/src/qt/locale/bitcoin_ro_RO.ts index 489ed076391..a16a497fb2c 100644 --- a/src/qt/locale/bitcoin_ro_RO.ts +++ b/src/qt/locale/bitcoin_ro_RO.ts @@ -41,7 +41,10 @@ &Delete &Şterge - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Repetaţi noua frază de acces - + BanTableModel @@ -435,7 +438,7 @@ Priority Prioritate - + EditAddressDialog @@ -458,7 +461,7 @@ &Address &Adresă - + FreespaceChecker @@ -582,7 +585,7 @@ Select payment request file Selectaţi fişierul cerere de plată - + OptionsDialog @@ -858,6 +861,9 @@ + PaymentServer + + PeerTableModel User Agent @@ -912,6 +918,9 @@ + QRImageWidget + + RPCConsole N/A @@ -1216,7 +1225,7 @@ Remove Înlătură - + ReceiveRequestDialog @@ -1235,7 +1244,10 @@ &Save Image... &Salvează imaginea... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1366,7 +1378,7 @@ S&end Trimit&e - + SendCoinsEntry @@ -1429,7 +1441,10 @@ Memo: Memo: - + + + SendConfirmationDialog + ShutdownWindow @@ -1519,7 +1534,7 @@ Reset all verify message fields Resetează toate cîmpurile mesajelor semnate - + SplashScreen @@ -1535,12 +1550,21 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Acest panou arată o descriere detaliată a tranzacţiei - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1549,6 +1573,15 @@ + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: @@ -1863,10 +1896,6 @@ Adresa -proxy nevalidă: '%s' - Set minimum block size in bytes (default: %u) - Setare mărime minimă bloc în octeţi (implicit: %u) - - Specify configuration file (default: %s) Specificaţi fişierul configuraţie (implicit: %s) diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index 60f5d5dfa2a..5e1a5ee9def 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -41,6 +41,77 @@ &Delete &Удалить + + Choose the address to send coins to + Выберите адрес для отправки перевода + + + Choose the address to receive coins with + Выберите адрес для получения перевода + + + C&hoose + &Выбрать + + + Sending addresses + Адреса отправки + + + Receiving addresses + Адреса получения + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Это ваши адреса Bitcoin для отправки платежей. Всегда проверяйте количество и адрес получателя перед отправкой перевода. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Это ваши адреса Bitcoin для приёма платежей. Рекомендуется использовать новый адрес получения для каждой транзакции. + + + &Copy Address + Копировать &адрес + + + Copy &Label + Копировать &метку + + + &Edit + &Правка + + + Export Address List + Экспортировать список адресов + + + Comma separated file (*.csv) + Текст, разделённый запятыми (*.csv) + + + Exporting Failed + Экспорт не удался + + + There was an error trying to save the address list to %1. Please try again. + Произошла ошибка при сохранении списка адресов в %1. Пожалуйста, попробуйте еще раз. + + + + AddressTableModel + + Label + Метка + + + Address + Адрес + + + (no label) + (нет метки) + AskPassphraseDialog @@ -60,6 +131,94 @@ Repeat new passphrase Повторите новый пароль + + 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>. + Введите новый пароль бумажника.<br/>Используйте пароль, состоящий из <b>десяти или более случайных символов</b>, или <b>восьми или более слов</b>. + + + Encrypt wallet + Зашифровать бумажник + + + This operation needs your wallet passphrase to unlock the wallet. + Для выполнения операции требуется пароль вашего бумажника. + + + Unlock wallet + Разблокировать бумажник + + + This operation needs your wallet passphrase to decrypt the wallet. + Для выполнения операции требуется пароль вашего бумажника. + + + Decrypt wallet + Расшифровать бумажник + + + Change passphrase + Сменить пароль + + + Enter the old passphrase and new passphrase to the wallet. + Введите старый и новый пароль для бумажника. + + + Confirm wallet encryption + Подтвердите шифрование бумажника + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Предупреждение: если вы зашифруете бумажник и потеряете пароль, вы <b>ПОТЕРЯЕТЕ ВСЕ ВАШИ БИТКОИНЫ</b>! + + + Are you sure you wish to encrypt your wallet? + Вы уверены, что хотите зашифровать ваш бумажник? + + + Wallet encrypted + Бумажник зашифрован + + + %1 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. + Сейчас %1 закроется для завершения процесса шифрования. Помните, что шифрование вашего бумажника не может полностью защитить ваши биткоины от кражи с помощью инфицирования вашего компьютера вредоносным ПО. + + + 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. + ВАЖНО: все предыдущие резервные копии вашего бумажника должны быть заменены новым зашифрованным файлом. В целях безопасности предыдущие резервные копии незашифрованного бумажника станут бесполезны, как только вы начнёте использовать новый зашифрованный бумажник. + + + Wallet encryption failed + Не удалось зашифровать бумажник + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Шифрование бумажника не удалось из-за внутренней ошибки. Ваш бумажник не был зашифрован. + + + The supplied passphrases do not match. + Введённые пароли не совпадают. + + + Wallet unlock failed + Разблокировка бумажника не удалась + + + The passphrase entered for the wallet decryption was incorrect. + Неверный пароль для расшифровки бумажника. + + + Wallet decryption failed + Расшифровка бумажника не удалась + + + Wallet passphrase was successfully changed. + Пароль бумажника успешно изменён. + + + Warning: The Caps Lock key is on! + Внимание: Caps Lock включен! + BanTableModel @@ -327,6 +486,10 @@ Синхронизировано + Show the %1 help message to get a list with possible Bitcoin command-line options + Показать помощь по %1, чтобы получить список доступных параметров командной строки + + %1 client %1 клиент @@ -459,6 +622,150 @@ Priority Приоритет + + Copy address + Копировать адрес + + + Copy label + Копировать метку + + + Copy amount + Копировать сумму + + + Copy transaction ID + Копировать ID транзакции + + + Lock unspent + Заблокировать непотраченное + + + Unlock unspent + Разблокировать непотраченное + + + Copy quantity + Копировать количество + + + Copy fee + Копировать комиссию + + + Copy after fee + Копировать после комиссии + + + Copy bytes + Копировать байты + + + Copy priority + Копировать приоритет + + + Copy dust + Копировать пыль + + + Copy change + Копировать сдачу + + + highest + самый высокий + + + higher + выше + + + high + высокий + + + medium-high + выше среднего + + + medium + средний + + + low-medium + ниже среднего + + + low + низкий + + + lower + ниже + + + lowest + самый низкий + + + (%1 locked) + (%1 заблокировано) + + + none + ничего + + + yes + да + + + no + нет + + + This label turns red if the transaction size is greater than 1000 bytes. + Эта метка станет красной, если размер транзакции будет больше 1000 байт. + + + This means a fee of at least %1 per kB is required. + Это значит, что требуется комиссия как минимум %1 на КБ. + + + Can vary +/- 1 byte per input. + Может отличаться на +/- 1 байт на вход. + + + Transactions with higher priority are more likely to get included into a block. + Транзакции с более высоким приоритетом будут вероятнее других включены в блок. + + + This label turns red if the priority is smaller than "medium". + Эта метка станет красной, если приоритет будет ниже "среднего". + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Эта метка станет красной, если любой получатель получит сумму меньше, чем текущий порог пыли. + + + Can vary +/- %1 satoshi(s) per input. + Может отличаться на +/- %1 сатоши на вход. + + + (no label) + (нет метки) + + + change from %1 (%2) + сдача с %1 (%2) + + + (change) + (сдача) + EditAddressDialog @@ -482,6 +789,38 @@ &Address &Адрес + + New receiving address + Новый адрес получения + + + New sending address + Новый адрес отправки + + + Edit receiving address + Изменить адрес получения + + + Edit sending address + Изменить адрес отправки + + + The entered address "%1" is not a valid Bitcoin address. + Введённый адрес "%1" не является правильным Bitcoin-адресом. + + + The entered address "%1" is already in the address book. + Введённый адрес "%1" уже находится в адресной книге. + + + Could not unlock wallet. + Не удается разблокировать бумажник. + + + New key generation failed. + Генерация нового ключа не удалась. + FreespaceChecker @@ -622,6 +961,10 @@ Select payment request file Выбрать файл запроса платежа + + Select payment request file to open + Выберите файл запроса платежа + OptionsDialog @@ -655,7 +998,7 @@ Accept connections from outside - Разрешать соединения извне + Принимать входящие соединения Allow incoming connections @@ -934,6 +1277,97 @@ + PaymentServer + + Payment request error + Ошибка запроса платежа + + + Cannot start bitcoin: click-to-pay handler + Не удаётся запустить bitcoin: обработчик click-to-pay + + + URI handling + Обработка URI + + + Payment request fetch URL is invalid: %1 + Неверный URL запроса платежа: %1 + + + Invalid payment address %1 + Неверный адрес платежа %1 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + Не удалось обработать URI! Это может быть связано с неверным адресом Bitcoin или неправильными параметрами URI. + + + Payment request file handling + Обработка файла запроса платежа + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + Файл запроса платежа не может быть прочитан! Обычно это происходит из-за неверного файла запроса платежа. + + + Payment request rejected + Запрос платежа отклонён + + + Payment request network doesn't match client network. + Сеть запроса платежа не совпадает с сетью клиента. + + + Payment request expired. + Запрос платежа просрочен. + + + Payment request is not initialized. + Запрос платежа не инициализирован. + + + Unverified payment requests to custom payment scripts are unsupported. + Непроверенные запросы платежей с нестандартными платёжными сценариями не поддерживаются. + + + Invalid payment request. + Неверный запрос платежа. + + + Requested payment amount of %1 is too small (considered dust). + Запрошенная сумма платежа %1 слишком мала (считается пылью). + + + Refund from %1 + Возврат от %1 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + Запрос платежа %1 слишком большой (%2 байтов, разрешено %3 байтов). + + + Error communicating with %1: %2 + Ошибка связи с %1: %2 + + + Payment request cannot be parsed! + Запрос платежа не может быть разобран! + + + Bad response from server %1 + Плохой ответ сервера %1 + + + Network request error + Ошибка сетевого запроса + + + Payment acknowledged + Платёж принят + + + PeerTableModel User Agent @@ -988,6 +1422,25 @@ + QRImageWidget + + &Save Image... + &Сохранить изображение... + + + &Copy Image + Копировать &изображение + + + Save QR Code + Сохранить QR-код + + + PNG Image (*.png) + Изображение PNG (*.png) + + + RPCConsole N/A @@ -1348,6 +1801,18 @@ Remove Удалить + + Copy label + Копировать метку + + + Copy message + Копировать сообщение + + + Copy amount + Копировать сумму + ReceiveRequestDialog @@ -1367,32 +1832,99 @@ &Save Image... &Сохранить изображение... - - - SendCoinsDialog - Send Coins - Отправка + Request payment to %1 + Запросить платёж на %1 - Coin Control Features - Функции Контроля Монет + Payment information + Информация платежа - Inputs... - Входы... + URI + URI - automatically selected - автоматически выбрано + Address + Адрес - Insufficient funds! - Недостаточно средств! + Amount + Сумма - Quantity: - Количество: + Label + Метка + + + Message + Сообщение + + + Resulting URI too long, try to reduce the text for label / message. + Получившийся URI слишком длинный, попробуйте сократить текст метки / сообщения. + + + Error encoding URI into QR Code. + Ошибка кодирования URI в QR-код + + + + RecentRequestsTableModel + + Date + Дата + + + Label + Метка + + + Message + Сообщение + + + (no label) + (нет метки) + + + (no message) + (нет сообщения) + + + (no amount requested) + (нет запрошенной суммы) + + + Requested + Запрошено + + + + SendCoinsDialog + + Send Coins + Отправка + + + Coin Control Features + Функции Контроля Монет + + + Inputs... + Входы... + + + automatically selected + автоматически выбрано + + + Insufficient funds! + Недостаточно средств! + + + Quantity: + Количество: Bytes: @@ -1518,6 +2050,114 @@ S&end &Отправить + + Copy quantity + Копировать количество + + + Copy amount + Копировать сумму + + + Copy fee + Копировать комиссию + + + Copy after fee + Копировать после комиссии + + + Copy bytes + Копировать байты + + + Copy priority + Копировать приоритет + + + Copy dust + Копировать пыль + + + Copy change + Копировать сдачу + + + %1 to %2 + С %1 на %2 + + + Are you sure you want to send? + Вы уверены, что хотите отправить? + + + added as transaction fee + добавлено как комиссия + + + Total Amount %1 + Общая сумма %1 + + + or + или + + + Confirm send coins + Подтвердите отправку монет + + + The recipient address is not valid. Please recheck. + Адрес получателя неверный. Пожалуйста, перепроверьте. + + + The amount to pay must be larger than 0. + Сумма для отправки должна быть больше 0. + + + The amount exceeds your balance. + Сумма превышает ваш баланс. + + + The total exceeds your balance when the %1 transaction fee is included. + Сумма с учётом комиссии %1 превысит ваш баланс. + + + Duplicate address found: addresses should only be used once each. + Обнаружен дублирующийся адрес: используйте каждый адрес только один раз. + + + Transaction creation failed! + Не удалось создать транзакцию! + + + 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. + Транзакция была отклонена! Такое может произойти, если некоторые монеты уже были потрачены, например, если Вы используете одну копию wallet.dat, а монеты были потрачены из другой копии, но не были отмечены как потраченные в этой. + + + A fee higher than %1 is considered an absurdly high fee. + Комиссия больше чем %1 считается невероятно большой. + + + Payment request expired. + Запрос платежа просрочен. + + + Pay only the required fee of %1 + Заплатить только обязательную комиссию %1 + + + Warning: Invalid Bitcoin address + Внимание: неверный адрес Bitcoin + + + Warning: Unknown change address + Внимание: неизвестный адрес для сдачи + + + (no label) + (нет метки) + SendCoinsEntry @@ -1597,6 +2237,17 @@ Memo: Примечание: + + Enter a label for this address to add it to your address book + Введите метку для данного адреса, чтобы добавить его в адресную книгу + + + + SendConfirmationDialog + + Yes + Да + ShutdownWindow @@ -1695,6 +2346,58 @@ Reset all verify message fields Сбросить все поля проверки сообщения + + Click "Sign Message" to generate signature + Нажмите "Подписать сообщение" для создания подписи + + + The entered address is invalid. + Введённый адрес неверен. + + + Please check the address and try again. + Пожалуйста, проверьте адрес и попробуйте ещё раз. + + + The entered address does not refer to a key. + Введённый адрес не связан с ключом. + + + Wallet unlock was cancelled. + Разблокировка бумажника была отменена. + + + Private key for the entered address is not available. + Недоступен секретный ключ для введённого адреса. + + + Message signing failed. + Не удалось подписать сообщение. + + + Message signed. + Сообщение подписано. + + + The signature could not be decoded. + Подпись не может быть раскодирована. + + + Please check the signature and try again. + Пожалуйста, проверьте подпись и попробуйте ещё раз. + + + The signature did not match the message digest. + Подпись не соответствует отпечатку сообщения. + + + Message verification failed. + Сообщение не прошло проверку. + + + Message verified. + Сообщение проверено. + SplashScreen @@ -1711,11 +2414,452 @@ + TransactionDesc + + Open for %n more block(s) + Открыто для ещё %n блокаОткрыто для ещё %n блоковОткрыто для ещё %n блоковОткрыто для ещё %n блоков + + + Open until %1 + Открыто до %1 + + + conflicted with a transaction with %1 confirmations + конфликт с транзакцией с %1 подтверждений + + + %1/offline + %1/отключен + + + 0/unconfirmed, %1 + 0/не подтверждено, %1 + + + in memory pool + В памяти + + + not in memory pool + Не в памяти + + + abandoned + заброшено + + + %1/unconfirmed + %1/не подтверждено + + + %1 confirmations + %1 подтверждений + + + Status + Статус + + + , has not been successfully broadcast yet + , ещё не было успешно разослано + + + , broadcast through %n node(s) + , разослано через %n узел, разослано через %n узла, разослано через %n узлов, разослано через %n узлов + + + Date + Дата + + + Source + Источник + + + Generated + Сгенерированно + + + From + От + + + unknown + неизвестно + + + To + Для + + + own address + свой адрес + + + watch-only + только наблюдение + + + label + метка + + + Credit + Кредит + + + matures in %n more block(s) + будет доступно через %n блокбудет доступно через %n блокабудет доступно через %n блоковбудет доступно через %n блоков + + + not accepted + не принято + + + Debit + Дебет + + + Total debit + Всего дебет + + + Total credit + Всего кредит + + + Transaction fee + Комиссия + + + Net amount + Чистая сумма + + + Message + Сообщение + + + Comment + Комментарий + + + Transaction ID + ID транзакции + + + Output index + Номер выхода + + + Merchant + Продавец + + + 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. + Сгенерированные монеты должны подождать %1 блоков, прежде чем они могут быть потрачены. Когда вы сгенерировали этот блок, он был отправлен в сеть для добавления в цепочку блоков. Если он не попадёт в цепь, его статус изменится на "не принят", и монеты будут недействительны. Это иногда происходит в случае, если другой узел сгенерирует блок на несколько секунд раньше вас. + + + Debug information + Отладочная информация + + + Transaction + Транзакция + + + Inputs + Входы + + + Amount + Сумма + + + true + истина + + + false + ложь + + + TransactionDescDialog This pane shows a detailed description of the transaction Эта панель отображает детальное описание транзакции. + + Details for %1 + Подробности %1 + + + + TransactionTableModel + + Date + Дата + + + Type + Тип + + + Label + Метка + + + Open for %n more block(s) + Открыто для ещё %n блокаОткрыто для ещё %n блоковОткрыто для ещё %n блоковОткрыто для ещё %n блоков + + + Open until %1 + Открыто до %1 + + + Offline + Отключен + + + Unconfirmed + Не подтверждено + + + Abandoned + Заброшено + + + Confirmed (%1 confirmations) + Подтверждено (%1 подтверждений) + + + Conflicted + В противоречии + + + Immature (%1 confirmations, will be available after %2) + Незрелый (%1 подтверждений, будет доступно после %2) + + + This block was not received by any other nodes and will probably not be accepted! + Этот блок не был получен другими узлами и, возможно, не будет принят! + + + Generated but not accepted + Сгенерировано, но не принято + + + Received with + Получено на + + + Received from + Получено от + + + Sent to + Отправлено на + + + Payment to yourself + Отправлено себе + + + Mined + Добыто + + + watch-only + только наблюдение + + + (n/a) + (недоступно) + + + (no label) + (нет метки) + + + Transaction status. Hover over this field to show number of confirmations. + Статус транзакции. Подведите курсор к этому полю, чтобы увидеть количество подтверждений. + + + Date and time that the transaction was received. + Дата и время получения транзакции. + + + Type of transaction. + Тип транзакции. + + + Whether or not a watch-only address is involved in this transaction. + Использовался ли в транзакции адрес для наблюдения. + + + User-defined intent/purpose of the transaction. + Определяемое пользователем намерение/цель транзакции. + + + Amount removed from or added to balance. + Снятая или добавленная к балансу сумма. + + + + TransactionView + + All + Все + + + Today + Сегодня + + + This week + На этой неделе + + + This month + В этом месяце + + + Last month + В прошлом месяце + + + This year + В этом году + + + Range... + Диапазон... + + + Received with + Получено на + + + Sent to + Отправлено на + + + To yourself + Себе + + + Mined + Добыто + + + Other + Другое + + + Enter address or label to search + Введите адрес или метку для поиска + + + Min amount + Мин. сумма + + + Abandon transaction + Отказаться от транзакции + + + Copy address + Копировать адрес + + + Copy label + Копировать метку + + + Copy amount + Копировать сумму + + + Copy transaction ID + Копировать ID транзакции + + + Copy raw transaction + Копировать исходный код транзакции + + + Copy full transaction details + Копировать все подробности транзакции + + + Edit label + Изменить метку + + + Show transaction details + Показать подробности транзакции + + + Export Transaction History + Экспортировать историю транзакций + + + Comma separated file (*.csv) + Текст, разделённый запятыми (*.csv) + + + Confirmed + Подтверждено + + + Watch-only + Для наблюдения + + + Date + Дата + + + Type + Тип + + + Label + Метка + + + Address + Адрес + + + ID + ID + + + Exporting Failed + Экспорт не удался + + + There was an error trying to save the transaction history to %1. + Произошла ошибка при сохранении истории транзакций в %1. + + + Exporting Successful + Экспорт успешно завершён + + + The transaction history was successfully saved to %1. + История транзакций была успешно сохранена в %1. + + + Range: + Диапазон: + + + to + до + UnitDisplayStatusBarControl @@ -1725,6 +2869,55 @@ + WalletFrame + + No wallet has been loaded. + Не был загружен ни один бумажник. + + + + WalletModel + + Send Coins + Отправка + + + + WalletView + + &Export + &Экспорт + + + Export the data in the current tab to a file + Экспортировать данные текущей вкладки в файл + + + Backup Wallet + Резервная копия бумажника + + + Wallet Data (*.dat) + Данные бумажника (*.dat) + + + Backup Failed + Резервное копирование не удалось + + + There was an error trying to save the wallet data to %1. + Произошла ошибка при сохранении данных бумажника в %1. + + + Backup Successful + Резервное копирование успешно завершено + + + The wallet data was successfully saved to %1. + Данные бумажника были успешно сохранены в %1. + + + bitcoin-core Options: @@ -1803,6 +2996,10 @@ Установлено очень большое значение -fallbackfee! Это комиссия за транзацию, которую вы можете заплатить, если оценка размера комиссии не доступна. + Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) + Принимать транзакции пересылаемые от узлов из белого списка даже если они не удовлетворяют требованиям ретрансляции (по умолчанию: %d) + + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Привязаться к указанному адресу и всегда прослушивать только его. Используйте [хост]:порт для IPv6 @@ -1819,6 +3016,14 @@ Распространяется под лицензией MIT, см. приложенный файл COPYING или <http://www.opensource.org/licenses/mit-license.php>. + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Эквивалентных байт на sigop в транзакциях для ретрансляции или добычи (по умолчанию: %u) + + + Error loading %s: You can't enable HD on a already existing non-HD wallet + Ошибка загрузки %s: Вы не можете включить HD в уже существующем не-HD кошельке + + Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. Ошибка чтения %s! Все ключи прочитаны верно, но данные транзакций или записи адресной книги могут отсутствовать или быть неправильными. @@ -1827,14 +3032,22 @@ Выполнить команду, когда меняется транзакция в бумажнике (%s в команде заменяется на TxID) - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Всегда разрешать транзакции, полученные от участников из белого списка (по умолчанию: %d) + Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) + Максимально допустимое среднее отклонение времени участников. Локальное представление времени может меняться вперед или назад на это количество. (по умолчанию: %u секунд) + + + Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s) + Максимальная сумма комиссий (%s) для одной транзакции в бумажнике или сырой транзакции; слишком низкое значение может вызвать прерывание больших транзакций (по умолчанию: %s) Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. Пожалуйста убедитесь в корректности установки времени и даты на вашем компьютере! Если время установлено неверно, %s не будет работать правильно. + Please contribute if you find %s useful. Visit %s for further information about the software. + Пожалуйста, внести свой вклад, если вы найдете %s полезными. Посетите %s для получения дополнительной информации о программном обеспечении. + + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Задать число потоков проверки скрипта (от %u до %d, 0=авто, <0 = оставить столько ядер свободными, по умолчанию: %d) @@ -1847,6 +3060,10 @@ Это пре-релизная тестовая сборка - используйте на свой страх и риск - не используйте для добычи или торговых приложений + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain + Невозможно отмотать базу данных до пред-форкового состояния. Вам будет необходимо перекачать цепочку блоков. + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) Использовать UPnP для проброса порта (по умолчанию: 1, если используется прослушивание и нет -proxy) @@ -1863,6 +3080,10 @@ Вносить в белый список участников, подключающихся с указанной маски сети или IP. Можно использовать многократно. + You need to rebuild the database using -reindex-chainstate to change -txindex + Вам необходимо пересобрать базы данных с помощью -reindex-chainstate, чтобы изменить -txindex + + %s corrupt, salvage failed %s поврежден, восстановить не удалось @@ -1887,6 +3108,14 @@ Параметры создания блоков: + Cannot resolve -%s address: '%s' + Не удаётся разрешить адрес в параметре -%s: '%s' + + + Change index out of range + Изменение индекса вне диапазона + + Connect only to the specified node(s) Подключаться только к указанному узлу(ам) @@ -1951,6 +3180,10 @@ Ошибка загрузки %s: Для бумажника требуется более новая версия %s + Error loading %s: You can't disable HD on a already existing HD wallet + Ошибка загрузки %s: Вы не можете включить HD в уже существующем не-HD кошельке + + Error loading block database Ошибка чтения базы данных блоков @@ -1975,6 +3208,10 @@ Неверный или отсутствующий начальный блок. Неправильный каталог данных для сети? + Initialization sanity check failed. %s is shutting down. + Начальная проверка исправности не удалась. %s завершает работу. + + Invalid -onion address: '%s' Неверный -onion адрес: '%s' @@ -2019,16 +3256,24 @@ Режим удаления блоков несовместим с -txindex. + Rebuild chain state and block index from the blk*.dat files on disk + Перестроить состояние цепи блоков и индекс блоков из blk*.dat файлов с диска + + Rebuild chain state from the currently indexed blocks Перестроить индекс цепи из текущих индексированных блоков + Rewinding blocks... + Перемотка блоков... + + Set database cache size in megabytes (%d to %d, default: %d) Установить размер кэша БД в мегабайтах(от %d до %d, по умолчанию: %d) - Set maximum block cost (default: %d) - Задать максимальную стоимость блока (по умолчанию: %d) + Set maximum BIP141 block weight (default: %d) + Задать максимальное BIP141 значение блока (по умолчанию: %d) Set maximum block size in bytes (default: %d) @@ -2039,6 +3284,10 @@ Укажите файл бумажника (внутри каталога данных) + Starting network threads... + Запускаем сетевые потоки... + + The source code is available from %s. Исходный код доступен в %s. @@ -2123,6 +3372,10 @@ Комиссии (в %s/Кб) меньшие этого значения считаются нулевыми для создания, ретрансляции, получения транзакции (по умолчанию: %s) + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + Всегда ретранслировать транзакции, полученные из белого списка участников, даже если они нарушают локальную политику ретрансляции (по умолчанию: %d) + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Если paytxfee не задан, включить достаточную комиссию для подтверждения транзакции в среднем за n блоков (по умолчанию: %u) @@ -2155,6 +3408,10 @@ Этот продукт включает ПО, разработанное OpenSSL Project для использования в OpenSSL Toolkit <https://www.openssl.org/> и криптографическое ПО, написанное Eric Young и ПО для работы с UPnP, написанное Thomas Bernard. + Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start + Использовать иерархическую детерминированную генерацию ключей (HD) после BIP32. Применяется в процессе создания бумажника / первого запуска + + 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 Участники из белого списка не могуть быть забанены за DoS, и их транзакции всегда транслируются, даже если они уже содержатся в памяти. Полезно, например, для шлюза. @@ -2375,6 +3632,10 @@ Обнаружен не поддерживаемый аргумент -socks. Выбор версии SOCKS более невозможен, поддерживаются только прокси SOCKS5. + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Не поддерживаемый аргумент -whitelistalwaysrelay игнорируется, используйте -whitelistrelay и/или -whitelistforcerelay. + + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Использовать отдельный прокси SOCKS5 для соединения с участниками через скрытые сервисы Tor (по умолчанию: %s) @@ -2451,10 +3712,6 @@ Установить размер пула ключей в <n> (по умолчанию: %u) - Set minimum block size in bytes (default: %u) - Задать минимальный размер блока в байтах (по умолчанию: %u) - - Set the number of threads to service RPC calls (default: %d) Задать число потоков выполнения запросов RPC (по умолчанию: %d) diff --git a/src/qt/locale/bitcoin_ru_RU.ts b/src/qt/locale/bitcoin_ru_RU.ts index 66419728e2c..db9b2e8c88e 100644 --- a/src/qt/locale/bitcoin_ru_RU.ts +++ b/src/qt/locale/bitcoin_ru_RU.ts @@ -23,7 +23,7 @@ C&lose - Закрыть + &Закрыть Delete the currently selected address from the list @@ -41,20 +41,27 @@ &Delete Удалить - + + + AddressTableModel + AskPassphraseDialog Repeat new passphrase Повторите новый пароль - + BanTableModel BitcoinGUI + Bitcoin + Bitcoin Core + + &Command-line options Опции командной строки @@ -136,12 +143,18 @@ OverviewPage + PaymentServer + + PeerTableModel QObject + QRImageWidget + + RPCConsole &Information @@ -155,12 +168,18 @@ ReceiveRequestDialog + RecentRequestsTableModel + + SendCoinsDialog SendCoinsEntry + SendConfirmationDialog + + ShutdownWindow @@ -173,18 +192,40 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Bitcoin Core Bitcoin Core + 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 + bitcoin-core + + Information Информация @@ -193,6 +234,10 @@ Предупреждение + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Do not keep transactions in the mempool longer than <n> hours (default: %u) + + Error Ошибка diff --git a/src/qt/locale/bitcoin_sk.ts b/src/qt/locale/bitcoin_sk.ts index a4f0ebcb4e1..7e46f251d03 100644 --- a/src/qt/locale/bitcoin_sk.ts +++ b/src/qt/locale/bitcoin_sk.ts @@ -3,7 +3,7 @@ AddressBookPage Right-click to edit address or label - Kliknutím pravým tlačidlom upravte adresu alebo popis + Kliknutím pravým tlačidlom upraviť adresu alebo popis Create a new address @@ -11,11 +11,11 @@ &New - &Nové + &Nový Copy the currently selected address to the system clipboard - Kopírovať práve zvolenú adresu do systémového klipbordu + Zkopírovať práve zvolenú adresu &Copy @@ -41,6 +41,13 @@ &Delete &Zmazať + + + AddressTableModel + + (no label) + (bez popisu) + AskPassphraseDialog @@ -60,7 +67,7 @@ Repeat new passphrase Zopakujte nové heslo - + BanTableModel @@ -115,6 +122,10 @@ &O %1 + Show information about %1 + Ukázať informácie o %1 + + About &Qt O &Qt @@ -127,6 +138,10 @@ &Možnosti... + Modify configuration options for %1 + Upraviť nastavenia pre %1 + + &Encrypt Wallet... &Zašifrovať Peňaženku... @@ -255,6 +270,14 @@ %n aktívne pripojenie do siete Bitcoin%n aktívne pripojenia do siete Bitcoin%n aktívnych pripojení do siete Bitcoin + Indexing blocks on disk... + Indexujem bloky na disku... + + + Processing blocks on disk... + Spracovávam bloky na disku... + + No block source available... Nedostupný zdroj blokov... @@ -311,6 +334,14 @@ Aktualizovaný + Show the %1 help message to get a list with possible Bitcoin command-line options + Ukáž %1 zoznam možných nastavení Bitcoinu pomocou príkazového riadku + + + %1 client + %1 klient + + Catching up... Sťahujem... @@ -439,7 +470,11 @@ Priority Priorita - + + (no label) + (bez popisu) + + EditAddressDialog @@ -462,7 +497,7 @@ &Address &Adresa - + FreespaceChecker @@ -497,6 +532,10 @@ (%1-bit) + About %1 + O %1 + + Command-line options Voľby príkazového riadku @@ -532,7 +571,11 @@ Show splash screen on startup (default: %u) Zobraziť uvítaciu obrazovku pri štarte (predvolené: %u) - + + Reset all settings changed in the GUI + Zrušiť všetky zmeny v GUI + + Intro @@ -540,6 +583,18 @@ Vitajte + Welcome to %1. + Vitajte v %1 + + + As this is the first time the program is launched, you can choose where %1 will store its data. + Keďže toto je prvé spustenie programu, môžete si vybrať, kam %1 bude ukladať vaše údaje. + + + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 stiahne a uloží kópiu Bitcoin block chain. Minimálne %2GB dát bude uložených v tejto zložke, a bude sa zväčšovať postupom času. Peňaženka bude taktiež uložená v tejto zložke. + + Use the default data directory Použiť predvolený dátový adresár @@ -582,7 +637,7 @@ Select payment request file Vyberte súbor s výzvou k platbe - + OptionsDialog @@ -594,6 +649,14 @@ &Hlavné + Automatically start %1 after logging in to the system. + Automaticky spustiť %1 pri spustení systému. + + + &Start %1 on system login + &Spustiť %1 pri prihlásení + + Size of &database cache Veľkosť vyrovnávacej pamäti &databázy @@ -730,6 +793,14 @@ &Okno + &Hide the icon from the system tray. + &Skryť ikonu zo systémovej lišty. + + + Hide tray icon + Skryť ikonu v oblasti oznámení + + Show only a tray icon after minimizing the window. Zobraziť len ikonu na lište po minimalizovaní okna. @@ -750,6 +821,10 @@ Jazyk užívateľského rozhrania: + The user interface language can be set here. This setting will take effect after restarting %1. + Jazyk uživateľského rozhrania sa dá nastaviť tu. Toto nastavenie sa uplatní až po reštarte %1. + + &Unit to show amounts in: &Zobrazovať hodnoty v jednotkách: @@ -874,6 +949,9 @@ + PaymentServer + + PeerTableModel User Agent @@ -928,6 +1006,9 @@ + QRImageWidget + + RPCConsole N/A @@ -954,6 +1035,10 @@ Používa BerkeleyDB verziu + Datadir + Zložka s dátami + + Startup time Čas spustenia @@ -1039,6 +1124,18 @@ Aplikácia + Open the %1 debug log file from the current data directory. This can take a few seconds for large log files. + Otvoriť %1 ladiaci výpis z aktuálnej zložky. Pre veľké súbory to môže chvíľu trvať. + + + Decrease font size + Zmenšiť písmo + + + Increase font size + Zväčšiť písmo + + Services Služby @@ -1063,6 +1160,10 @@ Čas odozvy + The duration of a currently outstanding ping. + Trvanie aktuálneho pingu + + Ping Wait Čakanie na ping @@ -1139,6 +1240,10 @@ &odblokovať uzol + Welcome to the %1 RPC console. + Vitajte v %1 RPC konzole + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Použi šípky hore a dolu pre navigáciu históriou a <b>Ctrl-L</b> pre vyčistenie obrazovky. @@ -1265,7 +1370,7 @@ Remove Odstrániť - + ReceiveRequestDialog @@ -1284,7 +1389,14 @@ &Save Image... Uložiť obrázok... - + + + RecentRequestsTableModel + + (no label) + (bez popisu) + + SendCoinsDialog @@ -1435,6 +1547,14 @@ S&end &Odoslať + + or + alebo + + + (no label) + (bez popisu) + SendCoinsEntry @@ -1514,10 +1634,17 @@ Memo: Poznámka: - + + + SendConfirmationDialog + ShutdownWindow + %1 is shutting down... + %1 sa vypína... + + Do not shut down the computer until this window disappears. Nevypínajte počítač kým toto okno nezmizne. @@ -1600,7 +1727,7 @@ Reset all verify message fields Obnoviť všetky polia v overiť správu - + SplashScreen @@ -1616,12 +1743,25 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Táto časť obrazovky zobrazuje detailný popis transakcie - + + + TransactionTableModel + + (no label) + (bez popisu) + + + + TransactionView + UnitDisplayStatusBarControl @@ -1630,6 +1770,15 @@ + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: @@ -1652,6 +1801,14 @@ Prijímať príkazy z príkazového riadku a JSON-RPC + If <category> is not supplied or if <category> = 1, output all debugging information. + Pokiaľ <category> nie je nastavená, alebo <category> = 1, vypíš všetky informácie pre ladenie. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + Redukcia nastavená pod minimálnu hodnotu %d MiB. Prosím použite vyššiu hodnotu. + + Error: A fatal internal error occurred, see debug.log for details Chyba: Vyskytla sa interná chyba, pre viac informácií zobrazte debug.log @@ -1680,10 +1837,18 @@ Jadro Bitcoin + -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. + -fallbackfee je nastavená veľmi vysoko. Ide o poplatok za transakciu, ktorý môže platiť, keď odhady poplatku nie sú k dispozícii. + + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Spojiť s danou adresou a vždy na nej počúvať. Použite zápis [host]:port pre IPv6 + Cannot obtain a lock on data directory %s. %s is probably already running. + Nemožné uzamknúť zložku %s. %s pravdepodobne už beží. + + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup Vymazať všetky transakcie z peňaženky a pri spustení znova získať z reťazca blokov iba tie získané pomocou -rescan @@ -1692,14 +1857,30 @@ Distribuované pod softvérovou licenciou MIT, viď sprievodný súbor COPYING alebo <http://www.opensource.org/licenses/mit-license.php>. + Error loading %s: You can't enable HD on a already existing non-HD wallet + Chyba počas načítavania %s: Nemôžete povoliť HD na už existujúcej non-HD peaženke + + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Vykonaj príkaz keď sa zmení transakcia peňaženky (%s v príkaze je nahradená TxID) + Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. + Prosím skontrolujte systémový čas a dátum. Keď je váš čas nesprávny, %s nebude fungovať správne. + + + Please contribute if you find %s useful. Visit %s for further information about the software. + Keď si myslíte, že %s je užitočný, podporte nás. Pre viac informácií o software navštívte %s. + + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Nastaviť počeť vlákien overujúcich skripty (%u až %d, 0 = auto, <0 = nechať toľkoto jadier voľných, prednastavené: %d) + 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 + Databáza blokov obsahuje blok, ktorý vyzerá byť z budúcnosti. Toto môže byť spôsobené nesprávnym systémovým časom vášho počítača. Obnovujte databázu blokov len keď ste si istý, že systémový čas je nastavený správne. + + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Toto je pred-testovacia verzia - použitie je na vlastné riziko - nepoužívajte na tvorbu bitcoin ani obchodovanie. @@ -1718,6 +1899,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Uzle na zoznam povolených, ktoré sa pripájajú z danej netmask alebo IP adresy. Môže byť zadané viac krát. + %s corrupt, salvage failed + %s je poškodený, záchrana zlyhala + + -maxmempool must be at least %d MB -maxmempool musí byť najmenej %d MB @@ -1730,6 +1915,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Voľby vytvorenia bloku: + Change index out of range + Menný index mimo rozsah + + Connect only to the specified node(s) Pripojiť sa len k určenej nóde @@ -1738,6 +1927,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Možnosti pripojenia: + Copyright (C) %i-%i + Copyright (C) %i-%i + + Corrupted block database detected Zistená poškodená databáza blokov @@ -1766,6 +1959,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Povoliť zverejnenie raw bloku pre <address> + Enable publish raw transaction in <address> + Povoliť publikovať hrubý prevod v <address> + + Error initializing block database Chyba inicializácie databázy blokov @@ -1810,6 +2007,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Nesprávny alebo žiadny genesis blok nájdený. Nesprávny dátový priečinok alebo sieť? + Initialization sanity check failed. %s is shutting down. + Kontrola čistoty pri inicializácií zlyhala. %s sa vypína. + + Invalid -onion address: '%s' Neplatná -onion adresa: '%s' @@ -1826,6 +2027,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Načítavam banlist... + Location of the auth cookie (default: data dir) + Poloha overovacieho cookie súboru (predvolená: zložka s dátami) + + Not enough file descriptors available. Nedostatok kľúčových slov súboru. @@ -1834,6 +2039,14 @@ The network does not appear to fully agree! Some miners appear to be experiencin Pripojiť iba k uzlom v sieti <net> (ipv4, ipv6, alebo onion) + Print this help message and exit + Vytlačiť túto pomocnú správu a ukončiť + + + Print version and exit + Vytlačiť verziu a ukončiť + + Prune cannot be configured with a negative value. Redukovanie nemôže byť nastavené na zápornú hodnotu. @@ -1842,6 +2055,14 @@ The network does not appear to fully agree! Some miners appear to be experiencin Redukovanie je nekompatibilné s -txindex. + Rebuild chain state and block index from the blk*.dat files on disk + Obnoviť stav reťazca a index blokov zo súborov blk*.dat na disku. + + + Rebuild chain state from the currently indexed blocks + Obnoviť stav reťazca z aktuálne indexovaných blokov. + + Set database cache size in megabytes (%d to %d, default: %d) Nastaviť veľkosť pomocnej pamäti databázy v megabajtoch (%d do %d, prednastavené: %d) @@ -1854,6 +2075,14 @@ The network does not appear to fully agree! Some miners appear to be experiencin Označ súbor peňaženky (v priečinku s dátami) + The source code is available from %s. + Zdrojový kód je dostupný z %s + + + Unable to bind to %s on this computer. %s is probably already running. + Nemožné pripojiť k %s na tomto počíťači. %s už pravdepodobne beží. + + Unsupported argument -benchmark ignored, use -debug=bench. Nepodporovaný parameter -benchmark bol ignorovaný, použite -debug=bench. @@ -1882,6 +2111,14 @@ The network does not appear to fully agree! Some miners appear to be experiencin Peňaženka %s sa nachádza mimo dátového priečinka %s + Wallet debugging/testing options: + Ladiace / testovacie možnosti peňaženky. + + + Wallet needed to be rewritten: restart %s to complete + Peňaženka musí byť prepísaná: pre dokončenie reštartujte %s + + Wallet options: Voľby peňaženky: @@ -1998,6 +2235,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Možnosti servra RPC: + Rescan the block chain for missing wallet transactions on startup + Pri spustení skontrolovať reťaz blokov pre chýbajúce transakcie peňaženky + + Send trace/debug info to console instead of debug.log file Odoslať trace/debug informácie na konzolu namiesto debug.info žurnálu @@ -2066,6 +2307,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Zmazať všetky transakcie z peňaženky... + ZeroMQ notification options: + Možnosti pripojenia ZeroMQ: + + Password for JSON-RPC connections Heslo pre JSON-rPC spojenia @@ -2102,10 +2347,38 @@ The network does not appear to fully agree! Some miners appear to be experiencin Výstupné ladiace informácie (predvolené: %u, dodanie <category> je voliteľné) + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + Celková dĺžka verzie sieťového reťazca (%i) prekračuje maximálnu dĺžku (%i). Znížte počet a veľkosť komentárov. + + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + Sa snaží držať odchádzajúce prevádzku v rámci daného cieľa (v MB za 24h), 0 = žiadny limit (predvolený: %d) + + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + Nepodporovaný argument -socks nájdený. Nastavenie SOCKS verzie už nie je viac moźné, iba SOCKS5 proxies sú podporované. + + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. + Nepodporovaný argument -whitelistalwaysrelay ignorovaný, použite -whitelistrelay a/alebo -whitelistforcerelay. + + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Použiť samostatný SOCKS5 proxy server na dosiahnutie počítačov cez skryté služby Tor (predvolené: %s) + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Užívateľské hash meno a heslo pre JSON-RPC pripojenia. Pole <userpw> je vo formáte <USERNAME>:<SALT>$<HASH>. Kanonický python skript je zahrnutý v share/rpcuser. Toto nastavenie môže byť špecifikované viac krát + + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect + Varovanie: Neznáma verzia blokov sa doluje! Je možné, že neznáme pravidlá majú efekt + + + Warning: Wallet file corrupt, data salvaged! Original %s saved as %s in %s; if your balance or transactions are incorrect you should restore from a backup. + Varovanie: Peňaženka poškodená, dáta boli zachránené! Originálna %s ako %s v %s; ak váš zostatok alebo transakcie sú nesprávne, mali by ste obnoviť zálohu. + + (default: %s) (predvolené: %s) @@ -2162,10 +2435,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin Nastaviť veľkosť kľúča fronty na <n> (predvolené: %u) - Set minimum block size in bytes (default: %u) - Nastaviť minimálnu veľkosť bloku v bajtoch (predvolené: %u) - - Set the number of threads to service RPC calls (default: %d) Nastaviť počet vlákien na obsluhu RPC volaní (predvolené: %d) diff --git a/src/qt/locale/bitcoin_sl_SI.ts b/src/qt/locale/bitcoin_sl_SI.ts index 16ef20ea3a0..8c8cf94a963 100644 --- a/src/qt/locale/bitcoin_sl_SI.ts +++ b/src/qt/locale/bitcoin_sl_SI.ts @@ -41,7 +41,10 @@ &Delete I&zbriši - + + + AddressTableModel + AskPassphraseDialog @@ -60,10 +63,18 @@ Repeat new passphrase Ponovite novo geslo - + BanTableModel - + + IP/Netmask + IP/Netmaska + + + Banned Until + Prepoved do + + BitcoinGUI @@ -243,6 +254,14 @@ %n aktivna povezava v omrežje Bitcoin%n aktivni povezavi v omrežje Bitcoin%n aktivne povezave v omrežje Bitcoin%n aktivnih povezav v omrežje Bitcoin + Indexing blocks on disk... + Indeksirani bloki na disku ... + + + Processing blocks on disk... + Obdelava blokov na disku ... + + No block source available... Ni virov za prenos blokov ... @@ -299,6 +318,10 @@ Posodobljeno + %1 client + %1 odjemalec + + Catching up... Dohitevam omrežje ... @@ -427,7 +450,7 @@ Priority Prioriteta - + EditAddressDialog @@ -450,7 +473,7 @@ &Address &Naslov - + FreespaceChecker @@ -485,6 +508,10 @@ (%1-bit) + About %1 + O %1 + + Command-line options Možnosti ukazne vrstice @@ -496,6 +523,18 @@ command-line options možnosti ukazne vrstice + + UI Options: + UI možnosti: + + + Set language, for example "de_DE" (default: system locale) + Nastavi jezik, na primer "sl_SI" (privzeto: sistemsko) + + + Start minimized + Začni minimizirano + Intro @@ -504,6 +543,10 @@ Dobrodošli + Welcome to %1. + Dobrodošli v %1 + + Use the default data directory Uporabi privzeto podatkovno mapo @@ -546,7 +589,7 @@ Select payment request file Izbiranje datoteke z zahtevkom za plačilo - + OptionsDialog @@ -814,6 +857,9 @@ + PaymentServer + + PeerTableModel User Agent @@ -868,6 +914,9 @@ + QRImageWidget + + RPCConsole N/A @@ -1136,7 +1185,7 @@ Remove Odstrani - + ReceiveRequestDialog @@ -1155,7 +1204,10 @@ &Save Image... &Shrani sliko ... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1306,7 +1358,7 @@ S&end &Pošlji - + SendCoinsEntry @@ -1385,7 +1437,10 @@ Memo: Opomba: - + + + SendConfirmationDialog + ShutdownWindow @@ -1479,7 +1534,7 @@ Reset all verify message fields Počisti vsa polja za vnos v oknu za preverjanje - + SplashScreen @@ -1495,12 +1550,21 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction V tem podoknu so prikazane podrobnosti o transakciji - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1509,6 +1573,15 @@ + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_sq.ts b/src/qt/locale/bitcoin_sq.ts index 6c86b7d9fcd..5a1f4d64ac2 100644 --- a/src/qt/locale/bitcoin_sq.ts +++ b/src/qt/locale/bitcoin_sq.ts @@ -33,7 +33,10 @@ &Delete &Fshi - + + + AddressTableModel + AskPassphraseDialog @@ -48,7 +51,7 @@ Repeat new passphrase Përsërisni frazkalimin e ri - + BanTableModel @@ -200,7 +203,7 @@ &Address &Adresa - + FreespaceChecker @@ -248,6 +251,9 @@ + PaymentServer + + PeerTableModel @@ -258,6 +264,9 @@ + QRImageWidget + + RPCConsole &Information @@ -303,6 +312,9 @@ + RecentRequestsTableModel + + SendCoinsDialog Send Coins @@ -361,6 +373,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -389,16 +404,34 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Ky panel tregon një përshkrim të detajuar të transaksionit - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_sr.ts b/src/qt/locale/bitcoin_sr.ts index 6b6f1af6f64..c43e9124776 100644 --- a/src/qt/locale/bitcoin_sr.ts +++ b/src/qt/locale/bitcoin_sr.ts @@ -2,6 +2,10 @@ AddressBookPage + Right-click to edit address or label + Kliknite desnim klikom radi izmene adrese ili oznake + + Create a new address Napravite novu adresu @@ -18,14 +22,25 @@ Kopirajte + C&lose + Zatvorite + + Delete the currently selected address from the list Izbrisite trenutno izabranu adresu sa liste + Export the data in the current tab to a file + Eksportuj podatke iz izabrane kartice u fajl + + &Delete &Избриши - + + + AddressTableModel + AskPassphraseDialog @@ -40,7 +55,7 @@ Repeat new passphrase Поновите нову лозинку - + BanTableModel @@ -188,7 +203,7 @@ &Address &Адреса - + FreespaceChecker @@ -236,6 +251,9 @@ + PaymentServer + + PeerTableModel @@ -246,6 +264,9 @@ + QRImageWidget + + RPCConsole @@ -271,6 +292,9 @@ + RecentRequestsTableModel + + SendCoinsDialog Send Coins @@ -288,7 +312,7 @@ S&end &Пошаљи - + SendCoinsEntry @@ -313,6 +337,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -337,16 +364,34 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Ovaj odeljak pokazuje detaljan opis transakcije - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_sr@latin.ts b/src/qt/locale/bitcoin_sr@latin.ts index 86243bc14c1..933e2ad35e2 100644 --- a/src/qt/locale/bitcoin_sr@latin.ts +++ b/src/qt/locale/bitcoin_sr@latin.ts @@ -41,7 +41,10 @@ &Delete &Izbrisati - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,55 @@ Repeat new passphrase Ponovo unesite pristupnu frazu - + + 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>. + Unesite novu pristupnu frazu u novčanik. <br/>Molimo, koristite pristupnu frazu koja ima <b> deset ili više nasumičnih znakova</b>, ili <b>osam ili više reči</b>. + + + Encrypt wallet + Šifrujte novčanik + + + This operation needs your wallet passphrase to unlock the wallet. + Da biste otključali novčanik potrebno je da unesete svoju pristupnu frazu. + + + Unlock wallet + Otključajte novčanik + + + This operation needs your wallet passphrase to decrypt the wallet. + Da biste dešifrovali novčanik, potrebno je da unesete svoju pristupnu frazu. + + + Decrypt wallet + Dešifrujte novčanik + + + Change passphrase + Promenite pristupnu frazu + + + Enter the old passphrase and new passphrase to the wallet. + Unesite u novčanik staru pristupnu frazu i novu pristupnu frazu. + + + Confirm wallet encryption + Potvrdite šifrovanje novčanika + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Upozorenje: Ako šifrujete svoj novčanik, i potom izgubite svoju pristupnu frazu <b>IZGUBIĆETE SVE SVOJE BITKOINE</b>! + + + Are you sure you wish to encrypt your wallet? + Da li ste sigurni da želite da šifrujete svoj novčanik? + + + Wallet encrypted + Novčanik je šifrovan + + BanTableModel @@ -75,13 +126,147 @@ BitcoinGUI + Synchronizing with network... + Usklađivanje sa mrežom... + + + &Overview + &Pregled + + + Quit application + Isključi aplikaciju + + + &Options... + &Opcije... + + + &Change Passphrase... + &Izmeni pristupnu frazu... + + + &Sending addresses... + &Slanje adresa... + + + &Receiving addresses... + &Primanje adresa... + + + Open &URI... + Otvori &URI... + + + Send coins to a Bitcoin address + Pošalji novčiće na Bitcoin adresu + + + &Verify message... + &Proveri poruku... + + + Bitcoin + Bitcoin + + + Wallet + Novčanik + + + &Send + &Pošalji + + + &Receive + &Primi + + + &Show / Hide + &Prikazati / Sakriti + + + Show or hide the main Window + Prikaži ili sakrij glavni prozor + + + &Settings + &Podešavanja + + + &Help + &Pomoć + + Error Greska + + Warning + Upozorenje + + + Information + Informacije + + + %1 client + %1 klijent + + + Date: %1 + + Datum: %1 + + + + Amount: %1 + + Iznos: %1 + + + + Type: %1 + + Tip: %1 + + + + Label: %1 + + Oznaka: %1 + + + + Address: %1 + + Adresa: %1 + + CoinControlDialog + Quantity: + Količina: + + + Amount: + Iznos: + + + Priority: + Prioritet: + + + Fee: + Naknada: + + + After Fee: + Nakon Naknade: + + Amount Kolicina @@ -89,9 +274,25 @@ Date Datum + + Priority + Prioritet + EditAddressDialog + + Edit Address + Izmeni Adresu + + + &Label + &Oznaka + + + &Address + &Adresa + FreespaceChecker @@ -116,6 +317,9 @@ OverviewPage + PaymentServer + + PeerTableModel @@ -126,6 +330,9 @@ + QRImageWidget + + RPCConsole @@ -135,12 +342,38 @@ ReceiveRequestDialog + RecentRequestsTableModel + + SendCoinsDialog + + Quantity: + Količina: + + + Amount: + Iznos: + + + Priority: + Prioritet: + + + Fee: + Naknada: + + + After Fee: + Nakon Naknade: + SendCoinsEntry + SendConfirmationDialog + + ShutdownWindow @@ -153,18 +386,44 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Bitcoin Core Bitcoin Core + Information + Informacije + + + Warning + Upozorenje + + Insufficient funds Nedovoljno sredstava diff --git a/src/qt/locale/bitcoin_sv.ts b/src/qt/locale/bitcoin_sv.ts index ee46974d8b4..7e30b263a2c 100644 --- a/src/qt/locale/bitcoin_sv.ts +++ b/src/qt/locale/bitcoin_sv.ts @@ -41,6 +41,78 @@ &Delete &Radera + + Choose the address to send coins to + Välj en adress att sända betalning till + + + Choose the address to receive coins with + Välj en adress att ta emot betalning till + + + C&hoose + V&älj + + + Sending addresses + Avsändaradresser + + + Receiving addresses + Mottagaradresser + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Detta är dina Bitcoin adresser för att skicka betalningar. Kolla alltid summan och den mottagande adressen innan du skickar Bitcoins. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Detta är dina Bitcoin adresser för att ta emot betalningar. Det rekommenderas att använda en ny mottagningsadress för varje transaktion. + + + &Copy Address + &Kopiera adress + + + Copy &Label + Kopiera &etikett + + + &Edit + &Redigera + + + Export Address List + Exportera adresslista + + + Comma separated file (*.csv) + Kommaseparerad fil (*.csv) + + + Exporting Failed + Export misslyckades + + + There was an error trying to save the address list to %1. Please try again. + Det inträffade ett fel när adresslistan skulle sparas till %1. +Var vänlig och försök igen. + + + + AddressTableModel + + Label + Etikett + + + Address + Adress + + + (no label) + (Ingen etikett) + AskPassphraseDialog @@ -60,6 +132,94 @@ Repeat new passphrase Upprepa nytt lösenord + + 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>. + Ange plånbokens nya lösenord. <br/> Använd ett lösenord på <b>tio eller fler slumpmässiga tecken,</b> eller <b>åtta eller fler ord.</b>. + + + Encrypt wallet + Kryptera plånbok + + + This operation needs your wallet passphrase to unlock the wallet. + Denna operation behöver din plånboks lösenord för att låsa upp plånboken. + + + Unlock wallet + Lås upp plånbok + + + This operation needs your wallet passphrase to decrypt the wallet. + Denna operation behöver din plånboks lösenord för att dekryptera plånboken. + + + Decrypt wallet + Dekryptera plånbok + + + Change passphrase + Ändra lösenord + + + Enter the old passphrase and new passphrase to the wallet. + Ge det gamla lösenordet och det nya lösenordet för plånboken. + + + Confirm wallet encryption + Bekräfta kryptering av plånbok + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + VARNING: Om du krypterar din plånbok och glömmer ditt lösenord, kommer du att <b>FÖRLORA ALLA DINA BITCOIN</b>! + + + Are you sure you wish to encrypt your wallet? + Är du säker på att du vill kryptera din plånbok? + + + Wallet encrypted + Plånbok krypterad + + + %1 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. + %1 kommer nu att stänga ner för att färdigställa krypteringen. Tänk på att en krypterad plånbok inte skyddar mot stöld om din dator är infekterad med en keylogger. + + + 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. + VIKTIGT: Alla tidigare säkerhetskopior du har gjort av plånboksfilen ska ersättas med den nya genererade, krypterade plånboksfilen. Av säkerhetsskäl kommer tidigare säkerhetskopior av den okrypterade plånboksfilen blir oanvändbara när du börjar använda en ny, krypterad plånbok. + + + Wallet encryption failed + Kryptering av plånbok misslyckades + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Kryptering av plånbok misslyckades på grund av ett internt fel. Din plånbok blev inte krypterad. + + + The supplied passphrases do not match. + De angivna lösenorden överensstämmer inte. + + + Wallet unlock failed + Misslyckades låsa upp plånboken + + + The passphrase entered for the wallet decryption was incorrect. + Lösenordet för dekryptering av plånboken var felaktig. + + + Wallet decryption failed + Dekryptering av plånbok misslyckades + + + Wallet passphrase was successfully changed. + Plånbokens lösenord har ändrats. + + + Warning: The Caps Lock key is on! + Varning: Caps Lock är påslaget! + BanTableModel @@ -463,7 +623,23 @@ Priority Prioritet - + + Copy address + Kopiera adress + + + Copy label + Kopiera etikett + + + Copy amount + Kopiera belopp + + + (no label) + (Ingen etikett) + + EditAddressDialog @@ -486,7 +662,7 @@ &Address &Adress - + FreespaceChecker @@ -626,7 +802,7 @@ Select payment request file Välj betalningsbegäransfil - + OptionsDialog @@ -938,6 +1114,9 @@ + PaymentServer + + PeerTableModel User Agent @@ -992,6 +1171,9 @@ + QRImageWidget + + RPCConsole N/A @@ -1352,6 +1534,14 @@ Remove Ta bort + + Copy label + Kopiera etikett + + + Copy amount + Kopiera belopp + ReceiveRequestDialog @@ -1371,7 +1561,26 @@ &Save Image... &Spara Bild... - + + Address + Adress + + + Label + Etikett + + + + RecentRequestsTableModel + + Label + Etikett + + + (no label) + (Ingen etikett) + + SendCoinsDialog @@ -1522,6 +1731,14 @@ S&end &Skicka + + Copy amount + Kopiera belopp + + + (no label) + (Ingen etikett) + SendCoinsEntry @@ -1601,7 +1818,10 @@ Memo: PM: - + + + SendConfirmationDialog + ShutdownWindow @@ -1699,7 +1919,7 @@ Reset all verify message fields Rensa alla fält - + SplashScreen @@ -1715,12 +1935,57 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Den här panelen visar en detaljerad beskrivning av transaktionen - + + + TransactionTableModel + + Label + Etikett + + + (no label) + (Ingen etikett) + + + + TransactionView + + Copy address + Kopiera adress + + + Copy label + Kopiera etikett + + + Copy amount + Kopiera belopp + + + Comma separated file (*.csv) + Kommaseparerad fil (*.csv) + + + Label + Etikett + + + Address + Adress + + + Exporting Failed + Export misslyckades + + UnitDisplayStatusBarControl @@ -1729,6 +1994,15 @@ + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: @@ -1827,6 +2101,10 @@ Distribuerad under MIT mjukvarulicens, se den bifogade filen COPYING eller <http://www.opensource.org/licenses/mit-license.php>. + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Samma antal byte per sigop i transaktioner som vi reläar och bryter (förvalt: %u) + + Error loading %s: You can't enable HD on a already existing non-HD wallet Fel vid laddning av %s: Du kan inte aktivera HD på en existerande icke-HD plånbok @@ -1839,10 +2117,6 @@ Exekvera kommando när en plånbokstransaktion ändras (%s i cmd är ersatt av TxID) - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Vidarebefodra alltid transaktioner från vitlistade noder även om de bryter mot lokala reläpolicyn (förvalt: %d) - - Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) Maximalt tillåten median-peer tidsoffset justering. Lokalt perspektiv av tiden kan bli påverkad av partners, framåt eller bakåt denna tidsrymd. (förvalt: %u sekunder) @@ -2051,10 +2325,6 @@ Plats för authcookie (förvalt: datamapp) - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Minimum antal byte per sigop i transaktioner som vi reläar och bryter (förvalt: %u) - - Not enough file descriptors available. Inte tillräckligt med filbeskrivningar tillgängliga. @@ -2095,8 +2365,8 @@ Sätt databasens cachestorlek i megabyte (%d till %d, förvalt: %d) - Set maximum block cost (default: %d) - Sätt maximal blockkostnad (förvalt: %d) + Set maximum BIP141 block weight (default: %d) + Sätt maximal BIP141 blockvikt (förvalt: %d) Set maximum block size in bytes (default: %d) @@ -2527,10 +2797,6 @@ Sätt storleken på nyckelpoolen till <n> (förvalt: %u) - Set minimum block size in bytes (default: %u) - Sätt minsta blockstorlek i byte (standard: %u) - - Set the number of threads to service RPC calls (default: %d) Ange antalet trådar för att hantera RPC anrop (förvalt: %d) diff --git a/src/qt/locale/bitcoin_ta.ts b/src/qt/locale/bitcoin_ta.ts index 921171c5449..1ce2c4df8f6 100644 --- a/src/qt/locale/bitcoin_ta.ts +++ b/src/qt/locale/bitcoin_ta.ts @@ -25,7 +25,22 @@ &Delete &அழி - + + Sending addresses + முகவரிகள் அனுப்பப்படுகின்றன + + + Receiving addresses + முகவரிகள் பெறப்படுகின்றன + + + + AddressTableModel + + Address + முகவரி + + AskPassphraseDialog @@ -205,7 +220,7 @@ Priority முன்னுரிமை - + EditAddressDialog @@ -332,6 +347,9 @@ + PaymentServer + + PeerTableModel User Agent @@ -370,6 +388,9 @@ + QRImageWidget + + RPCConsole N/A @@ -530,7 +551,7 @@ Remove நீக்கு - + ReceiveRequestDialog @@ -549,7 +570,14 @@ &Save Image... &படத்தை சேமி... - + + Address + முகவரி + + + + RecentRequestsTableModel + SendCoinsDialog @@ -600,7 +628,7 @@ S&end &அனுப்பு - + SendCoinsEntry @@ -625,6 +653,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -653,12 +684,34 @@ + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + Address + முகவரி + + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Bitcoin Core diff --git a/src/qt/locale/bitcoin_th_TH.ts b/src/qt/locale/bitcoin_th_TH.ts index 34c75263416..9c4a2679861 100644 --- a/src/qt/locale/bitcoin_th_TH.ts +++ b/src/qt/locale/bitcoin_th_TH.ts @@ -41,7 +41,10 @@ &Delete &ลบ - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase กรุณากรอกรหัสผ่านใหม่อีกครั้งหนึ่ง - + BanTableModel @@ -463,7 +466,7 @@ Priority ระดับความสำคัญ - + EditAddressDialog @@ -486,7 +489,7 @@ &Address &ที่เก็บ - + FreespaceChecker @@ -622,7 +625,7 @@ Select payment request file เลือก ไฟล์การเรียกการชำระเงิน - + OptionsDialog @@ -798,6 +801,9 @@ + PaymentServer + + PeerTableModel @@ -808,6 +814,9 @@ + QRImageWidget + + RPCConsole @@ -821,6 +830,9 @@ ReceiveRequestDialog + RecentRequestsTableModel + + SendCoinsDialog Send Coins @@ -867,6 +879,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -883,12 +898,30 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_tr.ts b/src/qt/locale/bitcoin_tr.ts index e3a811b504e..7a4b95a2282 100644 --- a/src/qt/locale/bitcoin_tr.ts +++ b/src/qt/locale/bitcoin_tr.ts @@ -41,7 +41,10 @@ &Delete &Sil - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Yeni parolayı tekrarlayınız - + BanTableModel @@ -463,7 +466,7 @@ Priority Öncelik - + EditAddressDialog @@ -486,7 +489,7 @@ &Address &Adres - + FreespaceChecker @@ -626,7 +629,7 @@ Select payment request file Ödeme talebi dosyasını seç - + OptionsDialog @@ -938,6 +941,9 @@ + PaymentServer + + PeerTableModel User Agent @@ -992,6 +998,9 @@ + QRImageWidget + + RPCConsole N/A @@ -1352,7 +1361,7 @@ Remove Kaldır - + ReceiveRequestDialog @@ -1371,7 +1380,10 @@ &Save Image... Resmi ka&ydet... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1522,7 +1534,7 @@ S&end G&önder - + SendCoinsEntry @@ -1601,7 +1613,10 @@ Memo: Not: - + + + SendConfirmationDialog + ShutdownWindow @@ -1699,7 +1714,7 @@ Reset all verify message fields Tüm mesaj kontrolü alanlarını sıfırla - + SplashScreen @@ -1715,12 +1730,21 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Bu pano muamelenin ayrıntılı açıklamasını gösterir - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1729,6 +1753,15 @@ + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: @@ -1831,6 +1864,10 @@ 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. + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + Oluşturma ve aktarşa muamelelerinde sigop başına eşdeğer bayt (varsayılan: %u) + + Error loading %s: You can't enable HD on a already existing non-HD wallet %s yüklenmesinde hata: zaten var olan ve HD olmayan bir cüzdanda HD etkinleştirilemez. @@ -1843,10 +1880,6 @@ Bir cüzdan muamelesi değiştiğinde komutu çalıştır (komuttaki %s muamele kimliği ile değiştirilecektir) - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - Yerel aktarma politikasını ihlal ettiklerinde bile beyaz listedeki eşlerden gelen muamelelerin aktarılmasını zorla (varsayılan: %d) - - Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) Müsaade edilen azami medyan eş zamanı değişiklik sınırının ayarlaması. Zamanın yerel perspektifi bu miktar kadar ileri ya da geri eşler tarafından etkilenebilir. (Varsayılan %u saniye) @@ -2055,10 +2088,6 @@ auth çerezinin konumu (varsayılan: veri klasörü) - Minimum bytes per sigop in transactions we relay and mine (default: %u) - Aktardığımız ve oluşturduğumuz muamelelerdeki sigop başına asgari bayt (varsayılan: %u) - - Not enough file descriptors available. Kafi derecede dosya tanımlayıcıları mevcut değil. @@ -2099,8 +2128,8 @@ Veritabanı önbellek boyutunu megabayt olarak belirt (%d ilâ %d, varsayılan: %d) - Set maximum block cost (default: %d) - Azami blok maliyetini ayarla (varsayılan: %d) + Set maximum BIP141 block weight (default: %d) + Azami BIP141 blok ağırlığını ayarla (varsayılan: %d) Set maximum block size in bytes (default: %d) @@ -2531,10 +2560,6 @@ Anahtar alan boyutunu <n> değerine ayarla (varsayılan: %u) - Set minimum block size in bytes (default: %u) - Bayt olarak asgari blok boyutunu tanımla (varsayılan: %u) - - Set the number of threads to service RPC calls (default: %d) Hizmet RCP aramaları iş parçacığı sayısını belirle (varsayılan: %d) diff --git a/src/qt/locale/bitcoin_tr_TR.ts b/src/qt/locale/bitcoin_tr_TR.ts index 344309c25fd..bc99091fbf7 100644 --- a/src/qt/locale/bitcoin_tr_TR.ts +++ b/src/qt/locale/bitcoin_tr_TR.ts @@ -41,7 +41,10 @@ &Delete &Sil - + + + AddressTableModel + AskPassphraseDialog @@ -68,7 +71,7 @@ &Address Adres - + FreespaceChecker @@ -88,12 +91,18 @@ OverviewPage + PaymentServer + + PeerTableModel QObject + QRImageWidget + + RPCConsole @@ -107,12 +116,18 @@ + RecentRequestsTableModel + + SendCoinsDialog SendCoinsEntry + SendConfirmationDialog + + ShutdownWindow @@ -125,12 +140,30 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core \ No newline at end of file diff --git a/src/qt/locale/bitcoin_uk.ts b/src/qt/locale/bitcoin_uk.ts index a06cc9e0921..09c167dfc78 100644 --- a/src/qt/locale/bitcoin_uk.ts +++ b/src/qt/locale/bitcoin_uk.ts @@ -41,7 +41,10 @@ &Delete &Видалити - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Повторіть пароль - + BanTableModel @@ -439,7 +442,7 @@ Priority Пріоритет - + EditAddressDialog @@ -462,7 +465,7 @@ &Address &Адреса - + FreespaceChecker @@ -582,7 +585,7 @@ Select payment request file Виберіть файл запиту платежу - + OptionsDialog @@ -874,6 +877,9 @@ + PaymentServer + + PeerTableModel User Agent @@ -928,6 +934,9 @@ + QRImageWidget + + RPCConsole N/A @@ -1268,7 +1277,7 @@ Remove Вилучити - + ReceiveRequestDialog @@ -1287,7 +1296,10 @@ &Save Image... &Зберегти зображення... - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1438,7 +1450,7 @@ S&end &Відправити - + SendCoinsEntry @@ -1517,7 +1529,10 @@ Memo: Нотатка: - + + + SendConfirmationDialog + ShutdownWindow @@ -1611,7 +1626,7 @@ Reset all verify message fields Скинути всі поля перевірки повідомлення - + SplashScreen @@ -1627,12 +1642,21 @@ + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Даний діалог показує детальну статистику по вибраній транзакції - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl @@ -1641,6 +1665,15 @@ + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: @@ -2263,10 +2296,6 @@ Встановити розмір пулу ключів <n> (типово: %u) - Set minimum block size in bytes (default: %u) - Встановити мінімальний розмір блоку в байтах (типово: %u) - - Set the number of threads to service RPC calls (default: %d) Встановити число потоків для обслуговування викликів RPC (типово: %d) diff --git a/src/qt/locale/bitcoin_ur_PK.ts b/src/qt/locale/bitcoin_ur_PK.ts index 6b43bf63e51..60311ac41e1 100644 --- a/src/qt/locale/bitcoin_ur_PK.ts +++ b/src/qt/locale/bitcoin_ur_PK.ts @@ -41,7 +41,10 @@ &Delete مٹا - + + + AddressTableModel + AskPassphraseDialog @@ -56,7 +59,7 @@ Repeat new passphrase نیا پاس فریز دہرائیں - + BanTableModel @@ -92,7 +95,7 @@ &Address پتہ - + FreespaceChecker @@ -116,6 +119,9 @@ OverviewPage + PaymentServer + + PeerTableModel @@ -126,6 +132,9 @@ + QRImageWidget + + RPCConsole @@ -139,6 +148,9 @@ + RecentRequestsTableModel + + SendCoinsDialog Insufficient funds! @@ -157,6 +169,9 @@ SendCoinsEntry + SendConfirmationDialog + + ShutdownWindow @@ -169,12 +184,30 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Insufficient funds diff --git a/src/qt/locale/bitcoin_uz@Cyrl.ts b/src/qt/locale/bitcoin_uz@Cyrl.ts index 0062abfc1d4..2503ed4a10a 100644 --- a/src/qt/locale/bitcoin_uz@Cyrl.ts +++ b/src/qt/locale/bitcoin_uz@Cyrl.ts @@ -41,7 +41,10 @@ &Delete &Ўчириш - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase Янги махфий сузни такрорланг - + BanTableModel @@ -381,7 +384,7 @@ Priority Муҳимлиги - + EditAddressDialog @@ -404,7 +407,7 @@ &Address &Манзил - + FreespaceChecker @@ -492,7 +495,7 @@ Select payment request file Тўлов сўрови файлини танлаш - + OptionsDialog @@ -684,6 +687,9 @@ + PaymentServer + + PeerTableModel User Agent @@ -726,6 +732,9 @@ + QRImageWidget + + RPCConsole N/A @@ -962,7 +971,7 @@ Remove Ўчириш - + ReceiveRequestDialog @@ -977,7 +986,10 @@ &Save Image... Расмни &сақлаш - + + + RecentRequestsTableModel + SendCoinsDialog @@ -1088,7 +1100,7 @@ S&end Жў&натиш - + SendCoinsEntry @@ -1133,6 +1145,9 @@ + SendConfirmationDialog + + ShutdownWindow @@ -1173,16 +1188,34 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog This pane shows a detailed description of the transaction Ушбу ойна операциянинг батафсил таърифини кўрсатади - + + + TransactionTableModel + + + TransactionView + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_vi.ts b/src/qt/locale/bitcoin_vi.ts index e8bf01ab1b7..46bf75f5838 100644 --- a/src/qt/locale/bitcoin_vi.ts +++ b/src/qt/locale/bitcoin_vi.ts @@ -21,7 +21,10 @@ &Delete &Xóa - + + + AddressTableModel + AskPassphraseDialog @@ -52,7 +55,7 @@ &Address Địa chỉ - + FreespaceChecker @@ -72,6 +75,9 @@ OverviewPage + PaymentServer + + PeerTableModel @@ -82,6 +88,9 @@ + QRImageWidget + + RPCConsole @@ -95,6 +104,9 @@ + RecentRequestsTableModel + + SendCoinsDialog Amount: @@ -105,6 +117,9 @@ SendCoinsEntry + SendConfirmationDialog + + ShutdownWindow @@ -117,12 +132,30 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core \ No newline at end of file diff --git a/src/qt/locale/bitcoin_vi_VN.ts b/src/qt/locale/bitcoin_vi_VN.ts index a4e1588c932..fdfc9211799 100644 --- a/src/qt/locale/bitcoin_vi_VN.ts +++ b/src/qt/locale/bitcoin_vi_VN.ts @@ -41,7 +41,10 @@ &Delete &Xó&a - + + + AddressTableModel + AskPassphraseDialog @@ -60,13 +63,29 @@ Repeat new passphrase Điền lại passphrase - + BanTableModel - + + IP/Netmask + IP/Netmask + + + Banned Until + Bị cấm đến + + BitcoinGUI + Sign &message... + Chứ ký & Tin nhắn... + + + Synchronizing with network... + Đồng bộ hóa với mạng + + &Overview &Tổng quan @@ -75,6 +94,18 @@ Node + Show general overview of wallet + Hiện thỉ thông tin sơ lược chung về Ví + + + &Transactions + &Giao dịch + + + Browse transaction history + Duyệt tìm lịch sử giao dịch + + E&xit T&hoát @@ -83,6 +114,14 @@ Thoát chương trình + &About %1 + &Thông tin về %1 + + + Show information about %1 + Hiện thông tin về %1 + + About &Qt Về &Qt @@ -91,6 +130,30 @@ Xem thông tin về Qt + &Options... + &Tùy chọn... + + + Modify configuration options for %1 + Chỉnh sửa thiết đặt tùy chọn cho %1 + + + &Encrypt Wallet... + &Mã hóa ví tiền + + + &Backup Wallet... + &Sao lưu ví tiền... + + + &Change Passphrase... + &Thay đổi mật khẩu... + + + &Sending addresses... + &Địa chỉ gửi + + &Receiving addresses... Địa chỉ nhận @@ -99,6 +162,30 @@ Mở &URI... + Reindexing blocks on disk... + Đánh chỉ số (indexing) lại các khối (blocks) trên ổ đĩa ... + + + Send coins to a Bitcoin address + Gửi coins đến tài khoản Bitcoin + + + Backup wallet to another location + Sao lưu ví tiền ở vị trí khác + + + Change the passphrase used for wallet encryption + Thay đổi cụm mật mã dùng cho mã hoá Ví + + + &Debug window + &Cửa sổ xử lý lỗi (debug) + + + &Verify message... + &Tin nhắn xác thực + + Bitcoin Bitcoin @@ -123,6 +210,18 @@ Hiện hoặc ẩn cửa sổ chính + Encrypt the private keys that belong to your wallet + Mã hoá các khoá bí mật trong Ví của bạn. + + + Sign messages with your Bitcoin addresses to prove you own them + Dùng địa chỉ Bitcoin của bạn ký các tin nhắn để xác minh những nội dung tin nhắn đó là của bạn. + + + Verify messages to ensure they were signed with specified Bitcoin addresses + Kiểm tra các tin nhắn để chắc chắn rằng chúng được ký bằng các địa chỉ Bitcoin xác định. + + &File &File @@ -134,6 +233,30 @@ &Help Trợ &giúp + + Tabs toolbar + Thanh công cụ (toolbar) + + + Request payments (generates QR codes and bitcoin: URIs) + Yêu cầu thanh toán(tạo mã QR và địa chỉ Bitcoin: URLs) + + + Show the list of used sending addresses and labels + Hiện thỉ danh sách các địa chỉ và nhãn đã dùng để gửi. + + + Show the list of used receiving addresses and labels + Hiện thỉ danh sách các địa chỉ và nhãn đã dùng để nhận. + + + Open a bitcoin: URI or payment request + Mở bitcoin:URL hoặc yêu cầu thanh toán + + + &Command-line options + 7Tùy chọn dòng lệnh + %n hour(s) %n giờ @@ -155,6 +278,18 @@ %n năm + %1 behind + %1 chậm trễ + + + Last received block was generated %1 ago. + Khối (block) cuối cùng nhận được cách đây %1 + + + Transactions after this will not yet be visible. + Những giao dịch sau đó sẽ không hiện thị. + + Error Lỗi @@ -171,6 +306,40 @@ Đã cập nhật + Catching up... + Bắt kịp... + + + Date: %1 + + Ngày: %1 + + + + Amount: %1 + + Số lượng: %1 + + + + Type: %1 + + Loại: %1 + + + + Label: %1 + + Nhãn hiệu: %1 + + + + Address: %1 + + Địa chỉ: %1 + + + Sent transaction Giao dịch đã gửi @@ -178,7 +347,15 @@ Incoming transaction Giao dịch đang tới - + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Ví tiền <b> đã được mã hóa</b>và hiện <b>đang mở</b> + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Ví tiền <b> đã được mã hóa</b>và hiện <b>đang khóa</b> + + CoinControlDialog @@ -202,10 +379,26 @@ Phí: + After Fee: + Sau thuế, phí: + + Change: Thay đổi: + (un)select all + (bỏ)chọn tất cả + + + Tree mode + Chế độ cây + + + List mode + Chế độ danh sách + + Amount Lượng @@ -225,10 +418,14 @@ Priority Tầm quan trọng - + EditAddressDialog + Edit Address + Thay đổi địa chỉ + + &Label Nhãn @@ -236,7 +433,7 @@ &Address Địa chỉ - + FreespaceChecker @@ -250,6 +447,30 @@ version version + + (%1-bit) + (%1-bit) + + + Command-line options + &Tùy chọn dòng lệnh + + + Usage: + Mức sử dụng + + + command-line options + tùy chọn dòng lệnh + + + Set language, for example "de_DE" (default: system locale) + Chọn ngôn ngữ, ví dụ "de_DE" (mặc định: Vị trí hệ thống) + + + Set SSL root certificates for payment request (default: -system-) + Đặt chứng nhận SSL gốc cho yêu cầu giao dịch (mặc định: -hệ thống-) + Intro @@ -258,6 +479,10 @@ Chào mừng + Use the default data directory + Sử dụng vị trí dữ liệu mặc định + + Error Lỗi @@ -288,14 +513,58 @@ MB + Accept connections from outside + Chấp nhận các kết nối từ bên ngoài + + + Allow incoming connections + Cho phép nhận kết nối + + + IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) + Địa chỉ IP của proxy (ví dụ IPv4: 127.0.0.1 / IPv6: ::1) + + + Third party transaction URLs + Phần mềm giao dịch bên thứ ba URLs + + W&allet + Connect to the Bitcoin network through a SOCKS5 proxy. + Kết nối đến máy chủ Bitcoin thông qua SOCKS5 proxy. + + + Proxy &IP: + Proxy &IP: + + + &Port: + &Cổng: + + + Port of the proxy (e.g. 9050) + Cổng proxy (e.g. 9050) + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + &Display &Hiển thị + User Interface &language: + Giao diện người dùng & ngôn ngữ + + &OK &OK @@ -307,6 +576,10 @@ default mặc định + + none + Trống + OverviewPage @@ -315,11 +588,22 @@ Form + Available: + Khả dụng + + + Pending: + Đang chờ + + Total: Tổng: + PaymentServer + + PeerTableModel User Agent @@ -334,6 +618,13 @@ + QRImageWidget + + &Save Image... + $Lưu hình ảnh... + + + RPCConsole &Information @@ -359,6 +650,58 @@ User Agent User Agent + + 1 &hour + 1&giờ + + + 1 &day + 1&ngày + + + 1 &week + 1&tuần + + + 1 &year + 1&năm + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + Sử dụng phím lên và xuống để di chuyển lịch sử, và <b>Ctrl-L</b> để xóa màn hình + + + Type <b>help</b> for an overview of available commands. + Gõ <b>help</b> để xem nhưng câu lệnh có sẵn + + + %1 B + %1 B + + + %1 KB + %1 KB + + + %1 MB + %1 MB + + + %1 GB + %1 GB + + + never + không bao giờ + + + Yes + Đồng ý + + + No + Không + ReceiveCoinsDialog @@ -366,17 +709,120 @@ &Amount: Lượng: + + &Label: + &Nhãn + + + &Message: + &Tin nhắn: + + + Use this form to request payments. All fields are <b>optional</b>. + Sử dụng form này để yêu cầu thanh toán. Tất cả các trường <b>không bắt buộc<b> + + + Clear all fields of the form. + Xóa tất cả các trường trong biểu mẫu + + + Clear + Xóa + + + Requested payments history + Lịch sử yêu cầu thanh toán + + + &Request payment + &Yêu cầu thanh toán + + + Show + Hiển thị + + + Remove the selected entries from the list + Xóa khỏi danh sách + + + Remove + Xóa + + + Copy message + Copy tin nhắn + ReceiveRequestDialog + QR Code + QR Code + + + Copy &URI + Copy &URI + + Copy &Address &Copy Địa Chỉ + + &Save Image... + $Lưu hình ảnh... + + + Request payment to %1 + Yêu cầu thanh toán cho %1 + + + Payment information + Thông tin thanh toán + + + URI + URI + + + Message + Tin nhắn + + + Error encoding URI into QR Code. + Lỗi khi encode từ URI thành QR Code + + + + RecentRequestsTableModel + + Message + Tin nhắn + + + (no message) + (không tin nhắn) + SendCoinsDialog + Send Coins + Gửi Coins + + + Coin Control Features + Tính năng Control Coin + + + Inputs... + Nhập... + + + automatically selected + Tự động chọn + + Insufficient funds! Không đủ tiền @@ -401,9 +847,93 @@ Phí: + After Fee: + Sau thuế, phí: + + Change: Thay đổi: + + Transaction Fee: + Phí giao dịch + + + Choose... + Chọn... + + + collapse fee-settings + Thu gọn fee-settings + + + per kilobyte + trên KB + + + Hide + Ẩn + + + total at least + Tổng cộng ít nhất + + + (read the tooltip) + (Đọc hướng dẫn) + + + Confirmation time: + Thời gian xác nhận + + + normal + Bình thường + + + fast + Nhanh + + + Send to multiple recipients at once + Gửi đến nhiều người nhận trong một lần + + + Add &Recipient + Thêm &Người nhận + + + Clear all fields of the form. + Xóa tất cả các trường trong biểu mẫu + + + Clear &All + Xóa &Tất cả + + + Balance: + Tài khoản + + + Confirm the send action + Xác nhận sự gửi + + + %1 to %2 + %1 đến %2 + + + Total Amount %1 + Tổng cộng %1 + + + or + hoặc + + + Confirm send coins + Xác nhận gửi coins + SendCoinsEntry @@ -411,12 +941,27 @@ A&mount: Lượng: + + &Label: + &Nhãn + + SendConfirmationDialog + + Yes + Đồng ý + + + ShutdownWindow SignVerifyMessageDialog + + Clear &All + Xóa &Tất cả + SplashScreen @@ -425,12 +970,38 @@ TrafficGraphWidget + TransactionDesc + + Message + Tin nhắn + + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + Send Coins + Gửi Coins + + + + WalletView + + bitcoin-core Options: diff --git a/src/qt/locale/bitcoin_zh.ts b/src/qt/locale/bitcoin_zh.ts index bceba9dfdd8..61b95f4b6c6 100644 --- a/src/qt/locale/bitcoin_zh.ts +++ b/src/qt/locale/bitcoin_zh.ts @@ -3,6 +3,9 @@ AddressBookPage + AddressTableModel + + AskPassphraseDialog @@ -52,12 +55,18 @@ OverviewPage + PaymentServer + + PeerTableModel QObject + QRImageWidget + + RPCConsole @@ -67,6 +76,9 @@ ReceiveRequestDialog + RecentRequestsTableModel + + SendCoinsDialog Insufficient funds! @@ -81,6 +93,9 @@ SendCoinsEntry + SendConfirmationDialog + + ShutdownWindow @@ -93,12 +108,30 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core Transaction amounts must be positive diff --git a/src/qt/locale/bitcoin_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts index 92a7006d30f..98142b7b004 100644 --- a/src/qt/locale/bitcoin_zh_CN.ts +++ b/src/qt/locale/bitcoin_zh_CN.ts @@ -41,6 +41,77 @@ &Delete 删除(&D) + + Choose the address to send coins to + 选择要付钱过去的地址 + + + Choose the address to receive coins with + 选择要收钱进来的地址 + + + C&hoose + 选择 + + + Sending addresses + 付款地址 + + + Receiving addresses + 收款地址 + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + 这些是你要付款过去的比特币地址。在付钱之前,务必要检查金额和收款地址是否正确。 + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + 这些是你用来收款的比特币地址。建议在每次交易时,都使用一个新的收款地址。 + + + &Copy Address + 复制地址 + + + Copy &Label + 复制标签 + + + &Edit + 编辑 + + + Export Address List + 导出地址列表 + + + Comma separated file (*.csv) + 逗号分隔文件 (*.csv) + + + Exporting Failed + 导出失败 + + + There was an error trying to save the address list to %1. Please try again. + 存储地址列表到 %1 时发生错误。请再试一次。 + + + + AddressTableModel + + Label + 标签 + + + Address + 地址 + + + (no label) + (无标签) + AskPassphraseDialog @@ -60,6 +131,94 @@ Repeat new passphrase 重复新密码 + + 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>. + 输入钱包的新密码。<br/>密码请用<b>10 个以上的随机字符</b>,或是<b>8 个以上的字词</b>。 + + + Encrypt wallet + 加密钱包 + + + This operation needs your wallet passphrase to unlock the wallet. + 这个操作需要你的钱包密码来解锁钱包。 + + + Unlock wallet + 解锁钱包 + + + This operation needs your wallet passphrase to decrypt the wallet. + 这个操作需要你的钱包密码来把钱包解密。 + + + Decrypt wallet + 解密钱包 + + + Change passphrase + 修改密码 + + + Enter the old passphrase and new passphrase to the wallet. + 请输入钱包的旧密码和新密码。 + + + Confirm wallet encryption + 确认钱包加密 + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + 警告: 如果把钱包加密后又忘记密码,你就会从此<b>失去其中所有的比特币了</b>! + + + Are you sure you wish to encrypt your wallet? + 你确定要把钱包加密吗? + + + Wallet encrypted + 钱包已加密 + + + %1 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. + %1 现在要关闭,以完成加密过程。请注意,加密钱包不能完全防止入侵你的电脑的恶意程序偷取钱币。 + + + 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. + 重要: 请改用新产生的有加密的钱包文件,来取代旧钱包文件的备份。为了安全性,当你开始使用新的有加密的钱包后,旧钱包文件的备份就不能再使用了。 + + + Wallet encryption failed + 钱包加密失败 + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + 因为内部错误导致钱包加密失败。你的钱包还是没加密。 + + + The supplied passphrases do not match. + 提供的密码不yi'zhi。 + + + Wallet unlock failed + 钱包解锁失败 + + + The passphrase entered for the wallet decryption was incorrect. + 输入用来解密钱包的密码不正确。 + + + Wallet decryption failed + 钱包解密失败 + + + Wallet passphrase was successfully changed. + 钱包密码修改成功。 + + + Warning: The Caps Lock key is on! + 警告: 大写字母锁定已开启! + BanTableModel @@ -112,7 +271,11 @@ &About %1 - &关于 %1 + 关于 %1 + + + Show information about %1 + 显示 %1 相关信息 About &Qt @@ -127,6 +290,10 @@ 选项(&O)... + Modify configuration options for %1 + 修改%1配置选项 + + &Encrypt Wallet... 加密钱包(&E)... @@ -232,7 +399,7 @@ Request payments (generates QR codes and bitcoin: URIs) - 请求支付(生成二维码和 bitcoin: URI) + 请求支付 (生成二维码和 bitcoin: URI) Show the list of used sending addresses and labels @@ -244,7 +411,7 @@ Open a bitcoin: URI or payment request - 打开一个比特币:URI 或支付请求 + 打开一个 bitcoin: URI 或支付请求 &Command-line options @@ -255,6 +422,14 @@ %n 个到比特币网络的活动连接 + Indexing blocks on disk... + 正在为数据块建立索引... + + + Processing blocks on disk... + 正在处理数据块... + + No block source available... 沒有可用的区块来源... @@ -311,6 +486,10 @@ 已是最新 + %1 client + %1 客戶 + + Catching up... 更新中... @@ -365,7 +544,7 @@ CoinControlDialog Coin Selection - 币源选择(Coin Selection) + 选择钱币 Quantity: @@ -439,6 +618,150 @@ Priority 优先级 + + Copy address + 复制地址 + + + Copy label + 复制标签 + + + Copy amount + 复制金额 + + + Copy transaction ID + 复制交易识别码 + + + Lock unspent + 锁定未花费 + + + Unlock unspent + 解锁未花费 + + + Copy quantity + 复制数目 + + + Copy fee + 复制手续费 + + + Copy after fee + 复制计费后金额 + + + Copy bytes + 复制字节数 + + + Copy priority + 复制优先度 + + + Copy dust + 复制零散金额 + + + Copy change + 复制找零金额 + + + highest + 最高 + + + higher + 很高 + + + high + + + + medium-high + 中高 + + + medium + 中等 + + + low-medium + 中低 + + + low + + + + lower + 很低 + + + lowest + 最低 + + + (%1 locked) + (锁定 %1 枚) + + + none + + + + yes + + + + no + + + + This label turns red if the transaction size is greater than 1000 bytes. + 当交易大小大于 1000 字节时,文字会变红色。 + + + This means a fee of at least %1 per kB is required. + 表示每一千字节(kB)需要至少 %1 的手续费。 + + + Can vary +/- 1 byte per input. + 每组输入可能会误差多或少 1 个字节。 + + + Transactions with higher priority are more likely to get included into a block. + 优先度较高的交易比较有可能被接受放进区块中。 + + + This label turns red if the priority is smaller than "medium". + 当优先度低于“中等”时,文字会变红色。 + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + 当任何一个收款金额小于目前的零散金额上限时,文字会变红色。 + + + Can vary +/- %1 satoshi(s) per input. + 每组输入可能有 +/- %1 个 satoshi 的误差。 + + + (no label) + (无标签) + + + change from %1 (%2) + 找零前是 %1 (%2) + + + (change) + (找零) + EditAddressDialog @@ -462,6 +785,38 @@ &Address 地址(&A) + + New receiving address + 新建收款地址 + + + New sending address + 新建付款地址 + + + Edit receiving address + 编辑收款地址 + + + Edit sending address + 编辑付款地址 + + + The entered address "%1" is not a valid Bitcoin address. + 输入的地址 %1 并不是有效的比特币地址。 + + + The entered address "%1" is already in the address book. + 输入的地址 %1 已经存在地址簿。 + + + Could not unlock wallet. + 无法将钱包解锁。 + + + New key generation failed. + 产生新的密钥失败了。 + FreespaceChecker @@ -497,6 +852,10 @@ (%1 位) + About %1 + 關於 %1 + + Command-line options 命令行选项 @@ -532,7 +891,11 @@ Show splash screen on startup (default: %u) 显示启动画面(默认:%u) - + + Reset all settings changed in the GUI + 重置图形界面所有的变更设置 + + Intro @@ -540,6 +903,19 @@ 欢迎 + Welcome to %1. + +歡迎來到 %1 + + + As this is the first time the program is launched, you can choose where %1 will store its data. + 由于这是第一次启动此程序,您可以选择%1的数据所存储的位置 + + + %1 will download and store a copy of the Bitcoin block chain. At least %2GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + %1 会下载并存储一份比特币区块链的副本。至少有 %2GB 的数据会存储到这个目录中,并且还会持续增长。另外钱包资料也会储存在这个目录。 + + Use the default data directory 使用默认的数据目录 @@ -582,6 +958,10 @@ Select payment request file 选择付款请求文件 + + Select payment request file to open + 选择要打开的付款请求文件 + OptionsDialog @@ -594,6 +974,14 @@ 主要(&M) + Automatically start %1 after logging in to the system. + 在登入系统后自动启动 %1 + + + &Start %1 on system login + 系统登入时启动 %1 + + Size of &database cache 数据库缓存大小(&D) @@ -719,7 +1107,7 @@ Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. - 在Tor匿名网络下通过不同的SOCKS5代理连接比特币网络 + 在 Tor 匿名网络下通过不同的 SOCKS5 代理连接比特币网络 Use separate SOCKS5 proxy to reach peers via Tor hidden services: @@ -730,6 +1118,14 @@ 窗口(&W) + &Hide the icon from the system tray. + 不在通知区显示图标 + + + Hide tray icon + 不显示通知区图标 + + Show only a tray icon after minimizing the window. 最小化窗口后仅显示托盘图标 @@ -750,6 +1146,10 @@ 用户界面语言(&L): + The user interface language can be set here. This setting will take effect after restarting %1. + 可以在这里设定用户界面的语言。这个设定在重启 %1 后才会生效。 + + &Unit to show amounts in: 比特币金额单位(&U): @@ -806,7 +1206,7 @@ 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. - 现在显示的消息可能是过期的. 在连接上比特币网络节点后,您的钱包将自动与网络同步,但是这个过程还没有完成。 + 现在显示的消息可能是过期的。在连接上比特币网络节点后,您的钱包将自动与网络同步,但是这个过程还没有完成。 Watch-only: @@ -874,6 +1274,58 @@ + PaymentServer + + Payment request error + 要求付款时发生错误 + + + Cannot start bitcoin: click-to-pay handler + 无法启动 bitcoin 协议的“ +一键支付”处理器 + + + URI handling + URI 处理 + + + Payment request fetch URL is invalid: %1 + 取得付款请求的 URL 无效: %1 + + + Invalid payment address %1 + 无效的付款地址 %1 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + 无法解析 URI 地址!可能是因为比特币地址无效,或是 URI 参数格式错误。 + + + Payment request file handling + 处理付款请求文件 + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + 无法读取付款请求文件!可能是文件无效造成的。 + + + Payment request rejected + 付款请求已被拒绝 + + + Payment request network doesn't match client network. + 付款请求的网络类型跟客户端不符。 + + + Payment request expired. + 付款请求已过期。 + + + Payment acknowledged + 付款已确认 + + + PeerTableModel User Agent @@ -928,6 +1380,25 @@ + QRImageWidget + + &Save Image... + 保存图片(&S)... + + + &Copy Image + 复制图片 + + + Save QR Code + 保存二维码 + + + PNG Image (*.png) + PNG 图像(*.png) + + + RPCConsole N/A @@ -954,6 +1425,10 @@ 使用的 BerkeleyDB 版本 + Datadir + 数据目录 + + Startup time 启动时间 @@ -1038,6 +1513,14 @@ 用户代理 + Decrease font size + 缩小文字 + + + Increase font size + 放大文字 + + Services 服务 @@ -1062,6 +1545,10 @@ Ping 时间 + The duration of a currently outstanding ping. + 目前这一次 ping 已经过去的时间。 + + Ping Wait Ping等待 @@ -1095,7 +1582,7 @@ In: - 输入: + 输入: Out: @@ -1138,6 +1625,10 @@ (&U)允许节点连接 + Welcome to the %1 RPC console. + 欢迎使用 %1 的 RPC 控制台。 + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. 使用上下方向键浏览历史, <b>Ctrl-L</b>清除屏幕。 @@ -1264,6 +1755,18 @@ Remove 移除 + + Copy label + 复制标签 + + + Copy message + 复制消息 + + + Copy amount + 复制金额 + ReceiveRequestDialog @@ -1283,8 +1786,55 @@ &Save Image... 保存图片(&S)... + + URI + URI + + + Address + 地址 + + + Amount + 金额 + + + Label + 标签 + + + Message + 消息 + + + Error encoding URI into QR Code. + 把 URI 编码成二维码时发生错误。 + + RecentRequestsTableModel + + Date + 日期 + + + Label + 标签 + + + Message + 消息 + + + (no label) + (无标签) + + + (no message) + (无消息) + + + SendCoinsDialog Send Coins @@ -1434,6 +1984,58 @@ S&end 发送(&E) + + Copy quantity + 复制数目 + + + Copy amount + 复制金额 + + + Copy fee + 复制手续费 + + + Copy after fee + 复制计费后金额 + + + Copy bytes + 复制字节数 + + + Copy priority + 复制优先度 + + + Copy dust + 复制零散金额 + + + Copy change + 复制找零金额 + + + Total Amount %1 + 总金额 %1 + + + or + + + + Payment request expired. + 付款请求已过期。 + + + Warning: Invalid Bitcoin address + 警告: 比特币地址无效 + + + (no label) + (无标签) + SendCoinsEntry @@ -1513,10 +2115,21 @@ Memo: 便条: + + + SendConfirmationDialog + + Yes + + ShutdownWindow + %1 is shutting down... + 正在关闭 %1 ... + + Do not shut down the computer until this window disappears. 在此窗口消失前不要关闭计算机。 @@ -1607,7 +2220,7 @@ Reset all verify message fields 清空所有验证消息栏 - + SplashScreen @@ -1623,11 +2236,176 @@ + TransactionDesc + + Date + 日期 + + + Message + 消息 + + + Merchant + 商家 + + + Debug information + 调试信息 + + + Transaction + 交易 + + + Inputs + 输入 + + + Amount + 金额 + + + true + + + + false + + + + TransactionDescDialog This pane shows a detailed description of the transaction 当前面板显示了交易的详细信息 + + + TransactionTableModel + + Date + 日期 + + + Type + 种类 + + + Label + 标签 + + + Received with + 收款 + + + Sent to + 付款 + + + Mined + 挖矿所得 + + + (no label) + (无标签) + + + + TransactionView + + All + 全部 + + + Today + 今天 + + + This week + 这星期 + + + This month + 这个月 + + + Last month + 上个月 + + + This year + 今年 + + + Range... + 指定范围... + + + Received with + 收款 + + + Sent to + 付款 + + + To yourself + 给自己 + + + Mined + 挖矿所得 + + + Other + 其它 + + + Copy address + 复制地址 + + + Copy label + 复制标签 + + + Copy amount + 复制金额 + + + Copy transaction ID + 复制交易识别码 + + + Comma separated file (*.csv) + 逗号分隔文件 (*.csv) + + + Date + 日期 + + + Type + 种类 + + + Label + 标签 + + + Address + 地址 + + + Exporting Failed + 导出失败 + + + to + + UnitDisplayStatusBarControl @@ -1637,6 +2415,27 @@ + WalletFrame + + + WalletModel + + + WalletView + + Backup Wallet + 备份钱包 + + + Backup Failed + 备份失败 + + + Backup Successful + 备份成功 + + + bitcoin-core Options: @@ -1709,7 +2508,11 @@ Bitcoin Core - 比特币核心 + Bitcoin Core + + + The %s developers + %s 开发人员 -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. @@ -1740,10 +2543,6 @@ 当最佳区块变化时执行命令 (命令行中的 %s 会被替换成区块哈希值) - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - 强制关联来自白名单同行的交易即使他们违反本地关联政策(默认: %d) - - Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) 设置脚本验证的程序 (%u 到 %d, 0 = 自动, <0 = 保留自由的核心, 默认值: %d) @@ -1796,6 +2595,10 @@ 连接选项: + Copyright (C) %i-%i + 版权所有 (C) %i-%i + + Corrupted block database detected 检测发现数据块数据库损坏。请使用 -reindex参数重启客户端。 @@ -1840,6 +2643,10 @@ Error initializing wallet database environment %s! + Error loading %s + 载入 %s 时发生错误 + + Error loading block database 导入数据块数据库出错 @@ -1880,10 +2687,6 @@ 认证Cookie的位置 (默认: data目录) - Minimum bytes per sigop in transactions we relay and mine (default: %u) - 我们关联和挖掘的每sigop的最低交易字节(默认: %u) - - Not enough file descriptors available. 没有足够的文件描述符可用。 @@ -1916,6 +2719,14 @@ 指定钱包文件(数据目录内) + Starting network threads... + 正在启动网络线程... + + + The source code is available from %s. + 源代码可以在 %s 获得。 + + Unsupported argument -benchmark ignored, use -debug=bench. 忽略不支持的选项 -benchmark,使用 -debug=bench @@ -1937,11 +2748,11 @@ Verifying blocks... - 正在验证数据库的完整性... + 正在验证区块... Verifying wallet... - 正在检测钱包的完整性... + 正在验证钱包... Wallet %s resides outside data directory %s @@ -2044,6 +2855,10 @@ 读取数据库出错,关闭中。 + Imports blocks from external blk000??.dat file on startup + 启动时从其他来源的 blk000??.dat 文件导入区块 + + Information 信息 @@ -2072,6 +2887,10 @@ RPC 服务器选项: + Reducing -maxconnections from %d to %d, because of system limitations. + 因为系统的限制,将 -maxconnections 参数从 %d 降到了 %d + + Rescan the block chain for missing wallet transactions on startup 重新扫描区块链以查找遗漏的钱包交易 @@ -2104,6 +2923,14 @@ 这是实验性的软件。 + Tor control port password (default: empty) + Tor 控制端口密码 (默认值: 空白) + + + Tor control port to use if onion listening enabled (default: %s) + 开启监听 onion 连接时的 Tor 控制端口号 (默认值: %s) + + Transaction amount too small 交易量太小 @@ -2136,12 +2963,16 @@ 警告 + Warning: unknown new rules activated (versionbit %i) + 警告: 不明的交易规则被启用了(versionbit %i) + + Whether to operate in a blocks only mode (default: %u) 是否用块方进行 (%u) Zapping all transactions from wallet... - Zapping all transactions from wallet... + 正在消除錢包中的所有交易... ZeroMQ notification options: @@ -2169,6 +3000,22 @@ (1 = 保留 tx meta data , 如 account owner 和 payment request information, 2 = 不保留 tx meta data) + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + 参数 -maxtxfee 设定了很高的金额!这是你一次交易就有可能付出的最高手续费。 + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + 参数 -paytxfee 设定了很高的金额!这是你交易付款时所要付的手续费。 + + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + 不要让交易留在内存池中超过 <n> 个小时 (默认值: %u) + + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + 当产生交易时,如果每千字节 (kB) 的手续费比这个值 (单位是 %s) 低,就视为没支付手续费 (默认值: %s) + + How thorough the block verification of -checkblocks is (0-4, default: %u) 数据块验证 严密级别 -checkblocks (0-4, 默认: %u) @@ -2185,10 +3032,22 @@ 输出调试信息 (默认: %u, 提供 <category> 是可选项) + Support filtering of blocks and transaction with bloom filters (default: %u) + 支持用 Bloom 过滤器来过滤区块和交易(默认值: %u) + + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + 网络版本字符串的总长度 (%i) 超过最大长度 (%i) 了。请减少 uacomment 参数的数目或长度。 + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) 尝试保持上传带宽低于(MiB/24h),0=无限制(默认:%d) + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + 找到不再支持的 -socks 参数。现在只支持 SOCKS5 协议的代理服务器,因此不可以指定 SOCKS 协议版本。 + + Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay. 一个不被支持的参数 -whitelistalwaysrelay 被忽略了。请使用 -whitelistrelay 或者 -whitelistforcerelay. @@ -2197,6 +3056,10 @@ 通过Tor隐藏服务连接节点时 使用不同的SOCKS5代理 (默认: %s) + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + JSON-RPC 连接要使用的用户名和散列密码。<userpw> 的格式是:<用户名>:<盐>$<散列值>。在 share/rpcuser 目录下有一个示范的 python 脚本。这个选项可以被多次指定。 + + Warning: Unknown block versions being mined! It's possible unknown rules are in effect 警告: 未知的区块版本被挖掘!未知规则可能已生效 @@ -2261,10 +3124,6 @@ 设置私钥池大小为 <n> (默认:%u) - Set minimum block size in bytes (default: %u) - 设置数据块 最小字节数 (默认: %u) - - Set the number of threads to service RPC calls (default: %d) 设置RPC服务线程数 (默认: %d) @@ -2298,7 +3157,7 @@ Loading block index... - 正在加载数据块索引... + 正在加载区块索引... Add a node to connect to and attempt to keep the connection open diff --git a/src/qt/locale/bitcoin_zh_HK.ts b/src/qt/locale/bitcoin_zh_HK.ts index aa014db0bd0..ecc00f3a278 100644 --- a/src/qt/locale/bitcoin_zh_HK.ts +++ b/src/qt/locale/bitcoin_zh_HK.ts @@ -41,7 +41,10 @@ &Delete 刪除 &D - + + + AddressTableModel + AskPassphraseDialog @@ -60,7 +63,7 @@ Repeat new passphrase 重複新密碼 - + BanTableModel @@ -224,12 +227,18 @@ OverviewPage + PaymentServer + + PeerTableModel QObject + QRImageWidget + + RPCConsole @@ -239,12 +248,18 @@ ReceiveRequestDialog + RecentRequestsTableModel + + SendCoinsDialog SendCoinsEntry + SendConfirmationDialog + + ShutdownWindow @@ -257,12 +272,30 @@ TrafficGraphWidget + TransactionDesc + + TransactionDescDialog + TransactionTableModel + + + TransactionView + + UnitDisplayStatusBarControl + WalletFrame + + + WalletModel + + + WalletView + + bitcoin-core \ No newline at end of file diff --git a/src/qt/locale/bitcoin_zh_TW.ts b/src/qt/locale/bitcoin_zh_TW.ts index ab56f96795a..4b1e81e9659 100644 --- a/src/qt/locale/bitcoin_zh_TW.ts +++ b/src/qt/locale/bitcoin_zh_TW.ts @@ -41,6 +41,77 @@ &Delete 刪掉 + + Choose the address to send coins to + 選擇要付錢過去的位址 + + + Choose the address to receive coins with + 選擇要收錢進來的位址 + + + C&hoose + 選取 + + + Sending addresses + 付款位址 + + + Receiving addresses + 收款位址 + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + 這些是你要付款過去的 Bitcoin 位址。在付錢之前,務必要檢查金額和收款位址是否正確。 + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + 這些是你用來收款的 Bitcoin 位址。建議在每次交易時,都使用一個新的收款位址。 + + + &Copy Address + 複製位址 + + + Copy &Label + 複製標記 + + + &Edit + 編輯 + + + Export Address List + 匯出位址清單 + + + Comma separated file (*.csv) + 逗點分隔資料檔(*.csv) + + + Exporting Failed + 匯出失敗 + + + There was an error trying to save the address list to %1. Please try again. + 儲存位址列表到 %1 時發生錯誤。請重試一次。 + + + + AddressTableModel + + Label + 標記 + + + Address + 位址 + + + (no label) + (無標記) + AskPassphraseDialog @@ -60,6 +131,94 @@ Repeat new passphrase 重複新密碼 + + 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>. + 輸入錢包的新密碼。<br/>密碼請用<b>10 個以上的隨機字元</b>,或是<b>8 個以上的字詞</b>。 + + + Encrypt wallet + 加密錢包 + + + This operation needs your wallet passphrase to unlock the wallet. + 這個動作需要你的錢包密碼來解鎖錢包。 + + + Unlock wallet + 解鎖錢包 + + + This operation needs your wallet passphrase to decrypt the wallet. + 這個動作需要你的錢包密碼來把錢包解密。 + + + Decrypt wallet + 解密錢包 + + + Change passphrase + 改變密碼 + + + Enter the old passphrase and new passphrase to the wallet. + 請輸入錢包的舊密碼和新密碼。 + + + Confirm wallet encryption + 確認錢包加密 + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + 警告: 如果把錢包加密後又忘記密碼,你就會從此<b>失去其中所有的 Bitcoin 了</b>! + + + Are you sure you wish to encrypt your wallet? + 你確定要把錢包加密嗎? + + + Wallet encrypted + 錢包已加密 + + + %1 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. + %1 現在要關閉,好完成加密程序。請注意,加密錢包不能完全防止入侵你的電腦的惡意程式偷取錢幣。 + + + 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. + 重要: 請改用新產生有加密的錢包檔,來取代舊錢包檔的備份。為了安全性的理由,當你開始使用新的有加密的錢包後,舊錢包檔的備份就不能再使用了。 + + + Wallet encryption failed + 錢包加密失敗 + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + 因為內部錯誤導致錢包加密失敗。你的錢包還是沒加密。 + + + The supplied passphrases do not match. + 提供的密碼不一樣。 + + + Wallet unlock failed + 錢包解鎖失敗 + + + The passphrase entered for the wallet decryption was incorrect. + 輸入要用來解密錢包的密碼不對。 + + + Wallet decryption failed + 錢包解密失敗 + + + Wallet passphrase was successfully changed. + 錢包密碼改成功了。 + + + Warning: The Caps Lock key is on! + 警告: 大寫字母鎖定作用中! + BanTableModel @@ -463,6 +622,150 @@ Priority 優先度 + + Copy address + 複製位址 + + + Copy label + 複製標記 + + + Copy amount + 複製金額 + + + Copy transaction ID + 複製交易識別碼 + + + Lock unspent + 鎖定不用 + + + Unlock unspent + 解鎖可用 + + + Copy quantity + 複製數目 + + + Copy fee + 複製手續費 + + + Copy after fee + 複製計費後金額 + + + Copy bytes + 複製位元組數 + + + Copy priority + 複製優先度 + + + Copy dust + 複製零散金額 + + + Copy change + 複製找零金額 + + + highest + 最高 + + + higher + 很高 + + + high + + + + medium-high + 中高 + + + medium + 中等 + + + low-medium + 中低 + + + low + + + + lower + 很低 + + + lowest + 最低 + + + (%1 locked) + (鎖定 %1 枚) + + + none + + + + yes + + + + no + + + + This label turns red if the transaction size is greater than 1000 bytes. + 當交易大小大於 1000 位元組時,文字會變紅色。 + + + This means a fee of at least %1 per kB is required. + 表示每一千位元組(kB)需要至少 %1 的手續費。 + + + Can vary +/- 1 byte per input. + 每組輸入可能會誤差多或少 1 個位元組。 + + + Transactions with higher priority are more likely to get included into a block. + 優先度較高的交易比較有可能被接受放進區塊中。 + + + This label turns red if the priority is smaller than "medium". + 當優先度低於「中等」時,文字會變紅色。 + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + 當任何一個收款金額小於目前的零散金額上限時,文字會變紅色。 + + + Can vary +/- %1 satoshi(s) per input. + 每組輸入可能有 +/- %1 個 satoshi 的誤差。 + + + (no label) + (無標記) + + + change from %1 (%2) + 找零前是 %1 (%2) + + + (change) + (找零) + EditAddressDialog @@ -486,6 +789,38 @@ &Address 位址 + + New receiving address + 造新的收款位址 + + + New sending address + 造新的付款位址 + + + Edit receiving address + 編輯收款位址 + + + Edit sending address + 編輯付款位址 + + + The entered address "%1" is not a valid Bitcoin address. + 輸入的位址 %1 並不是有效的 Bitcoin 位址。 + + + The entered address "%1" is already in the address book. + 輸入的位址 %1 在位址簿中已經有了。 + + + Could not unlock wallet. + 沒辦法把錢包解鎖。 + + + New key generation failed. + 產生新的密鑰失敗了。 + FreespaceChecker @@ -626,6 +961,10 @@ Select payment request file 選擇付款要求資料檔 + + Select payment request file to open + 選擇要開啟的付款要求資料檔 + OptionsDialog @@ -938,6 +1277,97 @@ + PaymentServer + + Payment request error + 要求付款時發生錯誤 + + + Cannot start bitcoin: click-to-pay handler + 沒辦法啟動 bitcoin 協議的「按就付」處理器 + + + URI handling + URI 處理 + + + Payment request fetch URL is invalid: %1 + 取得付款要求的 URL 無效: %1 + + + Invalid payment address %1 + 無效的付款位址 %1 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + 沒辦法解析 URI 位址!可能是因為 Bitcoin 位址無效,或是 URI 參數格式錯誤。 + + + Payment request file handling + 處理付款要求檔案 + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + 沒辦法讀取付款要求檔案!可能是無效的檔案造成的。 + + + Payment request rejected + 付款的要求被拒絕了 + + + Payment request network doesn't match client network. + 付款要求的網路類型跟客戶端不符。 + + + Payment request expired. + 付款的要求過期了。 + + + Payment request is not initialized. + 付款的要求沒有完成初始化。 + + + Unverified payment requests to custom payment scripts are unsupported. + 不支援含有自訂付款指令碼,且沒驗證過的付款要求。 + + + Invalid payment request. + 付款的要求無效。 + + + Requested payment amount of %1 is too small (considered dust). + 要求付款的金額 %1 太少(會被網路認為是沒必要的零散錢)。 + + + Refund from %1 + 來自 %1 的退款 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + 付款要求 %1 過大 (%2 位元組, 上限 %3 位元組). + + + Error communicating with %1: %2 + 跟 %1 通訊時發生錯誤: %2 + + + Payment request cannot be parsed! + 沒辦法解析付款要求內容! + + + Bad response from server %1 + 伺服器 %1 的回應有誤 + + + Network request error + 發出要求時發生網路錯誤 + + + Payment acknowledged + 付款已確認 + + + PeerTableModel User Agent @@ -992,6 +1422,25 @@ + QRImageWidget + + &Save Image... + 儲存圖片... + + + &Copy Image + 複製圖片 + + + Save QR Code + 儲存 QR Code + + + PNG Image (*.png) + PNG 圖檔(*.png) + + + RPCConsole N/A @@ -1352,6 +1801,18 @@ Remove 刪掉 + + Copy label + 複製標記 + + + Copy message + 複製訊息 + + + Copy amount + 複製金額 + ReceiveRequestDialog @@ -1371,27 +1832,94 @@ &Save Image... 儲存圖片... - - - SendCoinsDialog - Send Coins - 付款 + Request payment to %1 + 付款給 %1 的要求 - Coin Control Features - 錢幣控制功能 + Payment information + 付款資訊 - Inputs... - 輸入... + URI + URI - automatically selected - 自動選擇 + Address + 位址 - Insufficient funds! + Amount + 金額 + + + Label + 標記: + + + Message + 訊息 + + + Resulting URI too long, try to reduce the text for label / message. + 產生的 URI 過長,請試著縮短標記或訊息的文字內容。 + + + Error encoding URI into QR Code. + 把 URI 編碼成 QR Code 時發生錯誤。 + + + + RecentRequestsTableModel + + Date + 日期 + + + Label + 標記: + + + Message + 訊息 + + + (no label) + (無標記) + + + (no message) + (無訊息) + + + (no amount requested) + (無要求金額) + + + Requested + 要求金額 + + + + SendCoinsDialog + + Send Coins + 付款 + + + Coin Control Features + 錢幣控制功能 + + + Inputs... + 輸入... + + + automatically selected + 自動選擇 + + + Insufficient funds! 累計金額不足! @@ -1522,6 +2050,114 @@ S&end 付款 + + Copy quantity + 複製數目 + + + Copy amount + 複製金額 + + + Copy fee + 複製手續費 + + + Copy after fee + 複製計費後金額 + + + Copy bytes + 複製位元組數 + + + Copy priority + 複製優先度 + + + Copy dust + 複製零散金額 + + + Copy change + 複製找零金額 + + + %1 to %2 + %1 給 %2 + + + Are you sure you want to send? + 你確定要付錢出去嗎? + + + added as transaction fee + 加做交易手續費 + + + Total Amount %1 + 總金額 %1 + + + or + + + + Confirm send coins + 確認付款金額 + + + The recipient address is not valid. Please recheck. + 收款位址無效。請再檢查看看。 + + + The amount to pay must be larger than 0. + 付款金額必須大於零。 + + + The amount exceeds your balance. + 金額超過餘額了。 + + + The total exceeds your balance when the %1 transaction fee is included. + 包含 %1 的交易手續費後,總金額超過你的餘額了。 + + + Duplicate address found: addresses should only be used once each. + 發現有重複的位址: 每個位址只能出現一次。 + + + Transaction creation failed! + 製造交易失敗了! + + + 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. + 交易被拒絕了!有時候會發生這種錯誤,是因為你錢包中的一些錢已經被花掉了。比如說你複製了錢包檔 wallet.dat, 然後用複製的錢包花掉了錢,你現在所用的原來的錢包中,卻沒有那筆錢已經花掉的紀錄。 + + + A fee higher than %1 is considered an absurdly high fee. + 高於 %1 的手續費會被認為是不合理。 + + + Payment request expired. + 付款的要求過期了。 + + + Pay only the required fee of %1 + 只付必要的手續費 %1 + + + Warning: Invalid Bitcoin address + 警告: Bitcoin 位址無效 + + + Warning: Unknown change address + 警告: 不明的找零位址 + + + (no label) + (無標記) + SendCoinsEntry @@ -1601,6 +2237,17 @@ Memo: 備註: + + Enter a label for this address to add it to your address book + 請輸入這個位址的標記來把它加進位址簿中 + + + + SendConfirmationDialog + + Yes + + ShutdownWindow @@ -1699,6 +2346,58 @@ Reset all verify message fields 重設所有訊息驗證欄位 + + Click "Sign Message" to generate signature + 請按一下「簽署訊息」來產生簽章 + + + The entered address is invalid. + 輸入的位址無效。 + + + Please check the address and try again. + 請檢查位址是否正確後再試一次。 + + + The entered address does not refer to a key. + 輸入的位址沒有對應到你的任何密鑰。 + + + Wallet unlock was cancelled. + 錢包解鎖已取消。 + + + Private key for the entered address is not available. + 沒有對應輸入位址的密鑰。 + + + Message signing failed. + 訊息簽署失敗。 + + + Message signed. + 訊息簽署好了。 + + + The signature could not be decoded. + 沒辦法把這個簽章解碼。 + + + Please check the signature and try again. + 請檢查簽章是否正確後再試一次。 + + + The signature did not match the message digest. + 這個簽章跟訊息的數位摘要不符。 + + + Message verification failed. + 訊息驗證失敗。 + + + Message verified. + 訊息驗證沒錯。 + SplashScreen @@ -1715,11 +2414,456 @@ + TransactionDesc + + Open for %n more block(s) + 到下 %n 個區塊生出來前可修改 + + + Open until %1 + 到 %1 前可修改 + + + conflicted with a transaction with %1 confirmations + 跟一個目前確認 %1 次的交易互相衝突 + + + %1/offline + %1 次/離線中 + + + 0/unconfirmed, %1 + 0 次/未確認,%1 + + + in memory pool + 在記憶池中 + + + not in memory pool + 不在記憶池中 + + + abandoned + 已中止 + + + %1/unconfirmed + %1 次/未確認 + + + %1 confirmations + 確認 %1 次 + + + Status + 狀態 + + + , has not been successfully broadcast yet + ,還沒成功公告出去 + + + , broadcast through %n node(s) + ,已公告給 %n 個節點 + + + Date + 日期 + + + Source + 來源 + + + Generated + 生產出來 + + + From + 來源 + + + unknown + 未知 + + + To + 目的 + + + own address + 自己的位址 + + + watch-only + 只能看 + + + label + 標記 + + + Credit + 入帳 + + + matures in %n more block(s) + 再等 %n 個區塊生出來後成熟 + + + not accepted + 不被接受 + + + Debit + 出帳 + + + Total debit + 出帳總額 + + + Total credit + 入帳總額 + + + Transaction fee + 交易手續費 + + + Net amount + 淨額 + + + Message + 訊息 + + + Comment + 附註 + + + Transaction ID + 交易識別碼 + + + Output index + 輸出索引 + + + Merchant + 商家 + + + 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. + 生產出來的錢要再等 %1 個區塊生出來後才成熟可以用。當區塊生產出來時會公布到網路上,來被加進區塊鏈。如果加失敗了,狀態就會變成「不被接受」,而且不能夠花。如果在你生產出區塊的幾秒鐘內,也有其他節點生產出來的話,就有可能會發生這種情形。 + + + Debug information + 除錯資訊 + + + Transaction + 交易 + + + Inputs + 輸入 + + + Amount + 金額 + + + true + + + + false + + + + TransactionDescDialog This pane shows a detailed description of the transaction 這個版面顯示這次交易的詳細說明 + + Details for %1 + 交易 %1 的明細 + + + + TransactionTableModel + + Date + 日期 + + + Type + 種類 + + + Label + 標記: + + + Open for %n more block(s) + 到下 %n 個區塊生出來前可修改 + + + Open until %1 + 到 %1 前可修改 + + + Offline + 離線中 + + + Unconfirmed + 未確認 + + + Abandoned + 已中止 + + + Confirming (%1 of %2 recommended confirmations) + 確認中(已經 %1 次,建議至少 %2 次) + + + Confirmed (%1 confirmations) + 已確認(%1 次) + + + Conflicted + 有衝突 + + + Immature (%1 confirmations, will be available after %2) + 未成熟(確認 %1 次,會在 %2 次後可用) + + + This block was not received by any other nodes and will probably not be accepted! + 沒有其他節點收到這個區塊,也許它不會被接受! + + + Generated but not accepted + 生產出來但是不被接受 + + + Received with + 收款 + + + Received from + 收款自 + + + Sent to + 付款 + + + Payment to yourself + 付給自己 + + + Mined + 開採所得 + + + watch-only + 只能看 + + + (n/a) + (不適用) + + + (no label) + (無標記) + + + Transaction status. Hover over this field to show number of confirmations. + 交易狀態。把游標停在欄位上會顯示確認次數。 + + + Date and time that the transaction was received. + 收到交易的日期和時間。 + + + Type of transaction. + 交易的種類。 + + + Whether or not a watch-only address is involved in this transaction. + 不論如何有一個只能觀看的地只有參與這次的交易 + + + User-defined intent/purpose of the transaction. + 使用者定義的交易動機或理由。 + + + Amount removed from or added to balance. + 要減掉或加進餘額的金額。 + + + + TransactionView + + All + 全部 + + + Today + 今天 + + + This week + 這星期 + + + This month + 這個月 + + + Last month + 上個月 + + + This year + 今年 + + + Range... + 指定範圍... + + + Received with + 收款 + + + Sent to + 付款 + + + To yourself + 給自己 + + + Mined + 開採所得 + + + Other + 其它 + + + Enter address or label to search + 請輸入要搜尋的位址或標記 + + + Min amount + 最小金額 + + + Abandon transaction + 中止交易 + + + Copy address + 複製位址 + + + Copy label + 複製標記 + + + Copy amount + 複製金額 + + + Copy transaction ID + 複製交易識別碼 + + + Copy raw transaction + 複製交易原始資料 + + + Copy full transaction details + 複製完整交易明細 + + + Edit label + 編輯標記 + + + Show transaction details + 顯示交易明細 + + + Export Transaction History + 匯出交易記錄 + + + Comma separated file (*.csv) + 逗點分隔資料檔(*.csv) + + + Confirmed + 已確認 + + + Watch-only + 只能觀看的 + + + Date + 日期 + + + Type + 種類 + + + Label + 標記: + + + Address + 位址 + + + ID + 識別碼 + + + Exporting Failed + 匯出失敗 + + + There was an error trying to save the transaction history to %1. + 儲存交易記錄到 %1 時發生錯誤。 + + + Exporting Successful + 匯出成功 + + + The transaction history was successfully saved to %1. + 交易記錄已經成功儲存到 %1 了。 + + + Range: + 範圍: + + + to + + UnitDisplayStatusBarControl @@ -1729,6 +2873,55 @@ + WalletFrame + + No wallet has been loaded. + 沒有載入錢包。 + + + + WalletModel + + Send Coins + 付款 + + + + WalletView + + &Export + 匯出 + + + Export the data in the current tab to a file + 將目前分頁的資料匯出存成檔案 + + + Backup Wallet + 備份錢包 + + + Wallet Data (*.dat) + 錢包資料檔(*.dat) + + + Backup Failed + 備份失敗 + + + There was an error trying to save the wallet data to %1. + 儲存錢包資料到 %1 時發生錯誤。 + + + Backup Successful + 備份成功 + + + The wallet data was successfully saved to %1. + 錢包的資料已經成功儲存到 %1 了。 + + + bitcoin-core Options: @@ -1832,6 +3025,10 @@ 這套軟體是依據 MIT 軟體授權條款散布,詳情請見附帶的 COPYING 檔案,或是以下網站: <http://www.opensource.org/licenses/mit-license.php>. + Equivalent bytes per sigop in transactions for relay and mining (default: %u) + 轉發和開採時,交易資料中每個 sigop 的等同位元組數(預設值: %u) + + Error loading %s: You can't enable HD on a already existing non-HD wallet 載入 %s 發生錯誤:不能對已存在的非 HD 錢包啟用 HD 功能。 @@ -1844,10 +3041,6 @@ 當錢包有交易改變時要執行的指令(指令中的 %s 會被取代成交易識別碼) - Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d) - 強制轉發從白名點節點收到的交易,即使它們違反了本機的轉發準則(預設值: %d) - - Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds) 跟其他節點的時間差最高可接受的中位數值。本機所認為的時間可能會被其他節點影響,往前或往後在這個值之內。(預設值: %u 秒) @@ -2056,10 +3249,6 @@ 認證 cookie 資料的位置(預設值: 同資料目錄) - Minimum bytes per sigop in transactions we relay and mine (default: %u) - 轉發和開採時,對交易資料的 sigop 平均位元組數下限(預設值: %u) - - Not enough file descriptors available. 檔案描述元不足。 @@ -2093,15 +3282,15 @@ Rewinding blocks... - 倒轉回區塊鏈之前的狀態... + 正在倒轉回區塊鏈之前的狀態... Set database cache size in megabytes (%d to %d, default: %d) 設定資料庫快取大小是多少百萬位元組(MB,範圍: %d 到 %d,預設值: %d) - Set maximum block cost (default: %d) - 設定區塊成本的最大值(預設值: %d) + Set maximum BIP141 block weight (default: %d) + 設定 BIP141 區塊重量的最大值(預設值: %d) Set maximum block size in bytes (default: %d) @@ -2112,6 +3301,10 @@ 指定錢包檔(會在資料目錄中) + Starting network threads... + 正在啟動網路執行緒... + + The source code is available from %s. 原始碼可以在 %s 取得。 @@ -2196,6 +3389,10 @@ 當處理轉發的交易、挖礦、或製造交易時,如果每千位元組(kB)的手續費比這個值(單位是 %s)低,就視為沒付手續費(預設值: %s) + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + 強制轉發從白名點節點收到的交易,即使它們違反了本機的轉發準則(預設值: %d) + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) 當沒有設定 paytxfee 時,自動包含可以讓交易能在平均 n 個區塊內開始確認的手續費(預設值: %u) @@ -2532,10 +3729,6 @@ 設定密鑰池大小為 <n> (預設值: %u) - Set minimum block size in bytes (default: %u) - 設定區塊大小下限為多少位元組(預設值: %u) - - Set the number of threads to service RPC calls (default: %d) 設定處理 RPC 服務請求的執行緒數目(預設值: %d) diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index cc2cbc0e664..5538a28413d 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -16,6 +16,7 @@ #include "main.h" // For DEFAULT_SCRIPTCHECK_THREADS #include "net.h" #include "txdb.h" // for -dbcache defaults +#include "intro.h" #ifdef ENABLE_WALLET #include "wallet/wallet.h" @@ -43,6 +44,8 @@ void OptionsModel::Init(bool resetSettings) if (resetSettings) Reset(); + checkAndMigrate(); + QSettings settings; // Ensure restart flag is unset on client startup @@ -96,6 +99,9 @@ void OptionsModel::Init(bool resetSettings) if (!SoftSetArg("-par", settings.value("nThreadsScriptVerif").toString().toStdString())) addOverriddenOption("-par"); + if (!settings.contains("strDataDir")) + settings.setValue("strDataDir", Intro::getDefaultDataDirectory()); + // Wallet #ifdef ENABLE_WALLET if (!settings.contains("bSpendZeroConfChange")) @@ -148,9 +154,19 @@ void OptionsModel::Reset() { QSettings settings; + // Save the strDataDir setting + QString dataDir = Intro::getDefaultDataDirectory(); + dataDir = settings.value("strDataDir", dataDir).toString(); + // Remove all entries from our QSettings object settings.clear(); + // Set strDataDir + settings.setValue("strDataDir", dataDir); + + // Set that this was reset + settings.setValue("fReset", true); + // default setting for OptionsModel::StartAtStartup - disabled if (GUIUtil::GetStartOnSystemStartup()) GUIUtil::SetStartOnSystemStartup(false); @@ -429,3 +445,22 @@ bool OptionsModel::isRestartRequired() QSettings settings; return settings.value("fRestartRequired", false).toBool(); } + +void OptionsModel::checkAndMigrate() +{ + // Migration of default values + // Check if the QSettings container was already loaded with this client version + QSettings settings; + static const char strSettingsVersionKey[] = "nSettingsVersion"; + int settingsVersion = settings.contains(strSettingsVersionKey) ? settings.value(strSettingsVersionKey).toInt() : 0; + if (settingsVersion < CLIENT_VERSION) + { + // -dbcache was bumped from 100 to 300 in 0.13 + // see https://github.com/bitcoin/bitcoin/pull/8273 + // force people to upgrade to the new value if they are using 100MB + if (settingsVersion < 130000 && settings.contains("nDatabaseCache") && settings.value("nDatabaseCache").toLongLong() == 100) + settings.setValue("nDatabaseCache", (qint64)nDefaultDbCache); + + settings.setValue(strSettingsVersionKey, CLIENT_VERSION); + } +} \ No newline at end of file diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index 3b491ceac2c..b23b5f2607a 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -84,9 +84,11 @@ class OptionsModel : public QAbstractListModel /* settings that were overriden by command-line */ QString strOverriddenByCommandLine; - /// Add option to list of GUI options overridden through command line/config file + // Add option to list of GUI options overridden through command line/config file void addOverriddenOption(const std::string &option); + // Check settings version and upgrade default values if required + void checkAndMigrate(); Q_SIGNALS: void displayUnitChanged(int unit); void coinControlFeaturesChanged(bool); diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 6a0404cbf70..a010f010210 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -25,8 +25,8 @@ class TxViewDelegate : public QAbstractItemDelegate { Q_OBJECT public: - TxViewDelegate(const PlatformStyle *platformStyle): - QAbstractItemDelegate(), unit(BitcoinUnits::BTC), + TxViewDelegate(const PlatformStyle *platformStyle, QObject *parent=nullptr): + QAbstractItemDelegate(parent), unit(BitcoinUnits::BTC), platformStyle(platformStyle) { @@ -119,8 +119,7 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) currentWatchOnlyBalance(-1), currentWatchUnconfBalance(-1), currentWatchImmatureBalance(-1), - txdelegate(new TxViewDelegate(platformStyle)), - filter(0) + txdelegate(new TxViewDelegate(platformStyle, this)) { ui->setupUi(this); @@ -213,7 +212,7 @@ void OverviewPage::setWalletModel(WalletModel *model) if(model && model->getOptionsModel()) { // Set up transaction list - filter = new TransactionFilterProxy(); + filter.reset(new TransactionFilterProxy()); filter->setSourceModel(model->getTransactionTableModel()); filter->setLimit(NUM_ITEMS); filter->setDynamicSortFilter(true); @@ -221,7 +220,7 @@ void OverviewPage::setWalletModel(WalletModel *model) filter->setShowInactive(false); filter->sort(TransactionTableModel::Date, Qt::DescendingOrder); - ui->listTransactions->setModel(filter); + ui->listTransactions->setModel(filter.get()); ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress); // Keep up to date with wallet diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index 911443c76af..23746a6b48a 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -8,6 +8,7 @@ #include "amount.h" #include +#include class ClientModel; class TransactionFilterProxy; @@ -55,7 +56,7 @@ public Q_SLOTS: CAmount currentWatchImmatureBalance; TxViewDelegate *txdelegate; - TransactionFilterProxy *filter; + std::unique_ptr filter; private Q_SLOTS: void updateDisplayUnit(); diff --git a/src/qt/paymentrequest.proto b/src/qt/paymentrequest.proto index b2281c4c7b3..d2721a34bde 100644 --- a/src/qt/paymentrequest.proto +++ b/src/qt/paymentrequest.proto @@ -6,6 +6,8 @@ // https://en.bitcoin.it/wiki/Payment_Request // +syntax = "proto2"; + package payments; option java_package = "org.bitcoin.protocols.payments"; option java_outer_classname = "Protos"; diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index 20e1f79ffa2..82be4d831f6 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -159,14 +159,24 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c std::string data_to_verify; // Everything but the signature rcopy.SerializeToString(&data_to_verify); - EVP_MD_CTX ctx; +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + EVP_MD_CTX *ctx = EVP_MD_CTX_new(); + if (!ctx) throw SSLVerifyError("Error allocating OpenSSL context."); +#else + EVP_MD_CTX _ctx; + EVP_MD_CTX *ctx; + ctx = &_ctx; +#endif EVP_PKEY *pubkey = X509_get_pubkey(signing_cert); - EVP_MD_CTX_init(&ctx); - if (!EVP_VerifyInit_ex(&ctx, digestAlgorithm, NULL) || - !EVP_VerifyUpdate(&ctx, data_to_verify.data(), data_to_verify.size()) || - !EVP_VerifyFinal(&ctx, (const unsigned char*)paymentRequest.signature().data(), (unsigned int)paymentRequest.signature().size(), pubkey)) { + EVP_MD_CTX_init(ctx); + if (!EVP_VerifyInit_ex(ctx, digestAlgorithm, NULL) || + !EVP_VerifyUpdate(ctx, data_to_verify.data(), data_to_verify.size()) || + !EVP_VerifyFinal(ctx, (const unsigned char*)paymentRequest.signature().data(), (unsigned int)paymentRequest.signature().size(), pubkey)) { throw SSLVerifyError("Bad signature, invalid payment request."); } +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + EVP_MD_CTX_free(ctx); +#endif // OpenSSL API for getting human printable strings from certs is baroque. int textlen = X509_NAME_get_text_by_NID(certname, NID_commonName, NULL, 0); diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index c80aebb0098..1ef224b521a 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -58,14 +58,19 @@ const char* BIP71_MIMETYPE_PAYMENTREQUEST = "application/bitcoin-paymentrequest" // BIP70 max payment request size in bytes (DoS protection) const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE = 50000; -X509_STORE* PaymentServer::certStore = NULL; -void PaymentServer::freeCertStore() +struct X509StoreDeleter { + void operator()(X509_STORE* b) { + X509_STORE_free(b); + } +}; + +struct X509Deleter { + void operator()(X509* b) { X509_free(b); } +}; + +namespace // Anon namespace { - if (PaymentServer::certStore != NULL) - { - X509_STORE_free(PaymentServer::certStore); - PaymentServer::certStore = NULL; - } + std::unique_ptr certStore; } // @@ -80,7 +85,7 @@ static QString ipcServerName() // Append a simple hash of the datadir // Note that GetDataDir(true) returns a different path // for -testnet versus main net - QString ddir(QString::fromStdString(GetDataDir(true).string())); + QString ddir(GUIUtil::boostPathToQString(GetDataDir(true))); name.append(QString::number(qHash(ddir))); return name; @@ -107,20 +112,15 @@ static void ReportInvalidCertificate(const QSslCertificate& cert) // void PaymentServer::LoadRootCAs(X509_STORE* _store) { - if (PaymentServer::certStore == NULL) - atexit(PaymentServer::freeCertStore); - else - freeCertStore(); - // Unit tests mostly use this, to pass in fake root CAs: if (_store) { - PaymentServer::certStore = _store; + certStore.reset(_store); return; } // Normal execution, use either -rootcertificates or system certs: - PaymentServer::certStore = X509_STORE_new(); + certStore.reset(X509_STORE_new()); // Note: use "-system-" default here so that users can pass -rootcertificates="" // and get 'I don't like X.509 certificates, don't trust anybody' behavior: @@ -167,11 +167,11 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store) QByteArray certData = cert.toDer(); const unsigned char *data = (const unsigned char *)certData.data(); - X509* x509 = d2i_X509(0, &data, certData.size()); - if (x509 && X509_STORE_add_cert(PaymentServer::certStore, x509)) + std::unique_ptr x509(d2i_X509(0, &data, certData.size())); + if (x509 && X509_STORE_add_cert(certStore.get(), x509.get())) { - // Note: X509_STORE_free will free the X509* objects when - // the PaymentServer is destroyed + // Note: X509_STORE increases the reference count to the X509 object, + // we still have to release our reference to it. ++nRootCerts; } else @@ -550,7 +550,7 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen recipient.paymentRequest = request; recipient.message = GUIUtil::HtmlEscape(request.getDetails().memo()); - request.getMerchant(PaymentServer::certStore, recipient.authenticatedMerchant); + request.getMerchant(certStore.get(), recipient.authenticatedMerchant); QList > sendingTos = request.getPayTo(); QStringList addresses; @@ -807,3 +807,8 @@ bool PaymentServer::verifyAmount(const CAmount& requestAmount) } return fVerified; } + +X509_STORE* PaymentServer::getCertStore() +{ + return certStore.get(); +} diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index 2d27ed078b5..7202e7dada7 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -83,7 +83,7 @@ class PaymentServer : public QObject static void LoadRootCAs(X509_STORE* store = NULL); // Return certificate store - static X509_STORE* getCertStore() { return certStore; } + static X509_STORE* getCertStore(); // OptionsModel is used for getting proxy settings and display unit void setOptionsModel(OptionsModel *optionsModel); @@ -140,9 +140,6 @@ private Q_SLOTS: bool saveURIs; // true during startup QLocalServer* uriServer; - static X509_STORE* certStore; // Trusted root certificates - static void freeCertStore(); - QNetworkAccessManager* netManager; // Used to fetch payment requests OptionsModel *optionsModel; diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index 84ad0052fdd..3829696e0e6 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -115,12 +115,12 @@ PeerTableModel::PeerTableModel(ClientModel *parent) : timer(0) { columns << tr("Node/Service") << tr("User Agent") << tr("Ping Time"); - priv = new PeerTablePriv(); + priv.reset(new PeerTablePriv()); // default to unsorted priv->sortColumn = -1; // set up timer for auto refresh - timer = new QTimer(); + timer = new QTimer(this); connect(timer, SIGNAL(timeout()), SLOT(refresh())); timer->setInterval(MODEL_UPDATE_DELAY); @@ -128,6 +128,11 @@ PeerTableModel::PeerTableModel(ClientModel *parent) : refresh(); } +PeerTableModel::~PeerTableModel() +{ + // Intentionally left empty +} + void PeerTableModel::startAutoRefresh() { timer->start(); diff --git a/src/qt/peertablemodel.h b/src/qt/peertablemodel.h index a2aaaa5d24b..8227b5ec762 100644 --- a/src/qt/peertablemodel.h +++ b/src/qt/peertablemodel.h @@ -46,6 +46,7 @@ class PeerTableModel : public QAbstractTableModel public: explicit PeerTableModel(ClientModel *parent = 0); + ~PeerTableModel(); const CNodeCombinedStats *getNodeStats(int idx); int getRowByNodeId(NodeId nodeid); void startAutoRefresh(); @@ -74,7 +75,7 @@ public Q_SLOTS: private: ClientModel *clientModel; QStringList columns; - PeerTablePriv *priv; + std::unique_ptr priv; QTimer *timer; }; diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index 0b355837ab3..752a05a4096 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -25,6 +25,7 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent) : QDialog(parent), ui(new Ui::ReceiveCoinsDialog), + columnResizingFixer(0), model(0), platformStyle(platformStyle) { @@ -48,7 +49,7 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *platformStyle, QWidg QAction *copyAmountAction = new QAction(tr("Copy amount"), this); // context menu - contextMenu = new QMenu(); + contextMenu = new QMenu(this); contextMenu->addAction(copyLabelAction); contextMenu->addAction(copyMessageAction); contextMenu->addAction(copyAmountAction); @@ -88,7 +89,7 @@ void ReceiveCoinsDialog::setModel(WalletModel *model) SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(recentRequestsView_selectionChanged(QItemSelection, QItemSelection))); // Last 2 columns are set by the columnResizingFixer, when the table geometry is ready. - columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH); + columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH, this); } } diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index b13ea3df709..04cc2003c55 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -32,7 +32,7 @@ QRImageWidget::QRImageWidget(QWidget *parent): QLabel(parent), contextMenu(0) { - contextMenu = new QMenu(); + contextMenu = new QMenu(this); QAction *saveImageAction = new QAction(tr("&Save Image..."), this); connect(saveImageAction, SIGNAL(triggered()), this, SLOT(saveImage())); contextMenu->addAction(saveImageAction); diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp index 2335d6b282a..35d37bb22bb 100644 --- a/src/qt/recentrequeststablemodel.cpp +++ b/src/qt/recentrequeststablemodel.cpp @@ -14,7 +14,7 @@ #include RecentRequestsTableModel::RecentRequestsTableModel(CWallet *wallet, WalletModel *parent) : - walletModel(parent) + QAbstractTableModel(parent), walletModel(parent) { Q_UNUSED(wallet); nReceiveRequestsMaxId = 0; diff --git a/src/qt/res/movies/makespinner.sh b/src/qt/res/movies/makespinner.sh index a4c2fddbbfe..d0deb1238c2 100755 --- a/src/qt/res/movies/makespinner.sh +++ b/src/qt/res/movies/makespinner.sh @@ -1,3 +1,7 @@ +# 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. + FRAMEDIR=$(dirname $0) for i in {0..35} do diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 650ff8b00db..167a3474c15 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -288,7 +288,6 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : // based timer interface RPCSetTimerInterfaceIfUnset(rpcTimerInterface); - startExecutor(); setTrafficGraphRange(INITIAL_TRAFFIC_GRAPH_MINS); ui->detailWidget->hide(); @@ -302,7 +301,6 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : RPCConsole::~RPCConsole() { GUIUtil::saveWindowGeometry("nRPCConsoleWindow", this); - Q_EMIT stopExecutor(); RPCUnsetTimerInterface(rpcTimerInterface); delete rpcTimerInterface; delete ui; @@ -389,7 +387,7 @@ void RPCConsole::setClientModel(ClientModel *model) QAction* banAction365d = new QAction(tr("Ban Node for") + " " + tr("1 &year"), this); // create peer table context menu - peersTableContextMenu = new QMenu(); + peersTableContextMenu = new QMenu(this); peersTableContextMenu->addAction(disconnectAction); peersTableContextMenu->addAction(banAction1h); peersTableContextMenu->addAction(banAction24h); @@ -435,7 +433,7 @@ void RPCConsole::setClientModel(ClientModel *model) QAction* unbanAction = new QAction(tr("&Unban Node"), this); // create ban table context menu - banTableContextMenu = new QMenu(); + banTableContextMenu = new QMenu(this); banTableContextMenu->addAction(unbanAction); // ban table context menu signals @@ -466,6 +464,14 @@ void RPCConsole::setClientModel(ClientModel *model) autoCompleter = new QCompleter(wordList, this); ui->lineEdit->setCompleter(autoCompleter); autoCompleter->popup()->installEventFilter(this); + // Start thread to execute RPC commands. + startExecutor(); + } + if (!model) { + // Client model is being set to 0, this means shutdown() is about to be called. + // Make sure we clean up the executor thread + Q_EMIT stopExecutor(); + thread.wait(); } } @@ -646,9 +652,8 @@ void RPCConsole::browseHistory(int offset) void RPCConsole::startExecutor() { - QThread *thread = new QThread; RPCExecutor *executor = new RPCExecutor(); - executor->moveToThread(thread); + executor->moveToThread(&thread); // Replies from executor object must go to this object connect(executor, SIGNAL(reply(int,QString)), this, SLOT(message(int,QString))); @@ -656,16 +661,15 @@ void RPCConsole::startExecutor() connect(this, SIGNAL(cmdRequest(QString)), executor, SLOT(request(QString))); // On stopExecutor signal - // - queue executor for deletion (in execution thread) // - quit the Qt event loop in the execution thread - connect(this, SIGNAL(stopExecutor()), executor, SLOT(deleteLater())); - connect(this, SIGNAL(stopExecutor()), thread, SLOT(quit())); - // Queue the thread for deletion (in this thread) when it is finished - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + connect(this, SIGNAL(stopExecutor()), &thread, SLOT(quit())); + // - queue executor for deletion (in execution thread) + connect(&thread, SIGNAL(finished()), executor, SLOT(deleteLater()), Qt::DirectConnection); + connect(&thread, SIGNAL(finished()), this, SLOT(test()), Qt::DirectConnection); // Default implementation of QThread::run() simply spins up an event loop in the thread, // which is what we want. - thread->start(); + thread.start(); } void RPCConsole::on_tabWidget_currentChanged(int index) diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 28affa954dc..c1efa95f8c3 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -12,6 +12,7 @@ #include #include +#include class ClientModel; class PlatformStyle; @@ -140,6 +141,7 @@ public Q_SLOTS: QMenu *banTableContextMenu; int consoleFontSize; QCompleter *autoCompleter; + QThread thread; }; #endif // BITCOIN_QT_RPCCONSOLE_H diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 6d50be56ecb..546003622c0 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -592,6 +592,9 @@ void SendCoinsDialog::updateGlobalFeeVariables() { nTxConfirmTarget = defaultConfirmTarget - ui->sliderSmartFee->value(); payTxFee = CFeeRate(0); + + // set nMinimumTotalFee to 0 to not accidentally pay a custom fee + CoinControlDialog::coinControl->nMinimumTotalFee = 0; } else { @@ -790,7 +793,7 @@ void SendCoinsDialog::coinControlUpdateLabels() ui->radioCustomAtLeast->setVisible(true); // only enable the feature if inputs are selected - ui->radioCustomAtLeast->setEnabled(CoinControlDialog::coinControl->HasSelected()); + ui->radioCustomAtLeast->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked() &&CoinControlDialog::coinControl->HasSelected()); } else { diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index e36d86fddda..68e9ffeb949 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -147,6 +147,7 @@ void SplashScreen::slotFinish(QWidget *mainWin) if (isMinimized()) showNormal(); hide(); + deleteLater(); // No more need for this } static void InitMessage(SplashScreen *splash, const std::string &message) diff --git a/src/qt/test/compattests.cpp b/src/qt/test/compattests.cpp new file mode 100644 index 00000000000..2a7284b5b22 --- /dev/null +++ b/src/qt/test/compattests.cpp @@ -0,0 +1,23 @@ +// Copyright (c) 2016 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 "paymentrequestplus.h" // this includes protobuf's port.h which defines its own bswap macos + +#include "compattests.h" + +#include "compat/byteswap.h" + +void CompatTests::bswapTests() +{ + // Sibling in bitcoin/src/test/bswap_tests.cpp + uint16_t u1 = 0x1234; + uint32_t u2 = 0x56789abc; + uint64_t u3 = 0xdef0123456789abc; + uint16_t e1 = 0x3412; + uint32_t e2 = 0xbc9a7856; + uint64_t e3 = 0xbc9a78563412f0de; + QVERIFY(bswap_16(u1) == e1); + QVERIFY(bswap_32(u2) == e2); + QVERIFY(bswap_64(u3) == e3); +} diff --git a/src/qt/test/compattests.h b/src/qt/test/compattests.h new file mode 100644 index 00000000000..35dede77434 --- /dev/null +++ b/src/qt/test/compattests.h @@ -0,0 +1,19 @@ +// Copyright (c) 2009-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_TEST_COMPATTESTS_H +#define BITCOIN_QT_TEST_COMPATTESTS_H + +#include +#include + +class CompatTests : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void bswapTests(); +}; + +#endif // BITCOIN_QT_TEST_COMPATTESTS_H diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index db193420bfb..02650320bda 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -8,6 +8,7 @@ #include "util.h" #include "uritests.h" +#include "compattests.h" #ifdef ENABLE_WALLET #include "paymentservertests.h" @@ -48,6 +49,9 @@ int main(int argc, char *argv[]) if (QTest::qExec(&test2) != 0) fInvalid = true; #endif + CompatTests test4; + if (QTest::qExec(&test4) != 0) + fInvalid = true; return fInvalid; } diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 48cf9405029..79af4a1f9cd 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -37,7 +37,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *parent) : QWidget(parent), model(0), transactionProxyModel(0), - transactionView(0), abandonAction(0) + transactionView(0), abandonAction(0), columnResizingFixer(0) { // Build filter row setContentsMargins(0,0,0,0); @@ -147,7 +147,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa QAction *editLabelAction = new QAction(tr("Edit label"), this); QAction *showDetailsAction = new QAction(tr("Show transaction details"), this); - contextMenu = new QMenu(); + contextMenu = new QMenu(this); contextMenu->addAction(copyAddressAction); contextMenu->addAction(copyLabelAction); contextMenu->addAction(copyAmountAction); @@ -212,7 +212,7 @@ void TransactionView::setModel(WalletModel *model) transactionView->setColumnWidth(TransactionTableModel::Type, TYPE_COLUMN_WIDTH); transactionView->setColumnWidth(TransactionTableModel::Amount, AMOUNT_MINIMUM_COLUMN_WIDTH); - columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(transactionView, AMOUNT_MINIMUM_COLUMN_WIDTH, MINIMUM_COLUMN_WIDTH); + columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(transactionView, AMOUNT_MINIMUM_COLUMN_WIDTH, MINIMUM_COLUMN_WIDTH, this); if (model->getOptionsModel()) { diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 947bcdb15ae..4ec022881c1 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -171,22 +171,20 @@ ShutdownWindow::ShutdownWindow(QWidget *parent, Qt::WindowFlags f): setLayout(layout); } -void ShutdownWindow::showShutdownWindow(BitcoinGUI *window) +QWidget *ShutdownWindow::showShutdownWindow(BitcoinGUI *window) { if (!window) - return; + return nullptr; // Show a simple window indicating shutdown status QWidget *shutdownWindow = new ShutdownWindow(); - // We don't hold a direct pointer to the shutdown window after creation, so use - // Qt::WA_DeleteOnClose to make sure that the window will be deleted eventually. - shutdownWindow->setAttribute(Qt::WA_DeleteOnClose); shutdownWindow->setWindowTitle(window->windowTitle()); // Center shutdown window at where main window was const QPoint global = window->mapToGlobal(window->rect().center()); shutdownWindow->move(global.x() - shutdownWindow->width() / 2, global.y() - shutdownWindow->height() / 2); shutdownWindow->show(); + return shutdownWindow; } void ShutdownWindow::closeEvent(QCloseEvent *event) diff --git a/src/qt/utilitydialog.h b/src/qt/utilitydialog.h index 843bd7f67bc..b930429578c 100644 --- a/src/qt/utilitydialog.h +++ b/src/qt/utilitydialog.h @@ -43,7 +43,7 @@ class ShutdownWindow : public QWidget public: ShutdownWindow(QWidget *parent=0, Qt::WindowFlags f=0); - static void showShutdownWindow(BitcoinGUI *window); + static QWidget *showShutdownWindow(BitcoinGUI *window); protected: void closeEvent(QCloseEvent *event); diff --git a/src/rest.cpp b/src/rest.cpp index 2dff8d7dadd..57cd9baeb7a 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -228,7 +228,7 @@ static bool rest_block(HTTPRequest* req, return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); } - CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); ssBlock << block; switch (rf) { @@ -367,7 +367,7 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); - CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); ssTx << tx; switch (rf) { diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 20eefa1c574..b4d53a9f3d9 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -101,7 +101,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx result.push_back(Pair("confirmations", confirmations)); result.push_back(Pair("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS))); result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); - result.push_back(Pair("cost", (int)::GetBlockCost(block))); + result.push_back(Pair("weight", (int)::GetBlockWeight(block))); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", block.nVersion)); result.push_back(Pair("versionHex", strprintf("%08x", block.nVersion))); @@ -559,7 +559,7 @@ UniValue getblock(const UniValue& params, bool fHelp) " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n" " \"size\" : n, (numeric) The block size\n" " \"strippedsize\" : n, (numeric) The block size excluding witness data\n" - " \"cost\" : n (numeric) The block cost\n" + " \"weight\" : n (numeric) The block weight (BIP 141)\n" " \"height\" : n, (numeric) The block height or index\n" " \"version\" : n, (numeric) The block version\n" " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n" @@ -607,7 +607,7 @@ UniValue getblock(const UniValue& params, bool fHelp) if (!fVerbose) { - CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); ssBlock << block; std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); return strHex; @@ -704,6 +704,8 @@ UniValue gettxoutsetinfo(const UniValue& params, bool fHelp) ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize)); ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex())); ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount))); + } else { + throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set"); } return ret; } @@ -717,7 +719,7 @@ UniValue gettxout(const UniValue& params, bool fHelp) "\nArguments:\n" "1. \"txid\" (string, required) The transaction id\n" "2. n (numeric, required) vout number\n" - "3. includemempool (boolean, optional) Whether to include the mem pool\n" + "3. includemempool (boolean, optional) Whether to include the mempool\n" "\nResult:\n" "{\n" " \"bestblock\" : \"hash\", (string) the block hash\n" @@ -892,7 +894,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n" " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n" " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n" - " \"pruneheight\": xxxxxx, (numeric) heighest block available\n" + " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored\n" " \"softforks\": [ (array) status of softforks in progress\n" " {\n" " \"id\": \"xxxx\", (string) name of softfork\n" diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 4c4e5997818..30c495f2971 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -131,7 +131,7 @@ UniValue generateBlocks(boost::shared_ptr coinbaseScript, int nG continue; } CValidationState state; - if (!ProcessNewBlock(state, Params(), NULL, pblock, true, NULL)) + if (!ProcessNewBlock(state, Params(), NULL, pblock, true, NULL, false)) throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted"); ++nHeight; blockHashes.push_back(pblock->GetHash().GetHex()); @@ -224,13 +224,14 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) "{\n" " \"blocks\": nnn, (numeric) The current block\n" " \"currentblocksize\": nnn, (numeric) The last block size\n" - " \"currentblockcost\": nnn, (numeric) The last block cost\n" + " \"currentblockweight\": nnn, (numeric) The last block weight\n" " \"currentblocktx\": nnn, (numeric) The last block transaction\n" " \"difficulty\": xxx.xxxxx (numeric) The current difficulty\n" - " \"errors\": \"...\" (string) Current errors\n" - " \"pooledtx\": n (numeric) The size of the mem pool\n" + " \"errors\": \"...\" (string) Current errors\n" + " \"networkhashps\": nnn, (numeric) The network hashes per second\n" + " \"pooledtx\": n (numeric) The size of the mempool\n" " \"testnet\": true|false (boolean) If using testnet or not\n" - " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" + " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" "}\n" "\nExamples:\n" + HelpExampleCli("getmininginfo", "") @@ -243,7 +244,7 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) UniValue obj(UniValue::VOBJ); obj.push_back(Pair("blocks", (int)chainActive.Height())); obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize)); - obj.push_back(Pair("currentblockcost", (uint64_t)nLastBlockCost)); + obj.push_back(Pair("currentblockweight", (uint64_t)nLastBlockWeight)); obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx)); obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("errors", GetWarnings("statusbar"))); @@ -319,67 +320,73 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 1) throw runtime_error( - "getblocktemplate ( \"jsonrequestobject\" )\n" + "getblocktemplate ( TemplateRequest )\n" "\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n" "It returns data needed to construct a block to work on.\n" - "For full specification, see BIPs 22 and 9:\n" + "For full specification, see BIPs 22, 23, 9, and 145:\n" " https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki\n" + " https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki\n" " https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki#getblocktemplate_changes\n" + " https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki\n" "\nArguments:\n" - "1. \"jsonrequestobject\" (string, optional) A json object in the following spec\n" + "1. TemplateRequest (json object, optional) A json object in the following spec\n" " {\n" - " \"mode\":\"template\" (string, optional) This must be set to \"template\" or omitted\n" - " \"capabilities\":[ (array, optional) A list of strings\n" - " \"support\" (string) client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid'\n" + " \"mode\":\"template\" (string, optional) This must be set to \"template\", \"proposal\" (see BIP 23), or omitted\n" + " \"capabilities\":[ (array, optional) A list of strings\n" + " \"support\" (string) client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid'\n" " ,...\n" - " ]\n" + " ],\n" + " \"rules\":[ (array, optional) A list of strings\n" + " \"support\" (string) client side supported softfork deployment\n" + " ,...\n" + " ]\n" " }\n" "\n" "\nResult:\n" "{\n" - " \"version\" : n, (numeric) The block version\n" + " \"version\" : n, (numeric) The preferred block version\n" " \"rules\" : [ \"rulename\", ... ], (array of strings) specific block rules that are to be enforced\n" " \"vbavailable\" : { (json object) set of pending, supported versionbit (BIP 9) softfork deployments\n" - " \"rulename\" : bitnumber (numeric) identifies the bit number as indicating acceptance and readiness for the named softfork rule\n" + " \"rulename\" : bitnumber (numeric) identifies the bit number as indicating acceptance and readiness for the named softfork rule\n" " ,...\n" " },\n" " \"vbrequired\" : n, (numeric) bit mask of versionbits the server requires set in submissions\n" - " \"previousblockhash\" : \"xxxx\", (string) The hash of current highest block\n" + " \"previousblockhash\" : \"xxxx\", (string) The hash of current highest block\n" " \"transactions\" : [ (array) contents of non-coinbase transactions that should be included in the next block\n" " {\n" - " \"data\" : \"xxxx\", (string) transaction data encoded in hexadecimal (byte-for-byte)\n" - " \"txid\" : \"xxxx\", (string) transaction id encoded in little-endian hexadecimal\n" - " \"hash\" : \"xxxx\", (string) hash encoded in little-endian hexadecimal (including witness data)\n" - " \"depends\" : [ (array) array of numbers \n" - " n (numeric) transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is\n" + " \"data\" : \"xxxx\", (string) transaction data encoded in hexadecimal (byte-for-byte)\n" + " \"txid\" : \"xxxx\", (string) transaction id encoded in little-endian hexadecimal\n" + " \"hash\" : \"xxxx\", (string) hash encoded in little-endian hexadecimal (including witness data)\n" + " \"depends\" : [ (array) array of numbers \n" + " n (numeric) transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is\n" " ,...\n" " ],\n" - " \"fee\": n, (numeric) difference in value between transaction inputs and outputs (in Satoshis); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one\n" - " \"sigops\" : n, (numeric) total SigOps cost, as counted for purposes of block limits; if key is not present, sigop cost is unknown and clients MUST NOT assume it is zero\n" - " \"cost\" : n, (numeric) total transaction size cost, as counted for purposes of block limits\n" - " \"required\" : true|false (boolean) if provided and true, this transaction must be in the final block\n" + " \"fee\": n, (numeric) difference in value between transaction inputs and outputs (in Satoshis); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one\n" + " \"sigops\" : n, (numeric) total SigOps cost, as counted for purposes of block limits; if key is not present, sigop cost is unknown and clients MUST NOT assume it is zero\n" + " \"weight\" : n, (numeric) total transaction weight, as counted for purposes of block limits\n" + " \"required\" : true|false (boolean) if provided and true, this transaction must be in the final block\n" " }\n" " ,...\n" " ],\n" - " \"coinbaseaux\" : { (json object) data that should be included in the coinbase's scriptSig content\n" - " \"flags\" : \"flags\" (string) \n" + " \"coinbaseaux\" : { (json object) data that should be included in the coinbase's scriptSig content\n" + " \"flags\" : \"xx\" (string) key name is to be ignored, and value included in scriptSig\n" " },\n" - " \"coinbasevalue\" : n, (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in Satoshis)\n" - " \"coinbasetxn\" : { ... }, (json object) information for coinbase transaction\n" - " \"target\" : \"xxxx\", (string) The hash target\n" - " \"mintime\" : xxx, (numeric) The minimum timestamp appropriate for next block time in seconds since epoch (Jan 1 1970 GMT)\n" - " \"mutable\" : [ (array of string) list of ways the block template may be changed \n" - " \"value\" (string) A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'\n" + " \"coinbasevalue\" : n, (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in Satoshis)\n" + " \"coinbasetxn\" : { ... }, (json object) information for coinbase transaction\n" + " \"target\" : \"xxxx\", (string) The hash target\n" + " \"mintime\" : xxx, (numeric) The minimum timestamp appropriate for next block time in seconds since epoch (Jan 1 1970 GMT)\n" + " \"mutable\" : [ (array of string) list of ways the block template may be changed \n" + " \"value\" (string) A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'\n" " ,...\n" " ],\n" - " \"noncerange\" : \"00000000ffffffff\", (string) A range of valid nonces\n" - " \"sigoplimit\" : n, (numeric) cost limit of sigops in blocks\n" + " \"noncerange\" : \"00000000ffffffff\",(string) A range of valid nonces\n" + " \"sigoplimit\" : n, (numeric) limit of sigops in blocks\n" " \"sizelimit\" : n, (numeric) limit of block size\n" - " \"costlimit\" : n, (numeric) limit of block cost\n" + " \"weightlimit\" : n, (numeric) limit of block weight\n" " \"curtime\" : ttt, (numeric) current timestamp in seconds since epoch (Jan 1 1970 GMT)\n" - " \"bits\" : \"xxx\", (string) compressed target of next block\n" + " \"bits\" : \"xxxxxxxx\", (string) compressed target of next block\n" " \"height\" : n (numeric) The height of the next block\n" "}\n" @@ -546,6 +553,9 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) UpdateTime(pblock, consensusParams, pindexPrev); pblock->nNonce = 0; + // NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration + const bool fPreSegWit = (THRESHOLD_ACTIVE != VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT, versionbitscache)); + UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal"); UniValue transactions(UniValue::VARR); @@ -574,8 +584,13 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) int index_in_template = i - 1; entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template])); - entry.push_back(Pair("sigops", pblocktemplate->vTxSigOpsCost[index_in_template])); - entry.push_back(Pair("cost", GetTransactionCost(tx))); + int64_t nTxSigOps = pblocktemplate->vTxSigOpsCost[index_in_template]; + if (fPreSegWit) { + assert(nTxSigOps % WITNESS_SCALE_FACTOR == 0); + nTxSigOps /= WITNESS_SCALE_FACTOR; + } + entry.push_back(Pair("sigops", nTxSigOps)); + entry.push_back(Pair("weight", GetTransactionWeight(tx))); transactions.push_back(entry); } @@ -642,7 +657,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) if (nMaxVersionPreVB >= 2) { // If VB is supported by the client, nMaxVersionPreVB is -1, so we won't get here - // Because BIP 34 changed how the generation transaction is serialised, we can only use version/force back to v2 blocks + // Because BIP 34 changed how the generation transaction is serialized, we can only use version/force back to v2 blocks // This is safe to do [otherwise-]unconditionally only because we are throwing an exception above if a non-force deployment gets activated // Note that this can probably also be removed entirely after the first BIP9 non-force deployment (ie, probably segwit) gets activated aMutable.push_back("version/force"); @@ -657,13 +672,20 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1)); result.push_back(Pair("mutable", aMutable)); result.push_back(Pair("noncerange", "00000000ffffffff")); - result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS_COST)); + int64_t nSigOpLimit = MAX_BLOCK_SIGOPS_COST; + if (fPreSegWit) { + assert(nSigOpLimit % WITNESS_SCALE_FACTOR == 0); + nSigOpLimit /= WITNESS_SCALE_FACTOR; + } + result.push_back(Pair("sigoplimit", nSigOpLimit)); result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SERIALIZED_SIZE)); - result.push_back(Pair("costlimit", (int64_t)MAX_BLOCK_COST)); + result.push_back(Pair("weightlimit", (int64_t)MAX_BLOCK_WEIGHT)); result.push_back(Pair("curtime", pblock->GetBlockTime())); result.push_back(Pair("bits", strprintf("%08x", pblock->nBits))); result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1))); - if (!pblocktemplate->vchCoinbaseCommitment.empty()) { + + const struct BIP9DeploymentInfo& segwit_info = VersionBitsDeploymentInfo[Consensus::DEPLOYMENT_SEGWIT]; + if (!pblocktemplate->vchCoinbaseCommitment.empty() && setClientRules.find(segwit_info.name) != setClientRules.end()) { result.push_back(Pair("default_witness_commitment", HexStr(pblocktemplate->vchCoinbaseCommitment.begin(), pblocktemplate->vchCoinbaseCommitment.end()))); } @@ -740,7 +762,7 @@ UniValue submitblock(const UniValue& params, bool fHelp) CValidationState state; submitblock_StateCatcher sc(block.GetHash()); RegisterValidationInterface(&sc); - bool fAccepted = ProcessNewBlock(state, Params(), NULL, &block, true, NULL); + bool fAccepted = ProcessNewBlock(state, Params(), NULL, &block, true, NULL, false); UnregisterValidationInterface(&sc); if (fBlockPresent) { @@ -771,6 +793,8 @@ UniValue estimatefee(const UniValue& params, bool fHelp) "\n" "A negative value is returned if not enough transactions and blocks\n" "have been observed to make an estimate.\n" + "-1 is always returned for nblocks == 1 as it is impossible to calculate\n" + "a fee that is high enough to get reliably included in the next block.\n" "\nExample:\n" + HelpExampleCli("estimatefee", "6") ); diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index a8c5bcd177f..11befb529f7 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -57,7 +57,7 @@ UniValue getinfo(const UniValue& params, bool fHelp) " \"proxy\": \"host:port\", (string, optional) the proxy used by the server\n" " \"difficulty\": xxxxxx, (numeric) the current difficulty\n" " \"testnet\": true|false, (boolean) if the server is using testnet or not\n" - " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n" + " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since Unix 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 " + CURRENCY_UNIT + "/kB\n" @@ -320,43 +320,6 @@ UniValue createmultisig(const UniValue& params, bool fHelp) return result; } -UniValue createwitnessaddress(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() < 1 || params.size() > 1) - { - string msg = "createwitnessaddress \"script\"\n" - "\nCreates a witness address for a particular script.\n" - "It returns a json object with the address and witness script.\n" - - "\nArguments:\n" - "1. \"script\" (string, required) A hex encoded script\n" - - "\nResult:\n" - "{\n" - " \"address\":\"multisigaddress\", (string) The value of the new address (P2SH of witness script).\n" - " \"witnessScript\":\"script\" (string) The string value of the hex-encoded witness script.\n" - "}\n" - ; - throw runtime_error(msg); - } - - if (!IsHex(params[0].get_str())) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Script must be hex-encoded"); - } - - std::vector code = ParseHex(params[0].get_str()); - CScript script(code.begin(), code.end()); - CScript witscript = GetScriptForWitness(script); - CScriptID witscriptid(witscript); - CBitcoinAddress address(witscriptid); - - UniValue result(UniValue::VOBJ); - result.push_back(Pair("address", address.ToString())); - result.push_back(Pair("witnessScript", HexStr(witscript.begin(), witscript.end()))); - - return result; -} - UniValue verifymessage(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 3) @@ -490,7 +453,6 @@ static const CRPCCommand commands[] = { "control", "getinfo", &getinfo, true }, /* uses wallet if enabled */ { "util", "validateaddress", &validateaddress, true }, /* uses wallet if enabled */ { "util", "createmultisig", &createmultisig, true }, - { "util", "createwitnessaddress", &createwitnessaddress, true }, { "util", "verifymessage", &verifymessage, true }, { "util", "signmessagewithprivkey", &signmessagewithprivkey, true }, diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index b85c7b2e1aa..51f9d1c3337 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -344,7 +344,7 @@ UniValue getnettotals(const UniValue& params, bool fHelp) "{\n" " \"totalbytesrecv\": n, (numeric) Total bytes received\n" " \"totalbytessent\": n, (numeric) Total bytes sent\n" - " \"timemillis\": t, (numeric) Total cpu time\n" + " \"timemillis\": t, (numeric) Current UNIX time in milliseconds\n" " \"uploadtarget\":\n" " {\n" " \"timeframe\": n, (numeric) Length of the measuring timeframe in seconds\n" @@ -484,7 +484,7 @@ UniValue setban(const UniValue& params, bool fHelp) "\nExamples:\n" + HelpExampleCli("setban", "\"192.168.0.6\" \"add\" 86400") + HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"") - + HelpExampleRpc("setban", "\"192.168.0.6\", \"add\" 86400") + + HelpExampleRpc("setban", "\"192.168.0.6\", \"add\", 86400") ); CSubNet subNet; diff --git a/src/rpc/protocol.cpp b/src/rpc/protocol.cpp index f5275062a24..bb885bb5a65 100644 --- a/src/rpc/protocol.cpp +++ b/src/rpc/protocol.cpp @@ -77,9 +77,10 @@ boost::filesystem::path GetAuthCookieFile() bool GenerateAuthCookie(std::string *cookie_out) { - unsigned char rand_pwd[32]; - GetRandBytes(rand_pwd, 32); - std::string cookie = COOKIEAUTH_USER + ":" + EncodeBase64(&rand_pwd[0],32); + const size_t COOKIE_SIZE = 32; + unsigned char rand_pwd[COOKIE_SIZE]; + GetRandBytes(rand_pwd, COOKIE_SIZE); + std::string cookie = COOKIEAUTH_USER + ":" + HexStr(rand_pwd, rand_pwd+COOKIE_SIZE); /** the umask determines what permissions are used to create this file - * these are set to 077 in init.cpp unless overridden with -sysperms. diff --git a/src/rpc/protocol.h b/src/rpc/protocol.h index 55d0aac68b7..988e0fc5fac 100644 --- a/src/rpc/protocol.h +++ b/src/rpc/protocol.h @@ -38,18 +38,18 @@ enum RPCErrorCode RPC_PARSE_ERROR = -32700, //! General application defined errors - RPC_MISC_ERROR = -1, //! std::exception thrown in command handling - RPC_FORBIDDEN_BY_SAFE_MODE = -2, //! Server is in safe mode, and command is not allowed in safe mode - RPC_TYPE_ERROR = -3, //! Unexpected type was passed as parameter - RPC_INVALID_ADDRESS_OR_KEY = -5, //! Invalid address or key - RPC_OUT_OF_MEMORY = -7, //! Ran out of memory during operation - RPC_INVALID_PARAMETER = -8, //! Invalid, missing or duplicate parameter - RPC_DATABASE_ERROR = -20, //! Database error - RPC_DESERIALIZATION_ERROR = -22, //! Error parsing or validating structure in raw format - RPC_VERIFY_ERROR = -25, //! General error during transaction or block submission - RPC_VERIFY_REJECTED = -26, //! Transaction or block was rejected by network rules - RPC_VERIFY_ALREADY_IN_CHAIN = -27, //! Transaction already in chain - RPC_IN_WARMUP = -28, //! Client still warming up + RPC_MISC_ERROR = -1, //!< std::exception thrown in command handling + RPC_FORBIDDEN_BY_SAFE_MODE = -2, //!< Server is in safe mode, and command is not allowed in safe mode + RPC_TYPE_ERROR = -3, //!< Unexpected type was passed as parameter + RPC_INVALID_ADDRESS_OR_KEY = -5, //!< Invalid address or key + RPC_OUT_OF_MEMORY = -7, //!< Ran out of memory during operation + RPC_INVALID_PARAMETER = -8, //!< Invalid, missing or duplicate parameter + RPC_DATABASE_ERROR = -20, //!< Database error + RPC_DESERIALIZATION_ERROR = -22, //!< Error parsing or validating structure in raw format + RPC_VERIFY_ERROR = -25, //!< General error during transaction or block submission + RPC_VERIFY_REJECTED = -26, //!< Transaction or block was rejected by network rules + RPC_VERIFY_ALREADY_IN_CHAIN = -27, //!< Transaction already in chain + RPC_IN_WARMUP = -28, //!< Client still warming up //! Aliases for backward compatibility RPC_TRANSACTION_ERROR = RPC_VERIFY_ERROR, @@ -57,23 +57,23 @@ enum RPCErrorCode RPC_TRANSACTION_ALREADY_IN_CHAIN= RPC_VERIFY_ALREADY_IN_CHAIN, //! P2P client errors - RPC_CLIENT_NOT_CONNECTED = -9, //! Bitcoin is not connected - RPC_CLIENT_IN_INITIAL_DOWNLOAD = -10, //! Still downloading initial blocks - RPC_CLIENT_NODE_ALREADY_ADDED = -23, //! Node is already added - RPC_CLIENT_NODE_NOT_ADDED = -24, //! Node has not been added before - RPC_CLIENT_NODE_NOT_CONNECTED = -29, //! Node to disconnect not found in connected nodes - RPC_CLIENT_INVALID_IP_OR_SUBNET = -30, //! Invalid IP/Subnet + RPC_CLIENT_NOT_CONNECTED = -9, //!< Bitcoin is not connected + RPC_CLIENT_IN_INITIAL_DOWNLOAD = -10, //!< Still downloading initial blocks + RPC_CLIENT_NODE_ALREADY_ADDED = -23, //!< Node is already added + RPC_CLIENT_NODE_NOT_ADDED = -24, //!< Node has not been added before + RPC_CLIENT_NODE_NOT_CONNECTED = -29, //!< Node to disconnect not found in connected nodes + RPC_CLIENT_INVALID_IP_OR_SUBNET = -30, //!< Invalid IP/Subnet //! Wallet errors - RPC_WALLET_ERROR = -4, //! Unspecified problem with wallet (key not found etc.) - RPC_WALLET_INSUFFICIENT_FUNDS = -6, //! Not enough funds in wallet or account - RPC_WALLET_INVALID_ACCOUNT_NAME = -11, //! Invalid account name - RPC_WALLET_KEYPOOL_RAN_OUT = -12, //! Keypool ran out, call keypoolrefill first - RPC_WALLET_UNLOCK_NEEDED = -13, //! Enter the wallet passphrase with walletpassphrase first - RPC_WALLET_PASSPHRASE_INCORRECT = -14, //! The wallet passphrase entered was incorrect - RPC_WALLET_WRONG_ENC_STATE = -15, //! Command given in wrong wallet encryption state (encrypting an encrypted wallet etc.) - RPC_WALLET_ENCRYPTION_FAILED = -16, //! Failed to encrypt the wallet - RPC_WALLET_ALREADY_UNLOCKED = -17, //! Wallet is already unlocked + RPC_WALLET_ERROR = -4, //!< Unspecified problem with wallet (key not found etc.) + RPC_WALLET_INSUFFICIENT_FUNDS = -6, //!< Not enough funds in wallet or account + RPC_WALLET_INVALID_ACCOUNT_NAME = -11, //!< Invalid account name + RPC_WALLET_KEYPOOL_RAN_OUT = -12, //!< Keypool ran out, call keypoolrefill first + RPC_WALLET_UNLOCK_NEEDED = -13, //!< Enter the wallet passphrase with walletpassphrase first + RPC_WALLET_PASSPHRASE_INCORRECT = -14, //!< The wallet passphrase entered was incorrect + RPC_WALLET_WRONG_ENC_STATE = -15, //!< Command given in wrong wallet encryption state (encrypting an encrypted wallet etc.) + RPC_WALLET_ENCRYPTION_FAILED = -16, //!< Failed to encrypt the wallet + RPC_WALLET_ALREADY_UNLOCKED = -17, //!< Wallet is already unlocked }; std::string JSONRPCRequest(const std::string& strMethod, const UniValue& params, const UniValue& id); diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 3270cd384f4..2719829e65e 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -209,7 +209,7 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); - string strHex = EncodeHexTx(tx); + string strHex = EncodeHexTx(tx, RPCSerializationFlags()); if (!fVerbose) return strHex; @@ -535,7 +535,7 @@ UniValue decodescript(const UniValue& params, bool fHelp) " \"address\" (string) bitcoin address\n" " ,...\n" " ],\n" - " \"p2sh\",\"address\" (string) script address\n" + " \"p2sh\",\"address\" (string) address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH).\n" "}\n" "\nExamples:\n" + HelpExampleCli("decodescript", "\"hexstring\"") @@ -554,7 +554,15 @@ UniValue decodescript(const UniValue& params, bool fHelp) } ScriptPubKeyToJSON(script, r, false); - r.push_back(Pair("p2sh", CBitcoinAddress(CScriptID(script)).ToString())); + UniValue type; + type = find_value(r, "type"); + + if (type.isStr() && type.get_str() != "scripthash") { + // P2SH cannot be wrapped in a P2SH. If this script is already a P2SH, + // don't return the address for a P2SH of the P2SH. + r.push_back(Pair("p2sh", CBitcoinAddress(CScriptID(script)).ToString())); + } + return r; } diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 23149baa6d9..deeabcb8d7b 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -146,6 +146,8 @@ uint256 ParseHashV(const UniValue& v, string strName) strHex = v.get_str(); if (!IsHex(strHex)) // Note: IsHex("") is false throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')"); + if (64 != strHex.length()) + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be of length %d (not %d)", strName, 64, strHex.length())); uint256 result; result.SetHex(strHex); return result; @@ -493,4 +495,12 @@ void RPCRunLater(const std::string& name, boost::function func, int6 deadlineTimers.insert(std::make_pair(name, boost::shared_ptr(timerInterface->NewTimer(func, nSeconds*1000)))); } +int RPCSerializationFlags() +{ + int flag = 0; + if (GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) == 0) + flag |= SERIALIZE_TRANSACTION_NO_WITNESS; + return flag; +} + CRPCTable tableRPC; diff --git a/src/rpc/server.h b/src/rpc/server.h index b5ccc153d07..1ed8f2466d5 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -19,6 +19,8 @@ #include +static const unsigned int DEFAULT_RPC_SERIALIZE_VERSION = 1; + class CRPCCommand; namespace RPCServer @@ -195,4 +197,7 @@ void InterruptRPC(); void StopRPC(); std::string JSONRPCExecBatch(const UniValue& vReq); +// Retrieves any serialization flags requested in command line argument +int RPCSerializationFlags(); + #endif // BITCOIN_RPCSERVER_H diff --git a/src/scheduler.cpp b/src/scheduler.cpp index 52777b61f96..27c03f154cb 100644 --- a/src/scheduler.cpp +++ b/src/scheduler.cpp @@ -54,9 +54,10 @@ void CScheduler::serviceQueue() #else // Some boost versions have a conflicting overload of wait_until that returns void. // Explicitly use a template here to avoid hitting that overload. - while (!shouldStop() && !taskQueue.empty() && - newTaskScheduled.wait_until<>(lock, taskQueue.begin()->first) != boost::cv_status::timeout) { - // Keep waiting until timeout + while (!shouldStop() && !taskQueue.empty()) { + boost::chrono::system_clock::time_point timeToWaitFor = taskQueue.begin()->first; + if (newTaskScheduled.wait_until<>(lock, timeToWaitFor) == boost::cv_status::timeout) + break; // Exit loop after timeout, it means we reached the time of the event } #endif // If there are multiple threads, the queue can empty while we're waiting (another diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp index 62fd9031f85..b629f4278ba 100644 --- a/src/script/bitcoinconsensus.cpp +++ b/src/script/bitcoinconsensus.cpp @@ -84,8 +84,8 @@ static int verify_script(const unsigned char *scriptPubKey, unsigned int scriptP // Regardless of the verification result, the tx did not error. set_error(err, bitcoinconsensus_ERR_OK); - - return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), nIn < tx.wit.vtxinwit.size() ? &tx.wit.vtxinwit[nIn].scriptWitness : NULL, flags, TransactionSignatureChecker(&tx, nIn, amount), NULL); + PrecomputedTransactionData txdata(tx); + return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), nIn < tx.wit.vtxinwit.size() ? &tx.wit.vtxinwit[nIn].scriptWitness : NULL, flags, TransactionSignatureChecker(&tx, nIn, amount, txdata), NULL); } catch (const std::exception&) { return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing } diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h index 6f868d0d6d6..1d2d5c23e47 100644 --- a/src/script/bitcoinconsensus.h +++ b/src/script/bitcoinconsensus.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin Core developers +// Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -50,7 +50,9 @@ enum bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NONE = 0, bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG = (1U << 2), // enforce strict DER (BIP66) compliance + bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NULLDUMMY = (1U << 4), // enforce NULLDUMMY (BIP147) bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), // enable CHECKLOCKTIMEVERIFY (BIP65) + bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKSEQUENCEVERIFY = (1U << 10), // enable CHECKSEQUENCEVERIFY (BIP112) bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS = (1U << 11), // enable WITNESS (BIP141) }; diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index bc027e9f0c1..0e17ddc130b 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -79,8 +79,20 @@ bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) { return false; } } else { - // Non-canonical public key: neither compressed nor uncompressed - return false; + // Non-canonical public key: neither compressed nor uncompressed + return false; + } + return true; +} + +bool static IsCompressedPubKey(const valtype &vchPubKey) { + if (vchPubKey.size() != 33) { + // Non-canonical public key: invalid length for compressed key + return false; + } + if (vchPubKey[0] != 0x02 && vchPubKey[0] != 0x03) { + // Non-canonical public key: invalid prefix for compressed key + return false; } return true; } @@ -199,10 +211,14 @@ bool CheckSignatureEncoding(const vector &vchSig, unsigned int fl return true; } -bool static CheckPubKeyEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) { - if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsCompressedOrUncompressedPubKey(vchSig)) { +bool static CheckPubKeyEncoding(const valtype &vchPubKey, unsigned int flags, const SigVersion &sigversion, ScriptError* serror) { + if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsCompressedOrUncompressedPubKey(vchPubKey)) { return set_error(serror, SCRIPT_ERR_PUBKEYTYPE); } + // Only compressed keys are accepted in segwit + if ((flags & SCRIPT_VERIFY_WITNESS_PUBKEYTYPE) != 0 && sigversion == SIGVERSION_WITNESS_V0 && !IsCompressedPubKey(vchPubKey)) { + return set_error(serror, SCRIPT_ERR_WITNESS_PUBKEYTYPE); + } return true; } @@ -428,6 +444,12 @@ bool EvalScript(vector >& stack, const CScript& script, un if (stack.size() < 1) return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); valtype& vch = stacktop(-1); + if (sigversion == SIGVERSION_WITNESS_V0 && (flags & SCRIPT_VERIFY_MINIMALIF)) { + if (vch.size() > 1) + return set_error(serror, SCRIPT_ERR_MINIMALIF); + if (vch.size() == 1 && vch[0] != 1) + return set_error(serror, SCRIPT_ERR_MINIMALIF); + } fValue = CastToBool(vch); if (opcode == OP_NOTIF) fValue = !fValue; @@ -868,17 +890,20 @@ bool EvalScript(vector >& stack, const CScript& script, un // Subset of script starting at the most recent codeseparator CScript scriptCode(pbegincodehash, pend); - // Drop the signature, since there's no way for a signature to sign itself + // Drop the signature in pre-segwit scripts but not segwit scripts if (sigversion == SIGVERSION_BASE) { scriptCode.FindAndDelete(CScript(vchSig)); } - if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) { + if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, sigversion, serror)) { //serror is set return false; } bool fSuccess = checker.CheckSig(vchSig, vchPubKey, scriptCode, sigversion); + if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && vchSig.size()) + return set_error(serror, SCRIPT_ERR_SIG_NULLFAIL); + popstack(stack); popstack(stack); stack.push_back(fSuccess ? vchTrue : vchFalse); @@ -908,6 +933,9 @@ bool EvalScript(vector >& stack, const CScript& script, un if (nOpCount > MAX_OPS_PER_SCRIPT) return set_error(serror, SCRIPT_ERR_OP_COUNT); int ikey = ++i; + // ikey2 is the position of last non-signature item in the stack. Top stack item = 1. + // With SCRIPT_VERIFY_NULLFAIL, this is used for cleanup if operation fails. + int ikey2 = nKeysCount + 2; i += nKeysCount; if ((int)stack.size() < i) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); @@ -923,7 +951,7 @@ bool EvalScript(vector >& stack, const CScript& script, un // Subset of script starting at the most recent codeseparator CScript scriptCode(pbegincodehash, pend); - // Drop the signatures, since there's no way for a signature to sign itself + // Drop the signature in pre-segwit scripts but not segwit scripts for (int k = 0; k < nSigsCount; k++) { valtype& vchSig = stacktop(-isig-k); @@ -941,7 +969,7 @@ bool EvalScript(vector >& stack, const CScript& script, un // Note how this makes the exact order of pubkey/signature evaluation // distinguishable by CHECKMULTISIG NOT if the STRICTENC flag is set. // See the script_(in)valid tests for details. - if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) { + if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, sigversion, serror)) { // serror is set return false; } @@ -964,8 +992,14 @@ bool EvalScript(vector >& stack, const CScript& script, un } // Clean up stack of actual arguments - while (i-- > 1) + while (i-- > 1) { + // If the operation failed, we require that all signatures must be empty vector + if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && !ikey2 && stacktop(-1).size()) + return set_error(serror, SCRIPT_ERR_SIG_NULLFAIL); + if (ikey2 > 0) + ikey2--; popstack(stack); + } // A bug causes CHECKMULTISIG to consume one extra argument // whose contents were not checked in any way. @@ -1108,9 +1142,40 @@ class CTransactionSignatureSerializer { } }; +uint256 GetPrevoutHash(const CTransaction& txTo) { + CHashWriter ss(SER_GETHASH, 0); + for (unsigned int n = 0; n < txTo.vin.size(); n++) { + ss << txTo.vin[n].prevout; + } + return ss.GetHash(); +} + +uint256 GetSequenceHash(const CTransaction& txTo) { + CHashWriter ss(SER_GETHASH, 0); + for (unsigned int n = 0; n < txTo.vin.size(); n++) { + ss << txTo.vin[n].nSequence; + } + return ss.GetHash(); +} + +uint256 GetOutputsHash(const CTransaction& txTo) { + CHashWriter ss(SER_GETHASH, 0); + for (unsigned int n = 0; n < txTo.vout.size(); n++) { + ss << txTo.vout[n]; + } + return ss.GetHash(); +} + } // anon namespace -uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion) +PrecomputedTransactionData::PrecomputedTransactionData(const CTransaction& txTo) +{ + hashPrevouts = GetPrevoutHash(txTo); + hashSequence = GetSequenceHash(txTo); + hashOutputs = GetOutputsHash(txTo); +} + +uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache) { if (sigversion == SIGVERSION_WITNESS_V0) { uint256 hashPrevouts; @@ -1118,27 +1183,16 @@ uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsig uint256 hashOutputs; if (!(nHashType & SIGHASH_ANYONECANPAY)) { - CHashWriter ss(SER_GETHASH, 0); - for (unsigned int n = 0; n < txTo.vin.size(); n++) { - ss << txTo.vin[n].prevout; - } - hashPrevouts = ss.GetHash(); // TODO: cache this value for all signatures in a transaction + hashPrevouts = cache ? cache->hashPrevouts : GetPrevoutHash(txTo); } if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { - CHashWriter ss(SER_GETHASH, 0); - for (unsigned int n = 0; n < txTo.vin.size(); n++) { - ss << txTo.vin[n].nSequence; - } - hashSequence = ss.GetHash(); // TODO: cache this value for all signatures in a transaction + hashSequence = cache ? cache->hashSequence : GetSequenceHash(txTo); } + if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { - CHashWriter ss(SER_GETHASH, 0); - for (unsigned int n = 0; n < txTo.vout.size(); n++) { - ss << txTo.vout[n]; - } - hashOutputs = ss.GetHash(); // TODO: cache this value for all signatures in a transaction + hashOutputs = cache ? cache->hashOutputs : GetOutputsHash(txTo); } else if ((nHashType & 0x1f) == SIGHASH_SINGLE && nIn < txTo.vout.size()) { CHashWriter ss(SER_GETHASH, 0); ss << txTo.vout[nIn]; @@ -1209,7 +1263,7 @@ bool TransactionSignatureChecker::CheckSig(const vector& vchSigIn int nHashType = vchSig.back(); vchSig.pop_back(); - uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion); + uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion, this->txdata); if (!VerifySignature(vchSig, pubkey, sighash)) return false; diff --git a/src/script/interpreter.h b/src/script/interpreter.h index bd2f2116636..79894c53003 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin Core developers +// Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -94,17 +94,36 @@ enum // Making v1-v16 witness program non-standard // SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM = (1U << 12), + + // Segwit script only: Require the argument of OP_IF/NOTIF to be exactly 0x01 or empty vector + // + SCRIPT_VERIFY_MINIMALIF = (1U << 13), + + // Signature(s) must be empty vector if an CHECK(MULTI)SIG operation failed + // + SCRIPT_VERIFY_NULLFAIL = (1U << 14), + + // Public keys in segregated witness scripts must be compressed + // + SCRIPT_VERIFY_WITNESS_PUBKEYTYPE = (1U << 15), }; bool CheckSignatureEncoding(const std::vector &vchSig, unsigned int flags, ScriptError* serror); +struct PrecomputedTransactionData +{ + uint256 hashPrevouts, hashSequence, hashOutputs; + + PrecomputedTransactionData(const CTransaction& tx); +}; + enum SigVersion { SIGVERSION_BASE = 0, SIGVERSION_WITNESS_V0 = 1, }; -uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion); +uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache = NULL); class BaseSignatureChecker { @@ -133,12 +152,14 @@ class TransactionSignatureChecker : public BaseSignatureChecker const CTransaction* txTo; unsigned int nIn; const CAmount amount; + const PrecomputedTransactionData* txdata; protected: virtual bool VerifySignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; public: - TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn) : txTo(txToIn), nIn(nInIn), amount(amountIn) {} + TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(NULL) {} + TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, const PrecomputedTransactionData& txdataIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {} bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const; bool CheckLockTime(const CScriptNum& nLockTime) const; bool CheckSequence(const CScriptNum& nSequence) const; diff --git a/src/script/ismine.cpp b/src/script/ismine.cpp index 0bf180341e4..7467d23b2d3 100644 --- a/src/script/ismine.cpp +++ b/src/script/ismine.cpp @@ -29,13 +29,25 @@ unsigned int HaveKeys(const vector& pubkeys, const CKeyStore& keystore) return nResult; } -isminetype IsMine(const CKeyStore &keystore, const CTxDestination& dest) +isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey, SigVersion sigversion) +{ + bool isInvalid = false; + return IsMine(keystore, scriptPubKey, isInvalid, sigversion); +} + +isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest, SigVersion sigversion) +{ + bool isInvalid = false; + return IsMine(keystore, dest, isInvalid, sigversion); +} + +isminetype IsMine(const CKeyStore &keystore, const CTxDestination& dest, bool& isInvalid, SigVersion sigversion) { CScript script = GetScriptForDestination(dest); - return IsMine(keystore, script); + return IsMine(keystore, script, isInvalid, sigversion); } -isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) +isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey, bool& isInvalid, SigVersion sigversion) { vector vSolutions; txnouttype whichType; @@ -53,12 +65,35 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) break; case TX_PUBKEY: keyID = CPubKey(vSolutions[0]).GetID(); + if (sigversion != SIGVERSION_BASE && vSolutions[0].size() != 33) { + isInvalid = true; + return ISMINE_NO; + } if (keystore.HaveKey(keyID)) return ISMINE_SPENDABLE; break; - case TX_PUBKEYHASH: case TX_WITNESS_V0_KEYHASH: + { + if (!keystore.HaveCScript(CScriptID(CScript() << OP_0 << vSolutions[0]))) { + // We do not support bare witness outputs unless the P2SH version of it would be + // acceptable as well. This protects against matching before segwit activates. + // This also applies to the P2WSH case. + break; + } + isminetype ret = ::IsMine(keystore, GetScriptForDestination(CKeyID(uint160(vSolutions[0]))), isInvalid, SIGVERSION_WITNESS_V0); + if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid)) + return ret; + break; + } + case TX_PUBKEYHASH: keyID = CKeyID(uint160(vSolutions[0])); + if (sigversion != SIGVERSION_BASE) { + CPubKey pubkey; + if (keystore.GetPubKey(keyID, pubkey) && !pubkey.IsCompressed()) { + isInvalid = true; + return ISMINE_NO; + } + } if (keystore.HaveKey(keyID)) return ISMINE_SPENDABLE; break; @@ -67,21 +102,24 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) CScriptID scriptID = CScriptID(uint160(vSolutions[0])); CScript subscript; if (keystore.GetCScript(scriptID, subscript)) { - isminetype ret = IsMine(keystore, subscript); - if (ret == ISMINE_SPENDABLE) + isminetype ret = IsMine(keystore, subscript, isInvalid); + if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid)) return ret; } break; } case TX_WITNESS_V0_SCRIPTHASH: { + if (!keystore.HaveCScript(CScriptID(CScript() << OP_0 << vSolutions[0]))) { + break; + } uint160 hash; CRIPEMD160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(hash.begin()); CScriptID scriptID = CScriptID(hash); CScript subscript; if (keystore.GetCScript(scriptID, subscript)) { - isminetype ret = IsMine(keystore, subscript); - if (ret == ISMINE_SPENDABLE) + isminetype ret = IsMine(keystore, subscript, isInvalid, SIGVERSION_WITNESS_V0); + if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid)) return ret; } break; @@ -95,6 +133,14 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) // them) enable spend-out-from-under-you attacks, especially // in shared-wallet situations. vector keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1); + if (sigversion != SIGVERSION_BASE) { + for (size_t i = 0; i < keys.size(); i++) { + if (keys[i].size() != 33) { + isInvalid = true; + return ISMINE_NO; + } + } + } if (HaveKeys(keys, keystore) == keys.size()) return ISMINE_SPENDABLE; break; diff --git a/src/script/ismine.h b/src/script/ismine.h index 4b7db8802ba..ec7a620e330 100644 --- a/src/script/ismine.h +++ b/src/script/ismine.h @@ -28,7 +28,14 @@ enum isminetype /** used for bitflags of isminetype */ typedef uint8_t isminefilter; -isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey); -isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest); +/* isInvalid becomes true when the script is found invalid by consensus or policy. This will terminate the recursion + * and return a ISMINE_NO immediately, as an invalid script should never be considered as "mine". This is needed as + * different SIGVERSION may have different network rules. Currently the only use of isInvalid is indicate uncompressed + * keys in SIGVERSION_WITNESS_V0 script, but could also be used in similar cases in the future + */ +isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey, bool& isInvalid, SigVersion = SIGVERSION_BASE); +isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey, SigVersion = SIGVERSION_BASE); +isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest, bool& isInvalid, SigVersion = SIGVERSION_BASE); +isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest, SigVersion = SIGVERSION_BASE); #endif // BITCOIN_SCRIPT_ISMINE_H diff --git a/src/script/script_error.cpp b/src/script/script_error.cpp index cef807edcf4..2c5359fe8af 100644 --- a/src/script/script_error.cpp +++ b/src/script/script_error.cpp @@ -63,6 +63,10 @@ const char* ScriptErrorString(const ScriptError serror) return "Non-canonical signature: S value is unnecessarily high"; case SCRIPT_ERR_SIG_NULLDUMMY: return "Dummy CHECKMULTISIG argument must be zero"; + case SCRIPT_ERR_MINIMALIF: + return "OP_IF/NOTIF argument must be minimal"; + case SCRIPT_ERR_SIG_NULLFAIL: + return "Signature must be zero for failed CHECK(MULTI)SIG operation"; case SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS: return "NOPx reserved for soft-fork upgrades"; case SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM: @@ -81,6 +85,8 @@ const char* ScriptErrorString(const ScriptError serror) return "Witness requires only-redeemscript scriptSig"; case SCRIPT_ERR_WITNESS_UNEXPECTED: return "Witness provided for non-witness script"; + case SCRIPT_ERR_WITNESS_PUBKEYTYPE: + return "Using non-compressed keys in segwit"; case SCRIPT_ERR_UNKNOWN_ERROR: case SCRIPT_ERR_ERROR_COUNT: default: break; diff --git a/src/script/script_error.h b/src/script/script_error.h index 09dc6945adb..430836991b2 100644 --- a/src/script/script_error.h +++ b/src/script/script_error.h @@ -39,7 +39,7 @@ typedef enum ScriptError_t SCRIPT_ERR_NEGATIVE_LOCKTIME, SCRIPT_ERR_UNSATISFIED_LOCKTIME, - /* BIP62 */ + /* Malleability */ SCRIPT_ERR_SIG_HASHTYPE, SCRIPT_ERR_SIG_DER, SCRIPT_ERR_MINIMALDATA, @@ -48,6 +48,8 @@ typedef enum ScriptError_t SCRIPT_ERR_SIG_NULLDUMMY, SCRIPT_ERR_PUBKEYTYPE, SCRIPT_ERR_CLEANSTACK, + SCRIPT_ERR_MINIMALIF, + SCRIPT_ERR_SIG_NULLFAIL, /* softfork safeness */ SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS, @@ -60,6 +62,7 @@ typedef enum ScriptError_t SCRIPT_ERR_WITNESS_MALLEATED, SCRIPT_ERR_WITNESS_MALLEATED_P2SH, SCRIPT_ERR_WITNESS_UNEXPECTED, + SCRIPT_ERR_WITNESS_PUBKEYTYPE, SCRIPT_ERR_ERROR_COUNT } ScriptError; diff --git a/src/script/sigcache.h b/src/script/sigcache.h index 050bf8cc422..44551ec2bc4 100644 --- a/src/script/sigcache.h +++ b/src/script/sigcache.h @@ -22,7 +22,7 @@ class CachingTransactionSignatureChecker : public TransactionSignatureChecker bool store; public: - CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amount, bool storeIn) : TransactionSignatureChecker(txToIn, nInIn, amount), store(storeIn) {} + CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amount, bool storeIn, PrecomputedTransactionData& txdataIn) : TransactionSignatureChecker(txToIn, nInIn, amount, txdataIn), store(storeIn) {} bool VerifySignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; }; diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 87f38d9c725..f552ad5bbad 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin Core developers +// Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -26,6 +26,10 @@ bool TransactionSignatureCreator::CreateSig(std::vector& vchSig, if (!keystore->GetKey(address, key)) return false; + // Signing with uncompressed keys is disabled in witness scripts + if (sigversion == SIGVERSION_WITNESS_V0 && !key.IsCompressed()) + return false; + uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion); if (!key.Sign(hash, vchSig)) return false; diff --git a/src/script/sign.h b/src/script/sign.h index 6404b4523ec..f9aa6fca271 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -51,7 +51,7 @@ class MutableTransactionSignatureCreator : public TransactionSignatureCreator { MutableTransactionSignatureCreator(const CKeyStore* keystoreIn, const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amount, int nHashTypeIn) : TransactionSignatureCreator(keystoreIn, &tx, nInIn, amount, nHashTypeIn), tx(*txToIn) {} }; -/** A signature creator that just produces 72-byte empty signatyres. */ +/** A signature creator that just produces 72-byte empty signatures. */ class DummySignatureCreator : public BaseSignatureCreator { public: DummySignatureCreator(const CKeyStore* keystoreIn) : BaseSignatureCreator(keystoreIn) {} diff --git a/src/secp256k1/.gitignore b/src/secp256k1/.gitignore index e0b7b7a48a3..87fea161ba5 100644 --- a/src/secp256k1/.gitignore +++ b/src/secp256k1/.gitignore @@ -6,6 +6,7 @@ bench_schnorr_verify bench_recover bench_internal tests +exhaustive_tests gen_context *.exe *.so @@ -25,17 +26,24 @@ config.status libtool .deps/ .dirstamp -build-aux/ *.lo *.o *~ src/libsecp256k1-config.h src/libsecp256k1-config.h.in src/ecmult_static_context.h -m4/libtool.m4 -m4/ltoptions.m4 -m4/ltsugar.m4 -m4/ltversion.m4 -m4/lt~obsolete.m4 +build-aux/config.guess +build-aux/config.sub +build-aux/depcomp +build-aux/install-sh +build-aux/ltmain.sh +build-aux/m4/libtool.m4 +build-aux/m4/lt~obsolete.m4 +build-aux/m4/ltoptions.m4 +build-aux/m4/ltsugar.m4 +build-aux/m4/ltversion.m4 +build-aux/missing +build-aux/compile +build-aux/test-driver src/stamp-h1 libsecp256k1.pc diff --git a/src/secp256k1/.travis.yml b/src/secp256k1/.travis.yml index 4e1e73c39f5..24395292426 100644 --- a/src/secp256k1/.travis.yml +++ b/src/secp256k1/.travis.yml @@ -6,26 +6,30 @@ addons: compiler: - clang - gcc +cache: + directories: + - src/java/guava/ env: global: - - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no STATICPRECOMPUTATION=yes ASM=no BUILD=check EXTRAFLAGS= HOST= ECDH=no schnorr=no RECOVERY=no + - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no STATICPRECOMPUTATION=yes ASM=no BUILD=check EXTRAFLAGS= HOST= ECDH=no RECOVERY=no EXPERIMENTAL=no + - GUAVA_URL=https://search.maven.org/remotecontent?filepath=com/google/guava/guava/18.0/guava-18.0.jar GUAVA_JAR=src/java/guava/guava-18.0.jar matrix: - SCALAR=32bit RECOVERY=yes - - SCALAR=32bit FIELD=32bit ECDH=yes + - SCALAR=32bit FIELD=32bit ECDH=yes EXPERIMENTAL=yes - SCALAR=64bit - FIELD=64bit RECOVERY=yes - FIELD=64bit ENDOMORPHISM=yes - - FIELD=64bit ENDOMORPHISM=yes ECDH=yes + - FIELD=64bit ENDOMORPHISM=yes ECDH=yes EXPERIMENTAL=yes - FIELD=64bit ASM=x86_64 - FIELD=64bit ENDOMORPHISM=yes ASM=x86_64 - - FIELD=32bit SCHNORR=yes - FIELD=32bit ENDOMORPHISM=yes - BIGNUM=no - - BIGNUM=no ENDOMORPHISM=yes SCHNORR=yes RECOVERY=yes + - BIGNUM=no ENDOMORPHISM=yes RECOVERY=yes EXPERIMENTAL=yes - BIGNUM=no STATICPRECOMPUTATION=no - BUILD=distcheck - EXTRAFLAGS=CPPFLAGS=-DDETERMINISTIC - EXTRAFLAGS=CFLAGS=-O0 + - BUILD=check-java ECDH=yes EXPERIMENTAL=yes matrix: fast_finish: true include: @@ -55,9 +59,11 @@ matrix: packages: - gcc-multilib - libgmp-dev:i386 +before_install: mkdir -p `dirname $GUAVA_JAR` +install: if [ ! -f $GUAVA_JAR ]; then wget $GUAVA_URL -O $GUAVA_JAR; fi before_script: ./autogen.sh script: - if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi - if [ "x$HOST" = "xi686-linux-gnu" ]; then export CC="$CC -m32"; fi - - ./configure --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION --enable-module-ecdh=$ECDH --enable-module-schnorr=$SCHNORR --enable-module-recovery=$RECOVERY $EXTRAFLAGS $USE_HOST && make -j2 $BUILD + - ./configure --enable-experimental=$EXPERIMENTAL --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION --enable-module-ecdh=$ECDH --enable-module-recovery=$RECOVERY $EXTRAFLAGS $USE_HOST && make -j2 $BUILD os: linux diff --git a/src/secp256k1/Makefile.am b/src/secp256k1/Makefile.am index 7772a4e9d28..e5657f7f313 100644 --- a/src/secp256k1/Makefile.am +++ b/src/secp256k1/Makefile.am @@ -1,14 +1,22 @@ ACLOCAL_AMFLAGS = -I build-aux/m4 lib_LTLIBRARIES = libsecp256k1.la +if USE_JNI +JNI_LIB = libsecp256k1_jni.la +noinst_LTLIBRARIES = $(JNI_LIB) +else +JNI_LIB = +endif include_HEADERS = include/secp256k1.h noinst_HEADERS = noinst_HEADERS += src/scalar.h noinst_HEADERS += src/scalar_4x64.h noinst_HEADERS += src/scalar_8x32.h +noinst_HEADERS += src/scalar_low.h noinst_HEADERS += src/scalar_impl.h noinst_HEADERS += src/scalar_4x64_impl.h noinst_HEADERS += src/scalar_8x32_impl.h +noinst_HEADERS += src/scalar_low_impl.h noinst_HEADERS += src/group.h noinst_HEADERS += src/group_impl.h noinst_HEADERS += src/num_gmp.h @@ -32,6 +40,7 @@ noinst_HEADERS += src/field_5x52_impl.h noinst_HEADERS += src/field_5x52_int128_impl.h noinst_HEADERS += src/field_5x52_asm_impl.h noinst_HEADERS += src/java/org_bitcoin_NativeSecp256k1.h +noinst_HEADERS += src/java/org_bitcoin_Secp256k1Context.h noinst_HEADERS += src/util.h noinst_HEADERS += src/testrand.h noinst_HEADERS += src/testrand_impl.h @@ -45,33 +54,88 @@ noinst_HEADERS += contrib/lax_der_parsing.c noinst_HEADERS += contrib/lax_der_privatekey_parsing.h noinst_HEADERS += contrib/lax_der_privatekey_parsing.c +if USE_EXTERNAL_ASM +COMMON_LIB = libsecp256k1_common.la +noinst_LTLIBRARIES = $(COMMON_LIB) +else +COMMON_LIB = +endif + pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libsecp256k1.pc +if USE_EXTERNAL_ASM +if USE_ASM_ARM +libsecp256k1_common_la_SOURCES = src/asm/field_10x26_arm.s +endif +endif + libsecp256k1_la_SOURCES = src/secp256k1.c -libsecp256k1_la_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src $(SECP_INCLUDES) -libsecp256k1_la_LIBADD = $(SECP_LIBS) +libsecp256k1_la_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/include -I$(top_srcdir)/src $(SECP_INCLUDES) +libsecp256k1_la_LIBADD = $(JNI_LIB) $(SECP_LIBS) $(COMMON_LIB) +libsecp256k1_jni_la_SOURCES = src/java/org_bitcoin_NativeSecp256k1.c src/java/org_bitcoin_Secp256k1Context.c +libsecp256k1_jni_la_CPPFLAGS = -DSECP256K1_BUILD $(JNI_INCLUDES) noinst_PROGRAMS = if USE_BENCHMARK noinst_PROGRAMS += bench_verify bench_sign bench_internal bench_verify_SOURCES = src/bench_verify.c -bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS) +bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB) bench_sign_SOURCES = src/bench_sign.c -bench_sign_LDADD = libsecp256k1.la $(SECP_LIBS) +bench_sign_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB) bench_internal_SOURCES = src/bench_internal.c -bench_internal_LDADD = $(SECP_LIBS) -bench_internal_CPPFLAGS = $(SECP_INCLUDES) +bench_internal_LDADD = $(SECP_LIBS) $(COMMON_LIB) +bench_internal_CPPFLAGS = -DSECP256K1_BUILD $(SECP_INCLUDES) endif +TESTS = if USE_TESTS noinst_PROGRAMS += tests tests_SOURCES = src/tests.c -tests_CPPFLAGS = -DVERIFY -I$(top_srcdir)/src -I$(top_srcdir)/include $(SECP_INCLUDES) $(SECP_TEST_INCLUDES) -tests_LDADD = $(SECP_LIBS) $(SECP_TEST_LIBS) +tests_CPPFLAGS = -DSECP256K1_BUILD -DVERIFY -I$(top_srcdir)/src -I$(top_srcdir)/include $(SECP_INCLUDES) $(SECP_TEST_INCLUDES) +tests_LDADD = $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB) tests_LDFLAGS = -static -TESTS = tests +TESTS += tests +endif + +if USE_EXHAUSTIVE_TESTS +noinst_PROGRAMS += exhaustive_tests +exhaustive_tests_SOURCES = src/tests_exhaustive.c +exhaustive_tests_CPPFLAGS = -DSECP256K1_BUILD -DVERIFY -I$(top_srcdir)/src $(SECP_INCLUDES) +exhaustive_tests_LDADD = $(SECP_LIBS) +exhaustive_tests_LDFLAGS = -static +TESTS += exhaustive_tests +endif + +JAVAROOT=src/java +JAVAORG=org/bitcoin +JAVA_GUAVA=$(srcdir)/$(JAVAROOT)/guava/guava-18.0.jar +CLASSPATH_ENV=CLASSPATH=$(JAVA_GUAVA) +JAVA_FILES= \ + $(JAVAROOT)/$(JAVAORG)/NativeSecp256k1.java \ + $(JAVAROOT)/$(JAVAORG)/NativeSecp256k1Test.java \ + $(JAVAROOT)/$(JAVAORG)/NativeSecp256k1Util.java \ + $(JAVAROOT)/$(JAVAORG)/Secp256k1Context.java + +if USE_JNI + +$(JAVA_GUAVA): + @echo Guava is missing. Fetch it via: \ + wget https://search.maven.org/remotecontent?filepath=com/google/guava/guava/18.0/guava-18.0.jar -O $(@) + @false + +.stamp-java: $(JAVA_FILES) + @echo Compiling $^ + $(AM_V_at)$(CLASSPATH_ENV) javac $^ + @touch $@ + +if USE_TESTS + +check-java: libsecp256k1.la $(JAVA_GUAVA) .stamp-java + $(AM_V_at)java -Djava.library.path="./:./src:./src/.libs:.libs/" -cp "$(JAVA_GUAVA):$(JAVAROOT)" $(JAVAORG)/NativeSecp256k1Test + +endif endif if USE_ECMULT_STATIC_PRECOMPUTATION @@ -93,19 +157,15 @@ $(bench_internal_OBJECTS): src/ecmult_static_context.h src/ecmult_static_context.h: $(gen_context_BIN) ./$(gen_context_BIN) -CLEANFILES = $(gen_context_BIN) src/ecmult_static_context.h +CLEANFILES = $(gen_context_BIN) src/ecmult_static_context.h $(JAVAROOT)/$(JAVAORG)/*.class .stamp-java endif -EXTRA_DIST = autogen.sh src/gen_context.c src/basic-config.h +EXTRA_DIST = autogen.sh src/gen_context.c src/basic-config.h $(JAVA_FILES) if ENABLE_MODULE_ECDH include src/modules/ecdh/Makefile.am.include endif -if ENABLE_MODULE_SCHNORR -include src/modules/schnorr/Makefile.am.include -endif - if ENABLE_MODULE_RECOVERY include src/modules/recovery/Makefile.am.include endif diff --git a/src/secp256k1/README.md b/src/secp256k1/README.md index 6095db42205..8cd344ea812 100644 --- a/src/secp256k1/README.md +++ b/src/secp256k1/README.md @@ -1,7 +1,7 @@ libsecp256k1 ============ -[![Build Status](https://travis-ci.org/bitcoin/secp256k1.svg?branch=master)](https://travis-ci.org/bitcoin/secp256k1) +[![Build Status](https://travis-ci.org/bitcoin-core/secp256k1.svg?branch=master)](https://travis-ci.org/bitcoin-core/secp256k1) Optimized C library for EC operations on curve secp256k1. diff --git a/src/secp256k1/build-aux/m4/ax_jni_include_dir.m4 b/src/secp256k1/build-aux/m4/ax_jni_include_dir.m4 new file mode 100644 index 00000000000..1fc36276144 --- /dev/null +++ b/src/secp256k1/build-aux/m4/ax_jni_include_dir.m4 @@ -0,0 +1,140 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_jni_include_dir.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_JNI_INCLUDE_DIR +# +# DESCRIPTION +# +# AX_JNI_INCLUDE_DIR finds include directories needed for compiling +# programs using the JNI interface. +# +# JNI include directories are usually in the Java distribution. This is +# deduced from the value of $JAVA_HOME, $JAVAC, or the path to "javac", in +# that order. When this macro completes, a list of directories is left in +# the variable JNI_INCLUDE_DIRS. +# +# Example usage follows: +# +# AX_JNI_INCLUDE_DIR +# +# for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS +# do +# CPPFLAGS="$CPPFLAGS -I$JNI_INCLUDE_DIR" +# done +# +# If you want to force a specific compiler: +# +# - at the configure.in level, set JAVAC=yourcompiler before calling +# AX_JNI_INCLUDE_DIR +# +# - at the configure level, setenv JAVAC +# +# Note: This macro can work with the autoconf M4 macros for Java programs. +# This particular macro is not part of the original set of macros. +# +# LICENSE +# +# Copyright (c) 2008 Don Anderson +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 10 + +AU_ALIAS([AC_JNI_INCLUDE_DIR], [AX_JNI_INCLUDE_DIR]) +AC_DEFUN([AX_JNI_INCLUDE_DIR],[ + +JNI_INCLUDE_DIRS="" + +if test "x$JAVA_HOME" != x; then + _JTOPDIR="$JAVA_HOME" +else + if test "x$JAVAC" = x; then + JAVAC=javac + fi + AC_PATH_PROG([_ACJNI_JAVAC], [$JAVAC], [no]) + if test "x$_ACJNI_JAVAC" = xno; then + AC_MSG_WARN([cannot find JDK; try setting \$JAVAC or \$JAVA_HOME]) + fi + _ACJNI_FOLLOW_SYMLINKS("$_ACJNI_JAVAC") + _JTOPDIR=`echo "$_ACJNI_FOLLOWED" | sed -e 's://*:/:g' -e 's:/[[^/]]*$::'` +fi + +case "$host_os" in + darwin*) _JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[[^/]]*$::'` + _JINC="$_JTOPDIR/Headers";; + *) _JINC="$_JTOPDIR/include";; +esac +_AS_ECHO_LOG([_JTOPDIR=$_JTOPDIR]) +_AS_ECHO_LOG([_JINC=$_JINC]) + +# On Mac OS X 10.6.4, jni.h is a symlink: +# /System/Library/Frameworks/JavaVM.framework/Versions/Current/Headers/jni.h +# -> ../../CurrentJDK/Headers/jni.h. + +AC_CACHE_CHECK(jni headers, ac_cv_jni_header_path, +[ +if test -f "$_JINC/jni.h"; then + ac_cv_jni_header_path="$_JINC" + JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $ac_cv_jni_header_path" +else + _JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[[^/]]*$::'` + if test -f "$_JTOPDIR/include/jni.h"; then + ac_cv_jni_header_path="$_JTOPDIR/include" + JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $ac_cv_jni_header_path" + else + ac_cv_jni_header_path=none + fi +fi +]) + + + +# get the likely subdirectories for system specific java includes +case "$host_os" in +bsdi*) _JNI_INC_SUBDIRS="bsdos";; +darwin*) _JNI_INC_SUBDIRS="darwin";; +freebsd*) _JNI_INC_SUBDIRS="freebsd";; +linux*) _JNI_INC_SUBDIRS="linux genunix";; +osf*) _JNI_INC_SUBDIRS="alpha";; +solaris*) _JNI_INC_SUBDIRS="solaris";; +mingw*) _JNI_INC_SUBDIRS="win32";; +cygwin*) _JNI_INC_SUBDIRS="win32";; +*) _JNI_INC_SUBDIRS="genunix";; +esac + +if test "x$ac_cv_jni_header_path" != "xnone"; then + # add any subdirectories that are present + for JINCSUBDIR in $_JNI_INC_SUBDIRS + do + if test -d "$_JTOPDIR/include/$JINCSUBDIR"; then + JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JTOPDIR/include/$JINCSUBDIR" + fi + done +fi +]) + +# _ACJNI_FOLLOW_SYMLINKS +# Follows symbolic links on , +# finally setting variable _ACJNI_FOLLOWED +# ---------------------------------------- +AC_DEFUN([_ACJNI_FOLLOW_SYMLINKS],[ +# find the include directory relative to the javac executable +_cur="$1" +while ls -ld "$_cur" 2>/dev/null | grep " -> " >/dev/null; do + AC_MSG_CHECKING([symlink for $_cur]) + _slink=`ls -ld "$_cur" | sed 's/.* -> //'` + case "$_slink" in + /*) _cur="$_slink";; + # 'X' avoids triggering unwanted echo options. + *) _cur=`echo "X$_cur" | sed -e 's/^X//' -e 's:[[^/]]*$::'`"$_slink";; + esac + AC_MSG_RESULT([$_cur]) +done +_ACJNI_FOLLOWED="$_cur" +])# _ACJNI diff --git a/src/secp256k1/build-aux/m4/bitcoin_secp.m4 b/src/secp256k1/build-aux/m4/bitcoin_secp.m4 index d41bbb64870..b74acb8c138 100644 --- a/src/secp256k1/build-aux/m4/bitcoin_secp.m4 +++ b/src/secp256k1/build-aux/m4/bitcoin_secp.m4 @@ -3,13 +3,13 @@ AC_DEFUN([SECP_INT128_CHECK],[ has_int128=$ac_cv_type___int128 ]) -dnl +dnl escape "$0x" below using the m4 quadrigaph @S|@, and escape it again with a \ for the shell. AC_DEFUN([SECP_64BIT_ASM_CHECK],[ AC_MSG_CHECKING(for x86_64 assembly availability) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]],[[ uint64_t a = 11, tmp; - __asm__ __volatile__("movq $0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx"); + __asm__ __volatile__("movq \@S|@0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx"); ]])],[has_64bit_asm=yes],[has_64bit_asm=no]) AC_MSG_RESULT([$has_64bit_asm]) ]) @@ -46,6 +46,10 @@ if test x"$has_libcrypto" = x"yes" && test x"$has_openssl_ec" = x; then ECDSA_sign(0, NULL, 0, NULL, NULL, eckey); ECDSA_verify(0, NULL, 0, NULL, 0, eckey); EC_KEY_free(eckey); + ECDSA_SIG *sig_openssl; + sig_openssl = ECDSA_SIG_new(); + (void)sig_openssl->r; + ECDSA_SIG_free(sig_openssl); ]])],[has_openssl_ec=yes],[has_openssl_ec=no]) AC_MSG_RESULT([$has_openssl_ec]) fi diff --git a/src/secp256k1/configure.ac b/src/secp256k1/configure.ac index 786d8dcfb99..ec50ffe3a25 100644 --- a/src/secp256k1/configure.ac +++ b/src/secp256k1/configure.ac @@ -29,6 +29,7 @@ AC_PROG_CC_C89 if test x"$ac_cv_prog_cc_c89" = x"no"; then AC_MSG_ERROR([c89 compiler support required]) fi +AM_PROG_AS case $host_os in *darwin*) @@ -93,31 +94,46 @@ AC_ARG_ENABLE(tests, [use_tests=$enableval], [use_tests=yes]) +AC_ARG_ENABLE(openssl_tests, + AS_HELP_STRING([--enable-openssl-tests],[enable OpenSSL tests, if OpenSSL is available (default is auto)]), + [enable_openssl_tests=$enableval], + [enable_openssl_tests=auto]) + +AC_ARG_ENABLE(experimental, + AS_HELP_STRING([--enable-experimental],[allow experimental configure options (default is no)]), + [use_experimental=$enableval], + [use_experimental=no]) + +AC_ARG_ENABLE(exhaustive_tests, + AS_HELP_STRING([--enable-exhaustive-tests],[compile exhaustive tests (default is yes)]), + [use_exhaustive_tests=$enableval], + [use_exhaustive_tests=yes]) + AC_ARG_ENABLE(endomorphism, AS_HELP_STRING([--enable-endomorphism],[enable endomorphism (default is no)]), [use_endomorphism=$enableval], [use_endomorphism=no]) - + AC_ARG_ENABLE(ecmult_static_precomputation, AS_HELP_STRING([--enable-ecmult-static-precomputation],[enable precomputed ecmult table for signing (default is yes)]), [use_ecmult_static_precomputation=$enableval], - [use_ecmult_static_precomputation=yes]) + [use_ecmult_static_precomputation=auto]) AC_ARG_ENABLE(module_ecdh, - AS_HELP_STRING([--enable-module-ecdh],[enable ECDH shared secret computation (default is no)]), + AS_HELP_STRING([--enable-module-ecdh],[enable ECDH shared secret computation (experimental)]), [enable_module_ecdh=$enableval], [enable_module_ecdh=no]) -AC_ARG_ENABLE(module_schnorr, - AS_HELP_STRING([--enable-module-schnorr],[enable Schnorr signature module (default is no)]), - [enable_module_schnorr=$enableval], - [enable_module_schnorr=no]) - AC_ARG_ENABLE(module_recovery, AS_HELP_STRING([--enable-module-recovery],[enable ECDSA pubkey recovery module (default is no)]), [enable_module_recovery=$enableval], [enable_module_recovery=no]) +AC_ARG_ENABLE(jni, + AS_HELP_STRING([--enable-jni],[enable libsecp256k1_jni (default is auto)]), + [use_jni=$enableval], + [use_jni=auto]) + AC_ARG_WITH([field], [AS_HELP_STRING([--with-field=64bit|32bit|auto], [Specify Field Implementation. Default is auto])],[req_field=$withval], [req_field=auto]) @@ -127,8 +143,8 @@ AC_ARG_WITH([bignum], [AS_HELP_STRING([--with-bignum=gmp|no|auto], AC_ARG_WITH([scalar], [AS_HELP_STRING([--with-scalar=64bit|32bit|auto], [Specify scalar implementation. Default is auto])],[req_scalar=$withval], [req_scalar=auto]) -AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|no|auto] -[Specify assembly optimizations to use. Default is auto])],[req_asm=$withval], [req_asm=auto]) +AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|arm|no|auto] +[Specify assembly optimizations to use. Default is auto (experimental: arm)])],[req_asm=$withval], [req_asm=auto]) AC_CHECK_TYPES([__int128]) @@ -138,6 +154,34 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[void myfunc() {__builtin_expect(0,0);}]])], [ AC_MSG_RESULT([no]) ]) +if test x"$use_ecmult_static_precomputation" != x"no"; then + save_cross_compiling=$cross_compiling + cross_compiling=no + TEMP_CC="$CC" + CC="$CC_FOR_BUILD" + AC_MSG_CHECKING([native compiler: ${CC_FOR_BUILD}]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM([], [return 0])], + [working_native_cc=yes], + [working_native_cc=no],[dnl]) + CC="$TEMP_CC" + cross_compiling=$save_cross_compiling + + if test x"$working_native_cc" = x"no"; then + set_precomp=no + if test x"$use_ecmult_static_precomputation" = x"yes"; then + AC_MSG_ERROR([${CC_FOR_BUILD} does not produce working binaries. Please set CC_FOR_BUILD]) + else + AC_MSG_RESULT([${CC_FOR_BUILD} does not produce working binaries. Please set CC_FOR_BUILD]) + fi + else + AC_MSG_RESULT([ok]) + set_precomp=yes + fi +else + set_precomp=no +fi + if test x"$req_asm" = x"auto"; then SECP_64BIT_ASM_CHECK if test x"$has_64bit_asm" = x"yes"; then @@ -155,6 +199,8 @@ else AC_MSG_ERROR([x86_64 assembly optimization requested but not available]) fi ;; + arm) + ;; no) ;; *) @@ -247,10 +293,15 @@ else fi # select assembly optimization +use_external_asm=no + case $set_asm in x86_64) AC_DEFINE(USE_ASM_X86_64, 1, [Define this symbol to enable x86_64 assembly optimizations]) ;; +arm) + use_external_asm=yes + ;; no) ;; *) @@ -305,16 +356,48 @@ esac if test x"$use_tests" = x"yes"; then SECP_OPENSSL_CHECK if test x"$has_openssl_ec" = x"yes"; then - AC_DEFINE(ENABLE_OPENSSL_TESTS, 1, [Define this symbol if OpenSSL EC functions are available]) - SECP_TEST_INCLUDES="$SSL_CFLAGS $CRYPTO_CFLAGS" - SECP_TEST_LIBS="$CRYPTO_LIBS" - - case $host in - *mingw*) - SECP_TEST_LIBS="$SECP_TEST_LIBS -lgdi32" - ;; - esac + if test x"$enable_openssl_tests" != x"no"; then + AC_DEFINE(ENABLE_OPENSSL_TESTS, 1, [Define this symbol if OpenSSL EC functions are available]) + SECP_TEST_INCLUDES="$SSL_CFLAGS $CRYPTO_CFLAGS" + SECP_TEST_LIBS="$CRYPTO_LIBS" + + case $host in + *mingw*) + SECP_TEST_LIBS="$SECP_TEST_LIBS -lgdi32" + ;; + esac + fi + else + if test x"$enable_openssl_tests" = x"yes"; then + AC_MSG_ERROR([OpenSSL tests requested but OpenSSL with EC support is not available]) + fi + fi +else + if test x"$enable_openssl_tests" = x"yes"; then + AC_MSG_ERROR([OpenSSL tests requested but tests are not enabled]) + fi +fi +if test x"$use_jni" != x"no"; then + AX_JNI_INCLUDE_DIR + have_jni_dependencies=yes + if test x"$enable_module_ecdh" = x"no"; then + have_jni_dependencies=no + fi + if test "x$JNI_INCLUDE_DIRS" = "x"; then + have_jni_dependencies=no + fi + if test "x$have_jni_dependencies" = "xno"; then + if test x"$use_jni" = x"yes"; then + AC_MSG_ERROR([jni support explicitly requested but headers/dependencies were not found. Enable ECDH and try again.]) + fi + AC_MSG_WARN([jni headers/dependencies not found. jni support disabled]) + use_jni=no + else + use_jni=yes + for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS; do + JNI_INCLUDES="$JNI_INCLUDES -I$JNI_INCLUDE_DIR" + done fi fi @@ -327,7 +410,7 @@ if test x"$use_endomorphism" = x"yes"; then AC_DEFINE(USE_ENDOMORPHISM, 1, [Define this symbol to use endomorphism optimization]) fi -if test x"$use_ecmult_static_precomputation" = x"yes"; then +if test x"$set_precomp" = x"yes"; then AC_DEFINE(USE_ECMULT_STATIC_PRECOMPUTATION, 1, [Define this symbol to use a statically generated ecmult table]) fi @@ -335,38 +418,57 @@ if test x"$enable_module_ecdh" = x"yes"; then AC_DEFINE(ENABLE_MODULE_ECDH, 1, [Define this symbol to enable the ECDH module]) fi -if test x"$enable_module_schnorr" = x"yes"; then - AC_DEFINE(ENABLE_MODULE_SCHNORR, 1, [Define this symbol to enable the Schnorr signature module]) -fi - if test x"$enable_module_recovery" = x"yes"; then AC_DEFINE(ENABLE_MODULE_RECOVERY, 1, [Define this symbol to enable the ECDSA pubkey recovery module]) fi AC_C_BIGENDIAN() +if test x"$use_external_asm" = x"yes"; then + AC_DEFINE(USE_EXTERNAL_ASM, 1, [Define this symbol if an external (non-inline) assembly implementation is used]) +fi + +AC_MSG_NOTICE([Using static precomputation: $set_precomp]) AC_MSG_NOTICE([Using assembly optimizations: $set_asm]) AC_MSG_NOTICE([Using field implementation: $set_field]) AC_MSG_NOTICE([Using bignum implementation: $set_bignum]) AC_MSG_NOTICE([Using scalar implementation: $set_scalar]) AC_MSG_NOTICE([Using endomorphism optimizations: $use_endomorphism]) AC_MSG_NOTICE([Building ECDH module: $enable_module_ecdh]) - -AC_MSG_NOTICE([Building Schnorr signatures module: $enable_module_schnorr]) AC_MSG_NOTICE([Building ECDSA pubkey recovery module: $enable_module_recovery]) +AC_MSG_NOTICE([Using jni: $use_jni]) + +if test x"$enable_experimental" = x"yes"; then + AC_MSG_NOTICE([******]) + AC_MSG_NOTICE([WARNING: experimental build]) + AC_MSG_NOTICE([Experimental features do not have stable APIs or properties, and may not be safe for production use.]) + AC_MSG_NOTICE([Building ECDH module: $enable_module_ecdh]) + AC_MSG_NOTICE([******]) +else + if test x"$enable_module_ecdh" = x"yes"; then + AC_MSG_ERROR([ECDH module is experimental. Use --enable-experimental to allow.]) + fi + if test x"$set_asm" = x"arm"; then + AC_MSG_ERROR([ARM assembly optimization is experimental. Use --enable-experimental to allow.]) + fi +fi AC_CONFIG_HEADERS([src/libsecp256k1-config.h]) AC_CONFIG_FILES([Makefile libsecp256k1.pc]) +AC_SUBST(JNI_INCLUDES) AC_SUBST(SECP_INCLUDES) AC_SUBST(SECP_LIBS) AC_SUBST(SECP_TEST_LIBS) AC_SUBST(SECP_TEST_INCLUDES) AM_CONDITIONAL([USE_TESTS], [test x"$use_tests" != x"no"]) +AM_CONDITIONAL([USE_EXHAUSTIVE_TESTS], [test x"$use_exhaustive_tests" != x"no"]) AM_CONDITIONAL([USE_BENCHMARK], [test x"$use_benchmark" = x"yes"]) -AM_CONDITIONAL([USE_ECMULT_STATIC_PRECOMPUTATION], [test x"$use_ecmult_static_precomputation" = x"yes"]) +AM_CONDITIONAL([USE_ECMULT_STATIC_PRECOMPUTATION], [test x"$set_precomp" = x"yes"]) AM_CONDITIONAL([ENABLE_MODULE_ECDH], [test x"$enable_module_ecdh" = x"yes"]) -AM_CONDITIONAL([ENABLE_MODULE_SCHNORR], [test x"$enable_module_schnorr" = x"yes"]) AM_CONDITIONAL([ENABLE_MODULE_RECOVERY], [test x"$enable_module_recovery" = x"yes"]) +AM_CONDITIONAL([USE_JNI], [test x"$use_jni" == x"yes"]) +AM_CONDITIONAL([USE_EXTERNAL_ASM], [test x"$use_external_asm" = x"yes"]) +AM_CONDITIONAL([USE_ASM_ARM], [test x"$set_asm" = x"arm"]) dnl make sure nothing new is exported so that we don't break the cache PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH" diff --git a/src/secp256k1/include/secp256k1.h b/src/secp256k1/include/secp256k1.h index 7145dbcc54a..f268e309d0b 100644 --- a/src/secp256k1/include/secp256k1.h +++ b/src/secp256k1/include/secp256k1.h @@ -47,11 +47,8 @@ typedef struct secp256k1_context_struct secp256k1_context; * The exact representation of data inside is implementation defined and not * guaranteed to be portable between different platforms or versions. It is * however guaranteed to be 64 bytes in size, and can be safely copied/moved. - * If you need to convert to a format suitable for storage or transmission, use - * secp256k1_ec_pubkey_serialize and secp256k1_ec_pubkey_parse. - * - * Furthermore, it is guaranteed that identical public keys (ignoring - * compression) will have identical representation, so they can be memcmp'ed. + * If you need to convert to a format suitable for storage, transmission, or + * comparison, use secp256k1_ec_pubkey_serialize and secp256k1_ec_pubkey_parse. */ typedef struct { unsigned char data[64]; @@ -62,12 +59,9 @@ typedef struct { * The exact representation of data inside is implementation defined and not * guaranteed to be portable between different platforms or versions. It is * however guaranteed to be 64 bytes in size, and can be safely copied/moved. - * If you need to convert to a format suitable for storage or transmission, use - * the secp256k1_ecdsa_signature_serialize_* and + * If you need to convert to a format suitable for storage, transmission, or + * comparison, use the secp256k1_ecdsa_signature_serialize_* and * secp256k1_ecdsa_signature_serialize_* functions. - * - * Furthermore, it is guaranteed to identical signatures will have identical - * representation, so they can be memcmp'ed. */ typedef struct { unsigned char data[64]; diff --git a/src/secp256k1/include/secp256k1_schnorr.h b/src/secp256k1/include/secp256k1_schnorr.h deleted file mode 100644 index dc32fec1eac..00000000000 --- a/src/secp256k1/include/secp256k1_schnorr.h +++ /dev/null @@ -1,173 +0,0 @@ -#ifndef _SECP256K1_SCHNORR_ -# define _SECP256K1_SCHNORR_ - -# include "secp256k1.h" - -# ifdef __cplusplus -extern "C" { -# endif - -/** Create a signature using a custom EC-Schnorr-SHA256 construction. It - * produces non-malleable 64-byte signatures which support public key recovery - * batch validation, and multiparty signing. - * Returns: 1: signature created - * 0: the nonce generation function failed, or the private key was - * invalid. - * Args: ctx: pointer to a context object, initialized for signing - * (cannot be NULL) - * Out: sig64: pointer to a 64-byte array where the signature will be - * placed (cannot be NULL) - * In: msg32: the 32-byte message hash being signed (cannot be NULL) - * seckey: pointer to a 32-byte secret key (cannot be NULL) - * noncefp:pointer to a nonce generation function. If NULL, - * secp256k1_nonce_function_default is used - * ndata: pointer to arbitrary data used by the nonce generation - * function (can be NULL) - */ -SECP256K1_API int secp256k1_schnorr_sign( - const secp256k1_context* ctx, - unsigned char *sig64, - const unsigned char *msg32, - const unsigned char *seckey, - secp256k1_nonce_function noncefp, - const void *ndata -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Verify a signature created by secp256k1_schnorr_sign. - * Returns: 1: correct signature - * 0: incorrect signature - * Args: ctx: a secp256k1 context object, initialized for verification. - * In: sig64: the 64-byte signature being verified (cannot be NULL) - * msg32: the 32-byte message hash being verified (cannot be NULL) - * pubkey: the public key to verify with (cannot be NULL) - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_verify( - const secp256k1_context* ctx, - const unsigned char *sig64, - const unsigned char *msg32, - const secp256k1_pubkey *pubkey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Recover an EC public key from a Schnorr signature created using - * secp256k1_schnorr_sign. - * Returns: 1: public key successfully recovered (which guarantees a correct - * signature). - * 0: otherwise. - * Args: ctx: pointer to a context object, initialized for - * verification (cannot be NULL) - * Out: pubkey: pointer to a pubkey to set to the recovered public key - * (cannot be NULL). - * In: sig64: signature as 64 byte array (cannot be NULL) - * msg32: the 32-byte message hash assumed to be signed (cannot - * be NULL) - */ -SECP256K1_API int secp256k1_schnorr_recover( - const secp256k1_context* ctx, - secp256k1_pubkey *pubkey, - const unsigned char *sig64, - const unsigned char *msg32 -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Generate a nonce pair deterministically for use with - * secp256k1_schnorr_partial_sign. - * Returns: 1: valid nonce pair was generated. - * 0: otherwise (nonce generation function failed) - * Args: ctx: pointer to a context object, initialized for signing - * (cannot be NULL) - * Out: pubnonce: public side of the nonce (cannot be NULL) - * privnonce32: private side of the nonce (32 byte) (cannot be NULL) - * In: msg32: the 32-byte message hash assumed to be signed (cannot - * be NULL) - * sec32: the 32-byte private key (cannot be NULL) - * noncefp: pointer to a nonce generation function. If NULL, - * secp256k1_nonce_function_default is used - * noncedata: pointer to arbitrary data used by the nonce generation - * function (can be NULL) - * - * Do not use the output as a private/public key pair for signing/validation. - */ -SECP256K1_API int secp256k1_schnorr_generate_nonce_pair( - const secp256k1_context* ctx, - secp256k1_pubkey *pubnonce, - unsigned char *privnonce32, - const unsigned char *msg32, - const unsigned char *sec32, - secp256k1_nonce_function noncefp, - const void* noncedata -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Produce a partial Schnorr signature, which can be combined using - * secp256k1_schnorr_partial_combine, to end up with a full signature that is - * verifiable using secp256k1_schnorr_verify. - * Returns: 1: signature created successfully. - * 0: no valid signature exists with this combination of keys, nonces - * and message (chance around 1 in 2^128) - * -1: invalid private key, nonce, or public nonces. - * Args: ctx: pointer to context object, initialized for signing (cannot - * be NULL) - * Out: sig64: pointer to 64-byte array to put partial signature in - * In: msg32: pointer to 32-byte message to sign - * sec32: pointer to 32-byte private key - * pubnonce_others: pointer to pubkey containing the sum of the other's - * nonces (see secp256k1_ec_pubkey_combine) - * secnonce32: pointer to 32-byte array containing our nonce - * - * The intended procedure for creating a multiparty signature is: - * - Each signer S[i] with private key x[i] and public key Q[i] runs - * secp256k1_schnorr_generate_nonce_pair to produce a pair (k[i],R[i]) of - * private/public nonces. - * - All signers communicate their public nonces to each other (revealing your - * private nonce can lead to discovery of your private key, so it should be - * considered secret). - * - All signers combine all the public nonces they received (excluding their - * own) using secp256k1_ec_pubkey_combine to obtain an - * Rall[i] = sum(R[0..i-1,i+1..n]). - * - All signers produce a partial signature using - * secp256k1_schnorr_partial_sign, passing in their own private key x[i], - * their own private nonce k[i], and the sum of the others' public nonces - * Rall[i]. - * - All signers communicate their partial signatures to each other. - * - Someone combines all partial signatures using - * secp256k1_schnorr_partial_combine, to obtain a full signature. - * - The resulting signature is validatable using secp256k1_schnorr_verify, with - * public key equal to the result of secp256k1_ec_pubkey_combine of the - * signers' public keys (sum(Q[0..n])). - * - * Note that secp256k1_schnorr_partial_combine and secp256k1_ec_pubkey_combine - * function take their arguments in any order, and it is possible to - * pre-combine several inputs already with one call, and add more inputs later - * by calling the function again (they are commutative and associative). - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_partial_sign( - const secp256k1_context* ctx, - unsigned char *sig64, - const unsigned char *msg32, - const unsigned char *sec32, - const secp256k1_pubkey *pubnonce_others, - const unsigned char *secnonce32 -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6); - -/** Combine multiple Schnorr partial signatures. - * Returns: 1: the passed signatures were successfully combined. - * 0: the resulting signature is not valid (chance of 1 in 2^256) - * -1: some inputs were invalid, or the signatures were not created - * using the same set of nonces - * Args: ctx: pointer to a context object - * Out: sig64: pointer to a 64-byte array to place the combined signature - * (cannot be NULL) - * In: sig64sin: pointer to an array of n pointers to 64-byte input - * signatures - * n: the number of signatures to combine (at least 1) - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_partial_combine( - const secp256k1_context* ctx, - unsigned char *sig64, - const unsigned char * const * sig64sin, - size_t n -) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -# ifdef __cplusplus -} -# endif - -#endif diff --git a/src/secp256k1/libsecp256k1.pc.in b/src/secp256k1/libsecp256k1.pc.in index 1c72dd00037..a0d006f1131 100644 --- a/src/secp256k1/libsecp256k1.pc.in +++ b/src/secp256k1/libsecp256k1.pc.in @@ -5,7 +5,7 @@ includedir=@includedir@ Name: libsecp256k1 Description: Optimized C library for EC operations on curve secp256k1 -URL: https://github.com/bitcoin/secp256k1 +URL: https://github.com/bitcoin-core/secp256k1 Version: @PACKAGE_VERSION@ Cflags: -I${includedir} Libs.private: @SECP_LIBS@ diff --git a/src/secp256k1/sage/group_prover.sage b/src/secp256k1/sage/group_prover.sage new file mode 100644 index 00000000000..ab580c5b23b --- /dev/null +++ b/src/secp256k1/sage/group_prover.sage @@ -0,0 +1,322 @@ +# This code supports verifying group implementations which have branches +# or conditional statements (like cmovs), by allowing each execution path +# to independently set assumptions on input or intermediary variables. +# +# The general approach is: +# * A constraint is a tuple of two sets of of symbolic expressions: +# the first of which are required to evaluate to zero, the second of which +# are required to evaluate to nonzero. +# - A constraint is said to be conflicting if any of its nonzero expressions +# is in the ideal with basis the zero expressions (in other words: when the +# zero expressions imply that one of the nonzero expressions are zero). +# * There is a list of laws that describe the intended behaviour, including +# laws for addition and doubling. Each law is called with the symbolic point +# coordinates as arguments, and returns: +# - A constraint describing the assumptions under which it is applicable, +# called "assumeLaw" +# - A constraint describing the requirements of the law, called "require" +# * Implementations are transliterated into functions that operate as well on +# algebraic input points, and are called once per combination of branches +# exectured. Each execution returns: +# - A constraint describing the assumptions this implementation requires +# (such as Z1=1), called "assumeFormula" +# - A constraint describing the assumptions this specific branch requires, +# but which is by construction guaranteed to cover the entire space by +# merging the results from all branches, called "assumeBranch" +# - The result of the computation +# * All combinations of laws with implementation branches are tried, and: +# - If the combination of assumeLaw, assumeFormula, and assumeBranch results +# in a conflict, it means this law does not apply to this branch, and it is +# skipped. +# - For others, we try to prove the require constraints hold, assuming the +# information in assumeLaw + assumeFormula + assumeBranch, and if this does +# not succeed, we fail. +# + To prove an expression is zero, we check whether it belongs to the +# ideal with the assumed zero expressions as basis. This test is exact. +# + To prove an expression is nonzero, we check whether each of its +# factors is contained in the set of nonzero assumptions' factors. +# This test is not exact, so various combinations of original and +# reduced expressions' factors are tried. +# - If we succeed, we print out the assumptions from assumeFormula that +# weren't implied by assumeLaw already. Those from assumeBranch are skipped, +# as we assume that all constraints in it are complementary with each other. +# +# Based on the sage verification scripts used in the Explicit-Formulas Database +# by Tanja Lange and others, see http://hyperelliptic.org/EFD + +class fastfrac: + """Fractions over rings.""" + + def __init__(self,R,top,bot=1): + """Construct a fractional, given a ring, a numerator, and denominator.""" + self.R = R + if parent(top) == ZZ or parent(top) == R: + self.top = R(top) + self.bot = R(bot) + elif top.__class__ == fastfrac: + self.top = top.top + self.bot = top.bot * bot + else: + self.top = R(numerator(top)) + self.bot = R(denominator(top)) * bot + + def iszero(self,I): + """Return whether this fraction is zero given an ideal.""" + return self.top in I and self.bot not in I + + def reduce(self,assumeZero): + zero = self.R.ideal(map(numerator, assumeZero)) + return fastfrac(self.R, zero.reduce(self.top)) / fastfrac(self.R, zero.reduce(self.bot)) + + def __add__(self,other): + """Add two fractions.""" + if parent(other) == ZZ: + return fastfrac(self.R,self.top + self.bot * other,self.bot) + if other.__class__ == fastfrac: + return fastfrac(self.R,self.top * other.bot + self.bot * other.top,self.bot * other.bot) + return NotImplemented + + def __sub__(self,other): + """Subtract two fractions.""" + if parent(other) == ZZ: + return fastfrac(self.R,self.top - self.bot * other,self.bot) + if other.__class__ == fastfrac: + return fastfrac(self.R,self.top * other.bot - self.bot * other.top,self.bot * other.bot) + return NotImplemented + + def __neg__(self): + """Return the negation of a fraction.""" + return fastfrac(self.R,-self.top,self.bot) + + def __mul__(self,other): + """Multiply two fractions.""" + if parent(other) == ZZ: + return fastfrac(self.R,self.top * other,self.bot) + if other.__class__ == fastfrac: + return fastfrac(self.R,self.top * other.top,self.bot * other.bot) + return NotImplemented + + def __rmul__(self,other): + """Multiply something else with a fraction.""" + return self.__mul__(other) + + def __div__(self,other): + """Divide two fractions.""" + if parent(other) == ZZ: + return fastfrac(self.R,self.top,self.bot * other) + if other.__class__ == fastfrac: + return fastfrac(self.R,self.top * other.bot,self.bot * other.top) + return NotImplemented + + def __pow__(self,other): + """Compute a power of a fraction.""" + if parent(other) == ZZ: + if other < 0: + # Negative powers require flipping top and bottom + return fastfrac(self.R,self.bot ^ (-other),self.top ^ (-other)) + else: + return fastfrac(self.R,self.top ^ other,self.bot ^ other) + return NotImplemented + + def __str__(self): + return "fastfrac((" + str(self.top) + ") / (" + str(self.bot) + "))" + def __repr__(self): + return "%s" % self + + def numerator(self): + return self.top + +class constraints: + """A set of constraints, consisting of zero and nonzero expressions. + + Constraints can either be used to express knowledge or a requirement. + + Both the fields zero and nonzero are maps from expressions to description + strings. The expressions that are the keys in zero are required to be zero, + and the expressions that are the keys in nonzero are required to be nonzero. + + Note that (a != 0) and (b != 0) is the same as (a*b != 0), so all keys in + nonzero could be multiplied into a single key. This is often much less + efficient to work with though, so we keep them separate inside the + constraints. This allows higher-level code to do fast checks on the individual + nonzero elements, or combine them if needed for stronger checks. + + We can't multiply the different zero elements, as it would suffice for one of + the factors to be zero, instead of all of them. Instead, the zero elements are + typically combined into an ideal first. + """ + + def __init__(self, **kwargs): + if 'zero' in kwargs: + self.zero = dict(kwargs['zero']) + else: + self.zero = dict() + if 'nonzero' in kwargs: + self.nonzero = dict(kwargs['nonzero']) + else: + self.nonzero = dict() + + def negate(self): + return constraints(zero=self.nonzero, nonzero=self.zero) + + def __add__(self, other): + zero = self.zero.copy() + zero.update(other.zero) + nonzero = self.nonzero.copy() + nonzero.update(other.nonzero) + return constraints(zero=zero, nonzero=nonzero) + + def __str__(self): + return "constraints(zero=%s,nonzero=%s)" % (self.zero, self.nonzero) + + def __repr__(self): + return "%s" % self + + +def conflicts(R, con): + """Check whether any of the passed non-zero assumptions is implied by the zero assumptions""" + zero = R.ideal(map(numerator, con.zero)) + if 1 in zero: + return True + # First a cheap check whether any of the individual nonzero terms conflict on + # their own. + for nonzero in con.nonzero: + if nonzero.iszero(zero): + return True + # It can be the case that entries in the nonzero set do not individually + # conflict with the zero set, but their combination does. For example, knowing + # that either x or y is zero is equivalent to having x*y in the zero set. + # Having x or y individually in the nonzero set is not a conflict, but both + # simultaneously is, so that is the right thing to check for. + if reduce(lambda a,b: a * b, con.nonzero, fastfrac(R, 1)).iszero(zero): + return True + return False + + +def get_nonzero_set(R, assume): + """Calculate a simple set of nonzero expressions""" + zero = R.ideal(map(numerator, assume.zero)) + nonzero = set() + for nz in map(numerator, assume.nonzero): + for (f,n) in nz.factor(): + nonzero.add(f) + rnz = zero.reduce(nz) + for (f,n) in rnz.factor(): + nonzero.add(f) + return nonzero + + +def prove_nonzero(R, exprs, assume): + """Check whether an expression is provably nonzero, given assumptions""" + zero = R.ideal(map(numerator, assume.zero)) + nonzero = get_nonzero_set(R, assume) + expl = set() + ok = True + for expr in exprs: + if numerator(expr) in zero: + return (False, [exprs[expr]]) + allexprs = reduce(lambda a,b: numerator(a)*numerator(b), exprs, 1) + for (f, n) in allexprs.factor(): + if f not in nonzero: + ok = False + if ok: + return (True, None) + ok = True + for (f, n) in zero.reduce(numerator(allexprs)).factor(): + if f not in nonzero: + ok = False + if ok: + return (True, None) + ok = True + for expr in exprs: + for (f,n) in numerator(expr).factor(): + if f not in nonzero: + ok = False + if ok: + return (True, None) + ok = True + for expr in exprs: + for (f,n) in zero.reduce(numerator(expr)).factor(): + if f not in nonzero: + expl.add(exprs[expr]) + if expl: + return (False, list(expl)) + else: + return (True, None) + + +def prove_zero(R, exprs, assume): + """Check whether all of the passed expressions are provably zero, given assumptions""" + r, e = prove_nonzero(R, dict(map(lambda x: (fastfrac(R, x.bot, 1), exprs[x]), exprs)), assume) + if not r: + return (False, map(lambda x: "Possibly zero denominator: %s" % x, e)) + zero = R.ideal(map(numerator, assume.zero)) + nonzero = prod(x for x in assume.nonzero) + expl = [] + for expr in exprs: + if not expr.iszero(zero): + expl.append(exprs[expr]) + if not expl: + return (True, None) + return (False, expl) + + +def describe_extra(R, assume, assumeExtra): + """Describe what assumptions are added, given existing assumptions""" + zerox = assume.zero.copy() + zerox.update(assumeExtra.zero) + zero = R.ideal(map(numerator, assume.zero)) + zeroextra = R.ideal(map(numerator, zerox)) + nonzero = get_nonzero_set(R, assume) + ret = set() + # Iterate over the extra zero expressions + for base in assumeExtra.zero: + if base not in zero: + add = [] + for (f, n) in numerator(base).factor(): + if f not in nonzero: + add += ["%s" % f] + if add: + ret.add((" * ".join(add)) + " = 0 [%s]" % assumeExtra.zero[base]) + # Iterate over the extra nonzero expressions + for nz in assumeExtra.nonzero: + nzr = zeroextra.reduce(numerator(nz)) + if nzr not in zeroextra: + for (f,n) in nzr.factor(): + if zeroextra.reduce(f) not in nonzero: + ret.add("%s != 0" % zeroextra.reduce(f)) + return ", ".join(x for x in ret) + + +def check_symbolic(R, assumeLaw, assumeAssert, assumeBranch, require): + """Check a set of zero and nonzero requirements, given a set of zero and nonzero assumptions""" + assume = assumeLaw + assumeAssert + assumeBranch + + if conflicts(R, assume): + # This formula does not apply + return None + + describe = describe_extra(R, assumeLaw + assumeBranch, assumeAssert) + + ok, msg = prove_zero(R, require.zero, assume) + if not ok: + return "FAIL, %s fails (assuming %s)" % (str(msg), describe) + + res, expl = prove_nonzero(R, require.nonzero, assume) + if not res: + return "FAIL, %s fails (assuming %s)" % (str(expl), describe) + + if describe != "": + return "OK (assuming %s)" % describe + else: + return "OK" + + +def concrete_verify(c): + for k in c.zero: + if k != 0: + return (False, c.zero[k]) + for k in c.nonzero: + if k == 0: + return (False, c.nonzero[k]) + return (True, None) diff --git a/src/secp256k1/sage/secp256k1.sage b/src/secp256k1/sage/secp256k1.sage new file mode 100644 index 00000000000..a97e732f7fa --- /dev/null +++ b/src/secp256k1/sage/secp256k1.sage @@ -0,0 +1,306 @@ +# Test libsecp256k1' group operation implementations using prover.sage + +import sys + +load("group_prover.sage") +load("weierstrass_prover.sage") + +def formula_secp256k1_gej_double_var(a): + """libsecp256k1's secp256k1_gej_double_var, used by various addition functions""" + rz = a.Z * a.Y + rz = rz * 2 + t1 = a.X^2 + t1 = t1 * 3 + t2 = t1^2 + t3 = a.Y^2 + t3 = t3 * 2 + t4 = t3^2 + t4 = t4 * 2 + t3 = t3 * a.X + rx = t3 + rx = rx * 4 + rx = -rx + rx = rx + t2 + t2 = -t2 + t3 = t3 * 6 + t3 = t3 + t2 + ry = t1 * t3 + t2 = -t4 + ry = ry + t2 + return jacobianpoint(rx, ry, rz) + +def formula_secp256k1_gej_add_var(branch, a, b): + """libsecp256k1's secp256k1_gej_add_var""" + if branch == 0: + return (constraints(), constraints(nonzero={a.Infinity : 'a_infinite'}), b) + if branch == 1: + return (constraints(), constraints(zero={a.Infinity : 'a_finite'}, nonzero={b.Infinity : 'b_infinite'}), a) + z22 = b.Z^2 + z12 = a.Z^2 + u1 = a.X * z22 + u2 = b.X * z12 + s1 = a.Y * z22 + s1 = s1 * b.Z + s2 = b.Y * z12 + s2 = s2 * a.Z + h = -u1 + h = h + u2 + i = -s1 + i = i + s2 + if branch == 2: + r = formula_secp256k1_gej_double_var(a) + return (constraints(), constraints(zero={h : 'h=0', i : 'i=0', a.Infinity : 'a_finite', b.Infinity : 'b_finite'}), r) + if branch == 3: + return (constraints(), constraints(zero={h : 'h=0', a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={i : 'i!=0'}), point_at_infinity()) + i2 = i^2 + h2 = h^2 + h3 = h2 * h + h = h * b.Z + rz = a.Z * h + t = u1 * h2 + rx = t + rx = rx * 2 + rx = rx + h3 + rx = -rx + rx = rx + i2 + ry = -rx + ry = ry + t + ry = ry * i + h3 = h3 * s1 + h3 = -h3 + ry = ry + h3 + return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz)) + +def formula_secp256k1_gej_add_ge_var(branch, a, b): + """libsecp256k1's secp256k1_gej_add_ge_var, which assume bz==1""" + if branch == 0: + return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(nonzero={a.Infinity : 'a_infinite'}), b) + if branch == 1: + return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite'}, nonzero={b.Infinity : 'b_infinite'}), a) + z12 = a.Z^2 + u1 = a.X + u2 = b.X * z12 + s1 = a.Y + s2 = b.Y * z12 + s2 = s2 * a.Z + h = -u1 + h = h + u2 + i = -s1 + i = i + s2 + if (branch == 2): + r = formula_secp256k1_gej_double_var(a) + return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0', i : 'i=0'}), r) + if (branch == 3): + return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0'}, nonzero={i : 'i!=0'}), point_at_infinity()) + i2 = i^2 + h2 = h^2 + h3 = h * h2 + rz = a.Z * h + t = u1 * h2 + rx = t + rx = rx * 2 + rx = rx + h3 + rx = -rx + rx = rx + i2 + ry = -rx + ry = ry + t + ry = ry * i + h3 = h3 * s1 + h3 = -h3 + ry = ry + h3 + return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz)) + +def formula_secp256k1_gej_add_zinv_var(branch, a, b): + """libsecp256k1's secp256k1_gej_add_zinv_var""" + bzinv = b.Z^(-1) + if branch == 0: + return (constraints(), constraints(nonzero={b.Infinity : 'b_infinite'}), a) + if branch == 1: + bzinv2 = bzinv^2 + bzinv3 = bzinv2 * bzinv + rx = b.X * bzinv2 + ry = b.Y * bzinv3 + rz = 1 + return (constraints(), constraints(zero={b.Infinity : 'b_finite'}, nonzero={a.Infinity : 'a_infinite'}), jacobianpoint(rx, ry, rz)) + azz = a.Z * bzinv + z12 = azz^2 + u1 = a.X + u2 = b.X * z12 + s1 = a.Y + s2 = b.Y * z12 + s2 = s2 * azz + h = -u1 + h = h + u2 + i = -s1 + i = i + s2 + if branch == 2: + r = formula_secp256k1_gej_double_var(a) + return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0', i : 'i=0'}), r) + if branch == 3: + return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0'}, nonzero={i : 'i!=0'}), point_at_infinity()) + i2 = i^2 + h2 = h^2 + h3 = h * h2 + rz = a.Z + rz = rz * h + t = u1 * h2 + rx = t + rx = rx * 2 + rx = rx + h3 + rx = -rx + rx = rx + i2 + ry = -rx + ry = ry + t + ry = ry * i + h3 = h3 * s1 + h3 = -h3 + ry = ry + h3 + return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz)) + +def formula_secp256k1_gej_add_ge(branch, a, b): + """libsecp256k1's secp256k1_gej_add_ge""" + zeroes = {} + nonzeroes = {} + a_infinity = False + if (branch & 4) != 0: + nonzeroes.update({a.Infinity : 'a_infinite'}) + a_infinity = True + else: + zeroes.update({a.Infinity : 'a_finite'}) + zz = a.Z^2 + u1 = a.X + u2 = b.X * zz + s1 = a.Y + s2 = b.Y * zz + s2 = s2 * a.Z + t = u1 + t = t + u2 + m = s1 + m = m + s2 + rr = t^2 + m_alt = -u2 + tt = u1 * m_alt + rr = rr + tt + degenerate = (branch & 3) == 3 + if (branch & 1) != 0: + zeroes.update({m : 'm_zero'}) + else: + nonzeroes.update({m : 'm_nonzero'}) + if (branch & 2) != 0: + zeroes.update({rr : 'rr_zero'}) + else: + nonzeroes.update({rr : 'rr_nonzero'}) + rr_alt = s1 + rr_alt = rr_alt * 2 + m_alt = m_alt + u1 + if not degenerate: + rr_alt = rr + m_alt = m + n = m_alt^2 + q = n * t + n = n^2 + if degenerate: + n = m + t = rr_alt^2 + rz = a.Z * m_alt + infinity = False + if (branch & 8) != 0: + if not a_infinity: + infinity = True + zeroes.update({rz : 'r.z=0'}) + else: + nonzeroes.update({rz : 'r.z!=0'}) + rz = rz * 2 + q = -q + t = t + q + rx = t + t = t * 2 + t = t + q + t = t * rr_alt + t = t + n + ry = -t + rx = rx * 4 + ry = ry * 4 + if a_infinity: + rx = b.X + ry = b.Y + rz = 1 + if infinity: + return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zeroes, nonzero=nonzeroes), point_at_infinity()) + return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zeroes, nonzero=nonzeroes), jacobianpoint(rx, ry, rz)) + +def formula_secp256k1_gej_add_ge_old(branch, a, b): + """libsecp256k1's old secp256k1_gej_add_ge, which fails when ay+by=0 but ax!=bx""" + a_infinity = (branch & 1) != 0 + zero = {} + nonzero = {} + if a_infinity: + nonzero.update({a.Infinity : 'a_infinite'}) + else: + zero.update({a.Infinity : 'a_finite'}) + zz = a.Z^2 + u1 = a.X + u2 = b.X * zz + s1 = a.Y + s2 = b.Y * zz + s2 = s2 * a.Z + z = a.Z + t = u1 + t = t + u2 + m = s1 + m = m + s2 + n = m^2 + q = n * t + n = n^2 + rr = t^2 + t = u1 * u2 + t = -t + rr = rr + t + t = rr^2 + rz = m * z + infinity = False + if (branch & 2) != 0: + if not a_infinity: + infinity = True + else: + return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(nonzero={z : 'conflict_a'}, zero={z : 'conflict_b'}), point_at_infinity()) + zero.update({rz : 'r.z=0'}) + else: + nonzero.update({rz : 'r.z!=0'}) + rz = rz * (0 if a_infinity else 2) + rx = t + q = -q + rx = rx + q + q = q * 3 + t = t * 2 + t = t + q + t = t * rr + t = t + n + ry = -t + rx = rx * (0 if a_infinity else 4) + ry = ry * (0 if a_infinity else 4) + t = b.X + t = t * (1 if a_infinity else 0) + rx = rx + t + t = b.Y + t = t * (1 if a_infinity else 0) + ry = ry + t + t = (1 if a_infinity else 0) + rz = rz + t + if infinity: + return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zero, nonzero=nonzero), point_at_infinity()) + return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zero, nonzero=nonzero), jacobianpoint(rx, ry, rz)) + +if __name__ == "__main__": + check_symbolic_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var) + check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var) + check_symbolic_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var) + check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 16, formula_secp256k1_gej_add_ge) + check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old) + + if len(sys.argv) >= 2 and sys.argv[1] == "--exhaustive": + check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var, 43) + check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var, 43) + check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var, 43) + check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 16, formula_secp256k1_gej_add_ge, 43) + check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old, 43) diff --git a/src/secp256k1/sage/weierstrass_prover.sage b/src/secp256k1/sage/weierstrass_prover.sage new file mode 100644 index 00000000000..03ef2ec901e --- /dev/null +++ b/src/secp256k1/sage/weierstrass_prover.sage @@ -0,0 +1,264 @@ +# Prover implementation for Weierstrass curves of the form +# y^2 = x^3 + A * x + B, specifically with a = 0 and b = 7, with group laws +# operating on affine and Jacobian coordinates, including the point at infinity +# represented by a 4th variable in coordinates. + +load("group_prover.sage") + + +class affinepoint: + def __init__(self, x, y, infinity=0): + self.x = x + self.y = y + self.infinity = infinity + def __str__(self): + return "affinepoint(x=%s,y=%s,inf=%s)" % (self.x, self.y, self.infinity) + + +class jacobianpoint: + def __init__(self, x, y, z, infinity=0): + self.X = x + self.Y = y + self.Z = z + self.Infinity = infinity + def __str__(self): + return "jacobianpoint(X=%s,Y=%s,Z=%s,inf=%s)" % (self.X, self.Y, self.Z, self.Infinity) + + +def point_at_infinity(): + return jacobianpoint(1, 1, 1, 1) + + +def negate(p): + if p.__class__ == affinepoint: + return affinepoint(p.x, -p.y) + if p.__class__ == jacobianpoint: + return jacobianpoint(p.X, -p.Y, p.Z) + assert(False) + + +def on_weierstrass_curve(A, B, p): + """Return a set of zero-expressions for an affine point to be on the curve""" + return constraints(zero={p.x^3 + A*p.x + B - p.y^2: 'on_curve'}) + + +def tangential_to_weierstrass_curve(A, B, p12, p3): + """Return a set of zero-expressions for ((x12,y12),(x3,y3)) to be a line that is tangential to the curve at (x12,y12)""" + return constraints(zero={ + (p12.y - p3.y) * (p12.y * 2) - (p12.x^2 * 3 + A) * (p12.x - p3.x): 'tangential_to_curve' + }) + + +def colinear(p1, p2, p3): + """Return a set of zero-expressions for ((x1,y1),(x2,y2),(x3,y3)) to be collinear""" + return constraints(zero={ + (p1.y - p2.y) * (p1.x - p3.x) - (p1.y - p3.y) * (p1.x - p2.x): 'colinear_1', + (p2.y - p3.y) * (p2.x - p1.x) - (p2.y - p1.y) * (p2.x - p3.x): 'colinear_2', + (p3.y - p1.y) * (p3.x - p2.x) - (p3.y - p2.y) * (p3.x - p1.x): 'colinear_3' + }) + + +def good_affine_point(p): + return constraints(nonzero={p.x : 'nonzero_x', p.y : 'nonzero_y'}) + + +def good_jacobian_point(p): + return constraints(nonzero={p.X : 'nonzero_X', p.Y : 'nonzero_Y', p.Z^6 : 'nonzero_Z'}) + + +def good_point(p): + return constraints(nonzero={p.Z^6 : 'nonzero_X'}) + + +def finite(p, *affine_fns): + con = good_point(p) + constraints(zero={p.Infinity : 'finite_point'}) + if p.Z != 0: + return con + reduce(lambda a, b: a + b, (f(affinepoint(p.X / p.Z^2, p.Y / p.Z^3)) for f in affine_fns), con) + else: + return con + +def infinite(p): + return constraints(nonzero={p.Infinity : 'infinite_point'}) + + +def law_jacobian_weierstrass_add(A, B, pa, pb, pA, pB, pC): + """Check whether the passed set of coordinates is a valid Jacobian add, given assumptions""" + assumeLaw = (good_affine_point(pa) + + good_affine_point(pb) + + good_jacobian_point(pA) + + good_jacobian_point(pB) + + on_weierstrass_curve(A, B, pa) + + on_weierstrass_curve(A, B, pb) + + finite(pA) + + finite(pB) + + constraints(nonzero={pa.x - pb.x : 'different_x'})) + require = (finite(pC, lambda pc: on_weierstrass_curve(A, B, pc) + + colinear(pa, pb, negate(pc)))) + return (assumeLaw, require) + + +def law_jacobian_weierstrass_double(A, B, pa, pb, pA, pB, pC): + """Check whether the passed set of coordinates is a valid Jacobian doubling, given assumptions""" + assumeLaw = (good_affine_point(pa) + + good_affine_point(pb) + + good_jacobian_point(pA) + + good_jacobian_point(pB) + + on_weierstrass_curve(A, B, pa) + + on_weierstrass_curve(A, B, pb) + + finite(pA) + + finite(pB) + + constraints(zero={pa.x - pb.x : 'equal_x', pa.y - pb.y : 'equal_y'})) + require = (finite(pC, lambda pc: on_weierstrass_curve(A, B, pc) + + tangential_to_weierstrass_curve(A, B, pa, negate(pc)))) + return (assumeLaw, require) + + +def law_jacobian_weierstrass_add_opposites(A, B, pa, pb, pA, pB, pC): + assumeLaw = (good_affine_point(pa) + + good_affine_point(pb) + + good_jacobian_point(pA) + + good_jacobian_point(pB) + + on_weierstrass_curve(A, B, pa) + + on_weierstrass_curve(A, B, pb) + + finite(pA) + + finite(pB) + + constraints(zero={pa.x - pb.x : 'equal_x', pa.y + pb.y : 'opposite_y'})) + require = infinite(pC) + return (assumeLaw, require) + + +def law_jacobian_weierstrass_add_infinite_a(A, B, pa, pb, pA, pB, pC): + assumeLaw = (good_affine_point(pa) + + good_affine_point(pb) + + good_jacobian_point(pA) + + good_jacobian_point(pB) + + on_weierstrass_curve(A, B, pb) + + infinite(pA) + + finite(pB)) + require = finite(pC, lambda pc: constraints(zero={pc.x - pb.x : 'c.x=b.x', pc.y - pb.y : 'c.y=b.y'})) + return (assumeLaw, require) + + +def law_jacobian_weierstrass_add_infinite_b(A, B, pa, pb, pA, pB, pC): + assumeLaw = (good_affine_point(pa) + + good_affine_point(pb) + + good_jacobian_point(pA) + + good_jacobian_point(pB) + + on_weierstrass_curve(A, B, pa) + + infinite(pB) + + finite(pA)) + require = finite(pC, lambda pc: constraints(zero={pc.x - pa.x : 'c.x=a.x', pc.y - pa.y : 'c.y=a.y'})) + return (assumeLaw, require) + + +def law_jacobian_weierstrass_add_infinite_ab(A, B, pa, pb, pA, pB, pC): + assumeLaw = (good_affine_point(pa) + + good_affine_point(pb) + + good_jacobian_point(pA) + + good_jacobian_point(pB) + + infinite(pA) + + infinite(pB)) + require = infinite(pC) + return (assumeLaw, require) + + +laws_jacobian_weierstrass = { + 'add': law_jacobian_weierstrass_add, + 'double': law_jacobian_weierstrass_double, + 'add_opposite': law_jacobian_weierstrass_add_opposites, + 'add_infinite_a': law_jacobian_weierstrass_add_infinite_a, + 'add_infinite_b': law_jacobian_weierstrass_add_infinite_b, + 'add_infinite_ab': law_jacobian_weierstrass_add_infinite_ab +} + + +def check_exhaustive_jacobian_weierstrass(name, A, B, branches, formula, p): + """Verify an implementation of addition of Jacobian points on a Weierstrass curve, by executing and validating the result for every possible addition in a prime field""" + F = Integers(p) + print "Formula %s on Z%i:" % (name, p) + points = [] + for x in xrange(0, p): + for y in xrange(0, p): + point = affinepoint(F(x), F(y)) + r, e = concrete_verify(on_weierstrass_curve(A, B, point)) + if r: + points.append(point) + + for za in xrange(1, p): + for zb in xrange(1, p): + for pa in points: + for pb in points: + for ia in xrange(2): + for ib in xrange(2): + pA = jacobianpoint(pa.x * F(za)^2, pa.y * F(za)^3, F(za), ia) + pB = jacobianpoint(pb.x * F(zb)^2, pb.y * F(zb)^3, F(zb), ib) + for branch in xrange(0, branches): + assumeAssert, assumeBranch, pC = formula(branch, pA, pB) + pC.X = F(pC.X) + pC.Y = F(pC.Y) + pC.Z = F(pC.Z) + pC.Infinity = F(pC.Infinity) + r, e = concrete_verify(assumeAssert + assumeBranch) + if r: + match = False + for key in laws_jacobian_weierstrass: + assumeLaw, require = laws_jacobian_weierstrass[key](A, B, pa, pb, pA, pB, pC) + r, e = concrete_verify(assumeLaw) + if r: + if match: + print " multiple branches for (%s,%s,%s,%s) + (%s,%s,%s,%s)" % (pA.X, pA.Y, pA.Z, pA.Infinity, pB.X, pB.Y, pB.Z, pB.Infinity) + else: + match = True + r, e = concrete_verify(require) + if not r: + print " failure in branch %i for (%s,%s,%s,%s) + (%s,%s,%s,%s) = (%s,%s,%s,%s): %s" % (branch, pA.X, pA.Y, pA.Z, pA.Infinity, pB.X, pB.Y, pB.Z, pB.Infinity, pC.X, pC.Y, pC.Z, pC.Infinity, e) + print + + +def check_symbolic_function(R, assumeAssert, assumeBranch, f, A, B, pa, pb, pA, pB, pC): + assumeLaw, require = f(A, B, pa, pb, pA, pB, pC) + return check_symbolic(R, assumeLaw, assumeAssert, assumeBranch, require) + +def check_symbolic_jacobian_weierstrass(name, A, B, branches, formula): + """Verify an implementation of addition of Jacobian points on a Weierstrass curve symbolically""" + R. = PolynomialRing(QQ,8,order='invlex') + lift = lambda x: fastfrac(R,x) + ax = lift(ax) + ay = lift(ay) + Az = lift(Az) + bx = lift(bx) + by = lift(by) + Bz = lift(Bz) + Ai = lift(Ai) + Bi = lift(Bi) + + pa = affinepoint(ax, ay, Ai) + pb = affinepoint(bx, by, Bi) + pA = jacobianpoint(ax * Az^2, ay * Az^3, Az, Ai) + pB = jacobianpoint(bx * Bz^2, by * Bz^3, Bz, Bi) + + res = {} + + for key in laws_jacobian_weierstrass: + res[key] = [] + + print ("Formula " + name + ":") + count = 0 + for branch in xrange(branches): + assumeFormula, assumeBranch, pC = formula(branch, pA, pB) + pC.X = lift(pC.X) + pC.Y = lift(pC.Y) + pC.Z = lift(pC.Z) + pC.Infinity = lift(pC.Infinity) + + for key in laws_jacobian_weierstrass: + res[key].append((check_symbolic_function(R, assumeFormula, assumeBranch, laws_jacobian_weierstrass[key], A, B, pa, pb, pA, pB, pC), branch)) + + for key in res: + print " %s:" % key + val = res[key] + for x in val: + if x[0] is not None: + print " branch %i: %s" % (x[1], x[0]) + + print diff --git a/src/secp256k1/src/asm/field_10x26_arm.s b/src/secp256k1/src/asm/field_10x26_arm.s new file mode 100644 index 00000000000..5df561f2fc9 --- /dev/null +++ b/src/secp256k1/src/asm/field_10x26_arm.s @@ -0,0 +1,919 @@ +@ vim: set tabstop=8 softtabstop=8 shiftwidth=8 noexpandtab syntax=armasm: +/********************************************************************** + * Copyright (c) 2014 Wladimir J. van der Laan * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ +/* +ARM implementation of field_10x26 inner loops. + +Note: + +- To avoid unnecessary loads and make use of available registers, two + 'passes' have every time been interleaved, with the odd passes accumulating c' and d' + which will be added to c and d respectively in the the even passes + +*/ + + .syntax unified + .arch armv7-a + @ eabi attributes - see readelf -A + .eabi_attribute 8, 1 @ Tag_ARM_ISA_use = yes + .eabi_attribute 9, 0 @ Tag_Thumb_ISA_use = no + .eabi_attribute 10, 0 @ Tag_FP_arch = none + .eabi_attribute 24, 1 @ Tag_ABI_align_needed = 8-byte + .eabi_attribute 25, 1 @ Tag_ABI_align_preserved = 8-byte, except leaf SP + .eabi_attribute 30, 2 @ Tag_ABI_optimization_goals = Agressive Speed + .eabi_attribute 34, 1 @ Tag_CPU_unaligned_access = v6 + .text + + @ Field constants + .set field_R0, 0x3d10 + .set field_R1, 0x400 + .set field_not_M, 0xfc000000 @ ~M = ~0x3ffffff + + .align 2 + .global secp256k1_fe_mul_inner + .type secp256k1_fe_mul_inner, %function + @ Arguments: + @ r0 r Restrict: can overlap with a, not with b + @ r1 a + @ r2 b + @ Stack (total 4+10*4 = 44) + @ sp + #0 saved 'r' pointer + @ sp + #4 + 4*X t0,t1,t2,t3,t4,t5,t6,t7,u8,t9 +secp256k1_fe_mul_inner: + stmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r14} + sub sp, sp, #48 @ frame=44 + alignment + str r0, [sp, #0] @ save result address, we need it only at the end + + /****************************************** + * Main computation code. + ****************************************** + + Allocation: + r0,r14,r7,r8 scratch + r1 a (pointer) + r2 b (pointer) + r3:r4 c + r5:r6 d + r11:r12 c' + r9:r10 d' + + Note: do not write to r[] here, it may overlap with a[] + */ + + /* A - interleaved with B */ + ldr r7, [r1, #0*4] @ a[0] + ldr r8, [r2, #9*4] @ b[9] + ldr r0, [r1, #1*4] @ a[1] + umull r5, r6, r7, r8 @ d = a[0] * b[9] + ldr r14, [r2, #8*4] @ b[8] + umull r9, r10, r0, r8 @ d' = a[1] * b[9] + ldr r7, [r1, #2*4] @ a[2] + umlal r5, r6, r0, r14 @ d += a[1] * b[8] + ldr r8, [r2, #7*4] @ b[7] + umlal r9, r10, r7, r14 @ d' += a[2] * b[8] + ldr r0, [r1, #3*4] @ a[3] + umlal r5, r6, r7, r8 @ d += a[2] * b[7] + ldr r14, [r2, #6*4] @ b[6] + umlal r9, r10, r0, r8 @ d' += a[3] * b[7] + ldr r7, [r1, #4*4] @ a[4] + umlal r5, r6, r0, r14 @ d += a[3] * b[6] + ldr r8, [r2, #5*4] @ b[5] + umlal r9, r10, r7, r14 @ d' += a[4] * b[6] + ldr r0, [r1, #5*4] @ a[5] + umlal r5, r6, r7, r8 @ d += a[4] * b[5] + ldr r14, [r2, #4*4] @ b[4] + umlal r9, r10, r0, r8 @ d' += a[5] * b[5] + ldr r7, [r1, #6*4] @ a[6] + umlal r5, r6, r0, r14 @ d += a[5] * b[4] + ldr r8, [r2, #3*4] @ b[3] + umlal r9, r10, r7, r14 @ d' += a[6] * b[4] + ldr r0, [r1, #7*4] @ a[7] + umlal r5, r6, r7, r8 @ d += a[6] * b[3] + ldr r14, [r2, #2*4] @ b[2] + umlal r9, r10, r0, r8 @ d' += a[7] * b[3] + ldr r7, [r1, #8*4] @ a[8] + umlal r5, r6, r0, r14 @ d += a[7] * b[2] + ldr r8, [r2, #1*4] @ b[1] + umlal r9, r10, r7, r14 @ d' += a[8] * b[2] + ldr r0, [r1, #9*4] @ a[9] + umlal r5, r6, r7, r8 @ d += a[8] * b[1] + ldr r14, [r2, #0*4] @ b[0] + umlal r9, r10, r0, r8 @ d' += a[9] * b[1] + ldr r7, [r1, #0*4] @ a[0] + umlal r5, r6, r0, r14 @ d += a[9] * b[0] + @ r7,r14 used in B + + bic r0, r5, field_not_M @ t9 = d & M + str r0, [sp, #4 + 4*9] + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + + /* B */ + umull r3, r4, r7, r14 @ c = a[0] * b[0] + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u0 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u0 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t0 = c & M + str r14, [sp, #4 + 0*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u0 * R1 + umlal r3, r4, r0, r14 + + /* C - interleaved with D */ + ldr r7, [r1, #0*4] @ a[0] + ldr r8, [r2, #2*4] @ b[2] + ldr r14, [r2, #1*4] @ b[1] + umull r11, r12, r7, r8 @ c' = a[0] * b[2] + ldr r0, [r1, #1*4] @ a[1] + umlal r3, r4, r7, r14 @ c += a[0] * b[1] + ldr r8, [r2, #0*4] @ b[0] + umlal r11, r12, r0, r14 @ c' += a[1] * b[1] + ldr r7, [r1, #2*4] @ a[2] + umlal r3, r4, r0, r8 @ c += a[1] * b[0] + ldr r14, [r2, #9*4] @ b[9] + umlal r11, r12, r7, r8 @ c' += a[2] * b[0] + ldr r0, [r1, #3*4] @ a[3] + umlal r5, r6, r7, r14 @ d += a[2] * b[9] + ldr r8, [r2, #8*4] @ b[8] + umull r9, r10, r0, r14 @ d' = a[3] * b[9] + ldr r7, [r1, #4*4] @ a[4] + umlal r5, r6, r0, r8 @ d += a[3] * b[8] + ldr r14, [r2, #7*4] @ b[7] + umlal r9, r10, r7, r8 @ d' += a[4] * b[8] + ldr r0, [r1, #5*4] @ a[5] + umlal r5, r6, r7, r14 @ d += a[4] * b[7] + ldr r8, [r2, #6*4] @ b[6] + umlal r9, r10, r0, r14 @ d' += a[5] * b[7] + ldr r7, [r1, #6*4] @ a[6] + umlal r5, r6, r0, r8 @ d += a[5] * b[6] + ldr r14, [r2, #5*4] @ b[5] + umlal r9, r10, r7, r8 @ d' += a[6] * b[6] + ldr r0, [r1, #7*4] @ a[7] + umlal r5, r6, r7, r14 @ d += a[6] * b[5] + ldr r8, [r2, #4*4] @ b[4] + umlal r9, r10, r0, r14 @ d' += a[7] * b[5] + ldr r7, [r1, #8*4] @ a[8] + umlal r5, r6, r0, r8 @ d += a[7] * b[4] + ldr r14, [r2, #3*4] @ b[3] + umlal r9, r10, r7, r8 @ d' += a[8] * b[4] + ldr r0, [r1, #9*4] @ a[9] + umlal r5, r6, r7, r14 @ d += a[8] * b[3] + ldr r8, [r2, #2*4] @ b[2] + umlal r9, r10, r0, r14 @ d' += a[9] * b[3] + umlal r5, r6, r0, r8 @ d += a[9] * b[2] + + bic r0, r5, field_not_M @ u1 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u1 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t1 = c & M + str r14, [sp, #4 + 1*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u1 * R1 + umlal r3, r4, r0, r14 + + /* D */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u2 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u2 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t2 = c & M + str r14, [sp, #4 + 2*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u2 * R1 + umlal r3, r4, r0, r14 + + /* E - interleaved with F */ + ldr r7, [r1, #0*4] @ a[0] + ldr r8, [r2, #4*4] @ b[4] + umull r11, r12, r7, r8 @ c' = a[0] * b[4] + ldr r8, [r2, #3*4] @ b[3] + umlal r3, r4, r7, r8 @ c += a[0] * b[3] + ldr r7, [r1, #1*4] @ a[1] + umlal r11, r12, r7, r8 @ c' += a[1] * b[3] + ldr r8, [r2, #2*4] @ b[2] + umlal r3, r4, r7, r8 @ c += a[1] * b[2] + ldr r7, [r1, #2*4] @ a[2] + umlal r11, r12, r7, r8 @ c' += a[2] * b[2] + ldr r8, [r2, #1*4] @ b[1] + umlal r3, r4, r7, r8 @ c += a[2] * b[1] + ldr r7, [r1, #3*4] @ a[3] + umlal r11, r12, r7, r8 @ c' += a[3] * b[1] + ldr r8, [r2, #0*4] @ b[0] + umlal r3, r4, r7, r8 @ c += a[3] * b[0] + ldr r7, [r1, #4*4] @ a[4] + umlal r11, r12, r7, r8 @ c' += a[4] * b[0] + ldr r8, [r2, #9*4] @ b[9] + umlal r5, r6, r7, r8 @ d += a[4] * b[9] + ldr r7, [r1, #5*4] @ a[5] + umull r9, r10, r7, r8 @ d' = a[5] * b[9] + ldr r8, [r2, #8*4] @ b[8] + umlal r5, r6, r7, r8 @ d += a[5] * b[8] + ldr r7, [r1, #6*4] @ a[6] + umlal r9, r10, r7, r8 @ d' += a[6] * b[8] + ldr r8, [r2, #7*4] @ b[7] + umlal r5, r6, r7, r8 @ d += a[6] * b[7] + ldr r7, [r1, #7*4] @ a[7] + umlal r9, r10, r7, r8 @ d' += a[7] * b[7] + ldr r8, [r2, #6*4] @ b[6] + umlal r5, r6, r7, r8 @ d += a[7] * b[6] + ldr r7, [r1, #8*4] @ a[8] + umlal r9, r10, r7, r8 @ d' += a[8] * b[6] + ldr r8, [r2, #5*4] @ b[5] + umlal r5, r6, r7, r8 @ d += a[8] * b[5] + ldr r7, [r1, #9*4] @ a[9] + umlal r9, r10, r7, r8 @ d' += a[9] * b[5] + ldr r8, [r2, #4*4] @ b[4] + umlal r5, r6, r7, r8 @ d += a[9] * b[4] + + bic r0, r5, field_not_M @ u3 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u3 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t3 = c & M + str r14, [sp, #4 + 3*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u3 * R1 + umlal r3, r4, r0, r14 + + /* F */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u4 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u4 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t4 = c & M + str r14, [sp, #4 + 4*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u4 * R1 + umlal r3, r4, r0, r14 + + /* G - interleaved with H */ + ldr r7, [r1, #0*4] @ a[0] + ldr r8, [r2, #6*4] @ b[6] + ldr r14, [r2, #5*4] @ b[5] + umull r11, r12, r7, r8 @ c' = a[0] * b[6] + ldr r0, [r1, #1*4] @ a[1] + umlal r3, r4, r7, r14 @ c += a[0] * b[5] + ldr r8, [r2, #4*4] @ b[4] + umlal r11, r12, r0, r14 @ c' += a[1] * b[5] + ldr r7, [r1, #2*4] @ a[2] + umlal r3, r4, r0, r8 @ c += a[1] * b[4] + ldr r14, [r2, #3*4] @ b[3] + umlal r11, r12, r7, r8 @ c' += a[2] * b[4] + ldr r0, [r1, #3*4] @ a[3] + umlal r3, r4, r7, r14 @ c += a[2] * b[3] + ldr r8, [r2, #2*4] @ b[2] + umlal r11, r12, r0, r14 @ c' += a[3] * b[3] + ldr r7, [r1, #4*4] @ a[4] + umlal r3, r4, r0, r8 @ c += a[3] * b[2] + ldr r14, [r2, #1*4] @ b[1] + umlal r11, r12, r7, r8 @ c' += a[4] * b[2] + ldr r0, [r1, #5*4] @ a[5] + umlal r3, r4, r7, r14 @ c += a[4] * b[1] + ldr r8, [r2, #0*4] @ b[0] + umlal r11, r12, r0, r14 @ c' += a[5] * b[1] + ldr r7, [r1, #6*4] @ a[6] + umlal r3, r4, r0, r8 @ c += a[5] * b[0] + ldr r14, [r2, #9*4] @ b[9] + umlal r11, r12, r7, r8 @ c' += a[6] * b[0] + ldr r0, [r1, #7*4] @ a[7] + umlal r5, r6, r7, r14 @ d += a[6] * b[9] + ldr r8, [r2, #8*4] @ b[8] + umull r9, r10, r0, r14 @ d' = a[7] * b[9] + ldr r7, [r1, #8*4] @ a[8] + umlal r5, r6, r0, r8 @ d += a[7] * b[8] + ldr r14, [r2, #7*4] @ b[7] + umlal r9, r10, r7, r8 @ d' += a[8] * b[8] + ldr r0, [r1, #9*4] @ a[9] + umlal r5, r6, r7, r14 @ d += a[8] * b[7] + ldr r8, [r2, #6*4] @ b[6] + umlal r9, r10, r0, r14 @ d' += a[9] * b[7] + umlal r5, r6, r0, r8 @ d += a[9] * b[6] + + bic r0, r5, field_not_M @ u5 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u5 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t5 = c & M + str r14, [sp, #4 + 5*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u5 * R1 + umlal r3, r4, r0, r14 + + /* H */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u6 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u6 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t6 = c & M + str r14, [sp, #4 + 6*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u6 * R1 + umlal r3, r4, r0, r14 + + /* I - interleaved with J */ + ldr r8, [r2, #8*4] @ b[8] + ldr r7, [r1, #0*4] @ a[0] + ldr r14, [r2, #7*4] @ b[7] + umull r11, r12, r7, r8 @ c' = a[0] * b[8] + ldr r0, [r1, #1*4] @ a[1] + umlal r3, r4, r7, r14 @ c += a[0] * b[7] + ldr r8, [r2, #6*4] @ b[6] + umlal r11, r12, r0, r14 @ c' += a[1] * b[7] + ldr r7, [r1, #2*4] @ a[2] + umlal r3, r4, r0, r8 @ c += a[1] * b[6] + ldr r14, [r2, #5*4] @ b[5] + umlal r11, r12, r7, r8 @ c' += a[2] * b[6] + ldr r0, [r1, #3*4] @ a[3] + umlal r3, r4, r7, r14 @ c += a[2] * b[5] + ldr r8, [r2, #4*4] @ b[4] + umlal r11, r12, r0, r14 @ c' += a[3] * b[5] + ldr r7, [r1, #4*4] @ a[4] + umlal r3, r4, r0, r8 @ c += a[3] * b[4] + ldr r14, [r2, #3*4] @ b[3] + umlal r11, r12, r7, r8 @ c' += a[4] * b[4] + ldr r0, [r1, #5*4] @ a[5] + umlal r3, r4, r7, r14 @ c += a[4] * b[3] + ldr r8, [r2, #2*4] @ b[2] + umlal r11, r12, r0, r14 @ c' += a[5] * b[3] + ldr r7, [r1, #6*4] @ a[6] + umlal r3, r4, r0, r8 @ c += a[5] * b[2] + ldr r14, [r2, #1*4] @ b[1] + umlal r11, r12, r7, r8 @ c' += a[6] * b[2] + ldr r0, [r1, #7*4] @ a[7] + umlal r3, r4, r7, r14 @ c += a[6] * b[1] + ldr r8, [r2, #0*4] @ b[0] + umlal r11, r12, r0, r14 @ c' += a[7] * b[1] + ldr r7, [r1, #8*4] @ a[8] + umlal r3, r4, r0, r8 @ c += a[7] * b[0] + ldr r14, [r2, #9*4] @ b[9] + umlal r11, r12, r7, r8 @ c' += a[8] * b[0] + ldr r0, [r1, #9*4] @ a[9] + umlal r5, r6, r7, r14 @ d += a[8] * b[9] + ldr r8, [r2, #8*4] @ b[8] + umull r9, r10, r0, r14 @ d' = a[9] * b[9] + umlal r5, r6, r0, r8 @ d += a[9] * b[8] + + bic r0, r5, field_not_M @ u7 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u7 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t7 = c & M + str r14, [sp, #4 + 7*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u7 * R1 + umlal r3, r4, r0, r14 + + /* J */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u8 = d & M + str r0, [sp, #4 + 8*4] + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u8 * R0 + umlal r3, r4, r0, r14 + + /****************************************** + * compute and write back result + ****************************************** + Allocation: + r0 r + r3:r4 c + r5:r6 d + r7 t0 + r8 t1 + r9 t2 + r11 u8 + r12 t9 + r1,r2,r10,r14 scratch + + Note: do not read from a[] after here, it may overlap with r[] + */ + ldr r0, [sp, #0] + add r1, sp, #4 + 3*4 @ r[3..7] = t3..7, r11=u8, r12=t9 + ldmia r1, {r2,r7,r8,r9,r10,r11,r12} + add r1, r0, #3*4 + stmia r1, {r2,r7,r8,r9,r10} + + bic r2, r3, field_not_M @ r[8] = c & M + str r2, [r0, #8*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u8 * R1 + umlal r3, r4, r11, r14 + movw r14, field_R0 @ c += d * R0 + umlal r3, r4, r5, r14 + adds r3, r3, r12 @ c += t9 + adc r4, r4, #0 + + add r1, sp, #4 + 0*4 @ r7,r8,r9 = t0,t1,t2 + ldmia r1, {r7,r8,r9} + + ubfx r2, r3, #0, #22 @ r[9] = c & (M >> 4) + str r2, [r0, #9*4] + mov r3, r3, lsr #22 @ c >>= 22 + orr r3, r3, r4, asl #10 + mov r4, r4, lsr #22 + movw r14, field_R1 << 4 @ c += d * (R1 << 4) + umlal r3, r4, r5, r14 + + movw r14, field_R0 >> 4 @ d = c * (R0 >> 4) + t0 (64x64 multiply+add) + umull r5, r6, r3, r14 @ d = c.lo * (R0 >> 4) + adds r5, r5, r7 @ d.lo += t0 + mla r6, r14, r4, r6 @ d.hi += c.hi * (R0 >> 4) + adc r6, r6, 0 @ d.hi += carry + + bic r2, r5, field_not_M @ r[0] = d & M + str r2, [r0, #0*4] + + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + + movw r14, field_R1 >> 4 @ d += c * (R1 >> 4) + t1 (64x64 multiply+add) + umull r1, r2, r3, r14 @ tmp = c.lo * (R1 >> 4) + adds r5, r5, r8 @ d.lo += t1 + adc r6, r6, #0 @ d.hi += carry + adds r5, r5, r1 @ d.lo += tmp.lo + mla r2, r14, r4, r2 @ tmp.hi += c.hi * (R1 >> 4) + adc r6, r6, r2 @ d.hi += carry + tmp.hi + + bic r2, r5, field_not_M @ r[1] = d & M + str r2, [r0, #1*4] + mov r5, r5, lsr #26 @ d >>= 26 (ignore hi) + orr r5, r5, r6, asl #6 + + add r5, r5, r9 @ d += t2 + str r5, [r0, #2*4] @ r[2] = d + + add sp, sp, #48 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc} + .size secp256k1_fe_mul_inner, .-secp256k1_fe_mul_inner + + .align 2 + .global secp256k1_fe_sqr_inner + .type secp256k1_fe_sqr_inner, %function + @ Arguments: + @ r0 r Can overlap with a + @ r1 a + @ Stack (total 4+10*4 = 44) + @ sp + #0 saved 'r' pointer + @ sp + #4 + 4*X t0,t1,t2,t3,t4,t5,t6,t7,u8,t9 +secp256k1_fe_sqr_inner: + stmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r14} + sub sp, sp, #48 @ frame=44 + alignment + str r0, [sp, #0] @ save result address, we need it only at the end + /****************************************** + * Main computation code. + ****************************************** + + Allocation: + r0,r14,r2,r7,r8 scratch + r1 a (pointer) + r3:r4 c + r5:r6 d + r11:r12 c' + r9:r10 d' + + Note: do not write to r[] here, it may overlap with a[] + */ + /* A interleaved with B */ + ldr r0, [r1, #1*4] @ a[1]*2 + ldr r7, [r1, #0*4] @ a[0] + mov r0, r0, asl #1 + ldr r14, [r1, #9*4] @ a[9] + umull r3, r4, r7, r7 @ c = a[0] * a[0] + ldr r8, [r1, #8*4] @ a[8] + mov r7, r7, asl #1 + umull r5, r6, r7, r14 @ d = a[0]*2 * a[9] + ldr r7, [r1, #2*4] @ a[2]*2 + umull r9, r10, r0, r14 @ d' = a[1]*2 * a[9] + ldr r14, [r1, #7*4] @ a[7] + umlal r5, r6, r0, r8 @ d += a[1]*2 * a[8] + mov r7, r7, asl #1 + ldr r0, [r1, #3*4] @ a[3]*2 + umlal r9, r10, r7, r8 @ d' += a[2]*2 * a[8] + ldr r8, [r1, #6*4] @ a[6] + umlal r5, r6, r7, r14 @ d += a[2]*2 * a[7] + mov r0, r0, asl #1 + ldr r7, [r1, #4*4] @ a[4]*2 + umlal r9, r10, r0, r14 @ d' += a[3]*2 * a[7] + ldr r14, [r1, #5*4] @ a[5] + mov r7, r7, asl #1 + umlal r5, r6, r0, r8 @ d += a[3]*2 * a[6] + umlal r9, r10, r7, r8 @ d' += a[4]*2 * a[6] + umlal r5, r6, r7, r14 @ d += a[4]*2 * a[5] + umlal r9, r10, r14, r14 @ d' += a[5] * a[5] + + bic r0, r5, field_not_M @ t9 = d & M + str r0, [sp, #4 + 9*4] + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + + /* B */ + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u0 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u0 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t0 = c & M + str r14, [sp, #4 + 0*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u0 * R1 + umlal r3, r4, r0, r14 + + /* C interleaved with D */ + ldr r0, [r1, #0*4] @ a[0]*2 + ldr r14, [r1, #1*4] @ a[1] + mov r0, r0, asl #1 + ldr r8, [r1, #2*4] @ a[2] + umlal r3, r4, r0, r14 @ c += a[0]*2 * a[1] + mov r7, r8, asl #1 @ a[2]*2 + umull r11, r12, r14, r14 @ c' = a[1] * a[1] + ldr r14, [r1, #9*4] @ a[9] + umlal r11, r12, r0, r8 @ c' += a[0]*2 * a[2] + ldr r0, [r1, #3*4] @ a[3]*2 + ldr r8, [r1, #8*4] @ a[8] + umlal r5, r6, r7, r14 @ d += a[2]*2 * a[9] + mov r0, r0, asl #1 + ldr r7, [r1, #4*4] @ a[4]*2 + umull r9, r10, r0, r14 @ d' = a[3]*2 * a[9] + ldr r14, [r1, #7*4] @ a[7] + umlal r5, r6, r0, r8 @ d += a[3]*2 * a[8] + mov r7, r7, asl #1 + ldr r0, [r1, #5*4] @ a[5]*2 + umlal r9, r10, r7, r8 @ d' += a[4]*2 * a[8] + ldr r8, [r1, #6*4] @ a[6] + mov r0, r0, asl #1 + umlal r5, r6, r7, r14 @ d += a[4]*2 * a[7] + umlal r9, r10, r0, r14 @ d' += a[5]*2 * a[7] + umlal r5, r6, r0, r8 @ d += a[5]*2 * a[6] + umlal r9, r10, r8, r8 @ d' += a[6] * a[6] + + bic r0, r5, field_not_M @ u1 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u1 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t1 = c & M + str r14, [sp, #4 + 1*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u1 * R1 + umlal r3, r4, r0, r14 + + /* D */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u2 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u2 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t2 = c & M + str r14, [sp, #4 + 2*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u2 * R1 + umlal r3, r4, r0, r14 + + /* E interleaved with F */ + ldr r7, [r1, #0*4] @ a[0]*2 + ldr r0, [r1, #1*4] @ a[1]*2 + ldr r14, [r1, #2*4] @ a[2] + mov r7, r7, asl #1 + ldr r8, [r1, #3*4] @ a[3] + ldr r2, [r1, #4*4] + umlal r3, r4, r7, r8 @ c += a[0]*2 * a[3] + mov r0, r0, asl #1 + umull r11, r12, r7, r2 @ c' = a[0]*2 * a[4] + mov r2, r2, asl #1 @ a[4]*2 + umlal r11, r12, r0, r8 @ c' += a[1]*2 * a[3] + ldr r8, [r1, #9*4] @ a[9] + umlal r3, r4, r0, r14 @ c += a[1]*2 * a[2] + ldr r0, [r1, #5*4] @ a[5]*2 + umlal r11, r12, r14, r14 @ c' += a[2] * a[2] + ldr r14, [r1, #8*4] @ a[8] + mov r0, r0, asl #1 + umlal r5, r6, r2, r8 @ d += a[4]*2 * a[9] + ldr r7, [r1, #6*4] @ a[6]*2 + umull r9, r10, r0, r8 @ d' = a[5]*2 * a[9] + mov r7, r7, asl #1 + ldr r8, [r1, #7*4] @ a[7] + umlal r5, r6, r0, r14 @ d += a[5]*2 * a[8] + umlal r9, r10, r7, r14 @ d' += a[6]*2 * a[8] + umlal r5, r6, r7, r8 @ d += a[6]*2 * a[7] + umlal r9, r10, r8, r8 @ d' += a[7] * a[7] + + bic r0, r5, field_not_M @ u3 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u3 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t3 = c & M + str r14, [sp, #4 + 3*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u3 * R1 + umlal r3, r4, r0, r14 + + /* F */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u4 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u4 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t4 = c & M + str r14, [sp, #4 + 4*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u4 * R1 + umlal r3, r4, r0, r14 + + /* G interleaved with H */ + ldr r7, [r1, #0*4] @ a[0]*2 + ldr r0, [r1, #1*4] @ a[1]*2 + mov r7, r7, asl #1 + ldr r8, [r1, #5*4] @ a[5] + ldr r2, [r1, #6*4] @ a[6] + umlal r3, r4, r7, r8 @ c += a[0]*2 * a[5] + ldr r14, [r1, #4*4] @ a[4] + mov r0, r0, asl #1 + umull r11, r12, r7, r2 @ c' = a[0]*2 * a[6] + ldr r7, [r1, #2*4] @ a[2]*2 + umlal r11, r12, r0, r8 @ c' += a[1]*2 * a[5] + mov r7, r7, asl #1 + ldr r8, [r1, #3*4] @ a[3] + umlal r3, r4, r0, r14 @ c += a[1]*2 * a[4] + mov r0, r2, asl #1 @ a[6]*2 + umlal r11, r12, r7, r14 @ c' += a[2]*2 * a[4] + ldr r14, [r1, #9*4] @ a[9] + umlal r3, r4, r7, r8 @ c += a[2]*2 * a[3] + ldr r7, [r1, #7*4] @ a[7]*2 + umlal r11, r12, r8, r8 @ c' += a[3] * a[3] + mov r7, r7, asl #1 + ldr r8, [r1, #8*4] @ a[8] + umlal r5, r6, r0, r14 @ d += a[6]*2 * a[9] + umull r9, r10, r7, r14 @ d' = a[7]*2 * a[9] + umlal r5, r6, r7, r8 @ d += a[7]*2 * a[8] + umlal r9, r10, r8, r8 @ d' += a[8] * a[8] + + bic r0, r5, field_not_M @ u5 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u5 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t5 = c & M + str r14, [sp, #4 + 5*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u5 * R1 + umlal r3, r4, r0, r14 + + /* H */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u6 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u6 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t6 = c & M + str r14, [sp, #4 + 6*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u6 * R1 + umlal r3, r4, r0, r14 + + /* I interleaved with J */ + ldr r7, [r1, #0*4] @ a[0]*2 + ldr r0, [r1, #1*4] @ a[1]*2 + mov r7, r7, asl #1 + ldr r8, [r1, #7*4] @ a[7] + ldr r2, [r1, #8*4] @ a[8] + umlal r3, r4, r7, r8 @ c += a[0]*2 * a[7] + ldr r14, [r1, #6*4] @ a[6] + mov r0, r0, asl #1 + umull r11, r12, r7, r2 @ c' = a[0]*2 * a[8] + ldr r7, [r1, #2*4] @ a[2]*2 + umlal r11, r12, r0, r8 @ c' += a[1]*2 * a[7] + ldr r8, [r1, #5*4] @ a[5] + umlal r3, r4, r0, r14 @ c += a[1]*2 * a[6] + ldr r0, [r1, #3*4] @ a[3]*2 + mov r7, r7, asl #1 + umlal r11, r12, r7, r14 @ c' += a[2]*2 * a[6] + ldr r14, [r1, #4*4] @ a[4] + mov r0, r0, asl #1 + umlal r3, r4, r7, r8 @ c += a[2]*2 * a[5] + mov r2, r2, asl #1 @ a[8]*2 + umlal r11, r12, r0, r8 @ c' += a[3]*2 * a[5] + umlal r3, r4, r0, r14 @ c += a[3]*2 * a[4] + umlal r11, r12, r14, r14 @ c' += a[4] * a[4] + ldr r8, [r1, #9*4] @ a[9] + umlal r5, r6, r2, r8 @ d += a[8]*2 * a[9] + @ r8 will be used in J + + bic r0, r5, field_not_M @ u7 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u7 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t7 = c & M + str r14, [sp, #4 + 7*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u7 * R1 + umlal r3, r4, r0, r14 + + /* J */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + umlal r5, r6, r8, r8 @ d += a[9] * a[9] + + bic r0, r5, field_not_M @ u8 = d & M + str r0, [sp, #4 + 8*4] + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u8 * R0 + umlal r3, r4, r0, r14 + + /****************************************** + * compute and write back result + ****************************************** + Allocation: + r0 r + r3:r4 c + r5:r6 d + r7 t0 + r8 t1 + r9 t2 + r11 u8 + r12 t9 + r1,r2,r10,r14 scratch + + Note: do not read from a[] after here, it may overlap with r[] + */ + ldr r0, [sp, #0] + add r1, sp, #4 + 3*4 @ r[3..7] = t3..7, r11=u8, r12=t9 + ldmia r1, {r2,r7,r8,r9,r10,r11,r12} + add r1, r0, #3*4 + stmia r1, {r2,r7,r8,r9,r10} + + bic r2, r3, field_not_M @ r[8] = c & M + str r2, [r0, #8*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u8 * R1 + umlal r3, r4, r11, r14 + movw r14, field_R0 @ c += d * R0 + umlal r3, r4, r5, r14 + adds r3, r3, r12 @ c += t9 + adc r4, r4, #0 + + add r1, sp, #4 + 0*4 @ r7,r8,r9 = t0,t1,t2 + ldmia r1, {r7,r8,r9} + + ubfx r2, r3, #0, #22 @ r[9] = c & (M >> 4) + str r2, [r0, #9*4] + mov r3, r3, lsr #22 @ c >>= 22 + orr r3, r3, r4, asl #10 + mov r4, r4, lsr #22 + movw r14, field_R1 << 4 @ c += d * (R1 << 4) + umlal r3, r4, r5, r14 + + movw r14, field_R0 >> 4 @ d = c * (R0 >> 4) + t0 (64x64 multiply+add) + umull r5, r6, r3, r14 @ d = c.lo * (R0 >> 4) + adds r5, r5, r7 @ d.lo += t0 + mla r6, r14, r4, r6 @ d.hi += c.hi * (R0 >> 4) + adc r6, r6, 0 @ d.hi += carry + + bic r2, r5, field_not_M @ r[0] = d & M + str r2, [r0, #0*4] + + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + + movw r14, field_R1 >> 4 @ d += c * (R1 >> 4) + t1 (64x64 multiply+add) + umull r1, r2, r3, r14 @ tmp = c.lo * (R1 >> 4) + adds r5, r5, r8 @ d.lo += t1 + adc r6, r6, #0 @ d.hi += carry + adds r5, r5, r1 @ d.lo += tmp.lo + mla r2, r14, r4, r2 @ tmp.hi += c.hi * (R1 >> 4) + adc r6, r6, r2 @ d.hi += carry + tmp.hi + + bic r2, r5, field_not_M @ r[1] = d & M + str r2, [r0, #1*4] + mov r5, r5, lsr #26 @ d >>= 26 (ignore hi) + orr r5, r5, r6, asl #6 + + add r5, r5, r9 @ d += t2 + str r5, [r0, #2*4] @ r[2] = d + + add sp, sp, #48 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc} + .size secp256k1_fe_sqr_inner, .-secp256k1_fe_sqr_inner + diff --git a/src/secp256k1/src/bench_ecdh.c b/src/secp256k1/src/bench_ecdh.c index 5a7c6376e08..cde5e2dbb4e 100644 --- a/src/secp256k1/src/bench_ecdh.c +++ b/src/secp256k1/src/bench_ecdh.c @@ -28,7 +28,8 @@ static void bench_ecdh_setup(void* arg) { 0xa2, 0xba, 0xd1, 0x84, 0xf8, 0x83, 0xc6, 0x9f }; - data->ctx = secp256k1_context_create(0); + /* create a context with no capabilities */ + data->ctx = secp256k1_context_create(SECP256K1_FLAGS_TYPE_CONTEXT); for (i = 0; i < 32; i++) { data->scalar[i] = i + 1; } diff --git a/src/secp256k1/src/bench_internal.c b/src/secp256k1/src/bench_internal.c index 7809f5f8cfe..0809f77bda1 100644 --- a/src/secp256k1/src/bench_internal.c +++ b/src/secp256k1/src/bench_internal.c @@ -181,12 +181,12 @@ void bench_field_inverse_var(void* arg) { } } -void bench_field_sqrt_var(void* arg) { +void bench_field_sqrt(void* arg) { int i; bench_inv_t *data = (bench_inv_t*)arg; for (i = 0; i < 20000; i++) { - secp256k1_fe_sqrt_var(&data->fe_x, &data->fe_x); + secp256k1_fe_sqrt(&data->fe_x, &data->fe_x); secp256k1_fe_add(&data->fe_x, &data->fe_y); } } @@ -227,6 +227,15 @@ void bench_group_add_affine_var(void* arg) { } } +void bench_group_jacobi_var(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 20000; i++) { + secp256k1_gej_has_quad_y_var(&data->gej_x); + } +} + void bench_ecmult_wnaf(void* arg) { int i; bench_inv_t *data = (bench_inv_t*)arg; @@ -299,6 +308,21 @@ void bench_context_sign(void* arg) { } } +#ifndef USE_NUM_NONE +void bench_num_jacobi(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + secp256k1_num nx, norder; + + secp256k1_scalar_get_num(&nx, &data->scalar_x); + secp256k1_scalar_order_get_num(&norder); + secp256k1_scalar_get_num(&norder, &data->scalar_y); + + for (i = 0; i < 200000; i++) { + secp256k1_num_jacobi(&nx, &norder); + } +} +#endif int have_flag(int argc, char** argv, char *flag) { char** argm = argv + argc; @@ -333,12 +357,13 @@ int main(int argc, char **argv) { if (have_flag(argc, argv, "field") || have_flag(argc, argv, "mul")) run_benchmark("field_mul", bench_field_mul, bench_setup, NULL, &data, 10, 200000); if (have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse", bench_field_inverse, bench_setup, NULL, &data, 10, 20000); if (have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse_var", bench_field_inverse_var, bench_setup, NULL, &data, 10, 20000); - if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqrt")) run_benchmark("field_sqrt_var", bench_field_sqrt_var, bench_setup, NULL, &data, 10, 20000); + if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqrt")) run_benchmark("field_sqrt", bench_field_sqrt, bench_setup, NULL, &data, 10, 20000); if (have_flag(argc, argv, "group") || have_flag(argc, argv, "double")) run_benchmark("group_double_var", bench_group_double_var, bench_setup, NULL, &data, 10, 200000); if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_var", bench_group_add_var, bench_setup, NULL, &data, 10, 200000); if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine", bench_group_add_affine, bench_setup, NULL, &data, 10, 200000); if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine_var", bench_group_add_affine_var, bench_setup, NULL, &data, 10, 200000); + if (have_flag(argc, argv, "group") || have_flag(argc, argv, "jacobi")) run_benchmark("group_jacobi_var", bench_group_jacobi_var, bench_setup, NULL, &data, 10, 20000); if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("wnaf_const", bench_wnaf_const, bench_setup, NULL, &data, 10, 20000); if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("ecmult_wnaf", bench_ecmult_wnaf, bench_setup, NULL, &data, 10, 20000); @@ -350,5 +375,8 @@ int main(int argc, char **argv) { if (have_flag(argc, argv, "context") || have_flag(argc, argv, "verify")) run_benchmark("context_verify", bench_context_verify, bench_setup, NULL, &data, 10, 20); if (have_flag(argc, argv, "context") || have_flag(argc, argv, "sign")) run_benchmark("context_sign", bench_context_sign, bench_setup, NULL, &data, 10, 200); +#ifndef USE_NUM_NONE + if (have_flag(argc, argv, "num") || have_flag(argc, argv, "jacobi")) run_benchmark("num_jacobi", bench_num_jacobi, bench_setup, NULL, &data, 10, 200000); +#endif return 0; } diff --git a/src/secp256k1/src/bench_verify.c b/src/secp256k1/src/bench_verify.c index 5718320cda2..418defa0aa2 100644 --- a/src/secp256k1/src/bench_verify.c +++ b/src/secp256k1/src/bench_verify.c @@ -11,6 +11,12 @@ #include "util.h" #include "bench.h" +#ifdef ENABLE_OPENSSL_TESTS +#include +#include +#include +#endif + typedef struct { secp256k1_context *ctx; unsigned char msg[32]; @@ -19,6 +25,9 @@ typedef struct { size_t siglen; unsigned char pubkey[33]; size_t pubkeylen; +#ifdef ENABLE_OPENSSL_TESTS + EC_GROUP* ec_group; +#endif } benchmark_verify_t; static void benchmark_verify(void* arg) { @@ -40,6 +49,36 @@ static void benchmark_verify(void* arg) { } } +#ifdef ENABLE_OPENSSL_TESTS +static void benchmark_verify_openssl(void* arg) { + int i; + benchmark_verify_t* data = (benchmark_verify_t*)arg; + + for (i = 0; i < 20000; i++) { + data->sig[data->siglen - 1] ^= (i & 0xFF); + data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); + data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); + { + EC_KEY *pkey = EC_KEY_new(); + const unsigned char *pubkey = &data->pubkey[0]; + int result; + + CHECK(pkey != NULL); + result = EC_KEY_set_group(pkey, data->ec_group); + CHECK(result); + result = (o2i_ECPublicKey(&pkey, &pubkey, data->pubkeylen)) != NULL; + CHECK(result); + result = ECDSA_verify(0, &data->msg[0], sizeof(data->msg), &data->sig[0], data->siglen, pkey) == (i == 0); + CHECK(result); + EC_KEY_free(pkey); + } + data->sig[data->siglen - 1] ^= (i & 0xFF); + data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); + data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); + } +} +#endif + int main(void) { int i; secp256k1_pubkey pubkey; @@ -62,6 +101,11 @@ int main(void) { CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED) == 1); run_benchmark("ecdsa_verify", benchmark_verify, NULL, NULL, &data, 10, 20000); +#ifdef ENABLE_OPENSSL_TESTS + data.ec_group = EC_GROUP_new_by_curve_name(NID_secp256k1); + run_benchmark("ecdsa_verify_openssl", benchmark_verify_openssl, NULL, NULL, &data, 10, 20000); + EC_GROUP_free(data.ec_group); +#endif secp256k1_context_destroy(data.ctx); return 0; diff --git a/src/secp256k1/src/ecdsa_impl.h b/src/secp256k1/src/ecdsa_impl.h index d110b4bb1dc..9a42e519bd5 100644 --- a/src/secp256k1/src/ecdsa_impl.h +++ b/src/secp256k1/src/ecdsa_impl.h @@ -203,7 +203,9 @@ static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar *sigr, const secp256k1_scalar *sigs, const secp256k1_ge *pubkey, const secp256k1_scalar *message) { unsigned char c[32]; secp256k1_scalar sn, u1, u2; +#if !defined(EXHAUSTIVE_TEST_ORDER) secp256k1_fe xr; +#endif secp256k1_gej pubkeyj; secp256k1_gej pr; @@ -219,6 +221,21 @@ static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const if (secp256k1_gej_is_infinity(&pr)) { return 0; } + +#if defined(EXHAUSTIVE_TEST_ORDER) +{ + secp256k1_scalar computed_r; + int overflow = 0; + secp256k1_ge pr_ge; + secp256k1_ge_set_gej(&pr_ge, &pr); + secp256k1_fe_normalize(&pr_ge.x); + + secp256k1_fe_get_b32(c, &pr_ge.x); + secp256k1_scalar_set_b32(&computed_r, c, &overflow); + /* we fully expect overflow */ + return secp256k1_scalar_eq(sigr, &computed_r); +} +#else secp256k1_scalar_get_b32(c, sigr); secp256k1_fe_set_b32(&xr, c); @@ -252,6 +269,7 @@ static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const return 1; } return 0; +#endif } static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar *sigr, secp256k1_scalar *sigs, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid) { diff --git a/src/secp256k1/src/ecmult_const_impl.h b/src/secp256k1/src/ecmult_const_impl.h index 90ac94770ea..0db314c48e0 100644 --- a/src/secp256k1/src/ecmult_const_impl.h +++ b/src/secp256k1/src/ecmult_const_impl.h @@ -58,25 +58,27 @@ static int secp256k1_wnaf_const(int *wnaf, secp256k1_scalar s, int w) { int global_sign; int skew = 0; int word = 0; + /* 1 2 3 */ int u_last; int u; -#ifdef USE_ENDOMORPHISM int flip; int bit; secp256k1_scalar neg_s; int not_neg_one; - /* If we are using the endomorphism, we cannot handle even numbers by negating - * them, since we are working with 128-bit numbers whose negations would be 256 - * bits, eliminating the performance advantage. Instead we use a technique from + /* Note that we cannot handle even numbers by negating them to be odd, as is + * done in other implementations, since if our scalars were specified to have + * width < 256 for performance reasons, their negations would have width 256 + * and we'd lose any performance benefit. Instead, we use a technique from * Section 4.2 of the Okeya/Tagaki paper, which is to add either 1 (for even) - * or 2 (for odd) to the number we are encoding, then compensating after the - * multiplication. */ - /* Negative 128-bit numbers will be negated, since otherwise they are 256-bit */ + * or 2 (for odd) to the number we are encoding, returning a skew value indicating + * this, and having the caller compensate after doing the multiplication. */ + + /* Negative numbers will be negated to keep their bit representation below the maximum width */ flip = secp256k1_scalar_is_high(&s); /* We add 1 to even numbers, 2 to odd ones, noting that negation flips parity */ - bit = flip ^ (s.d[0] & 1); + bit = flip ^ !secp256k1_scalar_is_even(&s); /* We check for negative one, since adding 2 to it will cause an overflow */ secp256k1_scalar_negate(&neg_s, &s); not_neg_one = !secp256k1_scalar_is_one(&neg_s); @@ -89,11 +91,6 @@ static int secp256k1_wnaf_const(int *wnaf, secp256k1_scalar s, int w) { global_sign = secp256k1_scalar_cond_negate(&s, flip); global_sign *= not_neg_one * 2 - 1; skew = 1 << bit; -#else - /* Otherwise, we just negate to force oddness */ - int is_even = secp256k1_scalar_is_even(&s); - global_sign = secp256k1_scalar_cond_negate(&s, is_even); -#endif /* 4 */ u_last = secp256k1_scalar_shr_int(&s, w); @@ -127,15 +124,13 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons secp256k1_ge tmpa; secp256k1_fe Z; + int skew_1; + int wnaf_1[1 + WNAF_SIZE(WINDOW_A - 1)]; #ifdef USE_ENDOMORPHISM secp256k1_ge pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; - int wnaf_1[1 + WNAF_SIZE(WINDOW_A - 1)]; int wnaf_lam[1 + WNAF_SIZE(WINDOW_A - 1)]; - int skew_1; int skew_lam; secp256k1_scalar q_1, q_lam; -#else - int wnaf[1 + WNAF_SIZE(WINDOW_A - 1)]; #endif int i; @@ -145,18 +140,10 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons #ifdef USE_ENDOMORPHISM /* split q into q_1 and q_lam (where q = q_1 + q_lam*lambda, and q_1 and q_lam are ~128 bit) */ secp256k1_scalar_split_lambda(&q_1, &q_lam, &sc); - /* no need for zero correction when using endomorphism since even - * numbers have one added to them anyway */ skew_1 = secp256k1_wnaf_const(wnaf_1, q_1, WINDOW_A - 1); skew_lam = secp256k1_wnaf_const(wnaf_lam, q_lam, WINDOW_A - 1); #else - int is_zero = secp256k1_scalar_is_zero(scalar); - /* the wNAF ladder cannot handle zero, so bump this to one .. we will - * correct the result after the fact */ - sc.d[0] += is_zero; - VERIFY_CHECK(!secp256k1_scalar_is_zero(&sc)); - - secp256k1_wnaf_const(wnaf, sc, WINDOW_A - 1); + skew_1 = secp256k1_wnaf_const(wnaf_1, sc, WINDOW_A - 1); #endif /* Calculate odd multiples of a. @@ -179,21 +166,15 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons /* first loop iteration (separated out so we can directly set r, rather * than having it start at infinity, get doubled several times, then have * its new value added to it) */ -#ifdef USE_ENDOMORPHISM i = wnaf_1[WNAF_SIZE(WINDOW_A - 1)]; VERIFY_CHECK(i != 0); ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, i, WINDOW_A); secp256k1_gej_set_ge(r, &tmpa); - +#ifdef USE_ENDOMORPHISM i = wnaf_lam[WNAF_SIZE(WINDOW_A - 1)]; VERIFY_CHECK(i != 0); ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, i, WINDOW_A); secp256k1_gej_add_ge(r, r, &tmpa); -#else - i = wnaf[WNAF_SIZE(WINDOW_A - 1)]; - VERIFY_CHECK(i != 0); - ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, i, WINDOW_A); - secp256k1_gej_set_ge(r, &tmpa); #endif /* remaining loop iterations */ for (i = WNAF_SIZE(WINDOW_A - 1) - 1; i >= 0; i--) { @@ -202,59 +183,57 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons for (j = 0; j < WINDOW_A - 1; ++j) { secp256k1_gej_double_nonzero(r, r, NULL); } -#ifdef USE_ENDOMORPHISM + n = wnaf_1[i]; ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A); VERIFY_CHECK(n != 0); secp256k1_gej_add_ge(r, r, &tmpa); - +#ifdef USE_ENDOMORPHISM n = wnaf_lam[i]; ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, n, WINDOW_A); VERIFY_CHECK(n != 0); secp256k1_gej_add_ge(r, r, &tmpa); -#else - n = wnaf[i]; - VERIFY_CHECK(n != 0); - ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A); - secp256k1_gej_add_ge(r, r, &tmpa); #endif } secp256k1_fe_mul(&r->z, &r->z, &Z); -#ifdef USE_ENDOMORPHISM { /* Correct for wNAF skew */ secp256k1_ge correction = *a; secp256k1_ge_storage correction_1_stor; +#ifdef USE_ENDOMORPHISM secp256k1_ge_storage correction_lam_stor; +#endif secp256k1_ge_storage a2_stor; secp256k1_gej tmpj; secp256k1_gej_set_ge(&tmpj, &correction); secp256k1_gej_double_var(&tmpj, &tmpj, NULL); secp256k1_ge_set_gej(&correction, &tmpj); secp256k1_ge_to_storage(&correction_1_stor, a); +#ifdef USE_ENDOMORPHISM secp256k1_ge_to_storage(&correction_lam_stor, a); +#endif secp256k1_ge_to_storage(&a2_stor, &correction); /* For odd numbers this is 2a (so replace it), for even ones a (so no-op) */ secp256k1_ge_storage_cmov(&correction_1_stor, &a2_stor, skew_1 == 2); +#ifdef USE_ENDOMORPHISM secp256k1_ge_storage_cmov(&correction_lam_stor, &a2_stor, skew_lam == 2); +#endif /* Apply the correction */ secp256k1_ge_from_storage(&correction, &correction_1_stor); secp256k1_ge_neg(&correction, &correction); secp256k1_gej_add_ge(r, r, &correction); +#ifdef USE_ENDOMORPHISM secp256k1_ge_from_storage(&correction, &correction_lam_stor); secp256k1_ge_neg(&correction, &correction); secp256k1_ge_mul_lambda(&correction, &correction); secp256k1_gej_add_ge(r, r, &correction); - } -#else - /* correct for zero */ - r->infinity |= is_zero; #endif + } } #endif diff --git a/src/secp256k1/src/ecmult_gen_impl.h b/src/secp256k1/src/ecmult_gen_impl.h index b63c4d8662c..35f25460773 100644 --- a/src/secp256k1/src/ecmult_gen_impl.h +++ b/src/secp256k1/src/ecmult_gen_impl.h @@ -77,7 +77,7 @@ static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context *ctx secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej, NULL); } } - secp256k1_ge_set_all_gej_var(1024, prec, precj, cb); + secp256k1_ge_set_all_gej_var(prec, precj, 1024, cb); } for (j = 0; j < 64; j++) { for (i = 0; i < 16; i++) { diff --git a/src/secp256k1/src/ecmult_impl.h b/src/secp256k1/src/ecmult_impl.h index e6e5f471880..4e40104ad43 100644 --- a/src/secp256k1/src/ecmult_impl.h +++ b/src/secp256k1/src/ecmult_impl.h @@ -7,13 +7,29 @@ #ifndef _SECP256K1_ECMULT_IMPL_H_ #define _SECP256K1_ECMULT_IMPL_H_ +#include + #include "group.h" #include "scalar.h" #include "ecmult.h" +#if defined(EXHAUSTIVE_TEST_ORDER) +/* We need to lower these values for exhaustive tests because + * the tables cannot have infinities in them (this breaks the + * affine-isomorphism stuff which tracks z-ratios) */ +# if EXHAUSTIVE_TEST_ORDER > 128 +# define WINDOW_A 5 +# define WINDOW_G 8 +# elif EXHAUSTIVE_TEST_ORDER > 8 +# define WINDOW_A 4 +# define WINDOW_G 4 +# else +# define WINDOW_A 2 +# define WINDOW_G 2 +# endif +#else /* optimal for 128-bit and 256-bit exponents. */ #define WINDOW_A 5 - /** larger numbers may result in slightly better performance, at the cost of exponentially larger precomputed tables. */ #ifdef USE_ENDOMORPHISM @@ -23,6 +39,7 @@ /** One table for window size 16: 1.375 MiB. */ #define WINDOW_G 16 #endif +#endif /** The number of entries a table with precomputed multiples needs to have. */ #define ECMULT_TABLE_SIZE(w) (1 << ((w)-2)) @@ -101,7 +118,7 @@ static void secp256k1_ecmult_odd_multiples_table_storage_var(int n, secp256k1_ge /* Compute the odd multiples in Jacobian form. */ secp256k1_ecmult_odd_multiples_table(n, prej, zr, a); /* Convert them in batch to affine coordinates. */ - secp256k1_ge_set_table_gej_var(n, prea, prej, zr); + secp256k1_ge_set_table_gej_var(prea, prej, zr, n); /* Convert them to compact storage form. */ for (i = 0; i < n; i++) { secp256k1_ge_to_storage(&pre[i], &prea[i]); diff --git a/src/secp256k1/src/field.h b/src/secp256k1/src/field.h index 2d52af5e366..bbb1ee866cc 100644 --- a/src/secp256k1/src/field.h +++ b/src/secp256k1/src/field.h @@ -30,6 +30,8 @@ #error "Please select field implementation" #endif +#include "util.h" + /** Normalize a field element. */ static void secp256k1_fe_normalize(secp256k1_fe *r); @@ -50,6 +52,9 @@ static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r); /** Set a field element equal to a small integer. Resulting field element is normalized. */ static void secp256k1_fe_set_int(secp256k1_fe *r, int a); +/** Sets a field element equal to zero, initializing all fields. */ +static void secp256k1_fe_clear(secp256k1_fe *a); + /** Verify whether a field element is zero. Requires the input to be normalized. */ static int secp256k1_fe_is_zero(const secp256k1_fe *a); @@ -57,6 +62,9 @@ static int secp256k1_fe_is_zero(const secp256k1_fe *a); static int secp256k1_fe_is_odd(const secp256k1_fe *a); /** Compare two field elements. Requires magnitude-1 inputs. */ +static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b); + +/** Same as secp256k1_fe_equal, but may be variable time. */ static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b); /** Compare two field elements. Requires both inputs to be normalized */ @@ -92,7 +100,10 @@ static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a); * The input's magnitude can be at most 8. The output magnitude is 1 (but not * guaranteed to be normalized). The result in r will always be a square * itself. */ -static int secp256k1_fe_sqrt_var(secp256k1_fe *r, const secp256k1_fe *a); +static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a); + +/** Checks whether a field element is a quadratic residue. */ +static int secp256k1_fe_is_quad_var(const secp256k1_fe *a); /** Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be * at most 8. The output magnitude is 1 (but not guaranteed to be normalized). */ @@ -104,7 +115,7 @@ static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a); /** Calculate the (modular) inverses of a batch of field elements. Requires the inputs' magnitudes to be * at most 8. The output magnitudes are 1 (but not guaranteed to be normalized). The inputs and * outputs must not overlap in memory. */ -static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe *r, const secp256k1_fe *a); +static void secp256k1_fe_inv_all_var(secp256k1_fe *r, const secp256k1_fe *a, size_t len); /** Convert a field element to the storage type. */ static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a); diff --git a/src/secp256k1/src/field_10x26_impl.h b/src/secp256k1/src/field_10x26_impl.h index 212cc5396af..7b8c0796084 100644 --- a/src/secp256k1/src/field_10x26_impl.h +++ b/src/secp256k1/src/field_10x26_impl.h @@ -7,8 +7,6 @@ #ifndef _SECP256K1_FIELD_REPR_IMPL_H_ #define _SECP256K1_FIELD_REPR_IMPL_H_ -#include -#include #include "util.h" #include "num.h" #include "field.h" @@ -429,6 +427,14 @@ SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_f #endif } +#if defined(USE_EXTERNAL_ASM) + +/* External assembler implementation */ +void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t *a, const uint32_t * SECP256K1_RESTRICT b); +void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t *a); + +#else + #ifdef VERIFY #define VERIFY_BITS(x, n) VERIFY_CHECK(((x) >> (n)) == 0) #else @@ -1037,7 +1043,7 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t VERIFY_BITS(r[2], 27); /* [r9 r8 r7 r6 r5 r4 r3 r2 r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ } - +#endif static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b) { #ifdef VERIFY diff --git a/src/secp256k1/src/field_5x52_impl.h b/src/secp256k1/src/field_5x52_impl.h index b31e24ab811..7a99eb21ecc 100644 --- a/src/secp256k1/src/field_5x52_impl.h +++ b/src/secp256k1/src/field_5x52_impl.h @@ -11,7 +11,6 @@ #include "libsecp256k1-config.h" #endif -#include #include "util.h" #include "num.h" #include "field.h" diff --git a/src/secp256k1/src/field_5x52_int128_impl.h b/src/secp256k1/src/field_5x52_int128_impl.h index 9280bb5ea22..0bf22bdd3ec 100644 --- a/src/secp256k1/src/field_5x52_int128_impl.h +++ b/src/secp256k1/src/field_5x52_int128_impl.h @@ -137,7 +137,7 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t VERIFY_BITS(r[2], 52); VERIFY_BITS(c, 63); /* [d 0 0 0 t4 t3+c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - c += d * R + t3;; + c += d * R + t3; VERIFY_BITS(c, 100); /* [t4 c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ r[3] = c & M; c >>= 52; @@ -259,7 +259,7 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t VERIFY_BITS(c, 63); /* [d 0 0 0 t4 t3+c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - c += d * R + t3;; + c += d * R + t3; VERIFY_BITS(c, 100); /* [t4 c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ r[3] = c & M; c >>= 52; diff --git a/src/secp256k1/src/field_impl.h b/src/secp256k1/src/field_impl.h index 77f4aae2f97..5127b279bc7 100644 --- a/src/secp256k1/src/field_impl.h +++ b/src/secp256k1/src/field_impl.h @@ -21,6 +21,13 @@ #error "Please select field implementation" #endif +SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b) { + secp256k1_fe na; + secp256k1_fe_negate(&na, a, 1); + secp256k1_fe_add(&na, b); + return secp256k1_fe_normalizes_to_zero(&na); +} + SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b) { secp256k1_fe na; secp256k1_fe_negate(&na, a, 1); @@ -28,7 +35,7 @@ SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe *a, const return secp256k1_fe_normalizes_to_zero_var(&na); } -static int secp256k1_fe_sqrt_var(secp256k1_fe *r, const secp256k1_fe *a) { +static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a) { /** Given that p is congruent to 3 mod 4, we can compute the square root of * a mod p as the (p+1)/4'th power of a. * @@ -123,7 +130,7 @@ static int secp256k1_fe_sqrt_var(secp256k1_fe *r, const secp256k1_fe *a) { /* Check that a square root was actually calculated */ secp256k1_fe_sqr(&t1, r); - return secp256k1_fe_equal_var(&t1, a); + return secp256k1_fe_equal(&t1, a); } static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *a) { @@ -253,7 +260,7 @@ static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a) { #endif } -static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe *r, const secp256k1_fe *a) { +static void secp256k1_fe_inv_all_var(secp256k1_fe *r, const secp256k1_fe *a, size_t len) { secp256k1_fe u; size_t i; if (len < 1) { @@ -280,4 +287,29 @@ static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe *r, const secp256k r[0] = u; } +static int secp256k1_fe_is_quad_var(const secp256k1_fe *a) { +#ifndef USE_NUM_NONE + unsigned char b[32]; + secp256k1_num n; + secp256k1_num m; + /* secp256k1 field prime, value p defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ + static const unsigned char prime[32] = { + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F + }; + + secp256k1_fe c = *a; + secp256k1_fe_normalize_var(&c); + secp256k1_fe_get_b32(b, &c); + secp256k1_num_set_bin(&n, b, 32); + secp256k1_num_set_bin(&m, prime, 32); + return secp256k1_num_jacobi(&n, &m) >= 0; +#else + secp256k1_fe r; + return secp256k1_fe_sqrt(&r, a); +#endif +} + #endif diff --git a/src/secp256k1/src/group.h b/src/secp256k1/src/group.h index ebfe1ca70cc..4957b248fe6 100644 --- a/src/secp256k1/src/group.h +++ b/src/secp256k1/src/group.h @@ -47,7 +47,7 @@ static void secp256k1_ge_set_xy(secp256k1_ge *r, const secp256k1_fe *x, const se * and a Y coordinate that is a quadratic residue modulo p. The return value * is true iff a coordinate with the given X coordinate exists. */ -static int secp256k1_ge_set_xquad_var(secp256k1_ge *r, const secp256k1_fe *x); +static int secp256k1_ge_set_xquad(secp256k1_ge *r, const secp256k1_fe *x); /** Set a group element (affine) equal to the point with the given X coordinate, and given oddness * for Y. Return value indicates whether the result is valid. */ @@ -65,12 +65,12 @@ static void secp256k1_ge_neg(secp256k1_ge *r, const secp256k1_ge *a); static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a); /** Set a batch of group elements equal to the inputs given in jacobian coordinates */ -static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_callback *cb); +static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len, const secp256k1_callback *cb); /** Set a batch of group elements equal to the inputs given in jacobian * coordinates (with known z-ratios). zr must contain the known z-ratios such * that mul(a[i].z, zr[i+1]) == a[i+1].z. zr[0] is ignored. */ -static void secp256k1_ge_set_table_gej_var(size_t len, secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zr); +static void secp256k1_ge_set_table_gej_var(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zr, size_t len); /** Bring a batch inputs given in jacobian coordinates (with known z-ratios) to * the same global z "denominator". zr must contain the known z-ratios such @@ -94,6 +94,9 @@ static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a); /** Check whether a group element is the point at infinity. */ static int secp256k1_gej_is_infinity(const secp256k1_gej *a); +/** Check whether a group element's y coordinate is a quadratic residue. */ +static int secp256k1_gej_has_quad_y_var(const secp256k1_gej *a); + /** Set r equal to the double of a. If rzr is not-NULL, r->z = a->z * *rzr (where infinity means an implicit z = 0). * a may not be zero. Constant time. */ static void secp256k1_gej_double_nonzero(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr); diff --git a/src/secp256k1/src/group_impl.h b/src/secp256k1/src/group_impl.h index 42e2f6e6ebf..2e192b62fd2 100644 --- a/src/secp256k1/src/group_impl.h +++ b/src/secp256k1/src/group_impl.h @@ -7,12 +7,57 @@ #ifndef _SECP256K1_GROUP_IMPL_H_ #define _SECP256K1_GROUP_IMPL_H_ -#include - #include "num.h" #include "field.h" #include "group.h" +/* These points can be generated in sage as follows: + * + * 0. Setup a worksheet with the following parameters. + * b = 4 # whatever CURVE_B will be set to + * F = FiniteField (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F) + * C = EllipticCurve ([F (0), F (b)]) + * + * 1. Determine all the small orders available to you. (If there are + * no satisfactory ones, go back and change b.) + * print C.order().factor(limit=1000) + * + * 2. Choose an order as one of the prime factors listed in the above step. + * (You can also multiply some to get a composite order, though the + * tests will crash trying to invert scalars during signing.) We take a + * random point and scale it to drop its order to the desired value. + * There is some probability this won't work; just try again. + * order = 199 + * P = C.random_point() + * P = (int(P.order()) / int(order)) * P + * assert(P.order() == order) + * + * 3. Print the values. You'll need to use a vim macro or something to + * split the hex output into 4-byte chunks. + * print "%x %x" % P.xy() + */ +#if defined(EXHAUSTIVE_TEST_ORDER) +# if EXHAUSTIVE_TEST_ORDER == 199 +const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( + 0xFA7CC9A7, 0x0737F2DB, 0xA749DD39, 0x2B4FB069, + 0x3B017A7D, 0xA808C2F1, 0xFB12940C, 0x9EA66C18, + 0x78AC123A, 0x5ED8AEF3, 0x8732BC91, 0x1F3A2868, + 0x48DF246C, 0x808DAE72, 0xCFE52572, 0x7F0501ED +); + +const int CURVE_B = 4; +# elif EXHAUSTIVE_TEST_ORDER == 13 +const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( + 0xedc60018, 0xa51a786b, 0x2ea91f4d, 0x4c9416c0, + 0x9de54c3b, 0xa1316554, 0x6cf4345c, 0x7277ef15, + 0x54cb1b6b, 0xdc8c1273, 0x087844ea, 0x43f4603e, + 0x0eaf9a43, 0xf6effe55, 0x939f806d, 0x37adf8ac +); +const int CURVE_B = 2; +# else +# error No known generator for the specified exhaustive test group order. +# endif +#else /** Generator for secp256k1, value 'g' defined in * "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ @@ -23,8 +68,11 @@ static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( 0xFD17B448UL, 0xA6855419UL, 0x9C47D08FUL, 0xFB10D4B8UL ); +const int CURVE_B = 7; +#endif + static void secp256k1_ge_set_gej_zinv(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zi) { - secp256k1_fe zi2; + secp256k1_fe zi2; secp256k1_fe zi3; secp256k1_fe_sqr(&zi2, zi); secp256k1_fe_mul(&zi3, &zi2, zi); @@ -78,7 +126,7 @@ static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a) { r->y = a->y; } -static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_callback *cb) { +static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len, const secp256k1_callback *cb) { secp256k1_fe *az; secp256k1_fe *azi; size_t i; @@ -91,7 +139,7 @@ static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge *r, const secp } azi = (secp256k1_fe *)checked_malloc(cb, sizeof(secp256k1_fe) * count); - secp256k1_fe_inv_all_var(count, azi, az); + secp256k1_fe_inv_all_var(azi, az, count); free(az); count = 0; @@ -104,7 +152,7 @@ static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge *r, const secp free(azi); } -static void secp256k1_ge_set_table_gej_var(size_t len, secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zr) { +static void secp256k1_ge_set_table_gej_var(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zr, size_t len) { size_t i = len - 1; secp256k1_fe zi; @@ -147,9 +195,15 @@ static void secp256k1_ge_globalz_set_table_gej(size_t len, secp256k1_ge *r, secp static void secp256k1_gej_set_infinity(secp256k1_gej *r) { r->infinity = 1; - secp256k1_fe_set_int(&r->x, 0); - secp256k1_fe_set_int(&r->y, 0); - secp256k1_fe_set_int(&r->z, 0); + secp256k1_fe_clear(&r->x); + secp256k1_fe_clear(&r->y); + secp256k1_fe_clear(&r->z); +} + +static void secp256k1_ge_set_infinity(secp256k1_ge *r) { + r->infinity = 1; + secp256k1_fe_clear(&r->x); + secp256k1_fe_clear(&r->y); } static void secp256k1_gej_clear(secp256k1_gej *r) { @@ -165,19 +219,19 @@ static void secp256k1_ge_clear(secp256k1_ge *r) { secp256k1_fe_clear(&r->y); } -static int secp256k1_ge_set_xquad_var(secp256k1_ge *r, const secp256k1_fe *x) { +static int secp256k1_ge_set_xquad(secp256k1_ge *r, const secp256k1_fe *x) { secp256k1_fe x2, x3, c; r->x = *x; secp256k1_fe_sqr(&x2, x); secp256k1_fe_mul(&x3, x, &x2); r->infinity = 0; - secp256k1_fe_set_int(&c, 7); + secp256k1_fe_set_int(&c, CURVE_B); secp256k1_fe_add(&c, &x3); - return secp256k1_fe_sqrt_var(&r->y, &c); + return secp256k1_fe_sqrt(&r->y, &c); } static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd) { - if (!secp256k1_ge_set_xquad_var(r, x)) { + if (!secp256k1_ge_set_xquad(r, x)) { return 0; } secp256k1_fe_normalize_var(&r->y); @@ -230,7 +284,7 @@ static int secp256k1_gej_is_valid_var(const secp256k1_gej *a) { secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); secp256k1_fe_sqr(&z2, &a->z); secp256k1_fe_sqr(&z6, &z2); secp256k1_fe_mul(&z6, &z6, &z2); - secp256k1_fe_mul_int(&z6, 7); + secp256k1_fe_mul_int(&z6, CURVE_B); secp256k1_fe_add(&x3, &z6); secp256k1_fe_normalize_weak(&x3); return secp256k1_fe_equal_var(&y2, &x3); @@ -244,18 +298,30 @@ static int secp256k1_ge_is_valid_var(const secp256k1_ge *a) { /* y^2 = x^3 + 7 */ secp256k1_fe_sqr(&y2, &a->y); secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); - secp256k1_fe_set_int(&c, 7); + secp256k1_fe_set_int(&c, CURVE_B); secp256k1_fe_add(&x3, &c); secp256k1_fe_normalize_weak(&x3); return secp256k1_fe_equal_var(&y2, &x3); } static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr) { - /* Operations: 3 mul, 4 sqr, 0 normalize, 12 mul_int/add/negate */ + /* Operations: 3 mul, 4 sqr, 0 normalize, 12 mul_int/add/negate. + * + * Note that there is an implementation described at + * https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l + * which trades a multiply for a square, but in practice this is actually slower, + * mainly because it requires more normalizations. + */ secp256k1_fe t1,t2,t3,t4; /** For secp256k1, 2Q is infinity if and only if Q is infinity. This is because if 2Q = infinity, * Q must equal -Q, or that Q.y == -(Q.y), or Q.y is 0. For a point on y^2 = x^3 + 7 to have * y=0, x^3 must be -7 mod p. However, -7 has no cube root mod p. + * + * Having said this, if this function receives a point on a sextic twist, e.g. by + * a fault attack, it is possible for y to be 0. This happens for y^2 = x^3 + 6, + * since -6 does have a cube root mod p. For this point, this function will not set + * the infinity flag even though the point doubles to infinity, and the result + * point will be gibberish (z = 0 but infinity = 0). */ r->infinity = a->infinity; if (r->infinity) { @@ -623,4 +689,18 @@ static void secp256k1_ge_mul_lambda(secp256k1_ge *r, const secp256k1_ge *a) { } #endif +static int secp256k1_gej_has_quad_y_var(const secp256k1_gej *a) { + secp256k1_fe yz; + + if (a->infinity) { + return 0; + } + + /* We rely on the fact that the Jacobi symbol of 1 / a->z^3 is the same as + * that of a->z. Thus a->y / a->z^3 is a quadratic residue iff a->y * a->z + is */ + secp256k1_fe_mul(&yz, &a->y, &a->z); + return secp256k1_fe_is_quad_var(&yz); +} + #endif diff --git a/src/secp256k1/src/hash.h b/src/secp256k1/src/hash.h index 0ff01e63fa7..fca98cab9f8 100644 --- a/src/secp256k1/src/hash.h +++ b/src/secp256k1/src/hash.h @@ -11,7 +11,7 @@ #include typedef struct { - uint32_t s[32]; + uint32_t s[8]; uint32_t buf[16]; /* In big endian */ size_t bytes; } secp256k1_sha256_t; diff --git a/src/secp256k1/src/hash_impl.h b/src/secp256k1/src/hash_impl.h index ae55df6d8a2..b47e65f830a 100644 --- a/src/secp256k1/src/hash_impl.h +++ b/src/secp256k1/src/hash_impl.h @@ -269,15 +269,13 @@ static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256 rng->retry = 0; } - +#undef BE32 #undef Round -#undef sigma0 #undef sigma1 -#undef Sigma0 +#undef sigma0 #undef Sigma1 -#undef Ch +#undef Sigma0 #undef Maj -#undef ReadBE32 -#undef WriteBE32 +#undef Ch #endif diff --git a/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1.java b/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1.java index 90a498eaa2c..1c67802fba8 100644 --- a/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1.java +++ b/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1.java @@ -1,60 +1,446 @@ +/* + * Copyright 2013 Google Inc. + * Copyright 2014-2016 the libsecp256k1 contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.bitcoin; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.math.BigInteger; import com.google.common.base.Preconditions; - +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import static org.bitcoin.NativeSecp256k1Util.*; /** - * This class holds native methods to handle ECDSA verification. - * You can find an example library that can be used for this at - * https://github.com/sipa/secp256k1 + *

This class holds native methods to handle ECDSA verification.

+ * + *

You can find an example library that can be used for this at https://github.com/bitcoin/secp256k1

+ * + *

To build secp256k1 for use with bitcoinj, run + * `./configure --enable-jni --enable-experimental --enable-module-ecdh` + * and `make` then copy `.libs/libsecp256k1.so` to your system library path + * or point the JVM to the folder containing it with -Djava.library.path + *

*/ public class NativeSecp256k1 { - public static final boolean enabled; - static { - boolean isEnabled = true; - try { - System.loadLibrary("javasecp256k1"); - } catch (UnsatisfiedLinkError e) { - isEnabled = false; - } - enabled = isEnabled; - } - + + private static final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); + private static final Lock r = rwl.readLock(); + private static final Lock w = rwl.writeLock(); private static ThreadLocal nativeECDSABuffer = new ThreadLocal(); /** * Verifies the given secp256k1 signature in native code. * Calling when enabled == false is undefined (probably library not loaded) - * + * * @param data The data which was signed, must be exactly 32 bytes * @param signature The signature * @param pub The public key which did the signing */ - public static boolean verify(byte[] data, byte[] signature, byte[] pub) { + public static boolean verify(byte[] data, byte[] signature, byte[] pub) throws AssertFailException{ Preconditions.checkArgument(data.length == 32 && signature.length <= 520 && pub.length <= 520); ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null) { - byteBuff = ByteBuffer.allocateDirect(32 + 8 + 520 + 520); + if (byteBuff == null || byteBuff.capacity() < 520) { + byteBuff = ByteBuffer.allocateDirect(520); byteBuff.order(ByteOrder.nativeOrder()); nativeECDSABuffer.set(byteBuff); } byteBuff.rewind(); byteBuff.put(data); - byteBuff.putInt(signature.length); - byteBuff.putInt(pub.length); byteBuff.put(signature); byteBuff.put(pub); - return secp256k1_ecdsa_verify(byteBuff) == 1; + + byte[][] retByteArray; + + r.lock(); + try { + return secp256k1_ecdsa_verify(byteBuff, Secp256k1Context.getContext(), signature.length, pub.length) == 1; + } finally { + r.unlock(); + } + } + + /** + * libsecp256k1 Create an ECDSA signature. + * + * @param data Message hash, 32 bytes + * @param key Secret key, 32 bytes + * + * Return values + * @param sig byte array of signature + */ + public static byte[] sign(byte[] data, byte[] sec) throws AssertFailException{ + Preconditions.checkArgument(data.length == 32 && sec.length <= 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < 32 + 32) { + byteBuff = ByteBuffer.allocateDirect(32 + 32); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(data); + byteBuff.put(sec); + + byte[][] retByteArray; + + r.lock(); + try { + retByteArray = secp256k1_ecdsa_sign(byteBuff, Secp256k1Context.getContext()); + } finally { + r.unlock(); + } + + byte[] sigArr = retByteArray[0]; + int sigLen = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(sigArr.length, sigLen, "Got bad signature length."); + + return retVal == 0 ? new byte[0] : sigArr; + } + + /** + * libsecp256k1 Seckey Verify - returns 1 if valid, 0 if invalid + * + * @param seckey ECDSA Secret key, 32 bytes + */ + public static boolean secKeyVerify(byte[] seckey) { + Preconditions.checkArgument(seckey.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < seckey.length) { + byteBuff = ByteBuffer.allocateDirect(seckey.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(seckey); + + r.lock(); + try { + return secp256k1_ec_seckey_verify(byteBuff,Secp256k1Context.getContext()) == 1; + } finally { + r.unlock(); + } + } + + + /** + * libsecp256k1 Compute Pubkey - computes public key from secret key + * + * @param seckey ECDSA Secret key, 32 bytes + * + * Return values + * @param pubkey ECDSA Public key, 33 or 65 bytes + */ + //TODO add a 'compressed' arg + public static byte[] computePubkey(byte[] seckey) throws AssertFailException{ + Preconditions.checkArgument(seckey.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < seckey.length) { + byteBuff = ByteBuffer.allocateDirect(seckey.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(seckey); + + byte[][] retByteArray; + + r.lock(); + try { + retByteArray = secp256k1_ec_pubkey_create(byteBuff, Secp256k1Context.getContext()); + } finally { + r.unlock(); + } + + byte[] pubArr = retByteArray[0]; + int pubLen = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(pubArr.length, pubLen, "Got bad pubkey length."); + + return retVal == 0 ? new byte[0]: pubArr; + } + + /** + * libsecp256k1 Cleanup - This destroys the secp256k1 context object + * This should be called at the end of the program for proper cleanup of the context. + */ + public static synchronized void cleanup() { + w.lock(); + try { + secp256k1_destroy_context(Secp256k1Context.getContext()); + } finally { + w.unlock(); + } + } + + public static long cloneContext() { + r.lock(); + try { + return secp256k1_ctx_clone(Secp256k1Context.getContext()); + } finally { r.unlock(); } + } + + /** + * libsecp256k1 PrivKey Tweak-Mul - Tweak privkey by multiplying to it + * + * @param tweak some bytes to tweak with + * @param seckey 32-byte seckey + */ + public static byte[] privKeyTweakMul(byte[] privkey, byte[] tweak) throws AssertFailException{ + Preconditions.checkArgument(privkey.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < privkey.length + tweak.length) { + byteBuff = ByteBuffer.allocateDirect(privkey.length + tweak.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(privkey); + byteBuff.put(tweak); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_privkey_tweak_mul(byteBuff,Secp256k1Context.getContext()); + } finally { + r.unlock(); + } + + byte[] privArr = retByteArray[0]; + + int privLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(privArr.length, privLen, "Got bad pubkey length."); + + assertEquals(retVal, 1, "Failed return value check."); + + return privArr; + } + + /** + * libsecp256k1 PrivKey Tweak-Add - Tweak privkey by adding to it + * + * @param tweak some bytes to tweak with + * @param seckey 32-byte seckey + */ + public static byte[] privKeyTweakAdd(byte[] privkey, byte[] tweak) throws AssertFailException{ + Preconditions.checkArgument(privkey.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < privkey.length + tweak.length) { + byteBuff = ByteBuffer.allocateDirect(privkey.length + tweak.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(privkey); + byteBuff.put(tweak); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_privkey_tweak_add(byteBuff,Secp256k1Context.getContext()); + } finally { + r.unlock(); + } + + byte[] privArr = retByteArray[0]; + + int privLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(privArr.length, privLen, "Got bad pubkey length."); + + assertEquals(retVal, 1, "Failed return value check."); + + return privArr; + } + + /** + * libsecp256k1 PubKey Tweak-Add - Tweak pubkey by adding to it + * + * @param tweak some bytes to tweak with + * @param pubkey 32-byte seckey + */ + public static byte[] pubKeyTweakAdd(byte[] pubkey, byte[] tweak) throws AssertFailException{ + Preconditions.checkArgument(pubkey.length == 33 || pubkey.length == 65); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < pubkey.length + tweak.length) { + byteBuff = ByteBuffer.allocateDirect(pubkey.length + tweak.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(pubkey); + byteBuff.put(tweak); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_pubkey_tweak_add(byteBuff,Secp256k1Context.getContext(), pubkey.length); + } finally { + r.unlock(); + } + + byte[] pubArr = retByteArray[0]; + + int pubLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(pubArr.length, pubLen, "Got bad pubkey length."); + + assertEquals(retVal, 1, "Failed return value check."); + + return pubArr; + } + + /** + * libsecp256k1 PubKey Tweak-Mul - Tweak pubkey by multiplying to it + * + * @param tweak some bytes to tweak with + * @param pubkey 32-byte seckey + */ + public static byte[] pubKeyTweakMul(byte[] pubkey, byte[] tweak) throws AssertFailException{ + Preconditions.checkArgument(pubkey.length == 33 || pubkey.length == 65); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < pubkey.length + tweak.length) { + byteBuff = ByteBuffer.allocateDirect(pubkey.length + tweak.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(pubkey); + byteBuff.put(tweak); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_pubkey_tweak_mul(byteBuff,Secp256k1Context.getContext(), pubkey.length); + } finally { + r.unlock(); + } + + byte[] pubArr = retByteArray[0]; + + int pubLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(pubArr.length, pubLen, "Got bad pubkey length."); + + assertEquals(retVal, 1, "Failed return value check."); + + return pubArr; } /** - * @param byteBuff signature format is byte[32] data, - * native-endian int signatureLength, native-endian int pubkeyLength, - * byte[signatureLength] signature, byte[pubkeyLength] pub - * @returns 1 for valid signature, anything else for invalid + * libsecp256k1 create ECDH secret - constant time ECDH calculation + * + * @param seckey byte array of secret key used in exponentiaion + * @param pubkey byte array of public key used in exponentiaion */ - private static native int secp256k1_ecdsa_verify(ByteBuffer byteBuff); + public static byte[] createECDHSecret(byte[] seckey, byte[] pubkey) throws AssertFailException{ + Preconditions.checkArgument(seckey.length <= 32 && pubkey.length <= 65); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < 32 + pubkey.length) { + byteBuff = ByteBuffer.allocateDirect(32 + pubkey.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(seckey); + byteBuff.put(pubkey); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_ecdh(byteBuff, Secp256k1Context.getContext(), pubkey.length); + } finally { + r.unlock(); + } + + byte[] resArr = retByteArray[0]; + int retVal = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); + + assertEquals(resArr.length, 32, "Got bad result length."); + assertEquals(retVal, 1, "Failed return value check."); + + return resArr; + } + + /** + * libsecp256k1 randomize - updates the context randomization + * + * @param seed 32-byte random seed + */ + public static synchronized boolean randomize(byte[] seed) throws AssertFailException{ + Preconditions.checkArgument(seed.length == 32 || seed == null); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < seed.length) { + byteBuff = ByteBuffer.allocateDirect(seed.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(seed); + + w.lock(); + try { + return secp256k1_context_randomize(byteBuff, Secp256k1Context.getContext()) == 1; + } finally { + w.unlock(); + } + } + + private static native long secp256k1_ctx_clone(long context); + + private static native int secp256k1_context_randomize(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_privkey_tweak_add(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_privkey_tweak_mul(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_pubkey_tweak_add(ByteBuffer byteBuff, long context, int pubLen); + + private static native byte[][] secp256k1_pubkey_tweak_mul(ByteBuffer byteBuff, long context, int pubLen); + + private static native void secp256k1_destroy_context(long context); + + private static native int secp256k1_ecdsa_verify(ByteBuffer byteBuff, long context, int sigLen, int pubLen); + + private static native byte[][] secp256k1_ecdsa_sign(ByteBuffer byteBuff, long context); + + private static native int secp256k1_ec_seckey_verify(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_ec_pubkey_create(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_ec_pubkey_parse(ByteBuffer byteBuff, long context, int inputLen); + + private static native byte[][] secp256k1_ecdh(ByteBuffer byteBuff, long context, int inputLen); + } diff --git a/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1Test.java b/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1Test.java new file mode 100644 index 00000000000..c00d08899b9 --- /dev/null +++ b/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1Test.java @@ -0,0 +1,226 @@ +package org.bitcoin; + +import com.google.common.io.BaseEncoding; +import java.util.Arrays; +import java.math.BigInteger; +import javax.xml.bind.DatatypeConverter; +import static org.bitcoin.NativeSecp256k1Util.*; + +/** + * This class holds test cases defined for testing this library. + */ +public class NativeSecp256k1Test { + + //TODO improve comments/add more tests + /** + * This tests verify() for a valid signature + */ + public static void testVerifyPos() throws AssertFailException{ + boolean result = false; + byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()); //sha256hash of "testing" + byte[] sig = BaseEncoding.base16().lowerCase().decode("3044022079BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F817980220294F14E883B3F525B5367756C2A11EF6CF84B730B36C17CB0C56F0AAB2C98589".toLowerCase()); + byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); + + result = NativeSecp256k1.verify( data, sig, pub); + assertEquals( result, true , "testVerifyPos"); + } + + /** + * This tests verify() for a non-valid signature + */ + public static void testVerifyNeg() throws AssertFailException{ + boolean result = false; + byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A91".toLowerCase()); //sha256hash of "testing" + byte[] sig = BaseEncoding.base16().lowerCase().decode("3044022079BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F817980220294F14E883B3F525B5367756C2A11EF6CF84B730B36C17CB0C56F0AAB2C98589".toLowerCase()); + byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); + + result = NativeSecp256k1.verify( data, sig, pub); + //System.out.println(" TEST " + new BigInteger(1, resultbytes).toString(16)); + assertEquals( result, false , "testVerifyNeg"); + } + + /** + * This tests secret key verify() for a valid secretkey + */ + public static void testSecKeyVerifyPos() throws AssertFailException{ + boolean result = false; + byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); + + result = NativeSecp256k1.secKeyVerify( sec ); + //System.out.println(" TEST " + new BigInteger(1, resultbytes).toString(16)); + assertEquals( result, true , "testSecKeyVerifyPos"); + } + + /** + * This tests secret key verify() for a invalid secretkey + */ + public static void testSecKeyVerifyNeg() throws AssertFailException{ + boolean result = false; + byte[] sec = BaseEncoding.base16().lowerCase().decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".toLowerCase()); + + result = NativeSecp256k1.secKeyVerify( sec ); + //System.out.println(" TEST " + new BigInteger(1, resultbytes).toString(16)); + assertEquals( result, false , "testSecKeyVerifyNeg"); + } + + /** + * This tests public key create() for a valid secretkey + */ + public static void testPubKeyCreatePos() throws AssertFailException{ + byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); + + byte[] resultArr = NativeSecp256k1.computePubkey( sec); + String pubkeyString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( pubkeyString , "04C591A8FF19AC9C4E4E5793673B83123437E975285E7B442F4EE2654DFFCA5E2D2103ED494718C697AC9AEBCFD19612E224DB46661011863ED2FC54E71861E2A6" , "testPubKeyCreatePos"); + } + + /** + * This tests public key create() for a invalid secretkey + */ + public static void testPubKeyCreateNeg() throws AssertFailException{ + byte[] sec = BaseEncoding.base16().lowerCase().decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".toLowerCase()); + + byte[] resultArr = NativeSecp256k1.computePubkey( sec); + String pubkeyString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( pubkeyString, "" , "testPubKeyCreateNeg"); + } + + /** + * This tests sign() for a valid secretkey + */ + public static void testSignPos() throws AssertFailException{ + + byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()); //sha256hash of "testing" + byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); + + byte[] resultArr = NativeSecp256k1.sign(data, sec); + String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( sigString, "30440220182A108E1448DC8F1FB467D06A0F3BB8EA0533584CB954EF8DA112F1D60E39A202201C66F36DA211C087F3AF88B50EDF4F9BDAA6CF5FD6817E74DCA34DB12390C6E9" , "testSignPos"); + } + + /** + * This tests sign() for a invalid secretkey + */ + public static void testSignNeg() throws AssertFailException{ + byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()); //sha256hash of "testing" + byte[] sec = BaseEncoding.base16().lowerCase().decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".toLowerCase()); + + byte[] resultArr = NativeSecp256k1.sign(data, sec); + String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( sigString, "" , "testSignNeg"); + } + + /** + * This tests private key tweak-add + */ + public static void testPrivKeyTweakAdd_1() throws AssertFailException { + byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); + byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak" + + byte[] resultArr = NativeSecp256k1.privKeyTweakAdd( sec , data ); + String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( sigString , "A168571E189E6F9A7E2D657A4B53AE99B909F7E712D1C23CED28093CD57C88F3" , "testPrivKeyAdd_1"); + } + + /** + * This tests private key tweak-mul + */ + public static void testPrivKeyTweakMul_1() throws AssertFailException { + byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); + byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak" + + byte[] resultArr = NativeSecp256k1.privKeyTweakMul( sec , data ); + String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( sigString , "97F8184235F101550F3C71C927507651BD3F1CDB4A5A33B8986ACF0DEE20FFFC" , "testPrivKeyMul_1"); + } + + /** + * This tests private key tweak-add uncompressed + */ + public static void testPrivKeyTweakAdd_2() throws AssertFailException { + byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); + byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak" + + byte[] resultArr = NativeSecp256k1.pubKeyTweakAdd( pub , data ); + String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( sigString , "0411C6790F4B663CCE607BAAE08C43557EDC1A4D11D88DFCB3D841D0C6A941AF525A268E2A863C148555C48FB5FBA368E88718A46E205FABC3DBA2CCFFAB0796EF" , "testPrivKeyAdd_2"); + } + + /** + * This tests private key tweak-mul uncompressed + */ + public static void testPrivKeyTweakMul_2() throws AssertFailException { + byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); + byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak" + + byte[] resultArr = NativeSecp256k1.pubKeyTweakMul( pub , data ); + String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( sigString , "04E0FE6FE55EBCA626B98A807F6CAF654139E14E5E3698F01A9A658E21DC1D2791EC060D4F412A794D5370F672BC94B722640B5F76914151CFCA6E712CA48CC589" , "testPrivKeyMul_2"); + } + + /** + * This tests seed randomization + */ + public static void testRandomize() throws AssertFailException { + byte[] seed = BaseEncoding.base16().lowerCase().decode("A441B15FE9A3CF56661190A0B93B9DEC7D04127288CC87250967CF3B52894D11".toLowerCase()); //sha256hash of "random" + boolean result = NativeSecp256k1.randomize(seed); + assertEquals( result, true, "testRandomize"); + } + + public static void testCreateECDHSecret() throws AssertFailException{ + + byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); + byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); + + byte[] resultArr = NativeSecp256k1.createECDHSecret(sec, pub); + String ecdhString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( ecdhString, "2A2A67007A926E6594AF3EB564FC74005B37A9C8AEF2033C4552051B5C87F043" , "testCreateECDHSecret"); + } + + public static void main(String[] args) throws AssertFailException{ + + + System.out.println("\n libsecp256k1 enabled: " + Secp256k1Context.isEnabled() + "\n"); + + assertEquals( Secp256k1Context.isEnabled(), true, "isEnabled" ); + + //Test verify() success/fail + testVerifyPos(); + testVerifyNeg(); + + //Test secKeyVerify() success/fail + testSecKeyVerifyPos(); + testSecKeyVerifyNeg(); + + //Test computePubkey() success/fail + testPubKeyCreatePos(); + testPubKeyCreateNeg(); + + //Test sign() success/fail + testSignPos(); + testSignNeg(); + + //Test privKeyTweakAdd() 1 + testPrivKeyTweakAdd_1(); + + //Test privKeyTweakMul() 2 + testPrivKeyTweakMul_1(); + + //Test privKeyTweakAdd() 3 + testPrivKeyTweakAdd_2(); + + //Test privKeyTweakMul() 4 + testPrivKeyTweakMul_2(); + + //Test randomize() + testRandomize(); + + //Test ECDH + testCreateECDHSecret(); + + NativeSecp256k1.cleanup(); + + System.out.println(" All tests passed." ); + + } +} diff --git a/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1Util.java b/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1Util.java new file mode 100644 index 00000000000..04732ba0443 --- /dev/null +++ b/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1Util.java @@ -0,0 +1,45 @@ +/* + * Copyright 2014-2016 the libsecp256k1 contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.bitcoin; + +public class NativeSecp256k1Util{ + + public static void assertEquals( int val, int val2, String message ) throws AssertFailException{ + if( val != val2 ) + throw new AssertFailException("FAIL: " + message); + } + + public static void assertEquals( boolean val, boolean val2, String message ) throws AssertFailException{ + if( val != val2 ) + throw new AssertFailException("FAIL: " + message); + else + System.out.println("PASS: " + message); + } + + public static void assertEquals( String val, String val2, String message ) throws AssertFailException{ + if( !val.equals(val2) ) + throw new AssertFailException("FAIL: " + message); + else + System.out.println("PASS: " + message); + } + + public static class AssertFailException extends Exception { + public AssertFailException(String message) { + super( message ); + } + } +} diff --git a/src/secp256k1/src/java/org/bitcoin/Secp256k1Context.java b/src/secp256k1/src/java/org/bitcoin/Secp256k1Context.java new file mode 100644 index 00000000000..216c986a8b5 --- /dev/null +++ b/src/secp256k1/src/java/org/bitcoin/Secp256k1Context.java @@ -0,0 +1,51 @@ +/* + * Copyright 2014-2016 the libsecp256k1 contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.bitcoin; + +/** + * This class holds the context reference used in native methods + * to handle ECDSA operations. + */ +public class Secp256k1Context { + private static final boolean enabled; //true if the library is loaded + private static final long context; //ref to pointer to context obj + + static { //static initializer + boolean isEnabled = true; + long contextRef = -1; + try { + System.loadLibrary("secp256k1"); + contextRef = secp256k1_init_context(); + } catch (UnsatisfiedLinkError e) { + System.out.println("UnsatisfiedLinkError: " + e.toString()); + isEnabled = false; + } + enabled = isEnabled; + context = contextRef; + } + + public static boolean isEnabled() { + return enabled; + } + + public static long getContext() { + if(!enabled) return -1; //sanity check + return context; + } + + private static native long secp256k1_init_context(); +} diff --git a/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.c b/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.c index bb4cd707280..bcef7b32ce3 100644 --- a/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.c +++ b/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.c @@ -1,23 +1,377 @@ +#include +#include +#include #include "org_bitcoin_NativeSecp256k1.h" #include "include/secp256k1.h" +#include "include/secp256k1_ecdh.h" +#include "include/secp256k1_recovery.h" -JNIEXPORT jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify - (JNIEnv* env, jclass classObject, jobject byteBufferObject) + +SECP256K1_API jlong JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ctx_1clone + (JNIEnv* env, jclass classObject, jlong ctx_l) +{ + const secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + + jlong ctx_clone_l = (uintptr_t) secp256k1_context_clone(ctx); + + (void)classObject;(void)env; + + return ctx_clone_l; + +} + +SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1context_1randomize + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) { - unsigned char* data = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); - int sigLen = *((int*)(data + 32)); - int pubLen = *((int*)(data + 32 + 4)); + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + + const unsigned char* seed = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + + (void)classObject; + + return secp256k1_context_randomize(ctx, seed); - return secp256k1_ecdsa_verify(data, 32, data+32+8, sigLen, data+32+8+sigLen, pubLen); } -static void __javasecp256k1_attach(void) __attribute__((constructor)); -static void __javasecp256k1_detach(void) __attribute__((destructor)); +SECP256K1_API void JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1destroy_1context + (JNIEnv* env, jclass classObject, jlong ctx_l) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + + secp256k1_context_destroy(ctx); -static void __javasecp256k1_attach(void) { - secp256k1_start(SECP256K1_START_VERIFY); + (void)classObject;(void)env; } -static void __javasecp256k1_detach(void) { - secp256k1_stop(); +SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint siglen, jint publen) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + + unsigned char* data = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + const unsigned char* sigdata = { (unsigned char*) (data + 32) }; + const unsigned char* pubdata = { (unsigned char*) (data + siglen + 32) }; + + secp256k1_ecdsa_signature sig; + secp256k1_pubkey pubkey; + + int ret = secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigdata, siglen); + + if( ret ) { + ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pubdata, publen); + + if( ret ) { + ret = secp256k1_ecdsa_verify(ctx, &sig, data, &pubkey); + } + } + + (void)classObject; + + return ret; +} + +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1sign + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + unsigned char* data = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + unsigned char* secKey = (unsigned char*) (data + 32); + + jobjectArray retArray; + jbyteArray sigArray, intsByteArray; + unsigned char intsarray[2]; + + secp256k1_ecdsa_signature sig[72]; + + int ret = secp256k1_ecdsa_sign(ctx, sig, data, secKey, NULL, NULL ); + + unsigned char outputSer[72]; + size_t outputLen = 72; + + if( ret ) { + int ret2 = secp256k1_ecdsa_signature_serialize_der(ctx,outputSer, &outputLen, sig ); (void)ret2; + } + + intsarray[0] = outputLen; + intsarray[1] = ret; + + retArray = (*env)->NewObjectArray(env, 2, + (*env)->FindClass(env, "[B"), + (*env)->NewByteArray(env, 1)); + + sigArray = (*env)->NewByteArray(env, outputLen); + (*env)->SetByteArrayRegion(env, sigArray, 0, outputLen, (jbyte*)outputSer); + (*env)->SetObjectArrayElement(env, retArray, 0, sigArray); + + intsByteArray = (*env)->NewByteArray(env, 2); + (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); + (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); + + (void)classObject; + + return retArray; +} + +SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1seckey_1verify + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + unsigned char* secKey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + + (void)classObject; + + return secp256k1_ec_seckey_verify(ctx, secKey); +} + +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1pubkey_1create + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + const unsigned char* secKey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + + secp256k1_pubkey pubkey; + + jobjectArray retArray; + jbyteArray pubkeyArray, intsByteArray; + unsigned char intsarray[2]; + + int ret = secp256k1_ec_pubkey_create(ctx, &pubkey, secKey); + + unsigned char outputSer[65]; + size_t outputLen = 65; + + if( ret ) { + int ret2 = secp256k1_ec_pubkey_serialize(ctx,outputSer, &outputLen, &pubkey,SECP256K1_EC_UNCOMPRESSED );(void)ret2; + } + + intsarray[0] = outputLen; + intsarray[1] = ret; + + retArray = (*env)->NewObjectArray(env, 2, + (*env)->FindClass(env, "[B"), + (*env)->NewByteArray(env, 1)); + + pubkeyArray = (*env)->NewByteArray(env, outputLen); + (*env)->SetByteArrayRegion(env, pubkeyArray, 0, outputLen, (jbyte*)outputSer); + (*env)->SetObjectArrayElement(env, retArray, 0, pubkeyArray); + + intsByteArray = (*env)->NewByteArray(env, 2); + (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); + (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); + + (void)classObject; + + return retArray; + +} + +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1add + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + unsigned char* privkey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + const unsigned char* tweak = (unsigned char*) (privkey + 32); + + jobjectArray retArray; + jbyteArray privArray, intsByteArray; + unsigned char intsarray[2]; + + int privkeylen = 32; + + int ret = secp256k1_ec_privkey_tweak_add(ctx, privkey, tweak); + + intsarray[0] = privkeylen; + intsarray[1] = ret; + + retArray = (*env)->NewObjectArray(env, 2, + (*env)->FindClass(env, "[B"), + (*env)->NewByteArray(env, 1)); + + privArray = (*env)->NewByteArray(env, privkeylen); + (*env)->SetByteArrayRegion(env, privArray, 0, privkeylen, (jbyte*)privkey); + (*env)->SetObjectArrayElement(env, retArray, 0, privArray); + + intsByteArray = (*env)->NewByteArray(env, 2); + (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); + (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); + + (void)classObject; + + return retArray; +} + +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1mul + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + unsigned char* privkey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + const unsigned char* tweak = (unsigned char*) (privkey + 32); + + jobjectArray retArray; + jbyteArray privArray, intsByteArray; + unsigned char intsarray[2]; + + int privkeylen = 32; + + int ret = secp256k1_ec_privkey_tweak_mul(ctx, privkey, tweak); + + intsarray[0] = privkeylen; + intsarray[1] = ret; + + retArray = (*env)->NewObjectArray(env, 2, + (*env)->FindClass(env, "[B"), + (*env)->NewByteArray(env, 1)); + + privArray = (*env)->NewByteArray(env, privkeylen); + (*env)->SetByteArrayRegion(env, privArray, 0, privkeylen, (jbyte*)privkey); + (*env)->SetObjectArrayElement(env, retArray, 0, privArray); + + intsByteArray = (*env)->NewByteArray(env, 2); + (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); + (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); + + (void)classObject; + + return retArray; +} + +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1add + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; +/* secp256k1_pubkey* pubkey = (secp256k1_pubkey*) (*env)->GetDirectBufferAddress(env, byteBufferObject);*/ + unsigned char* pkey = (*env)->GetDirectBufferAddress(env, byteBufferObject); + const unsigned char* tweak = (unsigned char*) (pkey + publen); + + jobjectArray retArray; + jbyteArray pubArray, intsByteArray; + unsigned char intsarray[2]; + unsigned char outputSer[65]; + size_t outputLen = 65; + + secp256k1_pubkey pubkey; + int ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pkey, publen); + + if( ret ) { + ret = secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, tweak); + } + + if( ret ) { + int ret2 = secp256k1_ec_pubkey_serialize(ctx,outputSer, &outputLen, &pubkey,SECP256K1_EC_UNCOMPRESSED );(void)ret2; + } + + intsarray[0] = outputLen; + intsarray[1] = ret; + + retArray = (*env)->NewObjectArray(env, 2, + (*env)->FindClass(env, "[B"), + (*env)->NewByteArray(env, 1)); + + pubArray = (*env)->NewByteArray(env, outputLen); + (*env)->SetByteArrayRegion(env, pubArray, 0, outputLen, (jbyte*)outputSer); + (*env)->SetObjectArrayElement(env, retArray, 0, pubArray); + + intsByteArray = (*env)->NewByteArray(env, 2); + (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); + (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); + + (void)classObject; + + return retArray; +} + +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1mul + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + unsigned char* pkey = (*env)->GetDirectBufferAddress(env, byteBufferObject); + const unsigned char* tweak = (unsigned char*) (pkey + publen); + + jobjectArray retArray; + jbyteArray pubArray, intsByteArray; + unsigned char intsarray[2]; + unsigned char outputSer[65]; + size_t outputLen = 65; + + secp256k1_pubkey pubkey; + int ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pkey, publen); + + if ( ret ) { + ret = secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, tweak); + } + + if( ret ) { + int ret2 = secp256k1_ec_pubkey_serialize(ctx,outputSer, &outputLen, &pubkey,SECP256K1_EC_UNCOMPRESSED );(void)ret2; + } + + intsarray[0] = outputLen; + intsarray[1] = ret; + + retArray = (*env)->NewObjectArray(env, 2, + (*env)->FindClass(env, "[B"), + (*env)->NewByteArray(env, 1)); + + pubArray = (*env)->NewByteArray(env, outputLen); + (*env)->SetByteArrayRegion(env, pubArray, 0, outputLen, (jbyte*)outputSer); + (*env)->SetObjectArrayElement(env, retArray, 0, pubArray); + + intsByteArray = (*env)->NewByteArray(env, 2); + (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); + (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); + + (void)classObject; + + return retArray; +} + +SECP256K1_API jlong JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1pubkey_1combine + (JNIEnv * env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint numkeys) +{ + (void)classObject;(void)env;(void)byteBufferObject;(void)ctx_l;(void)numkeys; + + return 0; +} + +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdh + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + const unsigned char* secdata = (*env)->GetDirectBufferAddress(env, byteBufferObject); + const unsigned char* pubdata = (const unsigned char*) (secdata + 32); + + jobjectArray retArray; + jbyteArray outArray, intsByteArray; + unsigned char intsarray[1]; + secp256k1_pubkey pubkey; + unsigned char nonce_res[32]; + size_t outputLen = 32; + + int ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pubdata, publen); + + if (ret) { + ret = secp256k1_ecdh( + ctx, + nonce_res, + &pubkey, + secdata + ); + } + + intsarray[0] = ret; + + retArray = (*env)->NewObjectArray(env, 2, + (*env)->FindClass(env, "[B"), + (*env)->NewByteArray(env, 1)); + + outArray = (*env)->NewByteArray(env, outputLen); + (*env)->SetByteArrayRegion(env, outArray, 0, 32, (jbyte*)nonce_res); + (*env)->SetObjectArrayElement(env, retArray, 0, outArray); + + intsByteArray = (*env)->NewByteArray(env, 1); + (*env)->SetByteArrayRegion(env, intsByteArray, 0, 1, (jbyte*)intsarray); + (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); + + (void)classObject; + + return retArray; } diff --git a/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h b/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h index d7fb004fa84..fe613c9e9e7 100644 --- a/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h +++ b/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h @@ -1,5 +1,6 @@ /* DO NOT EDIT THIS FILE - it is machine generated */ #include +#include "include/secp256k1.h" /* Header for class org_bitcoin_NativeSecp256k1 */ #ifndef _Included_org_bitcoin_NativeSecp256k1 @@ -9,11 +10,108 @@ extern "C" { #endif /* * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_ctx_clone + * Signature: (J)J + */ +SECP256K1_API jlong JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ctx_1clone + (JNIEnv *, jclass, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_context_randomize + * Signature: (Ljava/nio/ByteBuffer;J)I + */ +SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1context_1randomize + (JNIEnv *, jclass, jobject, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_privkey_tweak_add + * Signature: (Ljava/nio/ByteBuffer;J)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1add + (JNIEnv *, jclass, jobject, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_privkey_tweak_mul + * Signature: (Ljava/nio/ByteBuffer;J)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1mul + (JNIEnv *, jclass, jobject, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_pubkey_tweak_add + * Signature: (Ljava/nio/ByteBuffer;JI)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1add + (JNIEnv *, jclass, jobject, jlong, jint); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_pubkey_tweak_mul + * Signature: (Ljava/nio/ByteBuffer;JI)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1mul + (JNIEnv *, jclass, jobject, jlong, jint); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_destroy_context + * Signature: (J)V + */ +SECP256K1_API void JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1destroy_1context + (JNIEnv *, jclass, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 * Method: secp256k1_ecdsa_verify - * Signature: (Ljava/nio/ByteBuffer;)I + * Signature: (Ljava/nio/ByteBuffer;JII)I + */ +SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify + (JNIEnv *, jclass, jobject, jlong, jint, jint); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_ecdsa_sign + * Signature: (Ljava/nio/ByteBuffer;J)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1sign + (JNIEnv *, jclass, jobject, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_ec_seckey_verify + * Signature: (Ljava/nio/ByteBuffer;J)I + */ +SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1seckey_1verify + (JNIEnv *, jclass, jobject, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_ec_pubkey_create + * Signature: (Ljava/nio/ByteBuffer;J)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1pubkey_1create + (JNIEnv *, jclass, jobject, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_ec_pubkey_parse + * Signature: (Ljava/nio/ByteBuffer;JI)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1pubkey_1parse + (JNIEnv *, jclass, jobject, jlong, jint); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_ecdh + * Signature: (Ljava/nio/ByteBuffer;JI)[[B */ -JNIEXPORT jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify - (JNIEnv *, jclass, jobject); +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdh + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen); + #ifdef __cplusplus } diff --git a/src/secp256k1/src/java/org_bitcoin_Secp256k1Context.c b/src/secp256k1/src/java/org_bitcoin_Secp256k1Context.c new file mode 100644 index 00000000000..a52939e7e7d --- /dev/null +++ b/src/secp256k1/src/java/org_bitcoin_Secp256k1Context.c @@ -0,0 +1,15 @@ +#include +#include +#include "org_bitcoin_Secp256k1Context.h" +#include "include/secp256k1.h" + +SECP256K1_API jlong JNICALL Java_org_bitcoin_Secp256k1Context_secp256k1_1init_1context + (JNIEnv* env, jclass classObject) +{ + secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + + (void)classObject;(void)env; + + return (uintptr_t)ctx; +} + diff --git a/src/secp256k1/src/java/org_bitcoin_Secp256k1Context.h b/src/secp256k1/src/java/org_bitcoin_Secp256k1Context.h new file mode 100644 index 00000000000..0d2bc84b7f3 --- /dev/null +++ b/src/secp256k1/src/java/org_bitcoin_Secp256k1Context.h @@ -0,0 +1,22 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +#include "include/secp256k1.h" +/* Header for class org_bitcoin_Secp256k1Context */ + +#ifndef _Included_org_bitcoin_Secp256k1Context +#define _Included_org_bitcoin_Secp256k1Context +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_bitcoin_Secp256k1Context + * Method: secp256k1_init_context + * Signature: ()J + */ +SECP256K1_API jlong JNICALL Java_org_bitcoin_Secp256k1Context_secp256k1_1init_1context + (JNIEnv *, jclass); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/secp256k1/src/modules/ecdh/Makefile.am.include b/src/secp256k1/src/modules/ecdh/Makefile.am.include index 670b9c1152e..e3088b46979 100644 --- a/src/secp256k1/src/modules/ecdh/Makefile.am.include +++ b/src/secp256k1/src/modules/ecdh/Makefile.am.include @@ -4,5 +4,5 @@ noinst_HEADERS += src/modules/ecdh/tests_impl.h if USE_BENCHMARK noinst_PROGRAMS += bench_ecdh bench_ecdh_SOURCES = src/bench_ecdh.c -bench_ecdh_LDADD = libsecp256k1.la $(SECP_LIBS) +bench_ecdh_LDADD = libsecp256k1.la $(SECP_LIBS) $(COMMON_LIB) endif diff --git a/src/secp256k1/src/modules/recovery/Makefile.am.include b/src/secp256k1/src/modules/recovery/Makefile.am.include index 5de3ea33ea5..bf23c26e71c 100644 --- a/src/secp256k1/src/modules/recovery/Makefile.am.include +++ b/src/secp256k1/src/modules/recovery/Makefile.am.include @@ -4,5 +4,5 @@ noinst_HEADERS += src/modules/recovery/tests_impl.h if USE_BENCHMARK noinst_PROGRAMS += bench_recover bench_recover_SOURCES = src/bench_recover.c -bench_recover_LDADD = libsecp256k1.la $(SECP_LIBS) +bench_recover_LDADD = libsecp256k1.la $(SECP_LIBS) $(COMMON_LIB) endif diff --git a/src/secp256k1/src/modules/recovery/main_impl.h b/src/secp256k1/src/modules/recovery/main_impl.h old mode 100644 new mode 100755 index ec42f4bb6cd..86f2f0cb2b5 --- a/src/secp256k1/src/modules/recovery/main_impl.h +++ b/src/secp256k1/src/modules/recovery/main_impl.h @@ -138,16 +138,15 @@ int secp256k1_ecdsa_sign_recoverable(const secp256k1_context* ctx, secp256k1_ecd secp256k1_scalar_set_b32(&sec, seckey, &overflow); /* Fail if the secret key is invalid. */ if (!overflow && !secp256k1_scalar_is_zero(&sec)) { + unsigned char nonce32[32]; unsigned int count = 0; secp256k1_scalar_set_b32(&msg, msg32, NULL); while (1) { - unsigned char nonce32[32]; ret = noncefp(nonce32, msg32, seckey, NULL, (void*)noncedata, count); if (!ret) { break; } secp256k1_scalar_set_b32(&non, nonce32, &overflow); - memset(nonce32, 0, 32); if (!secp256k1_scalar_is_zero(&non) && !overflow) { if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, &recid)) { break; @@ -155,6 +154,7 @@ int secp256k1_ecdsa_sign_recoverable(const secp256k1_context* ctx, secp256k1_ecd } count++; } + memset(nonce32, 0, 32); secp256k1_scalar_clear(&msg); secp256k1_scalar_clear(&non); secp256k1_scalar_clear(&sec); diff --git a/src/secp256k1/src/modules/schnorr/Makefile.am.include b/src/secp256k1/src/modules/schnorr/Makefile.am.include deleted file mode 100644 index b3bfa7d5cc4..00000000000 --- a/src/secp256k1/src/modules/schnorr/Makefile.am.include +++ /dev/null @@ -1,10 +0,0 @@ -include_HEADERS += include/secp256k1_schnorr.h -noinst_HEADERS += src/modules/schnorr/main_impl.h -noinst_HEADERS += src/modules/schnorr/schnorr.h -noinst_HEADERS += src/modules/schnorr/schnorr_impl.h -noinst_HEADERS += src/modules/schnorr/tests_impl.h -if USE_BENCHMARK -noinst_PROGRAMS += bench_schnorr_verify -bench_schnorr_verify_SOURCES = src/bench_schnorr_verify.c -bench_schnorr_verify_LDADD = libsecp256k1.la $(SECP_LIBS) -endif diff --git a/src/secp256k1/src/modules/schnorr/main_impl.h b/src/secp256k1/src/modules/schnorr/main_impl.h deleted file mode 100644 index fa176a1767f..00000000000 --- a/src/secp256k1/src/modules/schnorr/main_impl.h +++ /dev/null @@ -1,164 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_MODULE_SCHNORR_MAIN -#define SECP256K1_MODULE_SCHNORR_MAIN - -#include "include/secp256k1_schnorr.h" -#include "modules/schnorr/schnorr_impl.h" - -static void secp256k1_schnorr_msghash_sha256(unsigned char *h32, const unsigned char *r32, const unsigned char *msg32) { - secp256k1_sha256_t sha; - secp256k1_sha256_initialize(&sha); - secp256k1_sha256_write(&sha, r32, 32); - secp256k1_sha256_write(&sha, msg32, 32); - secp256k1_sha256_finalize(&sha, h32); -} - -static const unsigned char secp256k1_schnorr_algo16[17] = "Schnorr+SHA256 "; - -int secp256k1_schnorr_sign(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { - secp256k1_scalar sec, non; - int ret = 0; - int overflow = 0; - unsigned int count = 0; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(sig64 != NULL); - ARG_CHECK(seckey != NULL); - if (noncefp == NULL) { - noncefp = secp256k1_nonce_function_default; - } - - secp256k1_scalar_set_b32(&sec, seckey, NULL); - while (1) { - unsigned char nonce32[32]; - ret = noncefp(nonce32, msg32, seckey, secp256k1_schnorr_algo16, (void*)noncedata, count); - if (!ret) { - break; - } - secp256k1_scalar_set_b32(&non, nonce32, &overflow); - memset(nonce32, 0, 32); - if (!secp256k1_scalar_is_zero(&non) && !overflow) { - if (secp256k1_schnorr_sig_sign(&ctx->ecmult_gen_ctx, sig64, &sec, &non, NULL, secp256k1_schnorr_msghash_sha256, msg32)) { - break; - } - } - count++; - } - if (!ret) { - memset(sig64, 0, 64); - } - secp256k1_scalar_clear(&non); - secp256k1_scalar_clear(&sec); - return ret; -} - -int secp256k1_schnorr_verify(const secp256k1_context* ctx, const unsigned char *sig64, const unsigned char *msg32, const secp256k1_pubkey *pubkey) { - secp256k1_ge q; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(sig64 != NULL); - ARG_CHECK(pubkey != NULL); - - secp256k1_pubkey_load(ctx, &q, pubkey); - return secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64, &q, secp256k1_schnorr_msghash_sha256, msg32); -} - -int secp256k1_schnorr_recover(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *sig64, const unsigned char *msg32) { - secp256k1_ge q; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(sig64 != NULL); - ARG_CHECK(pubkey != NULL); - - if (secp256k1_schnorr_sig_recover(&ctx->ecmult_ctx, sig64, &q, secp256k1_schnorr_msghash_sha256, msg32)) { - secp256k1_pubkey_save(pubkey, &q); - return 1; - } else { - memset(pubkey, 0, sizeof(*pubkey)); - return 0; - } -} - -int secp256k1_schnorr_generate_nonce_pair(const secp256k1_context* ctx, secp256k1_pubkey *pubnonce, unsigned char *privnonce32, const unsigned char *sec32, const unsigned char *msg32, secp256k1_nonce_function noncefp, const void* noncedata) { - int count = 0; - int ret = 1; - secp256k1_gej Qj; - secp256k1_ge Q; - secp256k1_scalar sec; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(sec32 != NULL); - ARG_CHECK(pubnonce != NULL); - ARG_CHECK(privnonce32 != NULL); - - if (noncefp == NULL) { - noncefp = secp256k1_nonce_function_default; - } - - do { - int overflow; - ret = noncefp(privnonce32, sec32, msg32, secp256k1_schnorr_algo16, (void*)noncedata, count++); - if (!ret) { - break; - } - secp256k1_scalar_set_b32(&sec, privnonce32, &overflow); - if (overflow || secp256k1_scalar_is_zero(&sec)) { - continue; - } - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &Qj, &sec); - secp256k1_ge_set_gej(&Q, &Qj); - - secp256k1_pubkey_save(pubnonce, &Q); - break; - } while(1); - - secp256k1_scalar_clear(&sec); - if (!ret) { - memset(pubnonce, 0, sizeof(*pubnonce)); - } - return ret; -} - -int secp256k1_schnorr_partial_sign(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const unsigned char *sec32, const secp256k1_pubkey *pubnonce_others, const unsigned char *secnonce32) { - int overflow = 0; - secp256k1_scalar sec, non; - secp256k1_ge pubnon; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(sig64 != NULL); - ARG_CHECK(sec32 != NULL); - ARG_CHECK(secnonce32 != NULL); - ARG_CHECK(pubnonce_others != NULL); - - secp256k1_scalar_set_b32(&sec, sec32, &overflow); - if (overflow || secp256k1_scalar_is_zero(&sec)) { - return -1; - } - secp256k1_scalar_set_b32(&non, secnonce32, &overflow); - if (overflow || secp256k1_scalar_is_zero(&non)) { - return -1; - } - secp256k1_pubkey_load(ctx, &pubnon, pubnonce_others); - return secp256k1_schnorr_sig_sign(&ctx->ecmult_gen_ctx, sig64, &sec, &non, &pubnon, secp256k1_schnorr_msghash_sha256, msg32); -} - -int secp256k1_schnorr_partial_combine(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char * const *sig64sin, size_t n) { - ARG_CHECK(sig64 != NULL); - ARG_CHECK(n >= 1); - ARG_CHECK(sig64sin != NULL); - return secp256k1_schnorr_sig_combine(sig64, n, sig64sin); -} - -#endif diff --git a/src/secp256k1/src/modules/schnorr/schnorr.h b/src/secp256k1/src/modules/schnorr/schnorr.h deleted file mode 100644 index de18147bd52..00000000000 --- a/src/secp256k1/src/modules/schnorr/schnorr.h +++ /dev/null @@ -1,20 +0,0 @@ -/*********************************************************************** - * Copyright (c) 2014-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php. * - ***********************************************************************/ - -#ifndef _SECP256K1_MODULE_SCHNORR_H_ -#define _SECP256K1_MODULE_SCHNORR_H_ - -#include "scalar.h" -#include "group.h" - -typedef void (*secp256k1_schnorr_msghash)(unsigned char *h32, const unsigned char *r32, const unsigned char *msg32); - -static int secp256k1_schnorr_sig_sign(const secp256k1_ecmult_gen_context* ctx, unsigned char *sig64, const secp256k1_scalar *key, const secp256k1_scalar *nonce, const secp256k1_ge *pubnonce, secp256k1_schnorr_msghash hash, const unsigned char *msg32); -static int secp256k1_schnorr_sig_verify(const secp256k1_ecmult_context* ctx, const unsigned char *sig64, const secp256k1_ge *pubkey, secp256k1_schnorr_msghash hash, const unsigned char *msg32); -static int secp256k1_schnorr_sig_recover(const secp256k1_ecmult_context* ctx, const unsigned char *sig64, secp256k1_ge *pubkey, secp256k1_schnorr_msghash hash, const unsigned char *msg32); -static int secp256k1_schnorr_sig_combine(unsigned char *sig64, size_t n, const unsigned char * const *sig64ins); - -#endif diff --git a/src/secp256k1/src/modules/schnorr/schnorr_impl.h b/src/secp256k1/src/modules/schnorr/schnorr_impl.h deleted file mode 100644 index e13ab6db7cc..00000000000 --- a/src/secp256k1/src/modules/schnorr/schnorr_impl.h +++ /dev/null @@ -1,207 +0,0 @@ -/*********************************************************************** - * Copyright (c) 2014-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php. * - ***********************************************************************/ - -#ifndef _SECP256K1_SCHNORR_IMPL_H_ -#define _SECP256K1_SCHNORR_IMPL_H_ - -#include - -#include "schnorr.h" -#include "num.h" -#include "field.h" -#include "group.h" -#include "ecmult.h" -#include "ecmult_gen.h" - -/** - * Custom Schnorr-based signature scheme. They support multiparty signing, public key - * recovery and batch validation. - * - * Rationale for verifying R's y coordinate: - * In order to support batch validation and public key recovery, the full R point must - * be known to verifiers, rather than just its x coordinate. In order to not risk - * being more strict in batch validation than normal validation, validators must be - * required to reject signatures with incorrect y coordinate. This is only possible - * by including a (relatively slow) field inverse, or a field square root. However, - * batch validation offers potentially much higher benefits than this cost. - * - * Rationale for having an implicit y coordinate oddness: - * If we commit to having the full R point known to verifiers, there are two mechanism. - * Either include its oddness in the signature, or give it an implicit fixed value. - * As the R y coordinate can be flipped by a simple negation of the nonce, we choose the - * latter, as it comes with nearly zero impact on signing or validation performance, and - * saves a byte in the signature. - * - * Signing: - * Inputs: 32-byte message m, 32-byte scalar key x (!=0), 32-byte scalar nonce k (!=0) - * - * Compute point R = k * G. Reject nonce if R's y coordinate is odd (or negate nonce). - * Compute 32-byte r, the serialization of R's x coordinate. - * Compute scalar h = Hash(r || m). Reject nonce if h == 0 or h >= order. - * Compute scalar s = k - h * x. - * The signature is (r, s). - * - * - * Verification: - * Inputs: 32-byte message m, public key point Q, signature: (32-byte r, scalar s) - * - * Signature is invalid if s >= order. - * Signature is invalid if r >= p. - * Compute scalar h = Hash(r || m). Signature is invalid if h == 0 or h >= order. - * Option 1 (faster for single verification): - * Compute point R = h * Q + s * G. Signature is invalid if R is infinity or R's y coordinate is odd. - * Signature is valid if the serialization of R's x coordinate equals r. - * Option 2 (allows batch validation and pubkey recovery): - * Decompress x coordinate r into point R, with odd y coordinate. Fail if R is not on the curve. - * Signature is valid if R + h * Q + s * G == 0. - */ - -static int secp256k1_schnorr_sig_sign(const secp256k1_ecmult_gen_context* ctx, unsigned char *sig64, const secp256k1_scalar *key, const secp256k1_scalar *nonce, const secp256k1_ge *pubnonce, secp256k1_schnorr_msghash hash, const unsigned char *msg32) { - secp256k1_gej Rj; - secp256k1_ge Ra; - unsigned char h32[32]; - secp256k1_scalar h, s; - int overflow; - secp256k1_scalar n; - - if (secp256k1_scalar_is_zero(key) || secp256k1_scalar_is_zero(nonce)) { - return 0; - } - n = *nonce; - - secp256k1_ecmult_gen(ctx, &Rj, &n); - if (pubnonce != NULL) { - secp256k1_gej_add_ge(&Rj, &Rj, pubnonce); - } - secp256k1_ge_set_gej(&Ra, &Rj); - secp256k1_fe_normalize(&Ra.y); - if (secp256k1_fe_is_odd(&Ra.y)) { - /* R's y coordinate is odd, which is not allowed (see rationale above). - Force it to be even by negating the nonce. Note that this even works - for multiparty signing, as the R point is known to all participants, - which can all decide to flip the sign in unison, resulting in the - overall R point to be negated too. */ - secp256k1_scalar_negate(&n, &n); - } - secp256k1_fe_normalize(&Ra.x); - secp256k1_fe_get_b32(sig64, &Ra.x); - hash(h32, sig64, msg32); - overflow = 0; - secp256k1_scalar_set_b32(&h, h32, &overflow); - if (overflow || secp256k1_scalar_is_zero(&h)) { - secp256k1_scalar_clear(&n); - return 0; - } - secp256k1_scalar_mul(&s, &h, key); - secp256k1_scalar_negate(&s, &s); - secp256k1_scalar_add(&s, &s, &n); - secp256k1_scalar_clear(&n); - secp256k1_scalar_get_b32(sig64 + 32, &s); - return 1; -} - -static int secp256k1_schnorr_sig_verify(const secp256k1_ecmult_context* ctx, const unsigned char *sig64, const secp256k1_ge *pubkey, secp256k1_schnorr_msghash hash, const unsigned char *msg32) { - secp256k1_gej Qj, Rj; - secp256k1_ge Ra; - secp256k1_fe Rx; - secp256k1_scalar h, s; - unsigned char hh[32]; - int overflow; - - if (secp256k1_ge_is_infinity(pubkey)) { - return 0; - } - hash(hh, sig64, msg32); - overflow = 0; - secp256k1_scalar_set_b32(&h, hh, &overflow); - if (overflow || secp256k1_scalar_is_zero(&h)) { - return 0; - } - overflow = 0; - secp256k1_scalar_set_b32(&s, sig64 + 32, &overflow); - if (overflow) { - return 0; - } - if (!secp256k1_fe_set_b32(&Rx, sig64)) { - return 0; - } - secp256k1_gej_set_ge(&Qj, pubkey); - secp256k1_ecmult(ctx, &Rj, &Qj, &h, &s); - if (secp256k1_gej_is_infinity(&Rj)) { - return 0; - } - secp256k1_ge_set_gej_var(&Ra, &Rj); - secp256k1_fe_normalize_var(&Ra.y); - if (secp256k1_fe_is_odd(&Ra.y)) { - return 0; - } - return secp256k1_fe_equal_var(&Rx, &Ra.x); -} - -static int secp256k1_schnorr_sig_recover(const secp256k1_ecmult_context* ctx, const unsigned char *sig64, secp256k1_ge *pubkey, secp256k1_schnorr_msghash hash, const unsigned char *msg32) { - secp256k1_gej Qj, Rj; - secp256k1_ge Ra; - secp256k1_fe Rx; - secp256k1_scalar h, s; - unsigned char hh[32]; - int overflow; - - hash(hh, sig64, msg32); - overflow = 0; - secp256k1_scalar_set_b32(&h, hh, &overflow); - if (overflow || secp256k1_scalar_is_zero(&h)) { - return 0; - } - overflow = 0; - secp256k1_scalar_set_b32(&s, sig64 + 32, &overflow); - if (overflow) { - return 0; - } - if (!secp256k1_fe_set_b32(&Rx, sig64)) { - return 0; - } - if (!secp256k1_ge_set_xo_var(&Ra, &Rx, 0)) { - return 0; - } - secp256k1_gej_set_ge(&Rj, &Ra); - secp256k1_scalar_inverse_var(&h, &h); - secp256k1_scalar_negate(&s, &s); - secp256k1_scalar_mul(&s, &s, &h); - secp256k1_ecmult(ctx, &Qj, &Rj, &h, &s); - if (secp256k1_gej_is_infinity(&Qj)) { - return 0; - } - secp256k1_ge_set_gej(pubkey, &Qj); - return 1; -} - -static int secp256k1_schnorr_sig_combine(unsigned char *sig64, size_t n, const unsigned char * const *sig64ins) { - secp256k1_scalar s = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); - size_t i; - for (i = 0; i < n; i++) { - secp256k1_scalar si; - int overflow; - secp256k1_scalar_set_b32(&si, sig64ins[i] + 32, &overflow); - if (overflow) { - return -1; - } - if (i) { - if (memcmp(sig64ins[i - 1], sig64ins[i], 32) != 0) { - return -1; - } - } - secp256k1_scalar_add(&s, &s, &si); - } - if (secp256k1_scalar_is_zero(&s)) { - return 0; - } - memcpy(sig64, sig64ins[0], 32); - secp256k1_scalar_get_b32(sig64 + 32, &s); - secp256k1_scalar_clear(&s); - return 1; -} - -#endif diff --git a/src/secp256k1/src/modules/schnorr/tests_impl.h b/src/secp256k1/src/modules/schnorr/tests_impl.h deleted file mode 100644 index 5bd14a03e3c..00000000000 --- a/src/secp256k1/src/modules/schnorr/tests_impl.h +++ /dev/null @@ -1,175 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_MODULE_SCHNORR_TESTS -#define SECP256K1_MODULE_SCHNORR_TESTS - -#include "include/secp256k1_schnorr.h" - -void test_schnorr_end_to_end(void) { - unsigned char privkey[32]; - unsigned char message[32]; - unsigned char schnorr_signature[64]; - secp256k1_pubkey pubkey, recpubkey; - - /* Generate a random key and message. */ - { - secp256k1_scalar key; - random_scalar_order_test(&key); - secp256k1_scalar_get_b32(privkey, &key); - secp256k1_rand256_test(message); - } - - /* Construct and verify corresponding public key. */ - CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1); - - /* Schnorr sign. */ - CHECK(secp256k1_schnorr_sign(ctx, schnorr_signature, message, privkey, NULL, NULL) == 1); - CHECK(secp256k1_schnorr_verify(ctx, schnorr_signature, message, &pubkey) == 1); - CHECK(secp256k1_schnorr_recover(ctx, &recpubkey, schnorr_signature, message) == 1); - CHECK(memcmp(&pubkey, &recpubkey, sizeof(pubkey)) == 0); - /* Destroy signature and verify again. */ - schnorr_signature[secp256k1_rand_bits(6)] += 1 + secp256k1_rand_int(255); - CHECK(secp256k1_schnorr_verify(ctx, schnorr_signature, message, &pubkey) == 0); - CHECK(secp256k1_schnorr_recover(ctx, &recpubkey, schnorr_signature, message) != 1 || - memcmp(&pubkey, &recpubkey, sizeof(pubkey)) != 0); -} - -/** Horribly broken hash function. Do not use for anything but tests. */ -void test_schnorr_hash(unsigned char *h32, const unsigned char *r32, const unsigned char *msg32) { - int i; - for (i = 0; i < 32; i++) { - h32[i] = r32[i] ^ msg32[i]; - } -} - -void test_schnorr_sign_verify(void) { - unsigned char msg32[32]; - unsigned char sig64[3][64]; - secp256k1_gej pubkeyj[3]; - secp256k1_ge pubkey[3]; - secp256k1_scalar nonce[3], key[3]; - int i = 0; - int k; - - secp256k1_rand256_test(msg32); - - for (k = 0; k < 3; k++) { - random_scalar_order_test(&key[k]); - - do { - random_scalar_order_test(&nonce[k]); - if (secp256k1_schnorr_sig_sign(&ctx->ecmult_gen_ctx, sig64[k], &key[k], &nonce[k], NULL, &test_schnorr_hash, msg32)) { - break; - } - } while(1); - - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pubkeyj[k], &key[k]); - secp256k1_ge_set_gej_var(&pubkey[k], &pubkeyj[k]); - CHECK(secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64[k], &pubkey[k], &test_schnorr_hash, msg32)); - - for (i = 0; i < 4; i++) { - int pos = secp256k1_rand_bits(6); - int mod = 1 + secp256k1_rand_int(255); - sig64[k][pos] ^= mod; - CHECK(secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64[k], &pubkey[k], &test_schnorr_hash, msg32) == 0); - sig64[k][pos] ^= mod; - } - } -} - -void test_schnorr_threshold(void) { - unsigned char msg[32]; - unsigned char sec[5][32]; - secp256k1_pubkey pub[5]; - unsigned char nonce[5][32]; - secp256k1_pubkey pubnonce[5]; - unsigned char sig[5][64]; - const unsigned char* sigs[5]; - unsigned char allsig[64]; - const secp256k1_pubkey* pubs[5]; - secp256k1_pubkey allpub; - int n, i; - int damage; - int ret = 0; - - damage = secp256k1_rand_bits(1) ? (1 + secp256k1_rand_int(4)) : 0; - secp256k1_rand256_test(msg); - n = 2 + secp256k1_rand_int(4); - for (i = 0; i < n; i++) { - do { - secp256k1_rand256_test(sec[i]); - } while (!secp256k1_ec_seckey_verify(ctx, sec[i])); - CHECK(secp256k1_ec_pubkey_create(ctx, &pub[i], sec[i])); - CHECK(secp256k1_schnorr_generate_nonce_pair(ctx, &pubnonce[i], nonce[i], msg, sec[i], NULL, NULL)); - pubs[i] = &pub[i]; - } - if (damage == 1) { - nonce[secp256k1_rand_int(n)][secp256k1_rand_int(32)] ^= 1 + secp256k1_rand_int(255); - } else if (damage == 2) { - sec[secp256k1_rand_int(n)][secp256k1_rand_int(32)] ^= 1 + secp256k1_rand_int(255); - } - for (i = 0; i < n; i++) { - secp256k1_pubkey allpubnonce; - const secp256k1_pubkey *pubnonces[4]; - int j; - for (j = 0; j < i; j++) { - pubnonces[j] = &pubnonce[j]; - } - for (j = i + 1; j < n; j++) { - pubnonces[j - 1] = &pubnonce[j]; - } - CHECK(secp256k1_ec_pubkey_combine(ctx, &allpubnonce, pubnonces, n - 1)); - ret |= (secp256k1_schnorr_partial_sign(ctx, sig[i], msg, sec[i], &allpubnonce, nonce[i]) != 1) * 1; - sigs[i] = sig[i]; - } - if (damage == 3) { - sig[secp256k1_rand_int(n)][secp256k1_rand_bits(6)] ^= 1 + secp256k1_rand_int(255); - } - ret |= (secp256k1_ec_pubkey_combine(ctx, &allpub, pubs, n) != 1) * 2; - if ((ret & 1) == 0) { - ret |= (secp256k1_schnorr_partial_combine(ctx, allsig, sigs, n) != 1) * 4; - } - if (damage == 4) { - allsig[secp256k1_rand_int(32)] ^= 1 + secp256k1_rand_int(255); - } - if ((ret & 7) == 0) { - ret |= (secp256k1_schnorr_verify(ctx, allsig, msg, &allpub) != 1) * 8; - } - CHECK((ret == 0) == (damage == 0)); -} - -void test_schnorr_recovery(void) { - unsigned char msg32[32]; - unsigned char sig64[64]; - secp256k1_ge Q; - - secp256k1_rand256_test(msg32); - secp256k1_rand256_test(sig64); - secp256k1_rand256_test(sig64 + 32); - if (secp256k1_schnorr_sig_recover(&ctx->ecmult_ctx, sig64, &Q, &test_schnorr_hash, msg32) == 1) { - CHECK(secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64, &Q, &test_schnorr_hash, msg32) == 1); - } -} - -void run_schnorr_tests(void) { - int i; - for (i = 0; i < 32*count; i++) { - test_schnorr_end_to_end(); - } - for (i = 0; i < 32 * count; i++) { - test_schnorr_sign_verify(); - } - for (i = 0; i < 16 * count; i++) { - test_schnorr_recovery(); - } - for (i = 0; i < 10 * count; i++) { - test_schnorr_threshold(); - } -} - -#endif diff --git a/src/secp256k1/src/num.h b/src/secp256k1/src/num.h index ebfa71eb44b..7bb9c5be8cf 100644 --- a/src/secp256k1/src/num.h +++ b/src/secp256k1/src/num.h @@ -32,6 +32,9 @@ static void secp256k1_num_set_bin(secp256k1_num *r, const unsigned char *a, unsi /** Compute a modular inverse. The input must be less than the modulus. */ static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *m); +/** Compute the jacobi symbol (a|b). b must be positive and odd. */ +static int secp256k1_num_jacobi(const secp256k1_num *a, const secp256k1_num *b); + /** Compare the absolute value of two numbers. */ static int secp256k1_num_cmp(const secp256k1_num *a, const secp256k1_num *b); @@ -57,6 +60,9 @@ static void secp256k1_num_shift(secp256k1_num *r, int bits); /** Check whether a number is zero. */ static int secp256k1_num_is_zero(const secp256k1_num *a); +/** Check whether a number is one. */ +static int secp256k1_num_is_one(const secp256k1_num *a); + /** Check whether a number is strictly negative. */ static int secp256k1_num_is_neg(const secp256k1_num *a); diff --git a/src/secp256k1/src/num_gmp_impl.h b/src/secp256k1/src/num_gmp_impl.h index 7b6a89719ab..3a46495eeac 100644 --- a/src/secp256k1/src/num_gmp_impl.h +++ b/src/secp256k1/src/num_gmp_impl.h @@ -144,6 +144,32 @@ static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, memset(v, 0, sizeof(v)); } +static int secp256k1_num_jacobi(const secp256k1_num *a, const secp256k1_num *b) { + int ret; + mpz_t ga, gb; + secp256k1_num_sanity(a); + secp256k1_num_sanity(b); + VERIFY_CHECK(!b->neg && (b->limbs > 0) && (b->data[0] & 1)); + + mpz_inits(ga, gb, NULL); + + mpz_import(gb, b->limbs, -1, sizeof(mp_limb_t), 0, 0, b->data); + mpz_import(ga, a->limbs, -1, sizeof(mp_limb_t), 0, 0, a->data); + if (a->neg) { + mpz_neg(ga, ga); + } + + ret = mpz_jacobi(ga, gb); + + mpz_clears(ga, gb, NULL); + + return ret; +} + +static int secp256k1_num_is_one(const secp256k1_num *a) { + return (a->limbs == 1 && a->data[0] == 1); +} + static int secp256k1_num_is_zero(const secp256k1_num *a) { return (a->limbs == 1 && a->data[0] == 0); } diff --git a/src/secp256k1/src/scalar.h b/src/secp256k1/src/scalar.h index b590ccd6dde..27e9d8375e8 100644 --- a/src/secp256k1/src/scalar.h +++ b/src/secp256k1/src/scalar.h @@ -13,7 +13,9 @@ #include "libsecp256k1-config.h" #endif -#if defined(USE_SCALAR_4X64) +#if defined(EXHAUSTIVE_TEST_ORDER) +#include "scalar_low.h" +#elif defined(USE_SCALAR_4X64) #include "scalar_4x64.h" #elif defined(USE_SCALAR_8X32) #include "scalar_8x32.h" diff --git a/src/secp256k1/src/scalar_4x64_impl.h b/src/secp256k1/src/scalar_4x64_impl.h index aa2703dd23e..56e7bd82afd 100644 --- a/src/secp256k1/src/scalar_4x64_impl.h +++ b/src/secp256k1/src/scalar_4x64_impl.h @@ -282,8 +282,8 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "movq 56(%%rsi), %%r14\n" /* Initialize r8,r9,r10 */ "movq 0(%%rsi), %%r8\n" - "movq $0, %%r9\n" - "movq $0, %%r10\n" + "xorq %%r9, %%r9\n" + "xorq %%r10, %%r10\n" /* (r8,r9) += n0 * c0 */ "movq %8, %%rax\n" "mulq %%r11\n" @@ -291,7 +291,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "adcq %%rdx, %%r9\n" /* extract m0 */ "movq %%r8, %q0\n" - "movq $0, %%r8\n" + "xorq %%r8, %%r8\n" /* (r9,r10) += l1 */ "addq 8(%%rsi), %%r9\n" "adcq $0, %%r10\n" @@ -309,7 +309,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "adcq $0, %%r8\n" /* extract m1 */ "movq %%r9, %q1\n" - "movq $0, %%r9\n" + "xorq %%r9, %%r9\n" /* (r10,r8,r9) += l2 */ "addq 16(%%rsi), %%r10\n" "adcq $0, %%r8\n" @@ -332,7 +332,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "adcq $0, %%r9\n" /* extract m2 */ "movq %%r10, %q2\n" - "movq $0, %%r10\n" + "xorq %%r10, %%r10\n" /* (r8,r9,r10) += l3 */ "addq 24(%%rsi), %%r8\n" "adcq $0, %%r9\n" @@ -355,7 +355,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "adcq $0, %%r10\n" /* extract m3 */ "movq %%r8, %q3\n" - "movq $0, %%r8\n" + "xorq %%r8, %%r8\n" /* (r9,r10,r8) += n3 * c1 */ "movq %9, %%rax\n" "mulq %%r14\n" @@ -387,8 +387,8 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "movq %q11, %%r13\n" /* Initialize (r8,r9,r10) */ "movq %q5, %%r8\n" - "movq $0, %%r9\n" - "movq $0, %%r10\n" + "xorq %%r9, %%r9\n" + "xorq %%r10, %%r10\n" /* (r8,r9) += m4 * c0 */ "movq %12, %%rax\n" "mulq %%r11\n" @@ -396,7 +396,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "adcq %%rdx, %%r9\n" /* extract p0 */ "movq %%r8, %q0\n" - "movq $0, %%r8\n" + "xorq %%r8, %%r8\n" /* (r9,r10) += m1 */ "addq %q6, %%r9\n" "adcq $0, %%r10\n" @@ -414,7 +414,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "adcq $0, %%r8\n" /* extract p1 */ "movq %%r9, %q1\n" - "movq $0, %%r9\n" + "xorq %%r9, %%r9\n" /* (r10,r8,r9) += m2 */ "addq %q7, %%r10\n" "adcq $0, %%r8\n" @@ -472,7 +472,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "movq %%rax, 0(%q6)\n" /* Move to (r8,r9) */ "movq %%rdx, %%r8\n" - "movq $0, %%r9\n" + "xorq %%r9, %%r9\n" /* (r8,r9) += p1 */ "addq %q2, %%r8\n" "adcq $0, %%r9\n" @@ -483,7 +483,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "adcq %%rdx, %%r9\n" /* Extract r1 */ "movq %%r8, 8(%q6)\n" - "movq $0, %%r8\n" + "xorq %%r8, %%r8\n" /* (r9,r8) += p4 */ "addq %%r10, %%r9\n" "adcq $0, %%r8\n" @@ -492,7 +492,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) "adcq $0, %%r8\n" /* Extract r2 */ "movq %%r9, 16(%q6)\n" - "movq $0, %%r9\n" + "xorq %%r9, %%r9\n" /* (r8,r9) += p3 */ "addq %q4, %%r8\n" "adcq $0, %%r9\n" diff --git a/src/secp256k1/src/scalar_impl.h b/src/secp256k1/src/scalar_impl.h index 88ea97de863..f5b2376407b 100644 --- a/src/secp256k1/src/scalar_impl.h +++ b/src/secp256k1/src/scalar_impl.h @@ -7,8 +7,6 @@ #ifndef _SECP256K1_SCALAR_IMPL_H_ #define _SECP256K1_SCALAR_IMPL_H_ -#include - #include "group.h" #include "scalar.h" @@ -16,7 +14,9 @@ #include "libsecp256k1-config.h" #endif -#if defined(USE_SCALAR_4X64) +#if defined(EXHAUSTIVE_TEST_ORDER) +#include "scalar_low_impl.h" +#elif defined(USE_SCALAR_4X64) #include "scalar_4x64_impl.h" #elif defined(USE_SCALAR_8X32) #include "scalar_8x32_impl.h" @@ -33,17 +33,37 @@ static void secp256k1_scalar_get_num(secp256k1_num *r, const secp256k1_scalar *a /** secp256k1 curve order, see secp256k1_ecdsa_const_order_as_fe in ecdsa_impl.h */ static void secp256k1_scalar_order_get_num(secp256k1_num *r) { +#if defined(EXHAUSTIVE_TEST_ORDER) + static const unsigned char order[32] = { + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,EXHAUSTIVE_TEST_ORDER + }; +#else static const unsigned char order[32] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41 }; +#endif secp256k1_num_set_bin(r, order, 32); } #endif static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *x) { +#if defined(EXHAUSTIVE_TEST_ORDER) + int i; + *r = 0; + for (i = 0; i < EXHAUSTIVE_TEST_ORDER; i++) + if ((i * *x) % EXHAUSTIVE_TEST_ORDER == 1) + *r = i; + /* If this VERIFY_CHECK triggers we were given a noninvertible scalar (and thus + * have a composite group order; fix it in exhaustive_tests.c). */ + VERIFY_CHECK(*r != 0); +} +#else secp256k1_scalar *t; int i; /* First compute x ^ (2^N - 1) for some values of N. */ @@ -235,9 +255,9 @@ static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar } SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) { - /* d[0] is present and is the lowest word for all representations */ return !(a->d[0] & 1); } +#endif static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *x) { #if defined(USE_SCALAR_INV_BUILTIN) @@ -261,6 +281,18 @@ static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_sc } #ifdef USE_ENDOMORPHISM +#if defined(EXHAUSTIVE_TEST_ORDER) +/** + * Find k1 and k2 given k, such that k1 + k2 * lambda == k mod n; unlike in the + * full case we don't bother making k1 and k2 be small, we just want them to be + * nontrivial to get full test coverage for the exhaustive tests. We therefore + * (arbitrarily) set k2 = k + 5 and k1 = k - k2 * lambda. + */ +static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { + *r2 = (*a + 5) % EXHAUSTIVE_TEST_ORDER; + *r1 = (*a + (EXHAUSTIVE_TEST_ORDER - *r2) * EXHAUSTIVE_TEST_LAMBDA) % EXHAUSTIVE_TEST_ORDER; +} +#else /** * The Secp256k1 curve has an endomorphism, where lambda * (x, y) = (beta * x, y), where * lambda is {0x53,0x63,0xad,0x4c,0xc0,0x5c,0x30,0xe0,0xa5,0x26,0x1c,0x02,0x88,0x12,0x64,0x5a, @@ -333,5 +365,6 @@ static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar secp256k1_scalar_add(r1, r1, a); } #endif +#endif #endif diff --git a/src/secp256k1/src/scalar_low.h b/src/secp256k1/src/scalar_low.h new file mode 100644 index 00000000000..5574c44c7ae --- /dev/null +++ b/src/secp256k1/src/scalar_low.h @@ -0,0 +1,15 @@ +/********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_SCALAR_REPR_ +#define _SECP256K1_SCALAR_REPR_ + +#include + +/** A scalar modulo the group order of the secp256k1 curve. */ +typedef uint32_t secp256k1_scalar; + +#endif diff --git a/src/secp256k1/src/scalar_low_impl.h b/src/secp256k1/src/scalar_low_impl.h new file mode 100644 index 00000000000..4f94441f492 --- /dev/null +++ b/src/secp256k1/src/scalar_low_impl.h @@ -0,0 +1,114 @@ +/********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_SCALAR_REPR_IMPL_H_ +#define _SECP256K1_SCALAR_REPR_IMPL_H_ + +#include "scalar.h" + +#include + +SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) { + return !(*a & 1); +} + +SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { *r = 0; } +SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { *r = v; } + +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { + if (offset < 32) + return ((*a >> offset) & ((((uint32_t)1) << count) - 1)); + else + return 0; +} + +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { + return secp256k1_scalar_get_bits(a, offset, count); +} + +SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { return *a >= EXHAUSTIVE_TEST_ORDER; } + +static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { + *r = (*a + *b) % EXHAUSTIVE_TEST_ORDER; + return *r < *b; +} + +static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) { + if (flag && bit < 32) + *r += (1 << bit); +#ifdef VERIFY + VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0); +#endif +} + +static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) { + const int base = 0x100 % EXHAUSTIVE_TEST_ORDER; + int i; + *r = 0; + for (i = 0; i < 32; i++) { + *r = ((*r * base) + b32[i]) % EXHAUSTIVE_TEST_ORDER; + } + /* just deny overflow, it basically always happens */ + if (overflow) *overflow = 0; +} + +static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) { + memset(bin, 0, 32); + bin[28] = *a >> 24; bin[29] = *a >> 16; bin[30] = *a >> 8; bin[31] = *a; +} + +SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) { + return *a == 0; +} + +static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) { + if (*a == 0) { + *r = 0; + } else { + *r = EXHAUSTIVE_TEST_ORDER - *a; + } +} + +SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) { + return *a == 1; +} + +static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { + return *a > EXHAUSTIVE_TEST_ORDER / 2; +} + +static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { + if (flag) secp256k1_scalar_negate(r, r); + return flag ? -1 : 1; +} + +static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { + *r = (*a * *b) % EXHAUSTIVE_TEST_ORDER; +} + +static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) { + int ret; + VERIFY_CHECK(n > 0); + VERIFY_CHECK(n < 16); + ret = *r & ((1 << n) - 1); + *r >>= n; + return ret; +} + +static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a) { + *r = (*a * *a) % EXHAUSTIVE_TEST_ORDER; +} + +static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { + *r1 = *a; + *r2 = 0; +} + +SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) { + return *a == *b; +} + +#endif diff --git a/src/secp256k1/src/secp256k1.c b/src/secp256k1/src/secp256k1.c old mode 100644 new mode 100755 index 62d192baeb3..fb8b882faaf --- a/src/secp256k1/src/secp256k1.c +++ b/src/secp256k1/src/secp256k1.c @@ -4,8 +4,6 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#define SECP256K1_BUILD (1) - #include "include/secp256k1.h" #include "util.h" @@ -152,7 +150,6 @@ static void secp256k1_pubkey_save(secp256k1_pubkey* pubkey, secp256k1_ge* ge) { int secp256k1_ec_pubkey_parse(const secp256k1_context* ctx, secp256k1_pubkey* pubkey, const unsigned char *input, size_t inputlen) { secp256k1_ge Q; - (void)ctx; VERIFY_CHECK(ctx != NULL); ARG_CHECK(pubkey != NULL); memset(pubkey, 0, sizeof(*pubkey)); @@ -170,7 +167,6 @@ int secp256k1_ec_pubkey_serialize(const secp256k1_context* ctx, unsigned char *o size_t len; int ret = 0; - (void)ctx; VERIFY_CHECK(ctx != NULL); ARG_CHECK(outputlen != NULL); ARG_CHECK(*outputlen >= ((flags & SECP256K1_FLAGS_BIT_COMPRESSION) ? 33 : 65)); @@ -216,7 +212,7 @@ static void secp256k1_ecdsa_signature_save(secp256k1_ecdsa_signature* sig, const int secp256k1_ecdsa_signature_parse_der(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) { secp256k1_scalar r, s; - (void)ctx; + VERIFY_CHECK(ctx != NULL); ARG_CHECK(sig != NULL); ARG_CHECK(input != NULL); @@ -234,7 +230,7 @@ int secp256k1_ecdsa_signature_parse_compact(const secp256k1_context* ctx, secp25 int ret = 1; int overflow = 0; - (void)ctx; + VERIFY_CHECK(ctx != NULL); ARG_CHECK(sig != NULL); ARG_CHECK(input64 != NULL); @@ -253,7 +249,7 @@ int secp256k1_ecdsa_signature_parse_compact(const secp256k1_context* ctx, secp25 int secp256k1_ecdsa_signature_serialize_der(const secp256k1_context* ctx, unsigned char *output, size_t *outputlen, const secp256k1_ecdsa_signature* sig) { secp256k1_scalar r, s; - (void)ctx; + VERIFY_CHECK(ctx != NULL); ARG_CHECK(output != NULL); ARG_CHECK(outputlen != NULL); ARG_CHECK(sig != NULL); @@ -265,7 +261,7 @@ int secp256k1_ecdsa_signature_serialize_der(const secp256k1_context* ctx, unsign int secp256k1_ecdsa_signature_serialize_compact(const secp256k1_context* ctx, unsigned char *output64, const secp256k1_ecdsa_signature* sig) { secp256k1_scalar r, s; - (void)ctx; + VERIFY_CHECK(ctx != NULL); ARG_CHECK(output64 != NULL); ARG_CHECK(sig != NULL); @@ -363,16 +359,15 @@ int secp256k1_ecdsa_sign(const secp256k1_context* ctx, secp256k1_ecdsa_signature secp256k1_scalar_set_b32(&sec, seckey, &overflow); /* Fail if the secret key is invalid. */ if (!overflow && !secp256k1_scalar_is_zero(&sec)) { + unsigned char nonce32[32]; unsigned int count = 0; secp256k1_scalar_set_b32(&msg, msg32, NULL); while (1) { - unsigned char nonce32[32]; ret = noncefp(nonce32, msg32, seckey, NULL, (void*)noncedata, count); if (!ret) { break; } secp256k1_scalar_set_b32(&non, nonce32, &overflow); - memset(nonce32, 0, 32); if (!overflow && !secp256k1_scalar_is_zero(&non)) { if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, NULL)) { break; @@ -380,6 +375,7 @@ int secp256k1_ecdsa_sign(const secp256k1_context* ctx, secp256k1_ecdsa_signature } count++; } + memset(nonce32, 0, 32); secp256k1_scalar_clear(&msg); secp256k1_scalar_clear(&non); secp256k1_scalar_clear(&sec); @@ -398,7 +394,6 @@ int secp256k1_ec_seckey_verify(const secp256k1_context* ctx, const unsigned char int overflow; VERIFY_CHECK(ctx != NULL); ARG_CHECK(seckey != NULL); - (void)ctx; secp256k1_scalar_set_b32(&sec, seckey, &overflow); ret = !overflow && !secp256k1_scalar_is_zero(&sec); @@ -437,7 +432,6 @@ int secp256k1_ec_privkey_tweak_add(const secp256k1_context* ctx, unsigned char * VERIFY_CHECK(ctx != NULL); ARG_CHECK(seckey != NULL); ARG_CHECK(tweak != NULL); - (void)ctx; secp256k1_scalar_set_b32(&term, tweak, &overflow); secp256k1_scalar_set_b32(&sec, seckey, NULL); @@ -485,7 +479,6 @@ int secp256k1_ec_privkey_tweak_mul(const secp256k1_context* ctx, unsigned char * VERIFY_CHECK(ctx != NULL); ARG_CHECK(seckey != NULL); ARG_CHECK(tweak != NULL); - (void)ctx; secp256k1_scalar_set_b32(&factor, tweak, &overflow); secp256k1_scalar_set_b32(&sec, seckey, NULL); diff --git a/src/secp256k1/src/tests.c b/src/secp256k1/src/tests.c index 687a5f2fdd8..9ae7d302813 100644 --- a/src/secp256k1/src/tests.c +++ b/src/secp256k1/src/tests.c @@ -473,6 +473,8 @@ void test_num_negate(void) { } void test_num_add_sub(void) { + int i; + secp256k1_scalar s; secp256k1_num n1; secp256k1_num n2; secp256k1_num n1p2, n2p1, n1m2, n2m1; @@ -498,6 +500,110 @@ void test_num_add_sub(void) { CHECK(!secp256k1_num_eq(&n2p1, &n1)); secp256k1_num_sub(&n2p1, &n2p1, &n2); /* n2p1 = R2 + R1 - R2 = R1 */ CHECK(secp256k1_num_eq(&n2p1, &n1)); + + /* check is_one */ + secp256k1_scalar_set_int(&s, 1); + secp256k1_scalar_get_num(&n1, &s); + CHECK(secp256k1_num_is_one(&n1)); + /* check that 2^n + 1 is never 1 */ + secp256k1_scalar_get_num(&n2, &s); + for (i = 0; i < 250; ++i) { + secp256k1_num_add(&n1, &n1, &n1); /* n1 *= 2 */ + secp256k1_num_add(&n1p2, &n1, &n2); /* n1p2 = n1 + 1 */ + CHECK(!secp256k1_num_is_one(&n1p2)); + } +} + +void test_num_mod(void) { + int i; + secp256k1_scalar s; + secp256k1_num order, n; + + /* check that 0 mod anything is 0 */ + random_scalar_order_test(&s); + secp256k1_scalar_get_num(&order, &s); + secp256k1_scalar_set_int(&s, 0); + secp256k1_scalar_get_num(&n, &s); + secp256k1_num_mod(&n, &order); + CHECK(secp256k1_num_is_zero(&n)); + + /* check that anything mod 1 is 0 */ + secp256k1_scalar_set_int(&s, 1); + secp256k1_scalar_get_num(&order, &s); + secp256k1_scalar_get_num(&n, &s); + secp256k1_num_mod(&n, &order); + CHECK(secp256k1_num_is_zero(&n)); + + /* check that increasing the number past 2^256 does not break this */ + random_scalar_order_test(&s); + secp256k1_scalar_get_num(&n, &s); + /* multiply by 2^8, which'll test this case with high probability */ + for (i = 0; i < 8; ++i) { + secp256k1_num_add(&n, &n, &n); + } + secp256k1_num_mod(&n, &order); + CHECK(secp256k1_num_is_zero(&n)); +} + +void test_num_jacobi(void) { + secp256k1_scalar sqr; + secp256k1_scalar small; + secp256k1_scalar five; /* five is not a quadratic residue */ + secp256k1_num order, n; + int i; + /* squares mod 5 are 1, 4 */ + const int jacobi5[10] = { 0, 1, -1, -1, 1, 0, 1, -1, -1, 1 }; + + /* check some small values with 5 as the order */ + secp256k1_scalar_set_int(&five, 5); + secp256k1_scalar_get_num(&order, &five); + for (i = 0; i < 10; ++i) { + secp256k1_scalar_set_int(&small, i); + secp256k1_scalar_get_num(&n, &small); + CHECK(secp256k1_num_jacobi(&n, &order) == jacobi5[i]); + } + + /** test large values with 5 as group order */ + secp256k1_scalar_get_num(&order, &five); + /* we first need a scalar which is not a multiple of 5 */ + do { + secp256k1_num fiven; + random_scalar_order_test(&sqr); + secp256k1_scalar_get_num(&fiven, &five); + secp256k1_scalar_get_num(&n, &sqr); + secp256k1_num_mod(&n, &fiven); + } while (secp256k1_num_is_zero(&n)); + /* next force it to be a residue. 2 is a nonresidue mod 5 so we can + * just multiply by two, i.e. add the number to itself */ + if (secp256k1_num_jacobi(&n, &order) == -1) { + secp256k1_num_add(&n, &n, &n); + } + + /* test residue */ + CHECK(secp256k1_num_jacobi(&n, &order) == 1); + /* test nonresidue */ + secp256k1_num_add(&n, &n, &n); + CHECK(secp256k1_num_jacobi(&n, &order) == -1); + + /** test with secp group order as order */ + secp256k1_scalar_order_get_num(&order); + random_scalar_order_test(&sqr); + secp256k1_scalar_sqr(&sqr, &sqr); + /* test residue */ + secp256k1_scalar_get_num(&n, &sqr); + CHECK(secp256k1_num_jacobi(&n, &order) == 1); + /* test nonresidue */ + secp256k1_scalar_mul(&sqr, &sqr, &five); + secp256k1_scalar_get_num(&n, &sqr); + CHECK(secp256k1_num_jacobi(&n, &order) == -1); + /* test multiple of the order*/ + CHECK(secp256k1_num_jacobi(&order, &order) == 0); + + /* check one less than the order */ + secp256k1_scalar_set_int(&small, 1); + secp256k1_scalar_get_num(&n, &small); + secp256k1_num_sub(&n, &order, &n); + CHECK(secp256k1_num_jacobi(&n, &order) == 1); /* sage confirms this is 1 */ } void run_num_smalltests(void) { @@ -505,6 +611,8 @@ void run_num_smalltests(void) { for (i = 0; i < 100*count; i++) { test_num_negate(); test_num_add_sub(); + test_num_mod(); + test_num_jacobi(); } } #endif @@ -689,6 +797,10 @@ void scalar_test(void) { secp256k1_scalar_inverse(&inv, &inv); /* Inverting one must result in one. */ CHECK(secp256k1_scalar_is_one(&inv)); +#ifndef USE_NUM_NONE + secp256k1_scalar_get_num(&invnum, &inv); + CHECK(secp256k1_num_is_one(&invnum)); +#endif } } @@ -855,7 +967,7 @@ void run_scalar_tests(void) { secp256k1_scalar zzv; #endif int overflow; - unsigned char chal[32][2][32] = { + unsigned char chal[33][2][32] = { {{0xff, 0xff, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, @@ -1111,9 +1223,17 @@ void run_scalar_tests(void) { {0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xc7, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff}} + 0xff, 0xc7, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff}}, + {{0x82, 0xc9, 0xfa, 0xb0, 0x68, 0x04, 0xa0, 0x00, + 0x82, 0xc9, 0xfa, 0xb0, 0x68, 0x04, 0xa0, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0x03, 0xfb, + 0xfa, 0x8a, 0x7d, 0xdf, 0x13, 0x86, 0xe2, 0x03}, + {0x82, 0xc9, 0xfa, 0xb0, 0x68, 0x04, 0xa0, 0x00, + 0x82, 0xc9, 0xfa, 0xb0, 0x68, 0x04, 0xa0, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0x03, 0xfb, + 0xfa, 0x8a, 0x7d, 0xdf, 0x13, 0x86, 0xe2, 0x03}} }; - unsigned char res[32][2][32] = { + unsigned char res[33][2][32] = { {{0x0c, 0x3b, 0x0a, 0xca, 0x8d, 0x1a, 0x2f, 0xb9, 0x8a, 0x7b, 0x53, 0x5a, 0x1f, 0xc5, 0x22, 0xa1, 0x07, 0x2a, 0x48, 0xea, 0x02, 0xeb, 0xb3, 0xd6, @@ -1369,10 +1489,18 @@ void run_scalar_tests(void) { {0xe4, 0xf1, 0x23, 0x84, 0xe1, 0xb5, 0x9d, 0xf2, 0xb8, 0x73, 0x8b, 0x45, 0x2b, 0x35, 0x46, 0x38, 0x10, 0x2b, 0x50, 0xf8, 0x8b, 0x35, 0xcd, 0x34, - 0xc8, 0x0e, 0xf6, 0xdb, 0x09, 0x35, 0xf0, 0xda}} + 0xc8, 0x0e, 0xf6, 0xdb, 0x09, 0x35, 0xf0, 0xda}}, + {{0xdb, 0x21, 0x5c, 0x8d, 0x83, 0x1d, 0xb3, 0x34, + 0xc7, 0x0e, 0x43, 0xa1, 0x58, 0x79, 0x67, 0x13, + 0x1e, 0x86, 0x5d, 0x89, 0x63, 0xe6, 0x0a, 0x46, + 0x5c, 0x02, 0x97, 0x1b, 0x62, 0x43, 0x86, 0xf5}, + {0xdb, 0x21, 0x5c, 0x8d, 0x83, 0x1d, 0xb3, 0x34, + 0xc7, 0x0e, 0x43, 0xa1, 0x58, 0x79, 0x67, 0x13, + 0x1e, 0x86, 0x5d, 0x89, 0x63, 0xe6, 0x0a, 0x46, + 0x5c, 0x02, 0x97, 0x1b, 0x62, 0x43, 0x86, 0xf5}} }; secp256k1_scalar_set_int(&one, 1); - for (i = 0; i < 32; i++) { + for (i = 0; i < 33; i++) { secp256k1_scalar_set_b32(&x, chal[i][0], &overflow); CHECK(!overflow); secp256k1_scalar_set_b32(&y, chal[i][1], &overflow); @@ -1446,7 +1574,7 @@ void random_fe_non_zero(secp256k1_fe *nz) { void random_fe_non_square(secp256k1_fe *ns) { secp256k1_fe r; random_fe_non_zero(ns); - if (secp256k1_fe_sqrt_var(&r, ns)) { + if (secp256k1_fe_sqrt(&r, ns)) { secp256k1_fe_negate(ns, ns, 1); } } @@ -1605,18 +1733,18 @@ void run_field_inv_all_var(void) { secp256k1_fe x[16], xi[16], xii[16]; int i; /* Check it's safe to call for 0 elements */ - secp256k1_fe_inv_all_var(0, xi, x); + secp256k1_fe_inv_all_var(xi, x, 0); for (i = 0; i < count; i++) { size_t j; size_t len = secp256k1_rand_int(15) + 1; for (j = 0; j < len; j++) { random_fe_non_zero(&x[j]); } - secp256k1_fe_inv_all_var(len, xi, x); + secp256k1_fe_inv_all_var(xi, x, len); for (j = 0; j < len; j++) { CHECK(check_fe_inverse(&x[j], &xi[j])); } - secp256k1_fe_inv_all_var(len, xii, xi); + secp256k1_fe_inv_all_var(xii, xi, len); for (j = 0; j < len; j++) { CHECK(check_fe_equal(&x[j], &xii[j])); } @@ -1641,7 +1769,7 @@ void run_sqr(void) { void test_sqrt(const secp256k1_fe *a, const secp256k1_fe *k) { secp256k1_fe r1, r2; - int v = secp256k1_fe_sqrt_var(&r1, a); + int v = secp256k1_fe_sqrt(&r1, a); CHECK((v == 0) == (k == NULL)); if (k != NULL) { @@ -1802,7 +1930,7 @@ void test_ge(void) { zs[i] = gej[i].z; } } - secp256k1_fe_inv_all_var(4 * runs + 1, zinv, zs); + secp256k1_fe_inv_all_var(zinv, zs, 4 * runs + 1); free(zs); } @@ -1922,8 +2050,8 @@ void test_ge(void) { secp256k1_fe_mul(&zr[i + 1], &zinv[i], &gej[i + 1].z); } } - secp256k1_ge_set_table_gej_var(4 * runs + 1, ge_set_table, gej, zr); - secp256k1_ge_set_all_gej_var(4 * runs + 1, ge_set_all, gej, &ctx->error_callback); + secp256k1_ge_set_table_gej_var(ge_set_table, gej, zr, 4 * runs + 1); + secp256k1_ge_set_all_gej_var(ge_set_all, gej, 4 * runs + 1, &ctx->error_callback); for (i = 0; i < 4 * runs + 1; i++) { secp256k1_fe s; random_fe_non_zero(&s); @@ -1951,8 +2079,8 @@ void test_add_neg_y_diff_x(void) { * of the sum to be wrong (since infinity has no xy coordinates). * HOWEVER, if the x-coordinates are different, infinity is the * wrong answer, and such degeneracies are exposed. This is the - * root of https://github.com/bitcoin/secp256k1/issues/257 which - * this test is a regression test for. + * root of https://github.com/bitcoin-core/secp256k1/issues/257 + * which this test is a regression test for. * * These points were generated in sage as * # secp256k1 params @@ -2051,15 +2179,16 @@ void run_ec_combine(void) { void test_group_decompress(const secp256k1_fe* x) { /* The input itself, normalized. */ secp256k1_fe fex = *x; - secp256k1_fe tmp; + secp256k1_fe fez; /* Results of set_xquad_var, set_xo_var(..., 0), set_xo_var(..., 1). */ secp256k1_ge ge_quad, ge_even, ge_odd; + secp256k1_gej gej_quad; /* Return values of the above calls. */ int res_quad, res_even, res_odd; secp256k1_fe_normalize_var(&fex); - res_quad = secp256k1_ge_set_xquad_var(&ge_quad, &fex); + res_quad = secp256k1_ge_set_xquad(&ge_quad, &fex); res_even = secp256k1_ge_set_xo_var(&ge_even, &fex, 0); res_odd = secp256k1_ge_set_xo_var(&ge_odd, &fex, 1); @@ -2085,13 +2214,29 @@ void test_group_decompress(const secp256k1_fe* x) { CHECK(secp256k1_fe_equal_var(&ge_odd.x, x)); /* Check that the Y coordinate result in ge_quad is a square. */ - CHECK(secp256k1_fe_sqrt_var(&tmp, &ge_quad.y)); - secp256k1_fe_sqr(&tmp, &tmp); - CHECK(secp256k1_fe_equal_var(&tmp, &ge_quad.y)); + CHECK(secp256k1_fe_is_quad_var(&ge_quad.y)); /* Check odd/even Y in ge_odd, ge_even. */ CHECK(secp256k1_fe_is_odd(&ge_odd.y)); CHECK(!secp256k1_fe_is_odd(&ge_even.y)); + + /* Check secp256k1_gej_has_quad_y_var. */ + secp256k1_gej_set_ge(&gej_quad, &ge_quad); + CHECK(secp256k1_gej_has_quad_y_var(&gej_quad)); + do { + random_fe_test(&fez); + } while (secp256k1_fe_is_zero(&fez)); + secp256k1_gej_rescale(&gej_quad, &fez); + CHECK(secp256k1_gej_has_quad_y_var(&gej_quad)); + secp256k1_gej_neg(&gej_quad, &gej_quad); + CHECK(!secp256k1_gej_has_quad_y_var(&gej_quad)); + do { + random_fe_test(&fez); + } while (secp256k1_fe_is_zero(&fez)); + secp256k1_gej_rescale(&gej_quad, &fez); + CHECK(!secp256k1_gej_has_quad_y_var(&gej_quad)); + secp256k1_gej_neg(&gej_quad, &gej_quad); + CHECK(secp256k1_gej_has_quad_y_var(&gej_quad)); } } @@ -2383,9 +2528,7 @@ void test_constant_wnaf(const secp256k1_scalar *number, int w) { secp256k1_scalar x, shift; int wnaf[256] = {0}; int i; -#ifdef USE_ENDOMORPHISM int skew; -#endif secp256k1_scalar num = *number; secp256k1_scalar_set_int(&x, 0); @@ -2395,10 +2538,8 @@ void test_constant_wnaf(const secp256k1_scalar *number, int w) { for (i = 0; i < 16; ++i) { secp256k1_scalar_shr_int(&num, 8); } - skew = secp256k1_wnaf_const(wnaf, num, w); -#else - secp256k1_wnaf_const(wnaf, num, w); #endif + skew = secp256k1_wnaf_const(wnaf, num, w); for (i = WNAF_SIZE(w); i >= 0; --i) { secp256k1_scalar t; @@ -2417,10 +2558,8 @@ void test_constant_wnaf(const secp256k1_scalar *number, int w) { } secp256k1_scalar_add(&x, &x, &t); } -#ifdef USE_ENDOMORPHISM - /* Skew num because when encoding 128-bit numbers as odd we use an offset */ + /* Skew num because when encoding numbers as odd we use an offset */ secp256k1_scalar_cadd_bit(&num, skew == 2, 1); -#endif CHECK(secp256k1_scalar_eq(&x, &num)); } @@ -3484,12 +3623,14 @@ void run_ecdsa_end_to_end(void) { int test_ecdsa_der_parse(const unsigned char *sig, size_t siglen, int certainly_der, int certainly_not_der) { static const unsigned char zeroes[32] = {0}; +#ifdef ENABLE_OPENSSL_TESTS static const unsigned char max_scalar[32] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x40 }; +#endif int ret = 0; @@ -3607,13 +3748,13 @@ static void assign_big_endian(unsigned char *ptr, size_t ptrlen, uint32_t val) { static void damage_array(unsigned char *sig, size_t *len) { int pos; int action = secp256k1_rand_bits(3); - if (action < 1) { + if (action < 1 && *len > 3) { /* Delete a byte. */ pos = secp256k1_rand_int(*len); memmove(sig + pos, sig + pos + 1, *len - pos - 1); (*len)--; return; - } else if (action < 2) { + } else if (action < 2 && *len < 2048) { /* Insert a byte. */ pos = secp256k1_rand_int(1 + *len); memmove(sig + pos + 1, sig + pos, *len - pos); @@ -3785,6 +3926,7 @@ void run_ecdsa_der_parse(void) { int certainly_der = 0; int certainly_not_der = 0; random_ber_signature(buffer, &buflen, &certainly_der, &certainly_not_der); + CHECK(buflen <= 2048); for (j = 0; j < 16; j++) { int ret = 0; if (j > 0) { diff --git a/src/secp256k1/src/tests_exhaustive.c b/src/secp256k1/src/tests_exhaustive.c new file mode 100644 index 00000000000..bda6ee475c9 --- /dev/null +++ b/src/secp256k1/src/tests_exhaustive.c @@ -0,0 +1,329 @@ +/*********************************************************************** + * Copyright (c) 2016 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +#include +#include + +#include + +#undef USE_ECMULT_STATIC_PRECOMPUTATION + +#ifndef EXHAUSTIVE_TEST_ORDER +/* see group_impl.h for allowable values */ +#define EXHAUSTIVE_TEST_ORDER 13 +#define EXHAUSTIVE_TEST_LAMBDA 9 /* cube root of 1 mod 13 */ +#endif + +#include "include/secp256k1.h" +#include "group.h" +#include "secp256k1.c" +#include "testrand_impl.h" + +/** stolen from tests.c */ +void ge_equals_ge(const secp256k1_ge *a, const secp256k1_ge *b) { + CHECK(a->infinity == b->infinity); + if (a->infinity) { + return; + } + CHECK(secp256k1_fe_equal_var(&a->x, &b->x)); + CHECK(secp256k1_fe_equal_var(&a->y, &b->y)); +} + +void ge_equals_gej(const secp256k1_ge *a, const secp256k1_gej *b) { + secp256k1_fe z2s; + secp256k1_fe u1, u2, s1, s2; + CHECK(a->infinity == b->infinity); + if (a->infinity) { + return; + } + /* Check a.x * b.z^2 == b.x && a.y * b.z^3 == b.y, to avoid inverses. */ + secp256k1_fe_sqr(&z2s, &b->z); + secp256k1_fe_mul(&u1, &a->x, &z2s); + u2 = b->x; secp256k1_fe_normalize_weak(&u2); + secp256k1_fe_mul(&s1, &a->y, &z2s); secp256k1_fe_mul(&s1, &s1, &b->z); + s2 = b->y; secp256k1_fe_normalize_weak(&s2); + CHECK(secp256k1_fe_equal_var(&u1, &u2)); + CHECK(secp256k1_fe_equal_var(&s1, &s2)); +} + +void random_fe(secp256k1_fe *x) { + unsigned char bin[32]; + do { + secp256k1_rand256(bin); + if (secp256k1_fe_set_b32(x, bin)) { + return; + } + } while(1); +} +/** END stolen from tests.c */ + +int secp256k1_nonce_function_smallint(unsigned char *nonce32, const unsigned char *msg32, + const unsigned char *key32, const unsigned char *algo16, + void *data, unsigned int attempt) { + secp256k1_scalar s; + int *idata = data; + (void)msg32; + (void)key32; + (void)algo16; + /* Some nonces cannot be used because they'd cause s and/or r to be zero. + * The signing function has retry logic here that just re-calls the nonce + * function with an increased `attempt`. So if attempt > 0 this means we + * need to change the nonce to avoid an infinite loop. */ + if (attempt > 0) { + (*idata)++; + } + secp256k1_scalar_set_int(&s, *idata); + secp256k1_scalar_get_b32(nonce32, &s); + return 1; +} + +#ifdef USE_ENDOMORPHISM +void test_exhaustive_endomorphism(const secp256k1_ge *group, int order) { + int i; + for (i = 0; i < order; i++) { + secp256k1_ge res; + secp256k1_ge_mul_lambda(&res, &group[i]); + ge_equals_ge(&group[i * EXHAUSTIVE_TEST_LAMBDA % EXHAUSTIVE_TEST_ORDER], &res); + } +} +#endif + +void test_exhaustive_addition(const secp256k1_ge *group, const secp256k1_gej *groupj, int order) { + int i, j; + + /* Sanity-check (and check infinity functions) */ + CHECK(secp256k1_ge_is_infinity(&group[0])); + CHECK(secp256k1_gej_is_infinity(&groupj[0])); + for (i = 1; i < order; i++) { + CHECK(!secp256k1_ge_is_infinity(&group[i])); + CHECK(!secp256k1_gej_is_infinity(&groupj[i])); + } + + /* Check all addition formulae */ + for (j = 0; j < order; j++) { + secp256k1_fe fe_inv; + secp256k1_fe_inv(&fe_inv, &groupj[j].z); + for (i = 0; i < order; i++) { + secp256k1_ge zless_gej; + secp256k1_gej tmp; + /* add_var */ + secp256k1_gej_add_var(&tmp, &groupj[i], &groupj[j], NULL); + ge_equals_gej(&group[(i + j) % order], &tmp); + /* add_ge */ + if (j > 0) { + secp256k1_gej_add_ge(&tmp, &groupj[i], &group[j]); + ge_equals_gej(&group[(i + j) % order], &tmp); + } + /* add_ge_var */ + secp256k1_gej_add_ge_var(&tmp, &groupj[i], &group[j], NULL); + ge_equals_gej(&group[(i + j) % order], &tmp); + /* add_zinv_var */ + zless_gej.infinity = groupj[j].infinity; + zless_gej.x = groupj[j].x; + zless_gej.y = groupj[j].y; + secp256k1_gej_add_zinv_var(&tmp, &groupj[i], &zless_gej, &fe_inv); + ge_equals_gej(&group[(i + j) % order], &tmp); + } + } + + /* Check doubling */ + for (i = 0; i < order; i++) { + secp256k1_gej tmp; + if (i > 0) { + secp256k1_gej_double_nonzero(&tmp, &groupj[i], NULL); + ge_equals_gej(&group[(2 * i) % order], &tmp); + } + secp256k1_gej_double_var(&tmp, &groupj[i], NULL); + ge_equals_gej(&group[(2 * i) % order], &tmp); + } + + /* Check negation */ + for (i = 1; i < order; i++) { + secp256k1_ge tmp; + secp256k1_gej tmpj; + secp256k1_ge_neg(&tmp, &group[i]); + ge_equals_ge(&group[order - i], &tmp); + secp256k1_gej_neg(&tmpj, &groupj[i]); + ge_equals_gej(&group[order - i], &tmpj); + } +} + +void test_exhaustive_ecmult(const secp256k1_context *ctx, const secp256k1_ge *group, const secp256k1_gej *groupj, int order) { + int i, j, r_log; + for (r_log = 1; r_log < order; r_log++) { + for (j = 0; j < order; j++) { + for (i = 0; i < order; i++) { + secp256k1_gej tmp; + secp256k1_scalar na, ng; + secp256k1_scalar_set_int(&na, i); + secp256k1_scalar_set_int(&ng, j); + + secp256k1_ecmult(&ctx->ecmult_ctx, &tmp, &groupj[r_log], &na, &ng); + ge_equals_gej(&group[(i * r_log + j) % order], &tmp); + + if (i > 0) { + secp256k1_ecmult_const(&tmp, &group[i], &ng); + ge_equals_gej(&group[(i * j) % order], &tmp); + } + } + } + } +} + +void r_from_k(secp256k1_scalar *r, const secp256k1_ge *group, int k) { + secp256k1_fe x; + unsigned char x_bin[32]; + k %= EXHAUSTIVE_TEST_ORDER; + x = group[k].x; + secp256k1_fe_normalize(&x); + secp256k1_fe_get_b32(x_bin, &x); + secp256k1_scalar_set_b32(r, x_bin, NULL); +} + +void test_exhaustive_verify(const secp256k1_context *ctx, const secp256k1_ge *group, int order) { + int s, r, msg, key; + for (s = 1; s < order; s++) { + for (r = 1; r < order; r++) { + for (msg = 1; msg < order; msg++) { + for (key = 1; key < order; key++) { + secp256k1_ge nonconst_ge; + secp256k1_ecdsa_signature sig; + secp256k1_pubkey pk; + secp256k1_scalar sk_s, msg_s, r_s, s_s; + secp256k1_scalar s_times_k_s, msg_plus_r_times_sk_s; + int k, should_verify; + unsigned char msg32[32]; + + secp256k1_scalar_set_int(&s_s, s); + secp256k1_scalar_set_int(&r_s, r); + secp256k1_scalar_set_int(&msg_s, msg); + secp256k1_scalar_set_int(&sk_s, key); + + /* Verify by hand */ + /* Run through every k value that gives us this r and check that *one* works. + * Note there could be none, there could be multiple, ECDSA is weird. */ + should_verify = 0; + for (k = 0; k < order; k++) { + secp256k1_scalar check_x_s; + r_from_k(&check_x_s, group, k); + if (r_s == check_x_s) { + secp256k1_scalar_set_int(&s_times_k_s, k); + secp256k1_scalar_mul(&s_times_k_s, &s_times_k_s, &s_s); + secp256k1_scalar_mul(&msg_plus_r_times_sk_s, &r_s, &sk_s); + secp256k1_scalar_add(&msg_plus_r_times_sk_s, &msg_plus_r_times_sk_s, &msg_s); + should_verify |= secp256k1_scalar_eq(&s_times_k_s, &msg_plus_r_times_sk_s); + } + } + /* nb we have a "high s" rule */ + should_verify &= !secp256k1_scalar_is_high(&s_s); + + /* Verify by calling verify */ + secp256k1_ecdsa_signature_save(&sig, &r_s, &s_s); + memcpy(&nonconst_ge, &group[sk_s], sizeof(nonconst_ge)); + secp256k1_pubkey_save(&pk, &nonconst_ge); + secp256k1_scalar_get_b32(msg32, &msg_s); + CHECK(should_verify == + secp256k1_ecdsa_verify(ctx, &sig, msg32, &pk)); + } + } + } + } +} + +void test_exhaustive_sign(const secp256k1_context *ctx, const secp256k1_ge *group, int order) { + int i, j, k; + + /* Loop */ + for (i = 1; i < order; i++) { /* message */ + for (j = 1; j < order; j++) { /* key */ + for (k = 1; k < order; k++) { /* nonce */ + secp256k1_ecdsa_signature sig; + secp256k1_scalar sk, msg, r, s, expected_r; + unsigned char sk32[32], msg32[32]; + secp256k1_scalar_set_int(&msg, i); + secp256k1_scalar_set_int(&sk, j); + secp256k1_scalar_get_b32(sk32, &sk); + secp256k1_scalar_get_b32(msg32, &msg); + + secp256k1_ecdsa_sign(ctx, &sig, msg32, sk32, secp256k1_nonce_function_smallint, &k); + + secp256k1_ecdsa_signature_load(ctx, &r, &s, &sig); + /* Note that we compute expected_r *after* signing -- this is important + * because our nonce-computing function function might change k during + * signing. */ + r_from_k(&expected_r, group, k); + CHECK(r == expected_r); + CHECK((k * s) % order == (i + r * j) % order || + (k * (EXHAUSTIVE_TEST_ORDER - s)) % order == (i + r * j) % order); + } + } + } + + /* We would like to verify zero-knowledge here by counting how often every + * possible (s, r) tuple appears, but because the group order is larger + * than the field order, when coercing the x-values to scalar values, some + * appear more often than others, so we are actually not zero-knowledge. + * (This effect also appears in the real code, but the difference is on the + * order of 1/2^128th the field order, so the deviation is not useful to a + * computationally bounded attacker.) + */ +} + +int main(void) { + int i; + secp256k1_gej groupj[EXHAUSTIVE_TEST_ORDER]; + secp256k1_ge group[EXHAUSTIVE_TEST_ORDER]; + + /* Build context */ + secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + + /* TODO set z = 1, then do num_tests runs with random z values */ + + /* Generate the entire group */ + secp256k1_gej_set_infinity(&groupj[0]); + secp256k1_ge_set_gej(&group[0], &groupj[0]); + for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) { + /* Set a different random z-value for each Jacobian point */ + secp256k1_fe z; + random_fe(&z); + + secp256k1_gej_add_ge(&groupj[i], &groupj[i - 1], &secp256k1_ge_const_g); + secp256k1_ge_set_gej(&group[i], &groupj[i]); + secp256k1_gej_rescale(&groupj[i], &z); + + /* Verify against ecmult_gen */ + { + secp256k1_scalar scalar_i; + secp256k1_gej generatedj; + secp256k1_ge generated; + + secp256k1_scalar_set_int(&scalar_i, i); + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &generatedj, &scalar_i); + secp256k1_ge_set_gej(&generated, &generatedj); + + CHECK(group[i].infinity == 0); + CHECK(generated.infinity == 0); + CHECK(secp256k1_fe_equal_var(&generated.x, &group[i].x)); + CHECK(secp256k1_fe_equal_var(&generated.y, &group[i].y)); + } + } + + /* Run the tests */ +#ifdef USE_ENDOMORPHISM + test_exhaustive_endomorphism(group, EXHAUSTIVE_TEST_ORDER); +#endif + test_exhaustive_addition(group, groupj, EXHAUSTIVE_TEST_ORDER); + test_exhaustive_ecmult(ctx, group, groupj, EXHAUSTIVE_TEST_ORDER); + test_exhaustive_sign(ctx, group, EXHAUSTIVE_TEST_ORDER); + test_exhaustive_verify(ctx, group, EXHAUSTIVE_TEST_ORDER); + + return 0; +} + diff --git a/src/serialize.h b/src/serialize.h index 378ed39074e..04ab9aa2e77 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -322,8 +322,8 @@ uint64_t ReadCompactSize(Stream& is) * 0: [0x00] 256: [0x81 0x00] * 1: [0x01] 16383: [0xFE 0x7F] * 127: [0x7F] 16384: [0xFF 0x00] - * 128: [0x80 0x00] 16511: [0x80 0xFF 0x7F] - * 255: [0x80 0x7F] 65535: [0x82 0xFD 0x7F] + * 128: [0x80 0x00] 16511: [0xFF 0x7F] + * 255: [0x80 0x7F] 65535: [0x82 0xFE 0x7F] * 2^32: [0x8E 0xFE 0xFE 0xFF 0x00] */ diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp deleted file mode 100644 index 1b7d368e13e..00000000000 --- a/src/test/Checkpoints_tests.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// 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. - -// -// Unit tests for block-chain checkpoints -// - -#include "checkpoints.h" - -#include "uint256.h" -#include "test/test_bitcoin.h" -#include "chainparams.h" - -#include - -using namespace std; - -BOOST_FIXTURE_TEST_SUITE(Checkpoints_tests, BasicTestingSetup) - -BOOST_AUTO_TEST_CASE(sanity) -{ - const CCheckpointData& checkpoints = Params(CBaseChainParams::MAIN).Checkpoints(); - BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate(checkpoints) >= 134444); -} - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/README.md b/src/test/README.md index b2d6be14f14..61462642bfb 100644 --- a/src/test/README.md +++ b/src/test/README.md @@ -5,18 +5,15 @@ sense to simply use this framework rather than require developers to configure some other framework (we want as few impediments to creating unit tests as possible). -The build system is setup to compile an executable called "test_bitcoin" +The build system is setup to compile an executable called `test_bitcoin` that runs all of the unit tests. The main source file is called -test_bitcoin.cpp, which simply includes other files that contain the -actual unit tests (outside of a couple required preprocessor -directives). The pattern is to create one test file for each class or -source file for which you want to create unit tests. The file naming -convention is "_tests.cpp" and such files should wrap -their tests in a test suite called "_tests". For an -examples of this pattern, examine uint160_tests.cpp and -uint256_tests.cpp. - -Add the source files to /src/Makefile.test.include to add them to the build. +test_bitcoin.cpp. To add a new unit test file to our test suite you need +to add the file to `src/Makefile.test.include`. The pattern is to create +one test file for each class or source file for which you want to create +unit tests. The file naming convention is `_tests.cpp` +and such files should wrap their tests in a test suite +called `_tests`. For an example of this pattern, +examine `uint256_tests.cpp`. For further reading, I found the following website to be helpful in explaining how the boost unit test framework works: @@ -31,5 +28,5 @@ example, to run just the getarg_tests verbosely: test_bitcoin --run_test=getarg_tests/doubledash -Run test_bitcoin --help for the full list. +Run `test_bitcoin --help` for the full list. diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp index 53ab7e95ee0..b19d2faea01 100644 --- a/src/test/arith_uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -112,7 +112,7 @@ BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality BOOST_CHECK( (R1L & arith_uint256("0xffffffffffffffff")) == arith_uint256(R1LLow64)); BOOST_CHECK(ZeroL == arith_uint256(0)); BOOST_CHECK(OneL == arith_uint256(1)); - BOOST_CHECK(arith_uint256("0xffffffffffffffff") = arith_uint256(0xffffffffffffffffULL)); + BOOST_CHECK(arith_uint256("0xffffffffffffffff") == arith_uint256(0xffffffffffffffffULL)); // Assignment (from base_uint) arith_uint256 tmpL = ~ZeroL; BOOST_CHECK(tmpL == ~ZeroL); diff --git a/src/test/bctest.py b/src/test/bctest.py index 8105b87ffa3..39a27fcd0c4 100644 --- a/src/test/bctest.py +++ b/src/test/bctest.py @@ -24,6 +24,9 @@ def bctest(testDir, testObj, exeext): if "output_cmp" in testObj: outputFn = testObj['output_cmp'] outputData = open(testDir + "/" + outputFn).read() + if not outputData: + print("Output data missing for " + outputFn) + sys.exit(1) proc = subprocess.Popen(execrun, stdin=stdinCfg, stdout=subprocess.PIPE, stderr=subprocess.PIPE,universal_newlines=True) try: outs = proc.communicate(input=inputData) diff --git a/src/test/blockencodings_tests.cpp b/src/test/blockencodings_tests.cpp index 3884bf3fe37..153a41ba74c 100644 --- a/src/test/blockencodings_tests.cpp +++ b/src/test/blockencodings_tests.cpp @@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE(SimpleRoundTripTest) // Do a simple ShortTxIDs RT { - CBlockHeaderAndShortTxIDs shortIDs(block); + CBlockHeaderAndShortTxIDs shortIDs(block, true); CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << shortIDs; @@ -116,7 +116,7 @@ class TestHeaderAndShortIDs { stream >> *this; } TestHeaderAndShortIDs(const CBlock& block) : - TestHeaderAndShortIDs(CBlockHeaderAndShortTxIDs(block)) {} + TestHeaderAndShortIDs(CBlockHeaderAndShortTxIDs(block, true)) {} uint64_t GetShortID(const uint256& txhash) const { CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); @@ -267,7 +267,7 @@ BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest) // Test simple header round-trip with only coinbase { - CBlockHeaderAndShortTxIDs shortIDs(block); + CBlockHeaderAndShortTxIDs shortIDs(block, false); CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << shortIDs; diff --git a/src/test/bswap_tests.cpp b/src/test/bswap_tests.cpp new file mode 100644 index 00000000000..7b3134d327d --- /dev/null +++ b/src/test/bswap_tests.cpp @@ -0,0 +1,26 @@ +// Copyright (c) 2016 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 "compat/byteswap.h" +#include "test/test_bitcoin.h" + +#include + +BOOST_FIXTURE_TEST_SUITE(bswap_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(bswap_tests) +{ + // Sibling in bitcoin/src/qt/test/compattests.cpp + uint16_t u1 = 0x1234; + uint32_t u2 = 0x56789abc; + uint64_t u3 = 0xdef0123456789abc; + uint16_t e1 = 0x3412; + uint32_t e2 = 0xbc9a7856; + uint64_t e3 = 0xbc9a78563412f0de; + BOOST_CHECK(bswap_16(u1) == e1); + BOOST_CHECK(bswap_32(u2) == e2); + BOOST_CHECK(bswap_64(u3) == e3); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json index 5cb383de85a..9df61a7e793 100644 --- a/src/test/data/bitcoin-util-test.json +++ b/src/test/data/bitcoin-util-test.json @@ -1,19 +1,33 @@ [ - { "exec": "././bitcoin-tx", + { "exec": "./bitcoin-tx", "args": ["-create"], "output_cmp": "blanktx.hex" }, { "exec": "./bitcoin-tx", + "args": ["-json","-create"], + "output_cmp": "blanktx.json" + }, + { "exec": "./bitcoin-tx", "args": ["-"], "input": "blanktx.hex", "output_cmp": "blanktx.hex" }, { "exec": "./bitcoin-tx", + "args": ["-json","-"], + "input": "blanktx.hex", + "output_cmp": "blanktx.json" + }, + { "exec": "./bitcoin-tx", "args": ["-", "delin=1"], "input": "tx394b54bb.hex", "output_cmp": "tt-delin1-out.hex" }, { "exec": "./bitcoin-tx", + "args": ["-json", "-", "delin=1"], + "input": "tx394b54bb.hex", + "output_cmp": "tt-delin1-out.json" + }, + { "exec": "./bitcoin-tx", "args": ["-", "delin=31"], "input": "tx394b54bb.hex", "return_code": 1 @@ -24,6 +38,11 @@ "output_cmp": "tt-delout1-out.hex" }, { "exec": "./bitcoin-tx", + "args": ["-json", "-", "delout=1"], + "input": "tx394b54bb.hex", + "output_cmp": "tt-delout1-out.json" + }, + { "exec": "./bitcoin-tx", "args": ["-", "delout=2"], "input": "tx394b54bb.hex", "return_code": 1 @@ -34,6 +53,11 @@ "output_cmp": "tt-locktime317000-out.hex" }, { "exec": "./bitcoin-tx", + "args": ["-json", "-", "locktime=317000"], + "input": "tx394b54bb.hex", + "output_cmp": "tt-locktime317000-out.json" + }, + { "exec": "./bitcoin-tx", "args": ["-create", "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", @@ -44,10 +68,25 @@ "output_cmp": "txcreate1.hex" }, { "exec": "./bitcoin-tx", + "args": + ["-json", + "-create", + "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", + "in=bf829c6bcf84579331337659d31f89dfd138f7f7785802d5501c92333145ca7c:18", + "in=22a6f904655d53ae2ff70e701a0bbd90aa3975c0f40bfc6cc996a9049e31cdfc:1", + "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o", + "outaddr=4:1P8yWvZW8jVihP1bzHeqfE4aoXNX8AVa46"], + "output_cmp": "txcreate1.json" + }, + { "exec": "./bitcoin-tx", "args": ["-create", "outscript=0:"], "output_cmp": "txcreate2.hex" }, { "exec": "./bitcoin-tx", + "args": ["-json", "-create", "outscript=0:"], + "output_cmp": "txcreate2.json" + }, + { "exec": "./bitcoin-tx", "args": ["-create", "in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0", @@ -59,6 +98,17 @@ }, { "exec": "./bitcoin-tx", "args": + ["-json", + "-create", + "in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0", + "set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]", + "set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\",\"vout\":0,\"scriptPubKey\":\"76a91491b24bf9f5288532960ac687abb035127b1d28a588ac\"}]", + "sign=ALL", + "outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"], + "output_cmp": "txcreatesign.json" + }, + { "exec": "./bitcoin-tx", + "args": ["-create", "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", "outdata=4:badhexdata"], @@ -81,6 +131,15 @@ }, { "exec": "./bitcoin-tx", "args": + ["-json", + "-create", + "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", + "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o", + "outdata=4:54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"], + "output_cmp": "txcreatedata1.json" + }, + { "exec": "./bitcoin-tx", + "args": ["-create", "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o", @@ -89,6 +148,15 @@ }, { "exec": "./bitcoin-tx", "args": + ["-json", + "-create", + "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", + "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o", + "outdata=54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"], + "output_cmp": "txcreatedata2.json" + }, + { "exec": "./bitcoin-tx", + "args": ["-create", "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:4294967293", "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"], @@ -96,8 +164,23 @@ }, { "exec": "./bitcoin-tx", "args": + ["-json", + "-create", + "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:4294967293", + "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"], + "output_cmp": "txcreatedata_seq0.json" + }, + { "exec": "./bitcoin-tx", + "args": ["01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff0180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000", "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:1"], "output_cmp": "txcreatedata_seq1.hex" + }, + { "exec": "./bitcoin-tx", + "args": + ["-json", + "01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff0180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000", + "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:1"], + "output_cmp": "txcreatedata_seq1.json" } ] diff --git a/src/test/data/blanktx.json b/src/test/data/blanktx.json new file mode 100644 index 00000000000..51c25a5a98c --- /dev/null +++ b/src/test/data/blanktx.json @@ -0,0 +1,11 @@ +{ + "txid": "d21633ba23f70118185227be58a63527675641ad37967e2aa461559f577aec43", + "hash": "d21633ba23f70118185227be58a63527675641ad37967e2aa461559f577aec43", + "version": 1, + "locktime": 0, + "vin": [ + ], + "vout": [ + ], + "hex": "01000000000000000000" +} diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json index fcd5457386d..5c054ed3e8f 100644 --- a/src/test/data/script_tests.json +++ b/src/test/data/script_tests.json @@ -1492,6 +1492,27 @@ "BIP66 example 4, with DERSIG" ], [ + "0x09 0x300602010102010101", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", + "DERSIG", + "OK", + "BIP66 example 4, with DERSIG, non-null DER-compliant signature" +], +[ + "0", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", + "DERSIG,NULLFAIL", + "OK", + "BIP66 example 4, with DERSIG and NULLFAIL" +], +[ + "0x09 0x300602010102010101", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", + "DERSIG,NULLFAIL", + "NULLFAIL", + "BIP66 example 4, with DERSIG and NULLFAIL, non-null DER-compliant signature" +], +[ "1", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "", @@ -1834,6 +1855,8 @@ "OK", "P2SH with CLEANSTACK" ], + +["Testing with uncompressed keys in witness v0 without WITNESS_PUBKEYTYPE"], [ [ "304402200d461c140cfdfcf36b94961db57ae8c18d1cb80e9d95a9e47ac22470c1bf125502201c8dc1cbfef6a3ef90acbbb992ca22fe9466ee6f9d4898eda277a7ac3ab4b25101", @@ -2118,12 +2141,469 @@ "P2PK with witness" ], -["CHECKSEQUENCEVERIFY tests"], +["Testing with compressed keys in witness v0 with WITNESS_PUBKEYTYPE"], +[ + [ + "304402204256146fcf8e73b0fd817ffa2a4e408ff0418ff987dd08a4f485b62546f6c43c02203f3c8c3e2febc051e1222867f5f9d0eaf039d6792911c10940aa3cc74123378e01", + "210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", + 0.00000001 + ], + "", + "0 0x20 0x1863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "Basic P2WSH with compressed key" +], +[ + [ + "304402204edf27486f11432466b744df533e1acac727e0c83e5f912eb289a3df5bf8035f022075809fdd876ede40ad21667eba8b7e96394938f9c9c50f11b6a1280cce2cea8601", + "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", + 0.00000001 + ], + "", + "0 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "Basic P2WPKH with compressed key" +], +[ + [ + "304402203a549090cc46bce1e5e95c4922ea2c12747988e0207b04c42f81cdbe87bb1539022050f57a245b875fd5119c419aaf050bcdf41384f0765f04b809e5bced1fe7093d01", + "210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", + 0.00000001 + ], + "0x22 0x00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262", + "HASH160 0x14 0xe4300531190587e3880d4c3004f5355d88ff928d EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "Basic P2SH(P2WSH) with compressed key" +], +[ + [ + "304402201bc0d53046827f4a35a3166e33e3b3366c4085540dc383b95d21ed2ab11e368a0220333e78c6231214f5f8e59621e15d7eeab0d4e4d0796437e00bfbd2680c5f9c1701", + "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", + 0.00000001 + ], + "0x16 0x0014751e76e8199196d454941c45d1b3a323f1433bd6", + "HASH160 0x14 0xbcfeb728b584253d5f3f70bcb780e9ef218a68f4 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "Basic P2SH(P2WPKH) with compressed key" +], + +["Testing with uncompressed keys in witness v0 with WITNESS_PUBKEYTYPE"], +[ + [ + "304402200d461c140cfdfcf36b94961db57ae8c18d1cb80e9d95a9e47ac22470c1bf125502201c8dc1cbfef6a3ef90acbbb992ca22fe9466ee6f9d4898eda277a7ac3ab4b25101", + "410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + 0.00000001 + ], + "", + "0 0x20 0xb95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "Basic P2WSH" +], +[ + [ + "304402201e7216e5ccb3b61d46946ec6cc7e8c4e0117d13ac2fd4b152197e4805191c74202203e9903e33e84d9ee1dd13fb057afb7ccfb47006c23f6a067185efbc9dd780fc501", + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 0.00000001 + ], + "", + "0 0x14 0x91b24bf9f5288532960ac687abb035127b1d28a5", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "Basic P2WPKH" +], +[ + [ + "3044022066e02c19a513049d49349cf5311a1b012b7c4fae023795a18ab1d91c23496c22022025e216342c8e07ce8ef51e8daee88f84306a9de66236cab230bb63067ded1ad301", + "410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac", + 0.00000001 + ], + "0x22 0x0020b95237b48faaa69eb078e1170be3b5cbb3fddf16d0a991e14ad274f7b33a4f64", + "HASH160 0x14 0xf386c2ba255cc56d20cfa6ea8b062f8b59945518 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "Basic P2SH(P2WSH)" +], +[ + [ + "304402200929d11561cd958460371200f82e9cae64c727a495715a31828e27a7ad57b36d0220361732ced04a6f97351ecca21a56d0b8cd4932c1da1f8f569a2b68e5e48aed7801", + "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + 0.00000001 + ], + "0x16 0x001491b24bf9f5288532960ac687abb035127b1d28a5", + "HASH160 0x14 0x17743beb429c55c942d2ec703b98c4d57c2df5c6 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "Basic P2SH(P2WPKH)" +], + +["Testing P2WSH multisig with compressed keys"], +[ + [ + "", + "304402207eb8a59b5c65fc3f6aeef77066556ed5c541948a53a3ba7f7c375b8eed76ee7502201e036a7a9a98ff919ff94dc905d67a1ec006f79ef7cff0708485c8bb79dce38e01", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "", + "0 0x20 0x06c24420938f0fa3c1cb2707d867154220dca365cdbfa0dd2a83854730221460", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "P2WSH CHECKMULTISIG with compressed keys" +], +[ + [ + "", + "3044022033706aed33b8155d5486df3b9bca8cdd3bd4bdb5436dce46d72cdaba51d22b4002203626e94fe53a178af46624f17315c6931f20a30b103f5e044e1eda0c3fe185c601", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "0x22 0x002006c24420938f0fa3c1cb2707d867154220dca365cdbfa0dd2a83854730221460", + "HASH160 0x14 0x26282aad7c29369d15fed062a778b6100d31a340 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "P2SH(P2WSH) CHECKMULTISIG with compressed keys" +], +[ + [ + "", + "304402204048b7371ab1c544362efb89af0c80154747d665aa4fcfb2edfd2d161e57b42e02207e043748e96637080ffc3acbd4dcc6fee1e58d30f6d1269535f32188e5ddae7301", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "", + "0 0x20 0x06c24420938f0fa3c1cb2707d867154220dca365cdbfa0dd2a83854730221460", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "P2WSH CHECKMULTISIG with compressed keys" +], +[ + [ + "", + "3044022073902ef0b8a554c36c44cc03c1b64df96ce2914ebcf946f5bb36078fd5245cdf02205b148f1ba127065fb8c83a5a9576f2dcd111739788ed4bb3ee08b2bd3860c91c01", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "0x22 0x002006c24420938f0fa3c1cb2707d867154220dca365cdbfa0dd2a83854730221460", + "HASH160 0x14 0x26282aad7c29369d15fed062a778b6100d31a340 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "P2SH(P2WSH) CHECKMULTISIG with compressed keys" +], + +["Testing P2WSH multisig with compressed and uncompressed keys (first key being the key closer to the top of stack)"], +[ + [ + "", + "304402202d092ededd1f060609dbf8cb76950634ff42b3e62cf4adb69ab92397b07d742302204ff886f8d0817491a96d1daccdcc820f6feb122ee6230143303100db37dfa79f01", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "", + "0 0x20 0x08a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "P2SH,WITNESS", + "OK", + "P2WSH CHECKMULTISIG with first key uncompressed and signing with the first key" +], +[ + [ + "", + "304402202dd7e91243f2235481ffb626c3b7baf2c859ae3a5a77fb750ef97b99a8125dc002204960de3d3c3ab9496e218ec57e5240e0e10a6f9546316fe240c216d45116d29301", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "0x22 0x002008a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "HASH160 0x14 0x6f5ecd4b83b77f3c438f5214eff96454934fc5d1 EQUAL", + "P2SH,WITNESS", + "OK", + "P2SH(P2WSH) CHECKMULTISIG first key uncompressed and signing with the first key" +], +[ + [ + "", + "304402202d092ededd1f060609dbf8cb76950634ff42b3e62cf4adb69ab92397b07d742302204ff886f8d0817491a96d1daccdcc820f6feb122ee6230143303100db37dfa79f01", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "", + "0 0x20 0x08a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "P2WSH CHECKMULTISIG with first key uncompressed and signing with the first key" +], +[ + [ + "", + "304402202dd7e91243f2235481ffb626c3b7baf2c859ae3a5a77fb750ef97b99a8125dc002204960de3d3c3ab9496e218ec57e5240e0e10a6f9546316fe240c216d45116d29301", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "0x22 0x002008a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "HASH160 0x14 0x6f5ecd4b83b77f3c438f5214eff96454934fc5d1 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the first key" +], +[ + [ + "", + "304402201e9e6f7deef5b2f21d8223c5189b7d5e82d237c10e97165dd08f547c4e5ce6ed02206796372eb1cc6acb52e13ee2d7f45807780bf96b132cb6697f69434be74b1af901", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "", + "0 0x20 0x08a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "P2SH,WITNESS", + "OK", + "P2WSH CHECKMULTISIG with first key uncompressed and signing with the second key" +], +[ + [ + "", + "3044022045e667f3f0f3147b95597a24babe9afecea1f649fd23637dfa7ed7e9f3ac18440220295748e81005231135289fe3a88338dabba55afa1bdb4478691337009d82b68d01", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "0x22 0x002008a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "HASH160 0x14 0x6f5ecd4b83b77f3c438f5214eff96454934fc5d1 EQUAL", + "P2SH,WITNESS", + "OK", + "P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the second key" +], +[ + [ + "", + "304402201e9e6f7deef5b2f21d8223c5189b7d5e82d237c10e97165dd08f547c4e5ce6ed02206796372eb1cc6acb52e13ee2d7f45807780bf96b132cb6697f69434be74b1af901", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "", + "0 0x20 0x08a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "P2WSH CHECKMULTISIG with first key uncompressed and signing with the second key" +], +[ + [ + "", + "3044022045e667f3f0f3147b95597a24babe9afecea1f649fd23637dfa7ed7e9f3ac18440220295748e81005231135289fe3a88338dabba55afa1bdb4478691337009d82b68d01", + "5121038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b852ae", + 0.00000001 + ], + "0x22 0x002008a6665ebfd43b02323423e764e185d98d1587f903b81507dbb69bfc41005efa", + "HASH160 0x14 0x6f5ecd4b83b77f3c438f5214eff96454934fc5d1 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the second key" +], +[ + [ + "", + "3044022046f5367a261fd8f8d7de6eb390491344f8ec2501638fb9a1095a0599a21d3f4c02205c1b3b51d20091c5f1020841bbca87b44ebe25405c64e4acf758f2eae8665f8401", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "", + "0 0x20 0x230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "P2SH,WITNESS", + "OK", + "P2WSH CHECKMULTISIG with second key uncompressed and signing with the first key" +], +[ + [ + "", + "3044022053e210e4fb1881e6092fd75c3efc5163105599e246ded661c0ee2b5682cc2d6c02203a26b7ada8682a095b84c6d1b881637000b47d761fc837c4cee33555296d63f101", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "0x22 0x0020230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "HASH160 0x14 0x3478e7019ce61a68148f87549579b704cbe4c393 EQUAL", + "P2SH,WITNESS", + "OK", + "P2SH(P2WSH) CHECKMULTISIG second key uncompressed and signing with the first key" +], +[ + [ + "", + "3044022046f5367a261fd8f8d7de6eb390491344f8ec2501638fb9a1095a0599a21d3f4c02205c1b3b51d20091c5f1020841bbca87b44ebe25405c64e4acf758f2eae8665f8401", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "", + "0 0x20 0x230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "P2WSH CHECKMULTISIG with second key uncompressed and signing with the first key should pass as the uncompressed key is not used" +], +[ + [ + "", + "3044022053e210e4fb1881e6092fd75c3efc5163105599e246ded661c0ee2b5682cc2d6c02203a26b7ada8682a095b84c6d1b881637000b47d761fc837c4cee33555296d63f101", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "0x22 0x0020230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "HASH160 0x14 0x3478e7019ce61a68148f87549579b704cbe4c393 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "OK", + "P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the first key should pass as the uncompressed key is not used" +], +[ + [ + "", + "304402206c6d9f5daf85b54af2a93ec38b15ab27f205dbf5c735365ff12451e43613d1f40220736a44be63423ed5ebf53491618b7cc3d8a5093861908da853739c73717938b701", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "", + "0 0x20 0x230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "P2SH,WITNESS", + "OK", + "P2WSH CHECKMULTISIG with second key uncompressed and signing with the second key" +], +[ + [ + "", + "30440220687871bc6144012d75baf585bb26ce13997f7d8c626f4d8825b069c3b2d064470220108936fe1c57327764782253e99090b09c203ec400ed35ce9e026ce2ecf842a001", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "0x22 0x0020230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "HASH160 0x14 0x3478e7019ce61a68148f87549579b704cbe4c393 EQUAL", + "P2SH,WITNESS", + "OK", + "P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the second key" +], +[ + [ + "", + "304402206c6d9f5daf85b54af2a93ec38b15ab27f205dbf5c735365ff12451e43613d1f40220736a44be63423ed5ebf53491618b7cc3d8a5093861908da853739c73717938b701", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "", + "0 0x20 0x230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "P2WSH CHECKMULTISIG with second key uncompressed and signing with the second key" +], +[ + [ + "", + "30440220687871bc6144012d75baf585bb26ce13997f7d8c626f4d8825b069c3b2d064470220108936fe1c57327764782253e99090b09c203ec400ed35ce9e026ce2ecf842a001", + "5141048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179852ae", + 0.00000001 + ], + "0x22 0x0020230828ed48871f0f362ce9432aa52f620f442cc8d9ce7a8b5e798365595a38bb", + "HASH160 0x14 0x3478e7019ce61a68148f87549579b704cbe4c393 EQUAL", + "P2SH,WITNESS,WITNESS_PUBKEYTYPE", + "WITNESS_PUBKEYTYPE", + "P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the second key" +], + +["CHECKSEQUENCEVERIFY tests"], ["", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "INVALID_STACK_OPERATION", "CSV automatically fails on a empty stack"], ["-1", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "NEGATIVE_LOCKTIME", "CSV automatically fails if stack top is negative"], ["0x0100", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY,MINIMALDATA", "UNKNOWN_ERROR", "CSV fails if stack top is not minimally encoded"], ["0", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME", "CSV fails if stack top bit 1 << 31 is set and the tx version < 2"], ["4294967296", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME", "CSV fails if stack top bit 1 << 31 is not set, and tx version < 2"], + +["MINIMALIF tests"], +["MINIMALIF is not applied to non-segwit scripts"], +["1", "IF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "OK"], +["2", "IF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "OK"], +["0x02 0x0100", "IF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "OK"], +["0", "IF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["0x01 0x00", "IF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["1", "NOTIF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["2", "NOTIF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["0x02 0x0100", "NOTIF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["0", "NOTIF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "OK"], +["0x01 0x00", "NOTIF 1 ENDIF", "P2SH,WITNESS,MINIMALIF", "OK"], +["Normal P2SH IF 1 ENDIF"], +["1 0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"], +["2 0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"], +["0x02 0x0100 0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"], +["0 0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["0x01 0x00 0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["0x03 0x635168", "HASH160 0x14 0xe7309652a8e3f600f06f5d8d52d6df03d2176cc3 EQUAL", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"], +["Normal P2SH NOTIF 1 ENDIF"], +["1 0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["2 0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["0x02 0x0100 0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +["0 0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"], +["0x01 0x00 0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"], +["0x03 0x645168", "HASH160 0x14 0x0c3f8fe3d6ca266e76311ecda544c67d15fdd5b0 EQUAL", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"], +["P2WSH IF 1 ENDIF"], +[["01", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "OK"], +[["02", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "OK"], +[["0100", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "OK"], +[["", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "EVAL_FALSE"], +[["00", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "EVAL_FALSE"], +[["01", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "OK"], +[["02", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["0100", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +[["00", "635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS", "UNBALANCED_CONDITIONAL"], +[["635168", 0.00000001], "", "0 0x20 0xc7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"], +["P2WSH NOTIF 1 ENDIF"], +[["01", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "EVAL_FALSE"], +[["02", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "EVAL_FALSE"], +[["0100", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "EVAL_FALSE"], +[["", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "OK"], +[["00", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "OK"], +[["01", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +[["02", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["0100", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "OK"], +[["00", "645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS", "UNBALANCED_CONDITIONAL"], +[["645168", 0.00000001], "", "0 0x20 0xf913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"], + + + +["P2SH-P2WSH IF 1 ENDIF"], +[["01", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "OK"], +[["02", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "OK"], +[["0100", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "OK"], +[["", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "EVAL_FALSE"], +[["00", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "EVAL_FALSE"], +[["01", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"], +[["02", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["0100", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +[["00", "635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS", "UNBALANCED_CONDITIONAL"], +[["635168", 0.00000001], "0x22 0x0020c7eaf06d5ae01a58e376e126eb1e6fab2036076922b96b2711ffbec1e590665d", "HASH160 0x14 0x9b27ee6d9010c21bf837b334d043be5d150e7ba7 EQUAL", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"], +["P2SH-P2WSH NOTIF 1 ENDIF"], +[["01", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "EVAL_FALSE"], +[["02", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "EVAL_FALSE"], +[["0100", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "EVAL_FALSE"], +[["", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "OK"], +[["00", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "OK"], +[["01", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "EVAL_FALSE"], +[["02", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["0100", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "OK"], +[["00", "645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "MINIMALIF"], +[["645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS", "UNBALANCED_CONDITIONAL"], +[["645168", 0.00000001], "0x22 0x0020f913eacf2e38a5d6fc3a8311d72ae704cb83866350a984dd3e5eb76d2a8c28e8", "HASH160 0x14 0xdbb7d1c0a56b7a9c423300c8cca6e6e065baf1dc EQUAL", "P2SH,WITNESS,MINIMALIF", "UNBALANCED_CONDITIONAL"], + +["NULLFAIL should cover all signatures and signatures only"], +["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG", "OK", "BIP66 and NULLFAIL-compliant"], +["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL", "OK", "BIP66 and NULLFAIL-compliant"], +["1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL", "OK", "BIP66 and NULLFAIL-compliant, not NULLDUMMY-compliant"], +["1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL,NULLDUMMY", "SIG_NULLDUMMY", "BIP66 and NULLFAIL-compliant, not NULLDUMMY-compliant"], +["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0x09 0x300602010102010101", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG", "OK", "BIP66-compliant but not NULLFAIL-compliant"], +["0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0x09 0x300602010102010101", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL", "NULLFAIL", "BIP66-compliant but not NULLFAIL-compliant"], +["0 0x09 0x300602010102010101 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG", "OK", "BIP66-compliant but not NULLFAIL-compliant"], +["0 0x09 0x300602010102010101 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", "0x01 0x14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x01 0x14 CHECKMULTISIG NOT", "DERSIG,NULLFAIL", "NULLFAIL", "BIP66-compliant but not NULLFAIL-compliant"], + ["The End"] ] diff --git a/src/test/data/tt-delin1-out.json b/src/test/data/tt-delin1-out.json new file mode 100644 index 00000000000..712a2c27f8f --- /dev/null +++ b/src/test/data/tt-delin1-out.json @@ -0,0 +1,217 @@ +{ + "txid": "81b2035be1da1abe745c6141174a73d151009ec17b3d5ebffa2e177408c50dfd", + "hash": "81b2035be1da1abe745c6141174a73d151009ec17b3d5ebffa2e177408c50dfd", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "27871a1a27d833e99cd392a502a647beaaeda6da535417501c76312d52235cfd", + "vout": 332, + "scriptSig": { + "asm": "3046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "752f7f69b915637dc1c2f7aed1466ad676f6f3e24cf922809705f664e97ab3c1", + "vout": 1, + "scriptSig": { + "asm": "3044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba[ALL] 027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34", + "hex": "473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34" + }, + "sequence": 4294967295 + }, + { + "txid": "b0ac9cca2e69cd02410e31b1f4402a25758e71abd1ab06c265ef9077dc05d0ed", + "vout": 209, + "scriptSig": { + "asm": "304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "a135eafb595eaf4c1ea59ccb111cdc0eae1b2c979b226a1e5aa8b76fe2d628df", + "vout": 0, + "scriptSig": { + "asm": "3045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374[ALL] 03a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52", + "hex": "483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52" + }, + "sequence": 4294967295 + }, + { + "txid": "a5d6bf53ba21140b8a4d554feb00fe8bb9a62430ff9e4624aa2f58a120232aae", + "vout": 1, + "scriptSig": { + "asm": "3046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "1b299cf14f1a22e81ea56d71b7affbd7cf386807bf2b4d4b79a18a54125accb3", + "vout": 0, + "scriptSig": { + "asm": "3045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967[ALL] 03a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52", + "hex": "483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52" + }, + "sequence": 4294967295 + }, + { + "txid": "071df1cdcb3f0070f9d6af7b0274f02d0be2324a274727cfd288383167531485", + "vout": 21, + "scriptSig": { + "asm": "3045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "b012e500eb7adf7a13ed332dd6ece849f94f7a62bb3eac5babab356d1fc19282", + "vout": 9, + "scriptSig": { + "asm": "304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "58840fee9c833f2f2d40575842f30f4b8d2553094d06ad88b03d06869acf3d88", + "vout": 30, + "scriptSig": { + "asm": "30440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "e69f9cd16946e570a665245354428a3f507ea69f4568b581e4af98edb3db9766", + "vout": 114, + "scriptSig": { + "asm": "304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "595d1257f654ed2cbe5a65421e8aefd2b4d70b5b6c89a03f1d7e518221fc3f02", + "vout": 103, + "scriptSig": { + "asm": "3046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "06fc818f9555a261248ecd7aad0993eafb5a82ceb2b5c87c3ddfb06671c7f816", + "vout": 1, + "scriptSig": { + "asm": "3045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec7669018[ALL] 0234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd", + "hex": "483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd" + }, + "sequence": 4294967295 + }, + { + "txid": "fb416c8155d6bb1d43f9395466ca90a638a7c2dd3ff617aadf3a7ac8f3967b19", + "vout": 0, + "scriptSig": { + "asm": "304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a[ALL] 027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34", + "hex": "49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34" + }, + "sequence": 4294967295 + }, + { + "txid": "3940b9683bd6104ad24c978e640ba4095993cafdb27d2ed91baa27ee61a2d920", + "vout": 221, + "scriptSig": { + "asm": "3045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "711b5714d3b5136147c02194cd95bde94a4648c4263ca6f972d86cd1d579f150", + "vout": 1, + "scriptSig": { + "asm": "3045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba9074[ALL] 0234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd", + "hex": "483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd" + }, + "sequence": 4294967295 + }, + { + "txid": "6364b5c5efe018430789e7fb4e338209546cae5d9c5f5e300aac68155d861b55", + "vout": 27, + "scriptSig": { + "asm": "304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "0bb57f6e38012c86d4c5a28c904f2675082859147921a707d48961015a3e5057", + "vout": 1095, + "scriptSig": { + "asm": "304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "9b34274814a2540bb062107117f8f3e75ef85d953e9372d8261a3e9dfbc1163f", + "vout": 37, + "scriptSig": { + "asm": "3045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "b86b5cc0d8a7374d94e277850b0a249cb26a7b42ddf014f28a49b8859da64241", + "vout": 20, + "scriptSig": { + "asm": "304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "3d0a2353eeec44d3c10aed259038db321912122cd4150048f7bfa4c0ecfee236", + "vout": 242, + "scriptSig": { + "asm": "3046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 1.3782, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o" + ] + } + }, + { + "value": 0.01000001, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 6c772e9cf96371bba3da8cb733da70a2fcf20078 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "1AtWkdmfmYkErU16d3KYykJUbEp9MAj9Sb" + ] + } + } + ], + "hex": "0100000014fd5c23522d31761c50175453daa6edaabe47a602a592d39ce933d8271a1a87274c0100006c493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffc1b37ae964f605978022f94ce2f3f676d66a46d1aef7c2c17d6315b9697f2f75010000006a473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffffedd005dc7790ef65c206abd1ab718e75252a40f4b1310e4102cd692eca9cacb0d10000006b48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffdf28d6e26fb7a85a1e6a229b972c1bae0edc1c11cb9ca51e4caf5e59fbea35a1000000006b483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffffae2a2320a1582faa24469eff3024a6b98bfe00eb4f554d8a0b1421ba53bfd6a5010000006c493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffb3cc5a12548aa1794b4d2bbf076838cfd7fbafb7716da51ee8221a4ff19c291b000000006b483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffff85145367313888d2cf2747274a32e20b2df074027bafd6f970003fcbcdf11d07150000006b483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff8292c11f6d35abab5bac3ebb627a4ff949e8ecd62d33ed137adf7aeb00e512b0090000006b48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff883dcf9a86063db088ad064d0953258d4b0ff3425857402d2f3f839cee0f84581e0000006a4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff6697dbb3ed98afe481b568459fa67e503f8a4254532465a670e54669d19c9fe6720000006a47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff023ffc2182517e1d3fa0896c5b0bd7b4d2ef8a1e42655abe2ced54f657125d59670000006c493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff16f8c77166b0df3d7cc8b5b2ce825afbea9309ad7acd8e2461a255958f81fc06010000006b483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff197b96f3c87a3adfaa17f63fddc2a738a690ca665439f9431dbbd655816c41fb000000006c49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffff20d9a261ee27aa1bd92e7db2fdca935909a40b648e974cd24a10d63b68b94039dd0000006b483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff50f179d5d16cd872f9a63c26c448464ae9bd95cd9421c0476113b5d314571b71010000006b483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff551b865d1568ac0a305e5f9c5dae6c540982334efbe789074318e0efc5b564631b0000006b48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff57503e5a016189d407a721791459280875264f908ca2c5d4862c01386e7fb50b470400006b48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff3f16c1fb9d3e1a26d872933e955df85ee7f3f817711062b00b54a2144827349b250000006b483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff4142a69d85b8498af214f0dd427b6ab29c240a0b8577e2944d37a7d8c05c6bb8140000006b48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff36e2feecc0a4bff7480015d42c12121932db389025ed0ac1d344ecee53230a3df20000006c493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff0260f73608000000001976a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac41420f00000000001976a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac00000000" +} diff --git a/src/test/data/tt-delout1-out.json b/src/test/data/tt-delout1-out.json new file mode 100644 index 00000000000..afc4e95762d --- /dev/null +++ b/src/test/data/tt-delout1-out.json @@ -0,0 +1,213 @@ +{ + "txid": "c46ccd75b5050e942b2e86a3648f843f525fe6fc000bf0534ba5973063354493", + "hash": "c46ccd75b5050e942b2e86a3648f843f525fe6fc000bf0534ba5973063354493", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "27871a1a27d833e99cd392a502a647beaaeda6da535417501c76312d52235cfd", + "vout": 332, + "scriptSig": { + "asm": "3046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "a72ec96bd0d022d1b0c2f9078cdd46b3725b8eecdd001e17b21e3ababad14ecb", + "vout": 0, + "scriptSig": { + "asm": "3046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba[ALL] 03e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505", + "hex": "493046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba012103e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505" + }, + "sequence": 4294967295 + }, + { + "txid": "752f7f69b915637dc1c2f7aed1466ad676f6f3e24cf922809705f664e97ab3c1", + "vout": 1, + "scriptSig": { + "asm": "3044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba[ALL] 027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34", + "hex": "473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34" + }, + "sequence": 4294967295 + }, + { + "txid": "b0ac9cca2e69cd02410e31b1f4402a25758e71abd1ab06c265ef9077dc05d0ed", + "vout": 209, + "scriptSig": { + "asm": "304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "a135eafb595eaf4c1ea59ccb111cdc0eae1b2c979b226a1e5aa8b76fe2d628df", + "vout": 0, + "scriptSig": { + "asm": "3045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374[ALL] 03a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52", + "hex": "483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52" + }, + "sequence": 4294967295 + }, + { + "txid": "a5d6bf53ba21140b8a4d554feb00fe8bb9a62430ff9e4624aa2f58a120232aae", + "vout": 1, + "scriptSig": { + "asm": "3046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "1b299cf14f1a22e81ea56d71b7affbd7cf386807bf2b4d4b79a18a54125accb3", + "vout": 0, + "scriptSig": { + "asm": "3045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967[ALL] 03a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52", + "hex": "483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52" + }, + "sequence": 4294967295 + }, + { + "txid": "071df1cdcb3f0070f9d6af7b0274f02d0be2324a274727cfd288383167531485", + "vout": 21, + "scriptSig": { + "asm": "3045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "b012e500eb7adf7a13ed332dd6ece849f94f7a62bb3eac5babab356d1fc19282", + "vout": 9, + "scriptSig": { + "asm": "304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "58840fee9c833f2f2d40575842f30f4b8d2553094d06ad88b03d06869acf3d88", + "vout": 30, + "scriptSig": { + "asm": "30440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "e69f9cd16946e570a665245354428a3f507ea69f4568b581e4af98edb3db9766", + "vout": 114, + "scriptSig": { + "asm": "304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "595d1257f654ed2cbe5a65421e8aefd2b4d70b5b6c89a03f1d7e518221fc3f02", + "vout": 103, + "scriptSig": { + "asm": "3046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "06fc818f9555a261248ecd7aad0993eafb5a82ceb2b5c87c3ddfb06671c7f816", + "vout": 1, + "scriptSig": { + "asm": "3045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec7669018[ALL] 0234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd", + "hex": "483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd" + }, + "sequence": 4294967295 + }, + { + "txid": "fb416c8155d6bb1d43f9395466ca90a638a7c2dd3ff617aadf3a7ac8f3967b19", + "vout": 0, + "scriptSig": { + "asm": "304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a[ALL] 027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34", + "hex": "49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34" + }, + "sequence": 4294967295 + }, + { + "txid": "3940b9683bd6104ad24c978e640ba4095993cafdb27d2ed91baa27ee61a2d920", + "vout": 221, + "scriptSig": { + "asm": "3045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "711b5714d3b5136147c02194cd95bde94a4648c4263ca6f972d86cd1d579f150", + "vout": 1, + "scriptSig": { + "asm": "3045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba9074[ALL] 0234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd", + "hex": "483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd" + }, + "sequence": 4294967295 + }, + { + "txid": "6364b5c5efe018430789e7fb4e338209546cae5d9c5f5e300aac68155d861b55", + "vout": 27, + "scriptSig": { + "asm": "304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "0bb57f6e38012c86d4c5a28c904f2675082859147921a707d48961015a3e5057", + "vout": 1095, + "scriptSig": { + "asm": "304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "9b34274814a2540bb062107117f8f3e75ef85d953e9372d8261a3e9dfbc1163f", + "vout": 37, + "scriptSig": { + "asm": "3045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "b86b5cc0d8a7374d94e277850b0a249cb26a7b42ddf014f28a49b8859da64241", + "vout": 20, + "scriptSig": { + "asm": "304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "3d0a2353eeec44d3c10aed259038db321912122cd4150048f7bfa4c0ecfee236", + "vout": 242, + "scriptSig": { + "asm": "3046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 1.3782, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o" + ] + } + } + ], + "hex": "0100000015fd5c23522d31761c50175453daa6edaabe47a602a592d39ce933d8271a1a87274c0100006c493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffcb4ed1baba3a1eb2171e00ddec8e5b72b346dd8c07f9c2b0d122d0d06bc92ea7000000006c493046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba012103e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505ffffffffc1b37ae964f605978022f94ce2f3f676d66a46d1aef7c2c17d6315b9697f2f75010000006a473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffffedd005dc7790ef65c206abd1ab718e75252a40f4b1310e4102cd692eca9cacb0d10000006b48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffdf28d6e26fb7a85a1e6a229b972c1bae0edc1c11cb9ca51e4caf5e59fbea35a1000000006b483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffffae2a2320a1582faa24469eff3024a6b98bfe00eb4f554d8a0b1421ba53bfd6a5010000006c493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffb3cc5a12548aa1794b4d2bbf076838cfd7fbafb7716da51ee8221a4ff19c291b000000006b483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffff85145367313888d2cf2747274a32e20b2df074027bafd6f970003fcbcdf11d07150000006b483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff8292c11f6d35abab5bac3ebb627a4ff949e8ecd62d33ed137adf7aeb00e512b0090000006b48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff883dcf9a86063db088ad064d0953258d4b0ff3425857402d2f3f839cee0f84581e0000006a4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff6697dbb3ed98afe481b568459fa67e503f8a4254532465a670e54669d19c9fe6720000006a47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff023ffc2182517e1d3fa0896c5b0bd7b4d2ef8a1e42655abe2ced54f657125d59670000006c493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff16f8c77166b0df3d7cc8b5b2ce825afbea9309ad7acd8e2461a255958f81fc06010000006b483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff197b96f3c87a3adfaa17f63fddc2a738a690ca665439f9431dbbd655816c41fb000000006c49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffff20d9a261ee27aa1bd92e7db2fdca935909a40b648e974cd24a10d63b68b94039dd0000006b483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff50f179d5d16cd872f9a63c26c448464ae9bd95cd9421c0476113b5d314571b71010000006b483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff551b865d1568ac0a305e5f9c5dae6c540982334efbe789074318e0efc5b564631b0000006b48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff57503e5a016189d407a721791459280875264f908ca2c5d4862c01386e7fb50b470400006b48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff3f16c1fb9d3e1a26d872933e955df85ee7f3f817711062b00b54a2144827349b250000006b483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff4142a69d85b8498af214f0dd427b6ab29c240a0b8577e2944d37a7d8c05c6bb8140000006b48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff36e2feecc0a4bff7480015d42c12121932db389025ed0ac1d344ecee53230a3df20000006c493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff0160f73608000000001976a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac00000000" +} diff --git a/src/test/data/tt-locktime317000-out.json b/src/test/data/tt-locktime317000-out.json new file mode 100644 index 00000000000..2b9075f8ace --- /dev/null +++ b/src/test/data/tt-locktime317000-out.json @@ -0,0 +1,226 @@ +{ + "txid": "aded538f642c17e15f4d3306b8be7e1a4d1ae0c4616d641ab51ea09ba65e5cb5", + "hash": "aded538f642c17e15f4d3306b8be7e1a4d1ae0c4616d641ab51ea09ba65e5cb5", + "version": 1, + "locktime": 317000, + "vin": [ + { + "txid": "27871a1a27d833e99cd392a502a647beaaeda6da535417501c76312d52235cfd", + "vout": 332, + "scriptSig": { + "asm": "3046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "a72ec96bd0d022d1b0c2f9078cdd46b3725b8eecdd001e17b21e3ababad14ecb", + "vout": 0, + "scriptSig": { + "asm": "3046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba[ALL] 03e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505", + "hex": "493046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba012103e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505" + }, + "sequence": 4294967295 + }, + { + "txid": "752f7f69b915637dc1c2f7aed1466ad676f6f3e24cf922809705f664e97ab3c1", + "vout": 1, + "scriptSig": { + "asm": "3044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba[ALL] 027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34", + "hex": "473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34" + }, + "sequence": 4294967295 + }, + { + "txid": "b0ac9cca2e69cd02410e31b1f4402a25758e71abd1ab06c265ef9077dc05d0ed", + "vout": 209, + "scriptSig": { + "asm": "304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "a135eafb595eaf4c1ea59ccb111cdc0eae1b2c979b226a1e5aa8b76fe2d628df", + "vout": 0, + "scriptSig": { + "asm": "3045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374[ALL] 03a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52", + "hex": "483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52" + }, + "sequence": 4294967295 + }, + { + "txid": "a5d6bf53ba21140b8a4d554feb00fe8bb9a62430ff9e4624aa2f58a120232aae", + "vout": 1, + "scriptSig": { + "asm": "3046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "1b299cf14f1a22e81ea56d71b7affbd7cf386807bf2b4d4b79a18a54125accb3", + "vout": 0, + "scriptSig": { + "asm": "3045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967[ALL] 03a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52", + "hex": "483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52" + }, + "sequence": 4294967295 + }, + { + "txid": "071df1cdcb3f0070f9d6af7b0274f02d0be2324a274727cfd288383167531485", + "vout": 21, + "scriptSig": { + "asm": "3045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "b012e500eb7adf7a13ed332dd6ece849f94f7a62bb3eac5babab356d1fc19282", + "vout": 9, + "scriptSig": { + "asm": "304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "58840fee9c833f2f2d40575842f30f4b8d2553094d06ad88b03d06869acf3d88", + "vout": 30, + "scriptSig": { + "asm": "30440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "e69f9cd16946e570a665245354428a3f507ea69f4568b581e4af98edb3db9766", + "vout": 114, + "scriptSig": { + "asm": "304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "595d1257f654ed2cbe5a65421e8aefd2b4d70b5b6c89a03f1d7e518221fc3f02", + "vout": 103, + "scriptSig": { + "asm": "3046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "06fc818f9555a261248ecd7aad0993eafb5a82ceb2b5c87c3ddfb06671c7f816", + "vout": 1, + "scriptSig": { + "asm": "3045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec7669018[ALL] 0234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd", + "hex": "483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd" + }, + "sequence": 4294967295 + }, + { + "txid": "fb416c8155d6bb1d43f9395466ca90a638a7c2dd3ff617aadf3a7ac8f3967b19", + "vout": 0, + "scriptSig": { + "asm": "304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a[ALL] 027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34", + "hex": "49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34" + }, + "sequence": 4294967295 + }, + { + "txid": "3940b9683bd6104ad24c978e640ba4095993cafdb27d2ed91baa27ee61a2d920", + "vout": 221, + "scriptSig": { + "asm": "3045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "711b5714d3b5136147c02194cd95bde94a4648c4263ca6f972d86cd1d579f150", + "vout": 1, + "scriptSig": { + "asm": "3045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba9074[ALL] 0234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd", + "hex": "483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd" + }, + "sequence": 4294967295 + }, + { + "txid": "6364b5c5efe018430789e7fb4e338209546cae5d9c5f5e300aac68155d861b55", + "vout": 27, + "scriptSig": { + "asm": "304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "0bb57f6e38012c86d4c5a28c904f2675082859147921a707d48961015a3e5057", + "vout": 1095, + "scriptSig": { + "asm": "304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "9b34274814a2540bb062107117f8f3e75ef85d953e9372d8261a3e9dfbc1163f", + "vout": 37, + "scriptSig": { + "asm": "3045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "b86b5cc0d8a7374d94e277850b0a249cb26a7b42ddf014f28a49b8859da64241", + "vout": 20, + "scriptSig": { + "asm": "304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "3d0a2353eeec44d3c10aed259038db321912122cd4150048f7bfa4c0ecfee236", + "vout": 242, + "scriptSig": { + "asm": "3046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 1.3782, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o" + ] + } + }, + { + "value": 0.01000001, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 6c772e9cf96371bba3da8cb733da70a2fcf20078 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "1AtWkdmfmYkErU16d3KYykJUbEp9MAj9Sb" + ] + } + } + ], + "hex": "0100000015fd5c23522d31761c50175453daa6edaabe47a602a592d39ce933d8271a1a87274c0100006c493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffcb4ed1baba3a1eb2171e00ddec8e5b72b346dd8c07f9c2b0d122d0d06bc92ea7000000006c493046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba012103e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505ffffffffc1b37ae964f605978022f94ce2f3f676d66a46d1aef7c2c17d6315b9697f2f75010000006a473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffffedd005dc7790ef65c206abd1ab718e75252a40f4b1310e4102cd692eca9cacb0d10000006b48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffdf28d6e26fb7a85a1e6a229b972c1bae0edc1c11cb9ca51e4caf5e59fbea35a1000000006b483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffffae2a2320a1582faa24469eff3024a6b98bfe00eb4f554d8a0b1421ba53bfd6a5010000006c493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffb3cc5a12548aa1794b4d2bbf076838cfd7fbafb7716da51ee8221a4ff19c291b000000006b483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffff85145367313888d2cf2747274a32e20b2df074027bafd6f970003fcbcdf11d07150000006b483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff8292c11f6d35abab5bac3ebb627a4ff949e8ecd62d33ed137adf7aeb00e512b0090000006b48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff883dcf9a86063db088ad064d0953258d4b0ff3425857402d2f3f839cee0f84581e0000006a4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff6697dbb3ed98afe481b568459fa67e503f8a4254532465a670e54669d19c9fe6720000006a47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff023ffc2182517e1d3fa0896c5b0bd7b4d2ef8a1e42655abe2ced54f657125d59670000006c493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff16f8c77166b0df3d7cc8b5b2ce825afbea9309ad7acd8e2461a255958f81fc06010000006b483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff197b96f3c87a3adfaa17f63fddc2a738a690ca665439f9431dbbd655816c41fb000000006c49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffff20d9a261ee27aa1bd92e7db2fdca935909a40b648e974cd24a10d63b68b94039dd0000006b483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff50f179d5d16cd872f9a63c26c448464ae9bd95cd9421c0476113b5d314571b71010000006b483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff551b865d1568ac0a305e5f9c5dae6c540982334efbe789074318e0efc5b564631b0000006b48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff57503e5a016189d407a721791459280875264f908ca2c5d4862c01386e7fb50b470400006b48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff3f16c1fb9d3e1a26d872933e955df85ee7f3f817711062b00b54a2144827349b250000006b483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff4142a69d85b8498af214f0dd427b6ab29c240a0b8577e2944d37a7d8c05c6bb8140000006b48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff36e2feecc0a4bff7480015d42c12121932db389025ed0ac1d344ecee53230a3df20000006c493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff0260f73608000000001976a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac41420f00000000001976a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac48d60400" +} diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index f8baee05779..f7d9e1847ff 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -314,5 +314,31 @@ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x21 0xff25429251b5a84f452230a3c75fd886b7fc5a7865ce4a7bb7a9d7c5be6da3dbff", 1000]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"], +["FindAndDelete tests"], +["This is a test of FindAndDelete. The first tx is a spend of normal scriptPubKey and the second tx is a spend of bare P2WSH."], +["The redeemScript/witnessScript is CHECKSIGVERIFY <0x30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01>."], +["The signature is <0x30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01> ,"], +["where the pubkey is obtained through key recovery with sig and the wrong sighash."], +["This is to show that FindAndDelete is applied only to non-segwit scripts"], +["To show that the tests are 'correctly wrong', they should pass by modifying OP_CHECKSIG under interpreter.cpp"], +["by replacing (sigversion == SIGVERSION_BASE) with (sigversion != SIGVERSION_BASE)"], +["Non-segwit: wrong sighash (without FindAndDelete) = 1ba1fe3bc90c5d1265460e684ce6774e324f0fabdf67619eda729e64e8b6bc08"], +[[["f18783ace138abac5d3a7a5cf08e88fe6912f267ef936452e0c27d090621c169", 7000, "HASH160 0x14 0x0c746489e2d83cdbb5b90b432773342ba809c134 EQUAL", 200000]], +"010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f1581b0000b64830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012103b12a1ec8428fc74166926318c15e17408fea82dbb157575e16a8c365f546248f4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01ffffffff0101000000000000000000000000", "P2SH,WITNESS"], +["BIP143: wrong sighash (with FindAndDelete) = 71c9cd9b2869b9c70b01b1f0360c148f42dee72297db312638df136f43311f23"], +[[["f18783ace138abac5d3a7a5cf08e88fe6912f267ef936452e0c27d090621c169", 7500, "0x00 0x20 0x9e1be07558ea5cc8e02ed1d80c0911048afad949affa36d5c3951e3159dbea19", 200000]], +"0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9d7ed6e161f0e255c10bbfcca0128a9e2035c2c8da58899c54d22d3a31afdef4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000", "P2SH,WITNESS"], +["This is multisig version of the FindAndDelete tests"], +["Script is 2 CHECKMULTISIGVERIFY DROP"], +["52af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175"], +["Signature is 0 2 "], +["Should pass by replacing (sigversion == SIGVERSION_BASE) with (sigversion != SIGVERSION_BASE) under OP_CHECKMULTISIG"], +["Non-segwit: wrong sighash (without FindAndDelete) = 4bc6a53e8e16ef508c19e38bba08831daba85228b0211f323d4cb0999cf2a5e8"], +[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7000, "HASH160 0x14 0x5748407f5ca5cdca53ba30b79040260770c9ee1b EQUAL", 200000]], +"01000000019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a662896581b0000fd6f01004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596015221023fd5dd42b44769c5653cbc5947ff30ab8871f240ad0c0e7432aefe84b5b4ff3421039d52178dbde360b83f19cf348deb04fa8360e1bf5634577be8e50fafc2b0e4ef4c9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175ffffffff0101000000000000000000000000", "P2SH,WITNESS"], +["BIP143: wrong sighash (with FindAndDelete) = 17c50ec2181ecdfdc85ca081174b248199ba81fff730794d4f69b8ec031f2dce"], +[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7500, "0x00 0x20 0x9b66c15b4e0b4eb49fa877982cafded24859fe5b0e2dbfbe4f0df1de7743fd52", 200000]], +"010000000001019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a6628964c1d000000ffffffff0101000000000000000007004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c03959601010221023cb6055f4b57a1580c5a753e19610cafaedf7e0ff377731c77837fd666eae1712102c1b1db303ac232ffa8e5e7cc2cf5f96c6e40d3e6914061204c0541cb2043a0969552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596017500000000", "P2SH,WITNESS"], + ["Make diffs cleaner by leaving a comment here without comma at the end"] ] diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index 1ea70135b43..2f299aa5fea 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -487,5 +487,28 @@ [[["6eb98797a21c6c10aa74edf29d618be109f48a8e94c694f3701e08ca69186436", 1, "HASH160 0x14 0x9993a429037b5d912407a71c252019287b8d27a5 EQUAL", 987654321]], "0100000000010136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000023220020a16b5755f7f6f96dbd65f5f0d6ab9418b89af4b1f14a1bb8a09062c35f0dcb54ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac080047304402206ac44d672dac41f9b00e28f4df20c52eeb087207e8d758d76d92c6fab3b73e2b0220367750dbbe19290069cba53d096f44530e4f98acaa594810388cf7409a1870ce01473044022068c7946a43232757cbdf9176f009a928e1cd9a1a8c212f15c1e11ac9f2925d9002205b75f937ff2f9f3c1246e547e54f62e027f64eefa2695578cc6432cdabce271502473044022059ebf56d98010a932cf8ecfec54c48e6139ed6adb0728c09cbe1e4fa0915302e022007cd986c8fa870ff5d2b3a89139c9fe7e499259875357e20fcbb15571c76795403483045022100fbefd94bd0a488d50b79102b5dad4ab6ced30c4069f1eaa69a4b5a763414067e02203156c6a5c9cf88f91265f5a942e96213afae16d83321c8b31bb342142a14d16381483045022100a5263ea0553ba89221984bd7f0b13613db16e7a70c549a86de0cc0444141a407022005c360ef0ae5a5d4f9f2f87a56c1546cc8268cab08c73501d6b3be2e1e1a8a08824730440220525406a1482936d5a21888260dc165497a90a15669636d8edca6b9fe490d309c022032af0c646a34a44d1f4576bf6a4a74b67940f8faa84c7df9abe12a01a11e2b4783cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae00000000", "P2SH,WITNESS"], +["FindAndDelete tests"], +["This is a test of FindAndDelete. The first tx is a spend of normal P2SH and the second tx is a spend of bare P2WSH."], +["The redeemScript/witnessScript is CHECKSIGVERIFY <0x30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01>."], +["The signature is <0x30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01> ,"], +["where the pubkey is obtained through key recovery with sig and correct sighash."], +["This is to show that FindAndDelete is applied only to non-segwit scripts"], +["Non-segwit: correct sighash (with FindAndDelete) = 1ba1fe3bc90c5d1265460e684ce6774e324f0fabdf67619eda729e64e8b6bc08"], +[[["f18783ace138abac5d3a7a5cf08e88fe6912f267ef936452e0c27d090621c169", 7000, "HASH160 0x14 0x0c746489e2d83cdbb5b90b432773342ba809c134 EQUAL", 200000]], +"010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f1581b0000b64830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0121037a3fb04bcdb09eba90f69961ba1692a3528e45e67c85b200df820212d7594d334aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01ffffffff0101000000000000000000000000", "P2SH,WITNESS"], +["BIP143: correct sighash (without FindAndDelete) = 71c9cd9b2869b9c70b01b1f0360c148f42dee72297db312638df136f43311f23"], +[[["f18783ace138abac5d3a7a5cf08e88fe6912f267ef936452e0c27d090621c169", 7500, "0x00 0x20 0x9e1be07558ea5cc8e02ed1d80c0911048afad949affa36d5c3951e3159dbea19", 200000]], +"0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000", "P2SH,WITNESS"], +["This is multisig version of the FindAndDelete tests"], +["Script is 2 CHECKMULTISIGVERIFY DROP"], +["52af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175"], +["Signature is 0 2 "], +["Non-segwit: correct sighash (with FindAndDelete) = 1d50f00ba4db2917b903b0ec5002e017343bb38876398c9510570f5dce099295"], +[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7000, "HASH160 0x14 0x5748407f5ca5cdca53ba30b79040260770c9ee1b EQUAL", 200000]], +"01000000019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a662896581b0000fd6f01004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c03959601522102cd74a2809ffeeed0092bc124fd79836706e41f048db3f6ae9df8708cefb83a1c2102e615999372426e46fd107b76eaf007156a507584aa2cc21de9eee3bdbd26d36c4c9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175ffffffff0101000000000000000000000000", "P2SH,WITNESS"], +["BIP143: correct sighash (without FindAndDelete) = c1628a1e7c67f14ca0c27c06e4fdeec2e6d1a73c7a91d7c046ff83e835aebb72"], +[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7500, "0x00 0x20 0x9b66c15b4e0b4eb49fa877982cafded24859fe5b0e2dbfbe4f0df1de7743fd52", 200000]], +"010000000001019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a6628964c1d000000ffffffff0101000000000000000007004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960101022102966f109c54e85d3aee8321301136cedeb9fc710fdef58a9de8a73942f8e567c021034ffc99dd9a79dd3cb31e2ab3e0b09e0e67db41ac068c625cd1f491576016c84e9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596017500000000", "P2SH,WITNESS"], + ["Make diffs cleaner by leaving a comment here without comma at the end"] ] diff --git a/src/test/data/txcreate1.json b/src/test/data/txcreate1.json new file mode 100644 index 00000000000..567e8026a32 --- /dev/null +++ b/src/test/data/txcreate1.json @@ -0,0 +1,64 @@ +{ + "txid": "f70f0d6c71416ed538e37549f430ab3665fee2437a42f10238c1bd490e782231", + "hash": "f70f0d6c71416ed538e37549f430ab3665fee2437a42f10238c1bd490e782231", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + }, + { + "txid": "bf829c6bcf84579331337659d31f89dfd138f7f7785802d5501c92333145ca7c", + "vout": 18, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + }, + { + "txid": "22a6f904655d53ae2ff70e701a0bbd90aa3975c0f40bfc6cc996a9049e31cdfc", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.18, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o" + ] + } + }, + { + "value": 4.00, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 f2d4db28cad6502226ee484ae24505c2885cb12d OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914f2d4db28cad6502226ee484ae24505c2885cb12d88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "1P8yWvZW8jVihP1bzHeqfE4aoXNX8AVa46" + ] + } + } + ], + "hex": "01000000031f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff7cca453133921c50d5025878f7f738d1df891fd359763331935784cf6b9c82bf1200000000fffffffffccd319e04a996c96cfc0bf4c07539aa90bd0b1a700ef72fae535d6504f9a6220100000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0084d717000000001976a914f2d4db28cad6502226ee484ae24505c2885cb12d88ac00000000" +} diff --git a/src/test/data/txcreate2.json b/src/test/data/txcreate2.json new file mode 100644 index 00000000000..a70c1d302a2 --- /dev/null +++ b/src/test/data/txcreate2.json @@ -0,0 +1,20 @@ +{ + "txid": "cf90229625e9eb10f6be8156bf6aa5ec2eca19a42b1e05c11f3029b560a32e13", + "hash": "cf90229625e9eb10f6be8156bf6aa5ec2eca19a42b1e05c11f3029b560a32e13", + "version": 1, + "locktime": 0, + "vin": [ + ], + "vout": [ + { + "value": 0.00, + "n": 0, + "scriptPubKey": { + "asm": "", + "hex": "", + "type": "nonstandard" + } + } + ], + "hex": "01000000000100000000000000000000000000" +} diff --git a/src/test/data/txcreatedata1.json b/src/test/data/txcreatedata1.json new file mode 100644 index 00000000000..760518d30a9 --- /dev/null +++ b/src/test/data/txcreatedata1.json @@ -0,0 +1,42 @@ +{ + "txid": "07894b4d12fe7853dd911402db1620920d261b9627c447f931417d330c25f06e", + "hash": "07894b4d12fe7853dd911402db1620920d261b9627c447f931417d330c25f06e", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.18, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o" + ] + } + }, + { + "value": 4.00, + "n": 1, + "scriptPubKey": { + "asm": "OP_RETURN 54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e", + "hex": "6a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e", + "type": "nulldata" + } + } + ], + "hex": "01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0084d71700000000526a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e00000000" +} diff --git a/src/test/data/txcreatedata2.json b/src/test/data/txcreatedata2.json new file mode 100644 index 00000000000..56dfe4a1b05 --- /dev/null +++ b/src/test/data/txcreatedata2.json @@ -0,0 +1,42 @@ +{ + "txid": "4ed17118f5e932ba8c75c461787d171bc02a016d8557cb5bcf34cd416c27bb8b", + "hash": "4ed17118f5e932ba8c75c461787d171bc02a016d8557cb5bcf34cd416c27bb8b", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.18, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o" + ] + } + }, + { + "value": 0.00, + "n": 1, + "scriptPubKey": { + "asm": "OP_RETURN 54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e", + "hex": "6a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e", + "type": "nulldata" + } + } + ], + "hex": "01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0000000000000000526a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e00000000" +} diff --git a/src/test/data/txcreatedata_seq0.json b/src/test/data/txcreatedata_seq0.json new file mode 100644 index 00000000000..9bc0ed45936 --- /dev/null +++ b/src/test/data/txcreatedata_seq0.json @@ -0,0 +1,33 @@ +{ + "txid": "71603ccb1cd76d73d76eb6cfd5f0b9df6d65d90d76860ee52cb461c4be7032e8", + "hash": "71603ccb1cd76d73d76eb6cfd5f0b9df6d65d90d76860ee52cb461c4be7032e8", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967293 + } + ], + "vout": [ + { + "value": 0.18, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o" + ] + } + } + ], + "hex": "01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff0180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000" +} diff --git a/src/test/data/txcreatedata_seq1.json b/src/test/data/txcreatedata_seq1.json new file mode 100644 index 00000000000..d323255418d --- /dev/null +++ b/src/test/data/txcreatedata_seq1.json @@ -0,0 +1,42 @@ +{ + "txid": "c4dea671b0d7b48f8ab10bc46650e8329d3c5766931f548f513847a19f5ba75b", + "hash": "c4dea671b0d7b48f8ab10bc46650e8329d3c5766931f548f513847a19f5ba75b", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967293 + }, + { + "txid": "5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 1 + } + ], + "vout": [ + { + "value": 0.18, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o" + ] + } + } + ], + "hex": "01000000021f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff1f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000010000000180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000" +} diff --git a/src/test/data/txcreatesign.json b/src/test/data/txcreatesign.json new file mode 100644 index 00000000000..ff39e71b40c --- /dev/null +++ b/src/test/data/txcreatesign.json @@ -0,0 +1,33 @@ +{ + "txid": "977e7cd286cb72cd470d539ba6cb48400f8f387d97451d45cdb8819437a303af", + "hash": "977e7cd286cb72cd470d539ba6cb48400f8f387d97451d45cdb8819437a303af", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485", + "vout": 0, + "scriptSig": { + "asm": "304502210096a75056c9e2cc62b7214777b3d2a592cfda7092520126d4ebfcd6d590c99bd8022051bb746359cf98c0603f3004477eac68701132380db8facba19c89dc5ab5c5e2[ALL] 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + "hex": "48304502210096a75056c9e2cc62b7214777b3d2a592cfda7092520126d4ebfcd6d590c99bd8022051bb746359cf98c0603f3004477eac68701132380db8facba19c89dc5ab5c5e201410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.001, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 5834479edbbe0539b31ffd3a8f8ebadc2165ed01 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7" + ] + } + } + ], + "hex": "01000000018594c5bdcaec8f06b78b596f31cd292a294fd031e24eec716f43dac91ea7494d000000008b48304502210096a75056c9e2cc62b7214777b3d2a592cfda7092520126d4ebfcd6d590c99bd8022051bb746359cf98c0603f3004477eac68701132380db8facba19c89dc5ab5c5e201410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ffffffff01a0860100000000001976a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac00000000" +} diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp index 82d61209b5e..fa9624f13da 100644 --- a/src/test/hash_tests.cpp +++ b/src/test/hash_tests.cpp @@ -122,6 +122,10 @@ BOOST_AUTO_TEST_CASE(siphash) hasher3.Write(uint64_t(x)|(uint64_t(x+1)<<8)|(uint64_t(x+2)<<16)|(uint64_t(x+3)<<24)| (uint64_t(x+4)<<32)|(uint64_t(x+5)<<40)|(uint64_t(x+6)<<48)|(uint64_t(x+7)<<56)); } + + CHashWriter ss(SER_DISK, CLIENT_VERSION); + ss << CTransaction(); + BOOST_CHECK_EQUAL(SipHashUint256(1, 2, ss.GetHash()), 0x79751e980c2a0a35ULL); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index fd581db52ea..f2bd082cba2 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -181,9 +181,7 @@ void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, // NOTE: These tests rely on CreateNewBlock doing its own self-validation! BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { - // Disable size accounting (CPFP does not support it) - mapArgs["-blockmaxsize"] = strprintf("%u", MAX_BLOCK_SERIALIZED_SIZE); - + // Note that by default, these tests run with size accounting enabled. const CChainParams& chainparams = Params(CBaseChainParams::MAIN); CScript scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; CBlockTemplate *pblocktemplate; @@ -215,6 +213,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) txCoinbase.vin[0].scriptSig = CScript(); txCoinbase.vin[0].scriptSig.push_back(blockinfo[i].extranonce); txCoinbase.vin[0].scriptSig.push_back(chainActive.Height()); + txCoinbase.vout.resize(1); // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this) txCoinbase.vout[0].scriptPubKey = CScript(); pblock->vtx[0] = CTransaction(txCoinbase); if (txFirst.size() == 0) @@ -224,7 +223,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) pblock->hashMerkleRoot = BlockMerkleRoot(*pblock); pblock->nNonce = blockinfo[i].nonce; CValidationState state; - BOOST_CHECK(ProcessNewBlock(state, chainparams, NULL, pblock, true, NULL)); + BOOST_CHECK(ProcessNewBlock(state, chainparams, NULL, pblock, true, NULL, false)); BOOST_CHECK(state.IsValid()); pblock->hashPrevBlock = pblock->GetHash(); } diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index d005d6a1633..72bca9bbb8f 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -142,4 +142,26 @@ BOOST_AUTO_TEST_CASE(caddrdb_read_corrupted) BOOST_CHECK(addrman2.size() == 0); } +BOOST_AUTO_TEST_CASE(cnode_simple_test) +{ + SOCKET hSocket = INVALID_SOCKET; + + in_addr ipv4Addr; + ipv4Addr.s_addr = 0xa0b0c001; + + CAddress addr = CAddress(CService(ipv4Addr, 7777), NODE_NETWORK); + std::string pszDest = ""; + bool fInboundIn = false; + + // Test that fFeeler is false by default. + CNode* pnode1 = new CNode(hSocket, addr, pszDest, fInboundIn); + BOOST_CHECK(pnode1->fInbound == false); + BOOST_CHECK(pnode1->fFeeler == false); + + fInboundIn = true; + CNode* pnode2 = new CNode(hSocket, addr, pszDest, fInboundIn); + BOOST_CHECK(pnode2->fInbound == true); + BOOST_CHECK(pnode2->fFeeler == false); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp index 5c902387f12..fa00a1c465f 100644 --- a/src/test/policyestimator_tests.cpp +++ b/src/test/policyestimator_tests.cpp @@ -105,19 +105,26 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) // Highest feerate is 10*baseRate and gets in all blocks, // second highest feerate is 9*baseRate and gets in 9/10 blocks = 90%, // third highest feerate is 8*base rate, and gets in 8/10 blocks = 80%, - // so estimateFee(1) should return 10*baseRate. + // so estimateFee(1) would return 10*baseRate but is hardcoded to return failure // Second highest feerate has 100% chance of being included by 2 blocks, // so estimateFee(2) should return 9*baseRate etc... for (int i = 1; i < 10;i++) { origFeeEst.push_back(mpool.estimateFee(i).GetFeePerK()); origPriEst.push_back(mpool.estimatePriority(i)); if (i > 1) { // Fee estimates should be monotonically decreasing - BOOST_CHECK(origFeeEst[i-1] <= origFeeEst[i-2]); + if (i > 2) { + BOOST_CHECK(origFeeEst[i-1] <= origFeeEst[i-2]); + } BOOST_CHECK(origPriEst[i-1] <= origPriEst[i-2]); } int mult = 11-i; - BOOST_CHECK(origFeeEst[i-1] < mult*baseRate.GetFeePerK() + deltaFee); - BOOST_CHECK(origFeeEst[i-1] > mult*baseRate.GetFeePerK() - deltaFee); + if (i > 1) { + BOOST_CHECK(origFeeEst[i-1] < mult*baseRate.GetFeePerK() + deltaFee); + BOOST_CHECK(origFeeEst[i-1] > mult*baseRate.GetFeePerK() - deltaFee); + } + else { + BOOST_CHECK(origFeeEst[i-1] == CFeeRate(0).GetFeePerK()); + } BOOST_CHECK(origPriEst[i-1] < pow(10,mult) * basepri + deltaPri); BOOST_CHECK(origPriEst[i-1] > pow(10,mult) * basepri - deltaPri); } @@ -127,9 +134,12 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) while (blocknum < 250) mpool.removeForBlock(block, ++blocknum, dummyConflicted); + BOOST_CHECK(mpool.estimateFee(1) == CFeeRate(0)); for (int i = 1; i < 10;i++) { - BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() < origFeeEst[i-1] + deltaFee); - BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee); + if (i > 1) { + BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() < origFeeEst[i-1] + deltaFee); + BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee); + } BOOST_CHECK(mpool.estimatePriority(i) < origPriEst[i-1] + deltaPri); BOOST_CHECK(mpool.estimatePriority(i) > origPriEst[i-1] - deltaPri); } @@ -169,8 +179,10 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) } mpool.removeForBlock(block, 265, dummyConflicted); block.clear(); + BOOST_CHECK(mpool.estimateFee(1) == CFeeRate(0)); for (int i = 1; i < 10;i++) { - BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee); + if (i > 1) + BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee); BOOST_CHECK(mpool.estimatePriority(i) > origPriEst[i-1] - deltaPri); } @@ -190,8 +202,10 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) mpool.removeForBlock(block, ++blocknum, dummyConflicted); block.clear(); } + BOOST_CHECK(mpool.estimateFee(1) == CFeeRate(0)); for (int i = 1; i < 10; i++) { - BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() < origFeeEst[i-1] - deltaFee); + if (i > 1) + BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() < origFeeEst[i-1] - deltaFee); BOOST_CHECK(mpool.estimatePriority(i) < origPriEst[i-1] - deltaPri); } diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index 5224b57ca44..1a01593a8e1 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -107,18 +107,20 @@ BOOST_AUTO_TEST_CASE(sign) } // All of the above should be OK, and the txTos have valid signatures // Check to make sure signature verification fails if we use the wrong ScriptSig: - for (int i = 0; i < 8; i++) + for (int i = 0; i < 8; i++) { + PrecomputedTransactionData txdata(txTo[i]); for (int j = 0; j < 8; j++) { CScript sigSave = txTo[i].vin[0].scriptSig; txTo[i].vin[0].scriptSig = txTo[j].vin[0].scriptSig; - bool sigOK = CScriptCheck(CCoins(txFrom, 0), txTo[i], 0, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, false)(); + bool sigOK = CScriptCheck(CCoins(txFrom, 0), txTo[i], 0, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, false, &txdata)(); if (i == j) BOOST_CHECK_MESSAGE(sigOK, strprintf("VerifySignature %d %d", i, j)); else BOOST_CHECK_MESSAGE(!sigOK, strprintf("VerifySignature %d %d", i, j)); txTo[i].vin[0].scriptSig = sigSave; } + } } BOOST_AUTO_TEST_CASE(norecurse) diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 5a9aaf9bc07..532921a7224 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -89,6 +89,8 @@ static ScriptErrorDesc script_errors[]={ {SCRIPT_ERR_SIG_NULLDUMMY, "SIG_NULLDUMMY"}, {SCRIPT_ERR_PUBKEYTYPE, "PUBKEYTYPE"}, {SCRIPT_ERR_CLEANSTACK, "CLEANSTACK"}, + {SCRIPT_ERR_MINIMALIF, "MINIMALIF"}, + {SCRIPT_ERR_SIG_NULLFAIL, "NULLFAIL"}, {SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS, "DISCOURAGE_UPGRADABLE_NOPS"}, {SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM, "DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"}, {SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH, "WITNESS_PROGRAM_WRONG_LENGTH"}, @@ -97,6 +99,7 @@ static ScriptErrorDesc script_errors[]={ {SCRIPT_ERR_WITNESS_MALLEATED, "WITNESS_MALLEATED"}, {SCRIPT_ERR_WITNESS_MALLEATED_P2SH, "WITNESS_MALLEATED_P2SH"}, {SCRIPT_ERR_WITNESS_UNEXPECTED, "WITNESS_UNEXPECTED"}, + {SCRIPT_ERR_WITNESS_PUBKEYTYPE, "WITNESS_PUBKEYTYPE"}, }; const char *FormatScriptError(ScriptError_t err) @@ -823,6 +826,99 @@ BOOST_AUTO_TEST_CASE(script_build) "P2PK with witness", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH ).PushSig(keys.key0).Push("0").AsWit().ScriptError(SCRIPT_ERR_WITNESS_UNEXPECTED)); + // Compressed keys should pass SCRIPT_VERIFY_WITNESS_PUBKEYTYPE + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG, + "Basic P2WSH with compressed key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, + 0, 1).PushWitSig(keys.key0C).PushWitRedeem()); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C), + "Basic P2WPKH with compressed key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_PKH, + 0, 1).PushWitSig(keys.key0C).Push(keys.pubkey0C).AsWit()); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG, + "Basic P2SH(P2WSH) with compressed key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, + 0, 1).PushWitSig(keys.key0C).PushWitRedeem().PushRedeem()); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C), + "Basic P2SH(P2WPKH) with compressed key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_PKH, + 0, 1).PushWitSig(keys.key0C).Push(keys.pubkey0C).AsWit().PushRedeem()); + + // Testing uncompressed key in witness with SCRIPT_VERIFY_WITNESS_PUBKEYTYPE + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "Basic P2WSH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, + 0, 1).PushWitSig(keys.key0).PushWitRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), + "Basic P2WPKH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_PKH, + 0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "Basic P2SH(P2WSH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, + 0, 1).PushWitSig(keys.key0).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); + tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0), + "Basic P2SH(P2WPKH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_PKH, + 0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); + + // P2WSH 1-of-2 multisig with compressed keys + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2WSH CHECKMULTISIG with compressed keys", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2SH(P2WSH) CHECKMULTISIG with compressed keys", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem().PushRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2WSH CHECKMULTISIG with compressed keys", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2SH(P2WSH) CHECKMULTISIG with compressed keys", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().PushRedeem()); + + // P2WSH 1-of-2 multisig with first key uncompressed + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, + "P2WSH CHECKMULTISIG with first key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, + "P2SH(P2WSH) CHECKMULTISIG first key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem().PushRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, + "P2WSH CHECKMULTISIG with first key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, + "P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, + "P2WSH CHECKMULTISIG with first key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, + "P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().PushRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, + "P2WSH CHECKMULTISIG with first key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG, + "P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); + // P2WSH 1-of-2 multisig with second key uncompressed + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2WSH CHECKMULTISIG with second key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2SH(P2WSH) CHECKMULTISIG second key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem().PushRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2WSH CHECKMULTISIG with second key uncompressed and signing with the first key should pass as the uncompressed key is not used", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the first key should pass as the uncompressed key is not used", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem().PushRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2WSH CHECKMULTISIG with second key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem().PushRedeem()); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2WSH CHECKMULTISIG with second key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG, + "P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WITNESS_SH, + 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE)); + std::set tests_set; { diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 856f9b84230..09f9a362d02 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -60,6 +60,11 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha pcoinsdbview = new CCoinsViewDB(1 << 23, true); pcoinsTip = new CCoinsViewCache(pcoinsdbview); InitBlockIndex(chainparams); + { + CValidationState state; + bool ok = ActivateBestChain(state, chainparams); + BOOST_CHECK(ok); + } nScriptCheckThreads = 3; for (int i=0; i < nScriptCheckThreads-1; i++) threadGroup.create_thread(&ThreadScriptCheck); @@ -113,7 +118,7 @@ TestChain100Setup::CreateAndProcessBlock(const std::vector& while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce; CValidationState state; - ProcessNewBlock(state, chainparams, NULL, &block, true, NULL); + ProcessNewBlock(state, chainparams, NULL, &block, true, NULL, false); CBlock result = block; delete pblocktemplate; diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index fd4f174b40c..34d9547f3dc 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2015 The Bitcoin Core developers +// Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -7,6 +7,7 @@ #include "test/test_bitcoin.h" #include "clientversion.h" +#include "checkqueue.h" #include "consensus/validation.h" #include "core_io.h" #include "key.h" @@ -49,10 +50,13 @@ static std::map mapFlagNames = boost::assign::map_list_of (string("NULLDUMMY"), (unsigned int)SCRIPT_VERIFY_NULLDUMMY) (string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) (string("CLEANSTACK"), (unsigned int)SCRIPT_VERIFY_CLEANSTACK) + (string("MINIMALIF"), (unsigned int)SCRIPT_VERIFY_MINIMALIF) + (string("NULLFAIL"), (unsigned int)SCRIPT_VERIFY_NULLFAIL) (string("CHECKLOCKTIMEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY) (string("CHECKSEQUENCEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKSEQUENCEVERIFY) (string("WITNESS"), (unsigned int)SCRIPT_VERIFY_WITNESS) - (string("DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM); + (string("DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM) + (string("WITNESS_PUBKEYTYPE"), (unsigned int)SCRIPT_VERIFY_WITNESS_PUBKEYTYPE); unsigned int ParseScriptFlags(string strFlags) { @@ -153,6 +157,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) BOOST_CHECK_MESSAGE(CheckTransaction(tx, state), strTest); BOOST_CHECK(state.IsValid()); + PrecomputedTransactionData txdata(tx); for (unsigned int i = 0; i < tx.vin.size(); i++) { if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout)) @@ -168,7 +173,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); const CScriptWitness *witness = (i < tx.wit.vtxinwit.size()) ? &tx.wit.vtxinwit[i].scriptWitness : NULL; BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - witness, verify_flags, TransactionSignatureChecker(&tx, i, amount), &err), + witness, verify_flags, TransactionSignatureChecker(&tx, i, amount, txdata), &err), strTest); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } @@ -237,6 +242,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) CValidationState state; fValid = CheckTransaction(tx, state) && state.IsValid(); + PrecomputedTransactionData txdata(tx); for (unsigned int i = 0; i < tx.vin.size() && fValid; i++) { if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout)) @@ -252,7 +258,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) } const CScriptWitness *witness = (i < tx.wit.vtxinwit.size()) ? &tx.wit.vtxinwit[i].scriptWitness : NULL; fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - witness, verify_flags, TransactionSignatureChecker(&tx, i, amount), &err); + witness, verify_flags, TransactionSignatureChecker(&tx, i, amount, txdata), &err); } BOOST_CHECK_MESSAGE(!fValid, strTest); BOOST_CHECK_MESSAGE(err != SCRIPT_ERR_OK, ScriptErrorString(err)); @@ -419,6 +425,86 @@ void ReplaceRedeemScript(CScript& script, const CScript& redeemScript) script = PushAll(stack); } +BOOST_AUTO_TEST_CASE(test_big_witness_transaction) { + CMutableTransaction mtx; + mtx.nVersion = 1; + + CKey key; + key.MakeNewKey(true); // Need to use compressed keys in segwit or the signing will fail + CBasicKeyStore keystore; + keystore.AddKeyPubKey(key, key.GetPubKey()); + CKeyID hash = key.GetPubKey().GetID(); + CScript scriptPubKey = CScript() << OP_0 << std::vector(hash.begin(), hash.end()); + + vector sigHashes; + sigHashes.push_back(SIGHASH_NONE | SIGHASH_ANYONECANPAY); + sigHashes.push_back(SIGHASH_SINGLE | SIGHASH_ANYONECANPAY); + sigHashes.push_back(SIGHASH_ALL | SIGHASH_ANYONECANPAY); + sigHashes.push_back(SIGHASH_NONE); + sigHashes.push_back(SIGHASH_SINGLE); + sigHashes.push_back(SIGHASH_ALL); + + // create a big transaction of 4500 inputs signed by the same key + for(uint32_t ij = 0; ij < 4500; ij++) { + uint32_t i = mtx.vin.size(); + uint256 prevId; + prevId.SetHex("0000000000000000000000000000000000000000000000000000000000000100"); + COutPoint outpoint(prevId, i); + + mtx.vin.resize(mtx.vin.size() + 1); + mtx.vin[i].prevout = outpoint; + mtx.vin[i].scriptSig = CScript(); + + mtx.vout.resize(mtx.vout.size() + 1); + mtx.vout[i].nValue = 1000; + mtx.vout[i].scriptPubKey = CScript() << OP_1; + } + + // sign all inputs + for(uint32_t i = 0; i < mtx.vin.size(); i++) { + bool hashSigned = SignSignature(keystore, scriptPubKey, mtx, i, 1000, sigHashes.at(i % sigHashes.size())); + assert(hashSigned); + } + + CTransaction tx; + CDataStream ssout(SER_NETWORK, PROTOCOL_VERSION); + WithOrVersion(&ssout, 0) << mtx; + WithOrVersion(&ssout, 0) >> tx; + + // check all inputs concurrently, with the cache + PrecomputedTransactionData txdata(tx); + boost::thread_group threadGroup; + CCheckQueue scriptcheckqueue(128); + CCheckQueueControl control(&scriptcheckqueue); + + for (int i=0; i<20; i++) + threadGroup.create_thread(boost::bind(&CCheckQueue::Thread, boost::ref(scriptcheckqueue))); + + CCoins coins; + coins.nVersion = 1; + coins.fCoinBase = false; + for(uint32_t i = 0; i < mtx.vin.size(); i++) { + CTxOut txout; + txout.nValue = 1000; + txout.scriptPubKey = scriptPubKey; + coins.vout.push_back(txout); + } + + for(uint32_t i = 0; i < mtx.vin.size(); i++) { + std::vector vChecks; + CScriptCheck check(coins, tx, i, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false, &txdata); + vChecks.push_back(CScriptCheck()); + check.swap(vChecks.back()); + control.Add(vChecks); + } + + bool controlCheck = control.Wait(); + assert(controlCheck); + + threadGroup.interrupt_all(); + threadGroup.join_all(); +} + BOOST_AUTO_TEST_CASE(test_witness) { CBasicKeyStore keystore, keystore2; @@ -540,30 +626,13 @@ BOOST_AUTO_TEST_CASE(test_witness) CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false); CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false); - // Witness pay-to-uncompressed-pubkey (v1). - CreateCreditAndSpend(keystore, GetScriptForWitness(scriptPubkey1L), output1, input1); - CreateCreditAndSpend(keystore, GetScriptForWitness(scriptPubkey2L), output2, input2); - CheckWithFlag(output1, input1, 0, true); - CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true); - CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true); - CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); - CheckWithFlag(output1, input2, 0, true); - CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, true); - CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false); - CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false); + // Signing disabled for witness pay-to-uncompressed-pubkey (v1). + CreateCreditAndSpend(keystore, GetScriptForWitness(scriptPubkey1L), output1, input1, false); + CreateCreditAndSpend(keystore, GetScriptForWitness(scriptPubkey2L), output2, input2, false); - // P2SH witness pay-to-uncompressed-pubkey (v1). - CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(GetScriptForWitness(scriptPubkey1L))), output1, input1); - CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(GetScriptForWitness(scriptPubkey2L))), output2, input2); - ReplaceRedeemScript(input2.vin[0].scriptSig, GetScriptForWitness(scriptPubkey1L)); - CheckWithFlag(output1, input1, 0, true); - CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true); - CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true); - CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); - CheckWithFlag(output1, input2, 0, true); - CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, true); - CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false); - CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false); + // Signing disabled for P2SH witness pay-to-uncompressed-pubkey (v1). + CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(GetScriptForWitness(scriptPubkey1L))), output1, input1, false); + CreateCreditAndSpend(keystore, GetScriptForDestination(CScriptID(GetScriptForWitness(scriptPubkey2L))), output2, input2, false); // Normal 2-of-2 multisig CreateCreditAndSpend(keystore, scriptMulti, output1, input1, false); diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 0d6b655675d..261da728a64 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -469,7 +469,7 @@ void TorController::auth_cb(TorControlConnection& conn, const TorControlReply& r // Finally - now create the service if (private_key.empty()) // No private key, generate one - private_key = "NEW:BEST"; + private_key = "NEW:RSA1024"; // Explicitly request RSA1024 - see issue #9214 // Request hidden service, redirect port. // Note that the 'virtual' port doesn't have to be the same as our internal port, but this is just a convenient // choice. TODO; refactor the shutdown sequence some day. diff --git a/src/txmempool.cpp b/src/txmempool.cpp index a48a6d94659..63a26da326e 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -28,7 +28,7 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, hadNoDependencies(poolHasNoInputsOf), inChainInputValue(_inChainInputValue), spendsCoinbase(_spendsCoinbase), sigOpCost(_sigOpsCost), lockPoints(lp) { - nTxCost = GetTransactionCost(_tx); + nTxWeight = GetTransactionWeight(_tx); nModSize = _tx.CalculateModifiedSize(GetTxSize()); nUsageSize = RecursiveDynamicUsage(*tx) + memusage::DynamicUsage(tx); @@ -75,7 +75,7 @@ void CTxMemPoolEntry::UpdateLockPoints(const LockPoints& lp) size_t CTxMemPoolEntry::GetTxSize() const { - return GetVirtualTransactionSize(nTxCost); + return GetVirtualTransactionSize(nTxWeight, sigOpCost); } // Update the given tx for any in-mempool descendants. @@ -444,7 +444,7 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, totalTxSize += entry.GetTxSize(); minerPolicyEstimator->processTransaction(entry, fCurrentEstimate); - vTxHashes.emplace_back(hash, newit); + vTxHashes.emplace_back(tx.GetWitnessHash(), newit); newit->vTxHashesIdx = vTxHashes.size() - 1; return true; @@ -737,7 +737,8 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const waitingOnDependants.push_back(&(*it)); else { CValidationState state; - assert(CheckInputs(tx, state, mempoolDuplicate, false, 0, false, NULL)); + PrecomputedTransactionData txdata(tx); + assert(CheckInputs(tx, state, mempoolDuplicate, false, 0, false, txdata, NULL)); UpdateCoins(tx, mempoolDuplicate, 1000000); } } @@ -751,7 +752,8 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const stepsSinceLastRemove++; assert(stepsSinceLastRemove < waitingOnDependants.size()); } else { - assert(CheckInputs(entry->GetTx(), state, mempoolDuplicate, false, 0, false, NULL)); + PrecomputedTransactionData txdata(entry->GetTx()); + assert(CheckInputs(entry->GetTx(), state, mempoolDuplicate, false, 0, false, txdata, NULL)); UpdateCoins(entry->GetTx(), mempoolDuplicate, 1000000); stepsSinceLastRemove = 0; } @@ -1132,3 +1134,10 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector* pvNoSpendsRe if (maxFeeRateRemoved > CFeeRate(0)) LogPrint("mempool", "Removed %u txn, rolling minimum fee bumped to %s\n", nTxnRemoved, maxFeeRateRemoved.ToString()); } + +bool CTxMemPool::TransactionWithinChainLimit(const uint256& txid, size_t chainLimit) const { + LOCK(cs); + auto it = mapTx.find(txid); + return it == mapTx.end() || (it->GetCountWithAncestors() < chainLimit && + it->GetCountWithDescendants() < chainLimit); +} diff --git a/src/txmempool.h b/src/txmempool.h index e5a500e19d4..8129a05375f 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -78,7 +78,7 @@ class CTxMemPoolEntry private: std::shared_ptr tx; CAmount nFee; //!< Cached to avoid expensive parent-transaction lookups - size_t nTxCost; //!< ... and avoid recomputing tx cost (also used for GetTxSize()) + size_t nTxWeight; //!< ... and avoid recomputing tx weight (also used for GetTxSize()) size_t nModSize; //!< ... and modified size for priority size_t nUsageSize; //!< ... and total memory usage int64_t nTime; //!< Local time when entering the mempool @@ -122,7 +122,7 @@ class CTxMemPoolEntry double GetPriority(unsigned int currentHeight) const; const CAmount& GetFee() const { return nFee; } size_t GetTxSize() const; - size_t GetTxCost() const { return nTxCost; } + size_t GetTxWeight() const { return nTxWeight; } int64_t GetTime() const { return nTime; } unsigned int GetHeight() const { return entryHeight; } bool WasClearAtEntry() const { return hadNoDependencies; } @@ -462,7 +462,7 @@ class CTxMemPool indexed_transaction_set mapTx; typedef indexed_transaction_set::nth_index<0>::type::iterator txiter; - std::vector > vTxHashes; //!< All tx hashes/entries in mapTx, in random order + std::vector > vTxHashes; //!< All tx witness hashes/entries in mapTx, in random order struct CompareIteratorByHash { bool operator()(const txiter &a, const txiter &b) const { @@ -595,6 +595,9 @@ class CTxMemPool /** Expire all transaction (and their dependencies) in the mempool older than time. Return the number of removed transactions. */ int Expire(int64_t time); + /** Returns false if the transaction is in the mempool and not within the chain limit specified. */ + bool TransactionWithinChainLimit(const uint256& txid, size_t chainLimit) const; + unsigned long size() { LOCK(cs); diff --git a/src/util.cpp b/src/util.cpp index 9a9209c6214..ee12f2b4434 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -801,11 +801,10 @@ int GetNumCores() std::string CopyrightHolders(const std::string& strPrefix) { - std::string strCopyrightHolders = strPrefix + _(COPYRIGHT_HOLDERS); - if (strCopyrightHolders.find("%s") != strCopyrightHolders.npos) { - strCopyrightHolders = strprintf(strCopyrightHolders, _(COPYRIGHT_HOLDERS_SUBSTITUTION)); - } - if (strCopyrightHolders.find("Bitcoin Core developers") == strCopyrightHolders.npos) { + std::string strCopyrightHolders = strPrefix + strprintf(_(COPYRIGHT_HOLDERS), _(COPYRIGHT_HOLDERS_SUBSTITUTION)); + + // Check for untranslated substitution to make sure Bitcoin Core copyright is not removed by accident + if (strprintf(COPYRIGHT_HOLDERS, COPYRIGHT_HOLDERS_SUBSTITUTION).find("Bitcoin Core") == std::string::npos) { strCopyrightHolders += "\n" + strPrefix + "The Bitcoin Core developers"; } return strCopyrightHolders; diff --git a/src/version.h b/src/version.h index 68ccd6d3783..497f82be235 100644 --- a/src/version.h +++ b/src/version.h @@ -9,7 +9,7 @@ * network protocol versioning */ -static const int PROTOCOL_VERSION = 70014; +static const int PROTOCOL_VERSION = 70015; //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209; @@ -42,4 +42,7 @@ static const int FEEFILTER_VERSION = 70013; //! shord-id-based block download starts with this version static const int SHORT_IDS_BLOCKS_VERSION = 70014; +//! not banning for invalid compact blocks starts with this version +static const int INVALID_CB_NO_BAN_VERSION = 70015; + #endif // BITCOIN_VERSION_H diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index c906785e9e2..236c1d3246f 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -43,7 +43,7 @@ void CDBEnv::EnvShutdown() if (ret != 0) LogPrintf("CDBEnv::EnvShutdown: Error %d shutting down database environment: %s\n", ret, DbEnv::strerror(ret)); if (!fMockDb) - DbEnv(0).remove(strPath.c_str(), 0); + DbEnv((u_int32_t)0).remove(strPath.c_str(), 0); } void CDBEnv::Reset() @@ -284,7 +284,7 @@ CDB::CDB(const std::string& strFilename, const char* pszMode, bool fFlushOnClose pdb = NULL; --bitdb.mapFileUseCount[strFile]; strFile = ""; - throw runtime_error(strprintf("CDB: Error %d, can't open database %s", ret, strFile)); + throw runtime_error(strprintf("CDB: Error %d, can't open database %s", ret, strFilename)); } if (fCreate && !Exists(string("version"))) { diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index d55cc68dc03..34b8c1fb793 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -257,6 +257,7 @@ UniValue importprunedfunds(const UniValue& params, bool fHelp) if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; + // 0.13.x: Silently accept up to 3 params, but ignore the third: if (fHelp || params.size() < 2 || params.size() > 3) throw runtime_error( "importprunedfunds\n" @@ -264,7 +265,6 @@ UniValue importprunedfunds(const UniValue& params, bool fHelp) "\nArguments:\n" "1. \"rawtransaction\" (string, required) A raw transaction in hex funding an already-existing address in wallet\n" "2. \"txoutproof\" (string, required) The hex output from gettxoutproof that contains the transaction\n" - "3. \"label\" (string, optional) An optional label\n" ); CTransaction tx; @@ -277,10 +277,6 @@ UniValue importprunedfunds(const UniValue& params, bool fHelp) CMerkleBlock merkleBlock; ssMB >> merkleBlock; - string strLabel = ""; - if (params.size() == 3) - strLabel = params[2].get_str(); - //Search partial merkle tree in proof for our transaction and index in valid block vector vMatch; vector vIndex; @@ -350,8 +346,6 @@ UniValue removeprunedfunds(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction does not exist in wallet."); } - ThreadFlushWalletDB(pwalletMain->strWalletFile); - return NullUniValue; } @@ -602,19 +596,42 @@ UniValue dumpwallet(const UniValue& params, bool fHelp) file << strprintf("# * Best block at time of backup was %i (%s),\n", chainActive.Height(), chainActive.Tip()->GetBlockHash().ToString()); file << strprintf("# mined on %s\n", EncodeDumpTime(chainActive.Tip()->GetBlockTime())); file << "\n"; + + // add the base58check encoded extended master if the wallet uses HD + CKeyID masterKeyID = pwalletMain->GetHDChain().masterKeyID; + if (!masterKeyID.IsNull()) + { + CKey key; + if (pwalletMain->GetKey(masterKeyID, key)) + { + CExtKey masterKey; + masterKey.SetMaster(key.begin(), key.size()); + + CBitcoinExtKey b58extkey; + b58extkey.SetKey(masterKey); + + file << "# extended private masterkey: " << b58extkey.ToString() << "\n\n"; + } + } for (std::vector >::const_iterator it = vKeyBirth.begin(); it != vKeyBirth.end(); it++) { const CKeyID &keyid = it->second; std::string strTime = EncodeDumpTime(it->first); std::string strAddr = CBitcoinAddress(keyid).ToString(); CKey key; if (pwalletMain->GetKey(keyid, key)) { + file << strprintf("%s %s ", CBitcoinSecret(key).ToString(), strTime); if (pwalletMain->mapAddressBook.count(keyid)) { - file << strprintf("%s %s label=%s # addr=%s\n", CBitcoinSecret(key).ToString(), strTime, EncodeDumpString(pwalletMain->mapAddressBook[keyid].name), strAddr); + file << strprintf("label=%s", EncodeDumpString(pwalletMain->mapAddressBook[keyid].name)); + } else if (keyid == masterKeyID) { + file << "hdmaster=1"; } else if (setKeyPool.count(keyid)) { - file << strprintf("%s %s reserve=1 # addr=%s\n", CBitcoinSecret(key).ToString(), strTime, strAddr); + file << "reserve=1"; + } else if (pwalletMain->mapKeyMetadata[keyid].hdKeypath == "m") { + file << "inactivehdmaster=1"; } else { - file << strprintf("%s %s change=1 # addr=%s\n", CBitcoinSecret(key).ToString(), strTime, strAddr); + file << "change=1"; } + file << strprintf(" # addr=%s%s\n", strAddr, (pwalletMain->mapKeyMetadata[keyid].hdKeypath.size() > 0 ? " hdkeypath="+pwalletMain->mapKeyMetadata[keyid].hdKeypath : "")); } } file << "\n"; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index b4831ad7950..17bda050c35 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin Core developers +// Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -1020,9 +1020,12 @@ class Witnessifier : public boost::static_visitor bool operator()(const CKeyID &keyID) { CPubKey pubkey; - if (pwalletMain && pwalletMain->GetPubKey(keyID, pubkey)) { - CScript basescript; - basescript << ToByteVector(pubkey) << OP_CHECKSIG; + if (pwalletMain) { + CScript basescript = GetScriptForDestination(keyID); + isminetype typ; + typ = IsMine(*pwalletMain, basescript, SIGVERSION_WITNESS_V0); + if (typ != ISMINE_SPENDABLE && typ != ISMINE_WATCH_SOLVABLE) + return false; CScript witscript = GetScriptForWitness(basescript); pwalletMain->AddCScript(witscript); result = CScriptID(witscript); @@ -1040,6 +1043,10 @@ class Witnessifier : public boost::static_visitor result = scriptID; return true; } + isminetype typ; + typ = IsMine(*pwalletMain, subscript, SIGVERSION_WITNESS_V0); + if (typ != ISMINE_SPENDABLE && typ != ISMINE_WATCH_SOLVABLE) + return false; CScript witscript = GetScriptForWitness(subscript); pwalletMain->AddCScript(witscript); result = CScriptID(witscript); @@ -1085,9 +1092,11 @@ UniValue addwitnessaddress(const UniValue& params, bool fHelp) CTxDestination dest = address.Get(); bool ret = boost::apply_visitor(w, dest); if (!ret) { - throw JSONRPCError(RPC_WALLET_ERROR, "Public key or redeemscript not known to wallet"); + throw JSONRPCError(RPC_WALLET_ERROR, "Public key or redeemscript not known to wallet, or the key is uncompressed"); } + pwalletMain->SetAddressBook(w.result, "", "receive"); + return CBitcoinAddress(w.result).ToString(); } @@ -1771,7 +1780,7 @@ UniValue gettransaction(const UniValue& params, bool fHelp) ListTransactions(wtx, "*", 0, false, details, filter); entry.push_back(Pair("details", details)); - string strHex = EncodeHexTx(static_cast(wtx)); + string strHex = EncodeHexTx(static_cast(wtx), RPCSerializationFlags()); entry.push_back(Pair("hex", strHex)); return entry; @@ -2081,7 +2090,7 @@ UniValue encryptwallet(const UniValue& params, bool fHelp) // slack space in .dat files; that is bad if the old data is // unencrypted private keys. So: StartShutdown(); - return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet. The keypool has been flushed, you need to make a new backup."; + return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet. The keypool has been flushed and a new HD seed was generated (if you are using HD). You need to make a new backup."; } UniValue lockunspent(const UniValue& params, bool fHelp) @@ -2260,16 +2269,16 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) "Returns an object containing various wallet state info.\n" "\nResult:\n" "{\n" - " \"walletversion\": xxxxx, (numeric) the wallet version\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 " + CURRENCY_UNIT + "/kB\n" - " \"masterkeyid\": \"\", (string) the Hash160 of the HD master pubkey\n" + " \"walletversion\": xxxxx, (numeric) the wallet version\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 Unix 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 " + CURRENCY_UNIT + "/kB\n" + " \"hdmasterkeyid\": \"\", (string) the Hash160 of the HD master pubkey\n" "}\n" "\nExamples:\n" + HelpExampleCli("getwalletinfo", "") @@ -2291,7 +2300,7 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK()))); CKeyID masterKeyID = pwalletMain->GetHDChain().masterKeyID; if (!masterKeyID.IsNull()) - obj.push_back(Pair("masterkeyid", masterKeyID.GetHex())); + obj.push_back(Pair("hdmasterkeyid", masterKeyID.GetHex())); return obj; } diff --git a/src/wallet/test/crypto_tests.cpp b/src/wallet/test/crypto_tests.cpp index 05387f5f2b5..b235b96095c 100644 --- a/src/wallet/test/crypto_tests.cpp +++ b/src/wallet/test/crypto_tests.cpp @@ -42,15 +42,19 @@ bool OldEncrypt(const CKeyingMaterial& vchPlaintext, std::vector int nCLen = nLen + AES_BLOCK_SIZE, nFLen = 0; vchCiphertext = std::vector (nCLen); - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + + if (!ctx) return false; bool fOk = true; - EVP_CIPHER_CTX_init(&ctx); - if (fOk) fOk = EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0; - if (fOk) fOk = EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen) != 0; - if (fOk) fOk = EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0]) + nCLen, &nFLen) != 0; - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_init(ctx); + if (fOk) fOk = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0; + if (fOk) fOk = EVP_EncryptUpdate(ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen) != 0; + if (fOk) fOk = EVP_EncryptFinal_ex(ctx, (&vchCiphertext[0]) + nCLen, &nFLen) != 0; + EVP_CIPHER_CTX_cleanup(ctx); + + EVP_CIPHER_CTX_free(ctx); if (!fOk) return false; @@ -66,15 +70,19 @@ bool OldDecrypt(const std::vector& vchCiphertext, CKeyingMaterial vchPlaintext = CKeyingMaterial(nPLen); - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + + if (!ctx) return false; bool fOk = true; - EVP_CIPHER_CTX_init(&ctx); - if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0; - if (fOk) fOk = EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen) != 0; - if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0]) + nPLen, &nFLen) != 0; - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_init(ctx); + if (fOk) fOk = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0; + if (fOk) fOk = EVP_DecryptUpdate(ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen) != 0; + if (fOk) fOk = EVP_DecryptFinal_ex(ctx, (&vchPlaintext[0]) + nPLen, &nFLen) != 0; + EVP_CIPHER_CTX_cleanup(ctx); + + EVP_CIPHER_CTX_free(ctx); if (!fOk) return false; diff --git a/src/wallet/test/wallet_test_fixture.cpp b/src/wallet/test/wallet_test_fixture.cpp index 9036ee26d83..a76db376179 100644 --- a/src/wallet/test/wallet_test_fixture.cpp +++ b/src/wallet/test/wallet_test_fixture.cpp @@ -1,3 +1,7 @@ +// Copyright (c) 2016 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 "wallet/test/wallet_test_fixture.h" #include "rpc/server.h" diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index c6c5058984c..38637b2d5c1 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -78,24 +78,24 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) empty_wallet(); // with an empty wallet we can't even pay one cent - BOOST_CHECK(!wallet.SelectCoinsMinConf( 1 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf( 1 * CENT, 1, 6, 0, vCoins, setCoinsRet, nValueRet)); add_coin(1*CENT, 4); // add a new 1 cent coin // with a new 1 cent coin, we still can't find a mature 1 cent - BOOST_CHECK(!wallet.SelectCoinsMinConf( 1 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf( 1 * CENT, 1, 6, 0, vCoins, setCoinsRet, nValueRet)); // but we can find a new 1 cent - BOOST_CHECK( wallet.SelectCoinsMinConf( 1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf( 1 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); add_coin(2*CENT); // add a mature 2 cent coin // we can't make 3 cents of mature coins - BOOST_CHECK(!wallet.SelectCoinsMinConf( 3 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf( 3 * CENT, 1, 6, 0, vCoins, setCoinsRet, nValueRet)); // we can make 3 cents of new coins - BOOST_CHECK( wallet.SelectCoinsMinConf( 3 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf( 3 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 3 * CENT); add_coin(5*CENT); // add a mature 5 cent coin, @@ -105,33 +105,33 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // now we have new: 1+10=11 (of which 10 was self-sent), and mature: 2+5+20=27. total = 38 // we can't make 38 cents only if we disallow new coins: - BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT, 1, 6, 0, vCoins, setCoinsRet, nValueRet)); // we can't even make 37 cents if we don't allow new coins even if they're from us - BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT, 6, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT, 6, 6, 0, vCoins, setCoinsRet, nValueRet)); // but we can make 37 cents if we accept new coins from ourself - BOOST_CHECK( wallet.SelectCoinsMinConf(37 * CENT, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(37 * CENT, 1, 6, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 37 * CENT); // and we can make 38 cents if we accept all new coins - BOOST_CHECK( wallet.SelectCoinsMinConf(38 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(38 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 38 * CENT); // try making 34 cents from 1,2,5,10,20 - we can't do it exactly - BOOST_CHECK( wallet.SelectCoinsMinConf(34 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(34 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 35 * CENT); // but 35 cents is closest BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // the best should be 20+10+5. it's incredibly unlikely the 1 or 2 got included (but possible) // when we try making 7 cents, the smaller coins (1,2,5) are enough. We should see just 2+5 - BOOST_CHECK( wallet.SelectCoinsMinConf( 7 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf( 7 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 7 * CENT); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); // when we try making 8 cents, the smaller coins (1,2,5) are exactly enough. - BOOST_CHECK( wallet.SelectCoinsMinConf( 8 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf( 8 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK(nValueRet == 8 * CENT); BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // when we try making 9 cents, no subset of smaller coins is enough, and we get the next bigger coin (10) - BOOST_CHECK( wallet.SelectCoinsMinConf( 9 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf( 9 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 10 * CENT); BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); @@ -145,30 +145,30 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin(30*CENT); // now we have 6+7+8+20+30 = 71 cents total // check that we have 71 and not 72 - BOOST_CHECK( wallet.SelectCoinsMinConf(71 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK(!wallet.SelectCoinsMinConf(72 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(71 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf(72 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); // now try making 16 cents. the best smaller coins can do is 6+7+8 = 21; not as good at the next biggest coin, 20 - BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 20 * CENT); // we should get 20 in one coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); add_coin( 5*CENT); // now we have 5+6+7+8+20+30 = 75 cents total // now if we try making 16 cents again, the smaller coins can make 5+6+7 = 18 cents, better than the next biggest coin, 20 - BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 18 * CENT); // we should get 18 in 3 coins BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); add_coin( 18*CENT); // now we have 5+6+7+8+18+20+30 // and now if we try making 16 cents again, the smaller coins can make 5+6+7 = 18 cents, the same as the next biggest coin, 18 - BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 18 * CENT); // we should get 18 in 1 coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); // because in the event of a tie, the biggest coin wins // now try making 11 cents. we should get 5+6 - BOOST_CHECK( wallet.SelectCoinsMinConf(11 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(11 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 11 * CENT); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); @@ -177,11 +177,11 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin( 2*COIN); add_coin( 3*COIN); add_coin( 4*COIN); // now we have 5+6+7+8+18+20+30+100+200+300+400 = 1094 cents - BOOST_CHECK( wallet.SelectCoinsMinConf(95 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(95 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1 * COIN); // we should get 1 BTC in 1 coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); - BOOST_CHECK( wallet.SelectCoinsMinConf(195 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(195 * CENT, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 2 * COIN); // we should get 2 BTC in 1 coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); @@ -196,14 +196,14 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // try making 1 * MIN_CHANGE from the 1.5 * MIN_CHANGE // we'll get change smaller than MIN_CHANGE whatever happens, so can expect MIN_CHANGE exactly - BOOST_CHECK( wallet.SelectCoinsMinConf(MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(MIN_CHANGE, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE); // but if we add a bigger coin, small change is avoided add_coin(1111*MIN_CHANGE); // try making 1 from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 + 1111 = 1112.5 - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1 * MIN_CHANGE); // we should get the exact amount // if we add more small coins: @@ -211,7 +211,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin(MIN_CHANGE * 7 / 10); // and try again to make 1.0 * MIN_CHANGE - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1 * MIN_CHANGE); // we should get the exact amount // run the 'mtgox' test (see http://blockexplorer.com/tx/29a3efd3ef04f9153d47a990bd7b048a4b2d213daaa5fb8ed670fb85f13bdbcf) @@ -220,7 +220,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) for (int i = 0; i < 20; i++) add_coin(50000 * COIN); - BOOST_CHECK( wallet.SelectCoinsMinConf(500000 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(500000 * COIN, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 500000 * COIN); // we should get the exact amount BOOST_CHECK_EQUAL(setCoinsRet.size(), 10U); // in ten coins @@ -233,7 +233,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin(MIN_CHANGE * 6 / 10); add_coin(MIN_CHANGE * 7 / 10); add_coin(1111 * MIN_CHANGE); - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1111 * MIN_CHANGE); // we get the bigger coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); @@ -243,7 +243,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin(MIN_CHANGE * 6 / 10); add_coin(MIN_CHANGE * 8 / 10); add_coin(1111 * MIN_CHANGE); - BOOST_CHECK( wallet.SelectCoinsMinConf(MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK( wallet.SelectCoinsMinConf(MIN_CHANGE, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE); // we should get the exact amount BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); // in two coins 0.4+0.6 @@ -254,12 +254,12 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin(MIN_CHANGE * 100); // trying to make 100.01 from these three coins - BOOST_CHECK(wallet.SelectCoinsMinConf(MIN_CHANGE * 10001 / 100, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(MIN_CHANGE * 10001 / 100, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE * 10105 / 100); // we should get all coins BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // but if we try to make 99.9, we should take the bigger of the two small coins to avoid small change - BOOST_CHECK(wallet.SelectCoinsMinConf(MIN_CHANGE * 9990 / 100, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(MIN_CHANGE * 9990 / 100, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 101 * MIN_CHANGE); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); @@ -269,7 +269,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // Create 676 inputs (= MAX_STANDARD_TX_SIZE / 148 bytes per input) for (uint16_t j = 0; j < 676; j++) add_coin(amt); - BOOST_CHECK(wallet.SelectCoinsMinConf(2000, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(2000, 1, 1, 0, vCoins, setCoinsRet, nValueRet)); if (amt - 2000 < MIN_CHANGE) { // needs more than one input: uint16_t returnSize = std::ceil((2000.0 + MIN_CHANGE)/amt); @@ -291,8 +291,8 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // picking 50 from 100 coins doesn't depend on the shuffle, // but does depend on randomness in the stochastic approximation code - BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, vCoins, setCoinsRet , nValueRet)); - BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, vCoins, setCoinsRet2, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, 0, vCoins, setCoinsRet , nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, 0, vCoins, setCoinsRet2, nValueRet)); BOOST_CHECK(!equal_sets(setCoinsRet, setCoinsRet2)); int fails = 0; @@ -300,8 +300,8 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) { // selecting 1 from 100 identical coins depends on the shuffle; this test will fail 1% of the time // run the test RANDOM_REPEATS times and only complain if all of them fail - BOOST_CHECK(wallet.SelectCoinsMinConf(COIN, 1, 6, vCoins, setCoinsRet , nValueRet)); - BOOST_CHECK(wallet.SelectCoinsMinConf(COIN, 1, 6, vCoins, setCoinsRet2, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(COIN, 1, 6, 0, vCoins, setCoinsRet , nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(COIN, 1, 6, 0, vCoins, setCoinsRet2, nValueRet)); if (equal_sets(setCoinsRet, setCoinsRet2)) fails++; } @@ -321,8 +321,8 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) { // selecting 1 from 100 identical coins depends on the shuffle; this test will fail 1% of the time // run the test RANDOM_REPEATS times and only complain if all of them fail - BOOST_CHECK(wallet.SelectCoinsMinConf(90*CENT, 1, 6, vCoins, setCoinsRet , nValueRet)); - BOOST_CHECK(wallet.SelectCoinsMinConf(90*CENT, 1, 6, vCoins, setCoinsRet2, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(90*CENT, 1, 6, 0, vCoins, setCoinsRet , nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(90*CENT, 1, 6, 0, vCoins, setCoinsRet2, nValueRet)); if (equal_sets(setCoinsRet, setCoinsRet2)) fails++; } @@ -346,7 +346,7 @@ BOOST_AUTO_TEST_CASE(ApproximateBestSubset) add_coin(1000 * COIN); add_coin(3 * COIN); - BOOST_CHECK(wallet.SelectCoinsMinConf(1003 * COIN, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(1003 * COIN, 1, 6, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1003 * COIN); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 46ed5421581..7bcb9aaf11f 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -108,7 +108,7 @@ CPubKey CWallet::GenerateNewKey() // try to get the master key if (!GetKey(hdChain.masterKeyID, key)) - throw std::runtime_error("CWallet::GenerateNewKey(): Master key not found"); + throw std::runtime_error(std::string(__func__) + ": Master key not found"); masterKey.SetMaster(key.begin(), key.size()); @@ -135,7 +135,7 @@ CPubKey CWallet::GenerateNewKey() // update the chain model in the database if (!CWalletDB(strWalletFile).WriteHDChain(hdChain)) - throw std::runtime_error("CWallet::GenerateNewKey(): Writing HD chain model failed"); + throw std::runtime_error(std::string(__func__) + ": Writing HD chain model failed"); } else { secret.MakeNewKey(fCompressed); } @@ -152,7 +152,7 @@ CPubKey CWallet::GenerateNewKey() nTimeFirstKey = nCreationTime; if (!AddKeyPubKey(secret, pubkey)) - throw std::runtime_error("CWallet::GenerateNewKey(): AddKey failed"); + throw std::runtime_error(std::string(__func__) + ": AddKey failed"); return pubkey; } @@ -626,6 +626,15 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) Lock(); Unlock(strWalletPassphrase); + + // if we are using HD, replace the HD master key (seed) with a new one + if (!hdChain.masterKeyID.IsNull()) { + CKey key; + CPubKey masterPubKey = GenerateNewHDMasterKey(); + if (!SetHDMasterKey(masterPubKey)) + return false; + } + NewKeyPool(); Lock(); @@ -1084,7 +1093,7 @@ isminetype CWallet::IsMine(const CTxOut& txout) const CAmount CWallet::GetCredit(const CTxOut& txout, const isminefilter& filter) const { if (!MoneyRange(txout.nValue)) - throw std::runtime_error("CWallet::GetCredit(): value out of range"); + throw std::runtime_error(std::string(__func__) + ": value out of range"); return ((IsMine(txout) & filter) ? txout.nValue : 0); } @@ -1113,7 +1122,7 @@ bool CWallet::IsChange(const CTxOut& txout) const CAmount CWallet::GetChange(const CTxOut& txout) const { if (!MoneyRange(txout.nValue)) - throw std::runtime_error("CWallet::GetChange(): value out of range"); + throw std::runtime_error(std::string(__func__) + ": value out of range"); return (IsChange(txout) ? txout.nValue : 0); } @@ -1137,7 +1146,7 @@ CAmount CWallet::GetDebit(const CTransaction& tx, const isminefilter& filter) co { nDebit += GetDebit(txin, filter); if (!MoneyRange(nDebit)) - throw std::runtime_error("CWallet::GetDebit(): value out of range"); + throw std::runtime_error(std::string(__func__) + ": value out of range"); } return nDebit; } @@ -1149,7 +1158,7 @@ CAmount CWallet::GetCredit(const CTransaction& tx, const isminefilter& filter) c { nCredit += GetCredit(txout, filter); if (!MoneyRange(nCredit)) - throw std::runtime_error("CWallet::GetCredit(): value out of range"); + throw std::runtime_error(std::string(__func__) + ": value out of range"); } return nCredit; } @@ -1161,21 +1170,47 @@ CAmount CWallet::GetChange(const CTransaction& tx) const { nChange += GetChange(txout); if (!MoneyRange(nChange)) - throw std::runtime_error("CWallet::GetChange(): value out of range"); + throw std::runtime_error(std::string(__func__) + ": value out of range"); } return nChange; } -bool CWallet::SetHDMasterKey(const CKey& key) +CPubKey CWallet::GenerateNewHDMasterKey() { - LOCK(cs_wallet); + CKey key; + key.MakeNewKey(true); + + int64_t nCreationTime = GetTime(); + CKeyMetadata metadata(nCreationTime); - // store the key as normal "key"/"ckey" object - // in the database - // key metadata is not required + // calculate the pubkey CPubKey pubkey = key.GetPubKey(); - if (!AddKeyPubKey(key, pubkey)) - throw std::runtime_error("CWallet::GenerateNewKey(): AddKey failed"); + assert(key.VerifyPubKey(pubkey)); + + // set the hd keypath to "m" -> Master, refers the masterkeyid to itself + metadata.hdKeypath = "m"; + metadata.hdMasterKeyID = pubkey.GetID(); + + { + LOCK(cs_wallet); + + // mem store the metadata + mapKeyMetadata[pubkey.GetID()] = metadata; + + // write the key&metadata to the database + if (!AddKeyPubKey(key, pubkey)) + throw std::runtime_error(std::string(__func__) + ": AddKeyPubKey failed"); + } + + return pubkey; +} + +bool CWallet::SetHDMasterKey(const CPubKey& pubkey) +{ + LOCK(cs_wallet); + + // ensure this wallet.dat can only be opened by clients supporting HD + SetMinVersion(FEATURE_HD); // store the keyid (hash160) together with // the child index counter in the database @@ -1191,7 +1226,7 @@ bool CWallet::SetHDChain(const CHDChain& chain, bool memonly) { LOCK(cs_wallet); if (!memonly && !CWalletDB(strWalletFile).WriteHDChain(chain)) - throw runtime_error("AddHDChain(): writing chain failed"); + throw runtime_error(std::string(__func__) + ": writing chain failed"); hdChain = chain; return true; @@ -1407,16 +1442,19 @@ void CWallet::ReacceptWalletTransactions() CWalletTx& wtx = *(item.second); LOCK(mempool.cs); - wtx.AcceptToMemoryPool(false, maxTxFee); + CValidationState state; + wtx.AcceptToMemoryPool(false, maxTxFee, state); } } bool CWalletTx::RelayWalletTransaction() { assert(pwallet->GetBroadcastTransactions()); - if (!IsCoinBase()) + if (!IsCoinBase() && !isAbandoned() && GetDepthInMainChain() == 0) { - if (GetDepthInMainChain() == 0 && !isAbandoned() && InMempool()) { + CValidationState state; + /* GetDepthInMainChain already catches known conflicts. */ + if (InMempool() || AcceptToMemoryPool(false, maxTxFee, state)) { LogPrintf("Relaying wtx %s\n", GetHash().ToString()); RelayTransaction((CTransaction)*this); return true; @@ -1883,7 +1921,7 @@ static void ApproximateBestSubset(vector vCoins, +bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const int nConfMine, const int nConfTheirs, const uint64_t nMaxAncestors, vector vCoins, set >& setCoinsRet, CAmount& nValueRet) const { setCoinsRet.clear(); @@ -1908,6 +1946,9 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int if (output.nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? nConfMine : nConfTheirs)) continue; + if (!mempool.TransactionWithinChainLimit(pcoin->GetHash(), nMaxAncestors)) + continue; + int i = output.i; CAmount n = pcoin->vout[i].nValue; @@ -2033,10 +2074,17 @@ bool CWallet::SelectCoins(const vector& vAvailableCoins, const CAmount& ++it; } + size_t nMaxChainLength = std::min(GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT), GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT)); + bool fRejectLongChains = GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS); + bool res = nTargetValue <= nValueFromPresetInputs || - SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 6, vCoins, setCoinsRet, nValueRet) || - SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 1, vCoins, setCoinsRet, nValueRet) || - (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, vCoins, setCoinsRet, nValueRet)); + SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 6, 0, vCoins, setCoinsRet, nValueRet) || + SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 1, 0, vCoins, setCoinsRet, nValueRet) || + (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, 2, vCoins, setCoinsRet, nValueRet)) || + (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, std::min((size_t)4, nMaxChainLength/3), vCoins, setCoinsRet, nValueRet)) || + (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, nMaxChainLength/2, vCoins, setCoinsRet, nValueRet)) || + (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, nMaxChainLength, vCoins, setCoinsRet, nValueRet)) || + (bSpendZeroConfChange && !fRejectLongChains && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, std::numeric_limits::max(), vCoins, setCoinsRet, nValueRet)); // because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset setCoinsRet.insert(setPresetCoins.begin(), setPresetCoins.end()); @@ -2167,6 +2215,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt nChangePosInOut = nChangePosRequest; txNew.vin.clear(); txNew.vout.clear(); + txNew.wit.SetNull(); wtxNew.fFromMe = true; bool fFirst = true; @@ -2254,7 +2303,11 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt CPubKey vchPubKey; bool ret; ret = reservekey.GetReservedKey(vchPubKey); - assert(ret); // should never fail, as we just unlocked + if (!ret) + { + strFailReason = _("Keypool ran out, please call keypoolrefill first"); + return false; + } scriptChange = GetScriptForDestination(vchPubKey.GetID()); } @@ -2356,7 +2409,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt *static_cast(&wtxNew) = CTransaction(txNew); // Limit size - if (GetTransactionCost(txNew) >= MAX_STANDARD_TX_COST) + if (GetTransactionWeight(txNew) >= MAX_STANDARD_TX_WEIGHT) { strFailReason = _("Transaction too large"); return false; @@ -2399,6 +2452,21 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt } } + if (GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) { + // Lastly, ensure this tx will pass the mempool's chain limits + LockPoints lp; + CTxMemPoolEntry entry(txNew, 0, 0, 0, 0, false, 0, false, 0, lp); + 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 (!mempool.CalculateMemPoolAncestors(entry, setAncestors, nLimitAncestors, nLimitAncestorSize, nLimitDescendants, nLimitDescendantSize, errString)) { + strFailReason = _("Transaction has too long of a mempool chain"); + return false; + } + } return true; } @@ -2441,14 +2509,14 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) if (fBroadcastTransactions) { + CValidationState state; // Broadcast - if (!wtxNew.AcceptToMemoryPool(false, maxTxFee)) - { - // This must not fail. The transaction has already been signed and recorded. - LogPrintf("CommitTransaction(): Error: Transaction not valid\n"); - return false; + if (!wtxNew.AcceptToMemoryPool(false, maxTxFee, state)) { + LogPrintf("CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", state.GetRejectReason()); + // TODO: if we expect the failure to be long term or permanent, instead delete wtx from the wallet and return failure. + } else { + wtxNew.RelayWalletTransaction(); } - wtxNew.RelayWalletTransaction(); } } return true; @@ -2678,7 +2746,7 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize) if (!setKeyPool.empty()) nEnd = *(--setKeyPool.end()) + 1; if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey()))) - throw runtime_error("TopUpKeyPool(): writing generated key failed"); + throw runtime_error(std::string(__func__) + ": writing generated key failed"); setKeyPool.insert(nEnd); LogPrintf("keypool added key %d, size=%u\n", nEnd, setKeyPool.size()); } @@ -2705,9 +2773,9 @@ void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool) nIndex = *(setKeyPool.begin()); setKeyPool.erase(setKeyPool.begin()); if (!walletdb.ReadPool(nIndex, keypool)) - throw runtime_error("ReserveKeyFromKeyPool(): read failed"); + throw runtime_error(std::string(__func__) + ": read failed"); if (!HaveKey(keypool.vchPubKey.GetID())) - throw runtime_error("ReserveKeyFromKeyPool(): unknown key in key pool"); + throw runtime_error(std::string(__func__) + ": unknown key in key pool"); assert(keypool.vchPubKey.IsValid()); LogPrintf("keypool reserve %d\n", nIndex); } @@ -2766,7 +2834,7 @@ int64_t CWallet::GetOldestKeyPoolTime() CWalletDB walletdb(strWalletFile); int64_t nIndex = *(setKeyPool.begin()); if (!walletdb.ReadPool(nIndex, keypool)) - throw runtime_error("GetOldestKeyPoolTime(): read oldest key in keypool failed"); + throw runtime_error(std::string(__func__) + ": read oldest key in keypool failed"); assert(keypool.vchPubKey.IsValid()); return keypool.nTime; } @@ -2993,11 +3061,11 @@ void CWallet::GetAllReserveKeys(set& setAddress) const { CKeyPool keypool; if (!walletdb.ReadPool(id, keypool)) - throw runtime_error("GetAllReserveKeyHashes(): read failed"); + throw runtime_error(std::string(__func__) + ": read failed"); assert(keypool.vchPubKey.IsValid()); CKeyID keyID = keypool.vchPubKey.GetID(); if (!HaveKey(keyID)) - throw runtime_error("GetAllReserveKeyHashes(): unknown key in key pool"); + throw runtime_error(std::string(__func__) + ": unknown key in key pool"); setAddress.insert(keyID); } } @@ -3104,7 +3172,7 @@ void CWallet::GetKeyBirthTimes(std::map &mapKeyBirth) const { mapKeyBirth[it->first] = it->second.nCreateTime; // map in which we'll infer heights of other keys - CBlockIndex *pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganised; use a 144-block safety margin + CBlockIndex *pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganized; use a 144-block safety margin std::map mapKeyFirstBlock; std::set setKeys; GetKeys(setKeys); @@ -3220,6 +3288,7 @@ std::string CWallet::GetWalletHelpString(bool showDebug) strUsage += HelpMessageOpt("-dblogsize=", strprintf("Flush wallet database activity from memory to disk log every megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE)); strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", DEFAULT_FLUSHWALLET)); strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", DEFAULT_WALLET_PRIVDB)); + strUsage += HelpMessageOpt("-walletrejectlongchains", strprintf(_("Wallet will not create transactions that violate mempool chain limits (default: %u"), DEFAULT_WALLET_REJECT_LONG_CHAINS)); } return strUsage; @@ -3295,10 +3364,9 @@ bool CWallet::InitLoadWallet() // Create new keyUser and set as default key if (GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET) && walletInstance->hdChain.masterKeyID.IsNull()) { // generate a new master key - CKey key; - key.MakeNewKey(true); - if (!walletInstance->SetHDMasterKey(key)) - throw std::runtime_error("CWallet::GenerateNewKey(): Storing master key failed"); + CPubKey masterPubKey = walletInstance->GenerateNewHDMasterKey(); + if (!walletInstance->SetHDMasterKey(masterPubKey)) + throw std::runtime_error(std::string(__func__) + ": Storing master key failed"); } CPubKey newDefaultKey; if (walletInstance->GetKeyFromPool(newDefaultKey)) { @@ -3555,8 +3623,7 @@ int CMerkleTx::GetBlocksToMaturity() const } -bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, CAmount nAbsurdFee) +bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, CAmount nAbsurdFee, CValidationState& state) { - CValidationState state; return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, false, nAbsurdFee); } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index e9d669a7d1e..10f6ea8fed8 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -51,6 +51,8 @@ static const CAmount MIN_CHANGE = CENT; static const bool DEFAULT_SPEND_ZEROCONF_CHANGE = true; //! Default for -sendfreetransactions static const bool DEFAULT_SEND_FREE_TRANSACTIONS = false; +//! Default for -walletrejectlongchains +static const bool DEFAULT_WALLET_REJECT_LONG_CHAINS = false; //! -txconfirmtarget default static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 2; //! Largest (in bytes) free transaction we're willing to create @@ -78,7 +80,8 @@ enum WalletFeature FEATURE_WALLETCRYPT = 40000, // wallet encryption FEATURE_COMPRPUBKEY = 60000, // compressed public keys - FEATURE_LATEST = 60000 + FEATURE_HD = 130000, // Hierarchical key derivation after BIP32 (HD Wallet) + FEATURE_LATEST = FEATURE_COMPRPUBKEY // HD is optional, use FEATURE_COMPRPUBKEY as latest version }; @@ -212,7 +215,7 @@ class CMerkleTx : public CTransaction bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet) > 0; } int GetBlocksToMaturity() const; /** Pass this transaction to the mempool. Fails if absolute fee exceeds absurd fee. */ - bool AcceptToMemoryPool(bool fLimitFree, const CAmount nAbsurdFee); + bool AcceptToMemoryPool(bool fLimitFree, const CAmount nAbsurdFee, CValidationState& state); bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); } bool isAbandoned() const { return (hashBlock == ABANDON_HASH); } void setAbandoned() { hashBlock = ABANDON_HASH; } @@ -667,7 +670,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface * completion the coin set and corresponding actual target value is * assembled */ - bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, std::vector vCoins, std::set >& setCoinsRet, CAmount& nValueRet) const; + bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, uint64_t nMaxAncestors, std::vector vCoins, std::set >& setCoinsRet, CAmount& nValueRet) const; bool IsSpent(const uint256& hash, unsigned int n) const; @@ -898,10 +901,13 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface /* Set the HD chain model (chain child index counters) */ bool SetHDChain(const CHDChain& chain, bool memonly); + const CHDChain& GetHDChain() { return hdChain; } + /* Generates a new HD master key (will not be activated) */ + CPubKey GenerateNewHDMasterKey(); + /* Set the current HD master key (will reset the chain child index counters) */ - bool SetHDMasterKey(const CKey& key); - const CHDChain& GetHDChain() { return hdChain; } + bool SetHDMasterKey(const CPubKey& key); }; /** A key allocated from the key pool. */ diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 72af8ab7b25..31aec0f9e53 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -215,7 +215,7 @@ void CWalletDB::ListAccountCreditDebit(const string& strAccount, listclose(); - throw runtime_error("CWalletDB::ListAccountCreditDebit(): error scanning DB"); + throw runtime_error(std::string(__func__) + ": error scanning DB"); } // Unserialize diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index b6c907980f0..cdef17e08c8 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -6,6 +6,7 @@ #include "zmqpublishnotifier.h" #include "main.h" #include "util.h" +#include "rpc/server.h" static std::multimap mapPublishNotifiers; @@ -165,7 +166,7 @@ bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) LogPrint("zmq", "zmq: Publish rawblock %s\n", pindex->GetBlockHash().GetHex()); const Consensus::Params& consensusParams = Params().GetConsensus(); - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); { LOCK(cs_main); CBlock block; @@ -185,7 +186,7 @@ bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &tr { uint256 hash = transaction.GetHash(); LogPrint("zmq", "zmq: Publish rawtx %s\n", hash.GetHex()); - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); ss << transaction; return SendMessage(MSG_RAWTX, &(*ss.begin()), ss.size()); } diff --git a/src/zmq/zmqpublishnotifier.h b/src/zmq/zmqpublishnotifier.h index 22f02a3d0db..751ded39572 100644 --- a/src/zmq/zmqpublishnotifier.h +++ b/src/zmq/zmqpublishnotifier.h @@ -12,7 +12,7 @@ class CBlockIndex; class CZMQAbstractPublishNotifier : public CZMQAbstractNotifier { private: - uint32_t nSequence; //! upcounting per message sequence number + uint32_t nSequence; //!< upcounting per message sequence number public: