diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 47648cde2..fc8d58d97 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -38,7 +38,7 @@ fixes or code moves with actual code changes. Commit messages should be verbose by default consisting of a short subject line (50 chars max), a blank line and detailed explanatory text as separate paragraph(s); unless the title alone is self-explanatory (like "Corrected typo -in main.cpp") then a single title line is sufficient. Commit messages should be +in init.cpp") then a single title line is sufficient. Commit messages should be helpful to people reading your code in the future, so explain the reasoning for your decisions. Further explanation [here](http://chris.beams.io/posts/git-commit/). @@ -79,7 +79,7 @@ Examples: Consensus: Add new opcode for BIP-XXXX OP_CHECKAWESOMESIG Net: Automatically create hidden service, listen on Tor Qt: Add feed bump button - Trivial: Fix typo in main.cpp + Trivial: Fix typo in init.cpp If a pull request is specifically not to be considered for merging (yet) please prefix the title with [WIP] or use [Tasks Lists](https://help.github.com/articles/basic-writing-and-formatting-syntax/#task-lists) @@ -194,7 +194,7 @@ request. Typically reviewers will review the code for obvious errors, as well as test out the patch set and opine on the technical merits of the patch. Project maintainers take into account the peer review when determining if there is consensus to merge a pull request (remember that discussions may have been -spread out over github, mailing list and IRC discussions). The following +spread out over GitHub, mailing list and IRC discussions). The following language is used within pull-request comments: - ACK means "I have tested the code and I agree it should be merged"; diff --git a/Makefile.am b/Makefile.am index 6a8c1b761..1ee2dfb73 100644 --- a/Makefile.am +++ b/Makefile.am @@ -227,9 +227,6 @@ EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.py qa/rpc- CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER) -# This file is problematic for out-of-tree builds if it exists. -DISTCLEANFILES = qa/pull-tester/tests_config.pyc - .INTERMEDIATE: $(COVERAGE_INFO) DISTCHECK_CONFIGURE_FLAGS = --enable-man diff --git a/configure.ac b/configure.ac index 346695043..78129fb20 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) -define(_CLIENT_VERSION_MINOR, 13) +define(_CLIENT_VERSION_MINOR, 14) define(_CLIENT_VERSION_REVISION, 99) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, false) @@ -1087,7 +1087,7 @@ AC_SUBST(ZMQ_LIBS) AC_SUBST(PROTOBUF_LIBS) AC_SUBST(QR_LIBS) AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile share/setup.nsi share/qt/Info.plist src/test/buildenv.py]) -AC_CONFIG_FILES([qa/pull-tester/tests_config.py],[chmod +x qa/pull-tester/tests_config.py]) +AC_CONFIG_FILES([qa/pull-tester/tests_config.ini],[chmod +x qa/pull-tester/tests_config.ini]) AC_CONFIG_FILES([contrib/devtools/split-debug.sh],[chmod +x contrib/devtools/split-debug.sh]) AC_CONFIG_LINKS([qa/pull-tester/rpc-tests.py:qa/pull-tester/rpc-tests.py]) diff --git a/contrib/README.md b/contrib/README.md index 4ea9700f5..6f750106e 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -3,7 +3,7 @@ Repository Tools ### [Developer tools](/contrib/devtools) ### Specific tools for developers working on this repository. -Contains the script `github-merge.py` for merging github pull requests securely and signing them using GPG. +Contains the script `github-merge.py` for merging GitHub pull requests securely and signing them using GPG. ### [Verify-Commits](/contrib/verify-commits) ### Tool to verify that every merge commit was signed by a developer using the above `github-merge.py` script. diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md index 34f2af686..67c5e15a1 100644 --- a/contrib/devtools/README.md +++ b/contrib/devtools/README.md @@ -125,7 +125,7 @@ check or whatever). This means that there are no potential race conditions (where a pullreq gets updated while you're reviewing it, but before you click -merge), and when using GPG signatures, that even a compromised github +merge), and when using GPG signatures, that even a compromised GitHub couldn't mess with the sources. Setup diff --git a/contrib/devtools/update-translations.py b/contrib/devtools/update-translations.py index 78b9f9d17..201184100 100755 --- a/contrib/devtools/update-translations.py +++ b/contrib/devtools/update-translations.py @@ -65,6 +65,14 @@ def split_format_specifiers(specifiers): else: other.append(s) + # If both numeric format specifiers and "others" are used, assume we're dealing + # with a Qt-formatted message. In the case of Qt formatting (see https://doc.qt.io/qt-5/qstring.html#arg) + # only numeric formats are replaced at all. This means "(percentage: %1%)" is valid, without needing + # any kind of escaping that would be necessary for strprintf. Without this, this function + # would wrongly detect '%)' as a printf format specifier. + if numeric: + other = [] + # numeric (Qt) can be present in any order, others (strprintf) must be in specified order return set(numeric),other diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 6f43119ba..00af4bdc6 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -1,5 +1,5 @@ --- -name: "bitcoin-linux-0.13" +name: "bitcoin-linux-0.15" enable_cache: true suites: - "trusty" diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 991976d59..05cc65414 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -1,5 +1,5 @@ --- -name: "bitcoin-osx-0.13" +name: "bitcoin-osx-0.15" enable_cache: true suites: - "trusty" diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index fe01b5b95..6fead7c20 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -1,5 +1,5 @@ --- -name: "bitcoin-win-0.13" +name: "bitcoin-win-0.15" enable_cache: true suites: - "trusty" diff --git a/contrib/zmq/zmq_sub.py b/contrib/zmq/zmq_sub.py index 5707188f2..ea398a27e 100755 --- a/contrib/zmq/zmq_sub.py +++ b/contrib/zmq/zmq_sub.py @@ -1,43 +1,84 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # 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. +""" + ZMQ example using python3's asyncio + + Bitcoin should be started with the command line arguments: + bitcoind -testnet -daemon \ + -zmqpubhashblock=tcp://127.0.0.1:28332 \ + -zmqpubrawtx=tcp://127.0.0.1:28332 \ + -zmqpubhashtx=tcp://127.0.0.1:28332 \ + -zmqpubhashblock=tcp://127.0.0.1:28332 + + We use the asyncio library here. `self.handle()` installs itself as a + future at the end of the function. Since it never returns with the event + loop having an empty stack of futures, this creates an infinite loop. An + alternative is to wrap the contents of `handle` inside `while True`. + + A blocking example using python 2.7 can be obtained from the git history: + https://github.com/bitcoin/bitcoin/blob/37a7fe9e440b83e2364d5498931253937abe9294/contrib/zmq/zmq_sub.py +""" + import binascii +import asyncio import zmq +import zmq.asyncio +import signal import struct +import sys + +if not (sys.version_info.major >= 3 and sys.version_info.minor >= 5): + print("This example only works with Python 3.5 and greater") + exit(1) port = 28332 -zmqContext = zmq.Context() -zmqSubSocket = zmqContext.socket(zmq.SUB) -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashblock") -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashtx") -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "rawblock") -zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "rawtx") -zmqSubSocket.connect("tcp://127.0.0.1:%i" % port) +class ZMQHandler(): + def __init__(self): + self.loop = zmq.asyncio.install() + self.zmqContext = zmq.asyncio.Context() -try: - while True: - msg = zmqSubSocket.recv_multipart() - topic = str(msg[0]) + self.zmqSubSocket = self.zmqContext.socket(zmq.SUB) + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashblock") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashtx") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawblock") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawtx") + self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % port) + + async def handle(self) : + msg = await self.zmqSubSocket.recv_multipart() + topic = msg[0] body = msg[1] sequence = "Unknown" if len(msg[-1]) == 4: msgSequence = struct.unpack('= 3 and sys.version_info.minor >= 4): + print("This example only works with Python 3.4 and greater") + exit(1) + +port = 28332 + +class ZMQHandler(): + def __init__(self): + self.loop = zmq.asyncio.install() + self.zmqContext = zmq.asyncio.Context() + + self.zmqSubSocket = self.zmqContext.socket(zmq.SUB) + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashblock") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashtx") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawblock") + self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawtx") + self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % port) + + @asyncio.coroutine + def handle(self) : + msg = yield from self.zmqSubSocket.recv_multipart() + topic = msg[0] + body = msg[1] + sequence = "Unknown"; + if len(msg[-1]) == 4: + msgSequence = struct.unpack(' [params] Send command to Bitcoin Core -.TP -bitcoin\-cli [options] help -List commands -.TP -bitcoin\-cli [options] help -Get help for a command +.IP +bitcoin\-cli [options] \fB\-named\fR [name=value] ... Send command to Bitcoin Core (with named arguments) +bitcoin\-cli [options] help List commands +bitcoin\-cli [options] help Get help for a command .SH OPTIONS .HP \-? @@ -40,6 +38,10 @@ 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\-named\fR +.IP +Pass named instead of positional arguments (default: false) +.HP \fB\-rpcconnect=\fR .IP Send commands to node running on (default: 127.0.0.1) @@ -69,7 +71,7 @@ Timeout during HTTP requests (default: 900) 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 +Copyright (C) 2009-2017 The Bitcoin Core developers Please contribute if you find Bitcoin Core useful. Visit for further information about the software. @@ -77,8 +79,8 @@ The source code is available from . This is experimental software. Distributed under the MIT software license, see the accompanying file COPYING -or . +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. +OpenSSL Toolkit and cryptographic software written by +Eric Young and UPnP software written by Thomas Bernard. diff --git a/doc/man/bitcoin-qt.1 b/doc/man/bitcoin-qt.1 index 2129a151e..ce252612e 100644 --- a/doc/man/bitcoin-qt.1 +++ b/doc/man/bitcoin-qt.1 @@ -1,9 +1,9 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.5. -.TH BITCOIN-QT "1" "September 2016" "bitcoin-qt v0.13.0.0" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH BITCOIN-QT "1" "February 2017" "bitcoin-qt v0.14.99.0" "User Commands" .SH NAME -bitcoin-qt \- manual page for bitcoin-qt v0.13.0.0 +bitcoin-qt \- manual page for bitcoin-qt v0.14.99.0 .SH DESCRIPTION -Bitcoin Core version v0.13.0.0 (64\-bit) +Bitcoin Core version v0.14.99.0 (64\-bit) Usage: .IP bitcoin\-qt [command\-line options] @@ -27,13 +27,14 @@ long fork (%s in cmd is replaced by message) Execute command when the best block changes (%s in cmd is replaced by block hash) .HP -\fB\-checkblocks=\fR +\fB\-assumevalid=\fR .IP -How many blocks to check at startup (default: 288, 0 = all) -.HP -\fB\-checklevel=\fR -.IP -How thorough the block verification of \fB\-checkblocks\fR is (0\-4, default: 3) +If this block is in the chain assume that it and its ancestors are valid +and potentially skip their script verification (0 to verify all, +default: +00000000000000000013176bf8d7dfeab4e1db31dc93bc311b436e82ab226b90, +testnet: +00000000000128796ee387cf110ccb9d2f36cffaf7f73079c995377c65ac0dcc) .HP \fB\-conf=\fR .IP @@ -62,11 +63,16 @@ Keep the transaction memory pool below megabytes (default: 300) \fB\-mempoolexpiry=\fR .IP Do not keep transactions in the mempool longer than hours (default: -72) +336) +.HP +\fB\-blockreconstructionextratxn=\fR +.IP +Extra transactions to keep in memory for compact block reconstructions +(default: 100) .HP \fB\-par=\fR .IP -Set the number of script verification threads (\fB\-4\fR to 16, 0 = auto, <0 = +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 @@ -75,13 +81,15 @@ Specify pid file (default: bitcoind.pid) .HP \fB\-prune=\fR .IP -Reduce storage requirements by enabling pruning (deleting) of old blocks. -This allows the pruneblockchain RPC to be called to delete specific blocks, -and enables automatic pruning of old blocks if a target size in MiB is -provided. 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, 1 = allow manual pruning via RPC, >550 = -automatically prune block files to stay under the specified target size in MiB) +Reduce storage requirements by enabling pruning (deleting) of old +blocks. This allows the pruneblockchain RPC to be called to +delete specific blocks, and enables automatic pruning of old +blocks if a target size in MiB is provided. 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, 1 = allow manual pruning via RPC, +>550 = automatically prune block files to stay under the +specified target size in MiB) .HP \fB\-reindex\-chainstate\fR .IP @@ -123,7 +131,8 @@ for IPv6 .HP \fB\-connect=\fR .IP -Connect only to the specified node(s) +Connect only to the specified node(s); \fB\-noconnect\fR or \fB\-connect\fR=\fI\,0\/\fR alone to +disable automatic connections .HP \fB\-discover\fR .IP @@ -137,7 +146,7 @@ Allow DNS lookups for \fB\-addnode\fR, \fB\-seednode\fR and \fB\-connect\fR (def \fB\-dnsseed\fR .IP Query for peer addresses via DNS lookup, if low on addresses (default: 1 -unless \fB\-connect\fR) +unless \fB\-connect\fR/\-noconnect) .HP \fB\-externalip=\fR .IP @@ -149,7 +158,8 @@ 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) +Accept connections from outside (default: 1 if no \fB\-proxy\fR or +\fB\-connect\fR/\-noconnect) .HP \fB\-listenonion\fR .IP @@ -204,6 +214,11 @@ Connect through SOCKS5 proxy 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 @@ -221,17 +236,22 @@ Tor control port to use if onion listening enabled (default: .IP Tor control port password (default: empty) .HP +\fB\-upnp\fR +.IP +Use UPnP to map the listening port (default: 0) +.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 +\fB\-whitelist=\fR .IP -Whitelist peers connecting from the given netmask or IP address. Can be -specified multiple times. Whitelisted peers cannot be DoS banned -and their transactions are always relayed, even if they are -already in the mempool, useful e.g. for a gateway +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 @@ -240,7 +260,7 @@ not relaying transactions (default: 1) .HP \fB\-whitelistforcerelay\fR .IP -Force relay of transactions from whitelisted peers even they violate +Force relay of transactions from whitelisted peers even if they violate local relay policy (default: 1) .HP \fB\-maxuploadtarget=\fR @@ -287,13 +307,17 @@ Spend unconfirmed change when sending transactions (default: 1) \fB\-txconfirmtarget=\fR .IP If paytxfee is not set, include enough fee so transactions begin -confirmation on average within n blocks (default: 2) +confirmation on average within n blocks (default: 6) .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\-walletrbf\fR +.IP +Send transactions with full\-RBF opt\-in enabled (default: 0) +.HP \fB\-upgradewallet\fR .IP Upgrade wallet to latest format on startup @@ -347,9 +371,9 @@ Append comment to the user agent string Output debugging information (default: 0, supplying is optional). If is not supplied or if = 1, output all debugging information. can be: addrman, -alert, bench, coindb, db, http, libevent, lock, mempool, -mempoolrej, net, proxy, prune, rand, reindex, rpc, selectcoins, -tor, zmq, qt. +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 @@ -422,6 +446,11 @@ Set maximum block size in bytes (default: 750000) .IP Set maximum size of high\-priority/low\-fee transactions in bytes (default: 0) +.HP +\fB\-blockmintxfee=\fR +.IP +Set lowest fee rate (in BTC/kB) for transactions to be included in block +creation. (default: 0.00001) .PP RPC server options: .HP @@ -455,8 +484,10 @@ Password for JSON\-RPC connections .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 +canonical python script is included in share/rpcuser. The client +then connects normally using the +rpcuser=/rpcpassword= pair of arguments. This +option can be specified multiple times .HP \fB\-rpcport=\fR .IP @@ -500,7 +531,7 @@ Show splash screen on startup (default: 1) .IP Reset all settings changed in the GUI .SH COPYRIGHT -Copyright (C) 2009-2016 The Bitcoin Core developers +Copyright (C) 2009-2017 The Bitcoin Core developers Please contribute if you find Bitcoin Core useful. Visit for further information about the software. @@ -508,8 +539,8 @@ The source code is available from . This is experimental software. Distributed under the MIT software license, see the accompanying file COPYING -or . +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. +OpenSSL Toolkit and cryptographic software written by +Eric Young and UPnP software written by Thomas Bernard. diff --git a/doc/man/bitcoin-tx.1 b/doc/man/bitcoin-tx.1 index 5c4e31e7f..98adf2f5b 100644 --- a/doc/man/bitcoin-tx.1 +++ b/doc/man/bitcoin-tx.1 @@ -1,9 +1,9 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.5. -.TH BITCOIN-TX "1" "September 2016" "bitcoin-tx v0.13.0.0" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH BITCOIN-TX "1" "February 2017" "bitcoin-tx v0.14.99.0" "User Commands" .SH NAME -bitcoin-tx \- manual page for bitcoin-tx v0.13.0.0 +bitcoin-tx \- manual page for bitcoin-tx v0.14.99.0 .SH DESCRIPTION -Bitcoin Core bitcoin\-tx utility version v0.13.0.0 +Bitcoin Core bitcoin\-tx utility version v0.14.99.0 .SS "Usage:" .TP bitcoin\-tx [options] [commands] @@ -67,13 +67,28 @@ outaddr=VALUE:ADDRESS .IP Add address\-based output to TX .IP +outpubkey=VALUE:PUBKEY[:FLAGS] +.IP +Add pay\-to\-pubkey output to TX. Optionally add the "W" flag to produce a +pay\-to\-witness\-pubkey\-hash output. Optionally add the "S" flag to +wrap the output in a pay\-to\-script\-hash. +.IP outdata=[VALUE:]DATA .IP Add data\-based output to TX .IP -outscript=VALUE:SCRIPT +outscript=VALUE:SCRIPT[:FLAGS] .IP -Add raw script output to TX +Add raw script output to TX. Optionally add the "W" flag to produce a +pay\-to\-witness\-script\-hash output. Optionally add the "S" flag to +wrap the output in a pay\-to\-script\-hash. +.IP +outmultisig=VALUE:REQUIRED:PUBKEYS:PUBKEY1:PUBKEY2:....[:FLAGS] +.IP +Add Pay To n\-of\-m Multi\-sig output to TX. n = REQUIRED, m = PUBKEYS. +Optionally add the "W" flag to produce a +pay\-to\-witness\-script\-hash output. Optionally add the "S" flag to +wrap the output in a pay\-to\-script\-hash. .IP sign=SIGHASH\-FLAGS .IP @@ -92,7 +107,7 @@ set=NAME:JSON\-STRING .IP Set register NAME to given JSON\-STRING .SH COPYRIGHT -Copyright (C) 2009-2016 The Bitcoin Core developers +Copyright (C) 2009-2017 The Bitcoin Core developers Please contribute if you find Bitcoin Core useful. Visit for further information about the software. @@ -100,8 +115,8 @@ The source code is available from . This is experimental software. Distributed under the MIT software license, see the accompanying file COPYING -or . +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. +OpenSSL Toolkit and cryptographic software written by +Eric Young and UPnP software written by Thomas Bernard. diff --git a/doc/man/bitcoind.1 b/doc/man/bitcoind.1 index 47539d813..fb066e0c6 100644 --- a/doc/man/bitcoind.1 +++ b/doc/man/bitcoind.1 @@ -1,9 +1,9 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.5. -.TH BITCOIND "1" "September 2016" "bitcoind v0.13.0.0" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. +.TH BITCOIND "1" "February 2017" "bitcoind v0.14.99.0" "User Commands" .SH NAME -bitcoind \- manual page for bitcoind v0.13.0.0 +bitcoind \- manual page for bitcoind v0.14.99.0 .SH DESCRIPTION -Bitcoin Core Daemon version v0.13.0.0 +Bitcoin Core Daemon version v0.14.99.0 .SS "Usage:" .TP bitcoind [options] @@ -28,13 +28,14 @@ long fork (%s in cmd is replaced by message) Execute command when the best block changes (%s in cmd is replaced by block hash) .HP -\fB\-checkblocks=\fR +\fB\-assumevalid=\fR .IP -How many blocks to check at startup (default: 288, 0 = all) -.HP -\fB\-checklevel=\fR -.IP -How thorough the block verification of \fB\-checkblocks\fR is (0\-4, default: 3) +If this block is in the chain assume that it and its ancestors are valid +and potentially skip their script verification (0 to verify all, +default: +00000000000000000013176bf8d7dfeab4e1db31dc93bc311b436e82ab226b90, +testnet: +00000000000128796ee387cf110ccb9d2f36cffaf7f73079c995377c65ac0dcc) .HP \fB\-conf=\fR .IP @@ -67,11 +68,16 @@ Keep the transaction memory pool below megabytes (default: 300) \fB\-mempoolexpiry=\fR .IP Do not keep transactions in the mempool longer than hours (default: -72) +336) +.HP +\fB\-blockreconstructionextratxn=\fR +.IP +Extra transactions to keep in memory for compact block reconstructions +(default: 100) .HP \fB\-par=\fR .IP -Set the number of script verification threads (\fB\-4\fR to 16, 0 = auto, <0 = +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 @@ -80,13 +86,15 @@ Specify pid file (default: bitcoind.pid) .HP \fB\-prune=\fR .IP -Reduce storage requirements by enabling pruning (deleting) of old blocks. -This allows the pruneblockchain RPC to be called to delete specific blocks, -and enables automatic pruning of old blocks if a target size in MiB is -provided. 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, 1 = allow manual pruning via RPC, >550 = -automatically prune block files to stay under the specified target size in MiB) +Reduce storage requirements by enabling pruning (deleting) of old +blocks. This allows the pruneblockchain RPC to be called to +delete specific blocks, and enables automatic pruning of old +blocks if a target size in MiB is provided. 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, 1 = allow manual pruning via RPC, +>550 = automatically prune block files to stay under the +specified target size in MiB) .HP \fB\-reindex\-chainstate\fR .IP @@ -128,7 +136,8 @@ for IPv6 .HP \fB\-connect=\fR .IP -Connect only to the specified node(s) +Connect only to the specified node(s); \fB\-noconnect\fR or \fB\-connect\fR=\fI\,0\/\fR alone to +disable automatic connections .HP \fB\-discover\fR .IP @@ -142,7 +151,7 @@ Allow DNS lookups for \fB\-addnode\fR, \fB\-seednode\fR and \fB\-connect\fR (def \fB\-dnsseed\fR .IP Query for peer addresses via DNS lookup, if low on addresses (default: 1 -unless \fB\-connect\fR) +unless \fB\-connect\fR/\-noconnect) .HP \fB\-externalip=\fR .IP @@ -154,7 +163,8 @@ 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) +Accept connections from outside (default: 1 if no \fB\-proxy\fR or +\fB\-connect\fR/\-noconnect) .HP \fB\-listenonion\fR .IP @@ -209,6 +219,11 @@ Connect through SOCKS5 proxy 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 @@ -226,17 +241,22 @@ Tor control port to use if onion listening enabled (default: .IP Tor control port password (default: empty) .HP +\fB\-upnp\fR +.IP +Use UPnP to map the listening port (default: 0) +.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 +\fB\-whitelist=\fR .IP -Whitelist peers connecting from the given netmask or IP address. Can be -specified multiple times. Whitelisted peers cannot be DoS banned -and their transactions are always relayed, even if they are -already in the mempool, useful e.g. for a gateway +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 @@ -245,7 +265,7 @@ not relaying transactions (default: 1) .HP \fB\-whitelistforcerelay\fR .IP -Force relay of transactions from whitelisted peers even they violate +Force relay of transactions from whitelisted peers even if they violate local relay policy (default: 1) .HP \fB\-maxuploadtarget=\fR @@ -292,13 +312,17 @@ Spend unconfirmed change when sending transactions (default: 1) \fB\-txconfirmtarget=\fR .IP If paytxfee is not set, include enough fee so transactions begin -confirmation on average within n blocks (default: 2) +confirmation on average within n blocks (default: 6) .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\-walletrbf\fR +.IP +Send transactions with full\-RBF opt\-in enabled (default: 0) +.HP \fB\-upgradewallet\fR .IP Upgrade wallet to latest format on startup @@ -352,9 +376,9 @@ Append comment to the user agent string Output debugging information (default: 0, supplying is optional). If is not supplied or if = 1, output all debugging information. can be: addrman, -alert, bench, coindb, db, http, libevent, lock, mempool, -mempoolrej, net, proxy, prune, rand, reindex, rpc, selectcoins, -tor, zmq. +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 @@ -427,6 +451,11 @@ Set maximum block size in bytes (default: 750000) .IP Set maximum size of high\-priority/low\-fee transactions in bytes (default: 0) +.HP +\fB\-blockmintxfee=\fR +.IP +Set lowest fee rate (in BTC/kB) for transactions to be included in block +creation. (default: 0.00001) .PP RPC server options: .HP @@ -460,8 +489,10 @@ Password for JSON\-RPC connections .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 +canonical python script is included in share/rpcuser. The client +then connects normally using the +rpcuser=/rpcpassword= pair of arguments. This +option can be specified multiple times .HP \fB\-rpcport=\fR .IP @@ -479,7 +510,7 @@ option can be specified multiple times .IP Set the number of threads to service RPC calls (default: 4) .SH COPYRIGHT -Copyright (C) 2009-2016 The Bitcoin Core developers +Copyright (C) 2009-2017 The Bitcoin Core developers Please contribute if you find Bitcoin Core useful. Visit for further information about the software. @@ -487,8 +518,8 @@ The source code is available from . This is experimental software. Distributed under the MIT software license, see the accompanying file COPYING -or . +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. +OpenSSL Toolkit and cryptographic software written by +Eric Young and UPnP software written by Thomas Bernard. diff --git a/doc/release-notes.md b/doc/release-notes.md index 0ea9e1949..eaa0b330e 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -33,117 +33,6 @@ frequently tested on them. Notable changes =============== -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. - -Fee Estimation Changes ----------------------- - -- Since 0.13.2 fee estimation for a confirmation target of 1 block has been - disabled. This is only a minor behavior change as there was often insufficient - data for this target anyway. `estimatefee 1` will now always return -1 and - `estimatesmartfee 1` will start searching at a target of 2. - -- The default target for fee estimation is changed to 6 blocks in both the GUI - (previously 25) and for RPC calls (previously 2). - -Removal of Priority Estimation -------------------------------- - -- Estimation of "priority" needed for a transaction to be included within a target - number of blocks has been removed. The rpc calls are deprecated and will either - return -1 or 1e24 appropriately. The format for `fee_estimates.dat` has also - changed to no longer save these priority estimates. It will automatically be - converted to the new format which is not readable by prior versions of the - software. - -- The concept of "priority" (coin age) transactions is planned to be removed in - the next major version. To prepare for this, the default for the rate limit of - priority transactions (`-limitfreerelay`) has been set to `0` kB/minute. This - is not to be confused with the `prioritisetransaction` RPC which will remain - supported for adding fee deltas to transactions. - -P2P connection management --------------------------- - -- Peers manually added through the addnode option or addnode RPC now have their own - limit of eight connections which does not compete with other inbound or outbound - connection usage and is not subject to the maxconnections limitation. - -- New connections to manually added peers are much faster. - -Introduction of assumed-valid blocks -------------------------------------- - -- A significant portion of the initial block download time is spent verifying - scripts/signatures. Although the verification must pass to ensure the security - of the system, no other result from this verification is needed: If the node - knew the history of a given block were valid it could skip checking scripts - for its ancestors. - -- A new configuration option 'assumevalid' is provided to express this knowledge - to the software. Unlike the 'checkpoints' in the past this setting does not - force the use of a particular chain: chains that are consistent with it are - processed quicker, but other chains are still accepted if they'd otherwise - be chosen as best. Also unlike 'checkpoints' the user can configure which - block history is assumed true, this means that even outdated software can - sync more quickly if the setting is updated by the user. - -- Because the validity of a chain history is a simple objective fact it is much - easier to review this setting. As a result the software ships with a default - value adjusted to match the current chain shortly before release. The use - of this default value can be disabled by setting -assumevalid=0 - -0.14.0 Change log -================= - -Detailed release notes follow. This overview includes changes that affect -behavior, not code moves, refactors and string updates. For convenience in locating -the code changes and accompanying discussion, both the pull request and -git merge commit are mentioned. - -### RPC and REST - -UTXO set query (`GET /rest/getutxos//-/-/.../-.`) responses -were changed to return status code HTTP_BAD_REQUEST (400) instead of HTTP_INTERNAL_SERVER_ERROR (500) when requests -contain invalid parameters. - -The first boolean argument to `getaddednodeinfo` has been removed. This is an incompatible change. - -Call "getmininginfo" loses the "testnet" field in favor of the more generic "chain" (which has been present for years). - -### Configuration and command-line options - -### Block and transaction handling - -### P2P protocol and network code - -### Validation - -### Build system - -### Wallet - -0.14.0 Fundrawtransaction change address reuse -============================================== - -Before 0.14, `fundrawtransaction` was by default wallet stateless. In almost all cases `fundrawtransaction` does add a change-output to the outputs of the funded transaction. Before 0.14, the used keypool key was never marked as change-address key and directly returned to the keypool (leading to address reuse). -Before 0.14, calling `getnewaddress` directly after `fundrawtransaction` did generate the same address as the change-output address. - -Since 0.14, fundrawtransaction does reserve the change-output-key from the keypool by default (optional by setting `reserveChangeKey`, default = `true`) - -Users should also consider using `getrawchangeaddress()` in conjunction with `fundrawtransaction`'s `changeAddress` option. - -### GUI - -### Tests - -### Miscellaneous - Credits ======= diff --git a/doc/translation_process.md b/doc/translation_process.md index 9e9ced245..1702637d5 100644 --- a/doc/translation_process.md +++ b/doc/translation_process.md @@ -4,7 +4,7 @@ Translations The Bitcoin-Core project has been designed to support multiple localisations. This makes adding new phrases, and completely new languages easily achievable. For managing all application translations, Bitcoin-Core makes use of the Transifex online translation management tool. ### 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. +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-border money transfers, any help making that easier is greatly appreciated. @@ -32,7 +32,7 @@ QToolBar *toolbar = addToolBar(tr("Tabs toolbar")); ### Creating a pull-request For general PRs, you shouldn’t include any updates to the translation source files. They will be updated periodically, primarily around pre-releases, allowing time for any new phrases to be translated before public releases. This is also important in avoiding translation related merge conflicts. -When an updated source file is merged into the Github repo, Transifex will automatically detect it (although it can take several hours). Once processed, the new strings will show up as "Remaining" in the Transifex web interface and are ready for translators. +When an updated source file is merged into the GitHub repo, Transifex will automatically detect it (although it can take several hours). Once processed, the new strings will show up as "Remaining" in the Transifex web interface and are ready for translators. To create the pull-request, use the following commands: ``` diff --git a/doc/zmq.md b/doc/zmq.md index 6079e3254..1019ff665 100644 --- a/doc/zmq.md +++ b/doc/zmq.md @@ -1,4 +1,4 @@ -# Block and Transaction Broadcasting With ZeroMQ +# Block and Transaction Broadcasting with ZeroMQ [ZeroMQ](http://zeromq.org/) is a lightweight wrapper around TCP connections, inter-process communication, and shared-memory, @@ -50,7 +50,7 @@ during the *configure* step of building bitcoind: $ ./configure --disable-zmq (other options) To actually enable operation, one must set the appropriate options on -the commandline or in the configuration file. +the command line or in the configuration file. ## Usage diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 26bc6a73d..973165c4c 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -2,25 +2,21 @@ # 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. - """ -Run Regression Test Suite +rpc-tests.py - run regression test suite This module calls down into individual test cases via subprocess. It will -forward all unrecognized arguments onto the individual test scripts, other -than: +forward all unrecognized arguments onto the individual test scripts. - - `-extended`: run the "extended" test suite in addition to the basic one. - - `-win`: signal that this is running in a Windows environment, and we - should run the tests. - - `--coverage`: this generates a basic coverage report for the RPC - interface. +RPC tests are disabled on Windows by default. Use --force to run them anyway. For a description of arguments recognized by test scripts, see `qa/pull-tester/test_framework/test_framework.py:BitcoinTestFramework.main`. """ +import argparse +import configparser import os import time import shutil @@ -29,77 +25,9 @@ import subprocess import tempfile import re -sys.path.append("qa/pull-tester/") -from tests_config import * - -BOLD = ("","") -if os.name == 'posix': - # primitive formatting on supported - # terminal via ANSI escape sequences: - BOLD = ('\033[0m', '\033[1m') - -RPC_TESTS_DIR = SRCDIR + '/qa/rpc-tests/' - -#If imported values are not defined then set to zero (or disabled) -if 'ENABLE_WALLET' not in vars(): - ENABLE_WALLET=0 -if 'ENABLE_BITCOIND' not in vars(): - ENABLE_BITCOIND=0 -if 'ENABLE_UTILS' not in vars(): - ENABLE_UTILS=0 -if 'ENABLE_ZMQ' not in vars(): - ENABLE_ZMQ=0 - -ENABLE_COVERAGE=0 - -#Create a set to store arguments and create the passon string -opts = set() -passon_args = [] -PASSON_REGEX = re.compile("^--") -PARALLEL_REGEX = re.compile('^-parallel=') - -print_help = False -run_parallel = 4 - -for arg in sys.argv[1:]: - if arg == "--help" or arg == "-h" or arg == "-?": - print_help = True - break - if arg == '--coverage': - ENABLE_COVERAGE = 1 - elif PASSON_REGEX.match(arg): - passon_args.append(arg) - elif PARALLEL_REGEX.match(arg): - run_parallel = int(arg.split(sep='=', maxsplit=1)[1]) - else: - opts.add(arg) - -#Set env vars -if "BITCOIND" not in os.environ: - os.environ["BITCOIND"] = BUILDDIR + '/src/bitcoind' + EXEEXT - -if EXEEXT == ".exe" and "-win" not in opts: - # https://github.com/bitcoin/bitcoin/commit/d52802551752140cf41f0d9a225a43e84404d3e9 - # https://github.com/bitcoin/bitcoin/pull/5677#issuecomment-136646964 - print("Win tests currently disabled by default. Use -win option to enable") - sys.exit(0) - -if not (ENABLE_WALLET == 1 and ENABLE_UTILS == 1 and ENABLE_BITCOIND == 1): - print("No rpc tests to run. Wallet, utils, and bitcoind must all be enabled") - sys.exit(0) - -# python3-zmq may not be installed. Handle this gracefully and with some helpful info -if ENABLE_ZMQ: - try: - import zmq - 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 - -testScripts = [ - # longest test should go first, to favor running tests in parallel +BASE_SCRIPTS= [ + # Scripts that are run by the travis build process. + # Longest test should go first, to favor running tests in parallel 'wallet-hd.py', 'walletbackup.py', # vv Tests less than 5m vv @@ -154,11 +82,17 @@ testScripts = [ 'bumpfee.py', 'rpcnamedargs.py', 'listsinceblock.py', + 'p2p-leaktests.py', ] -if ENABLE_ZMQ: - testScripts.append('zmq_test.py') -testScriptsExt = [ +ZMQ_SCRIPTS = [ + # ZMQ test can only be run if bitcoin was built with zmq-enabled. + # call rpc_tests.py with -nozmq to explicitly exclude these tests. + "zmq_test.py"] + +EXTENDED_SCRIPTS = [ + # These tests are not run by the travis build process. + # Longest test should go first, to favor running tests in parallel 'pruning.py', # vv Tests less than 20m vv 'smartfees.py', @@ -168,6 +102,7 @@ testScriptsExt = [ # vv Tests less than 2m vv 'bip68-sequence.py', 'getblocktemplate_longpoll.py', + 'p2p-timeouts.py', # vv Tests less than 60s vv 'bip9-softforks.py', 'p2p-feefilter.py', @@ -187,44 +122,126 @@ testScriptsExt = [ 'replace-by-fee.py', ] +ALL_SCRIPTS = BASE_SCRIPTS + ZMQ_SCRIPTS + EXTENDED_SCRIPTS -def runtests(): - test_list = [] - if '-extended' in opts: - test_list = testScripts + testScriptsExt - elif len(opts) == 0 or (len(opts) == 1 and "-win" in opts): - test_list = testScripts - else: - for t in testScripts + testScriptsExt: - if t in opts or re.sub(".py$", "", t) in opts: - test_list.append(t) +def main(): + # Parse arguments and pass through unrecognised args + parser = argparse.ArgumentParser(add_help=False, + usage='%(prog)s [rpc-test.py options] [script options] [scripts]', + description=__doc__, + epilog=''' + Help text and arguments for individual test script:''', + formatter_class=argparse.RawTextHelpFormatter) + parser.add_argument('--coverage', action='store_true', help='generate a basic coverage report for the RPC interface') + parser.add_argument('--extended', action='store_true', help='run the extended test suite in addition to the basic tests') + parser.add_argument('--force', '-f', action='store_true', help='run tests even on platforms where they are disabled by default (e.g. windows).') + parser.add_argument('--help', '-h', '-?', action='store_true', help='print help text and exit') + parser.add_argument('--jobs', '-j', type=int, default=4, help='how many test scripts to run in parallel. Default=4.') + parser.add_argument('--nozmq', action='store_true', help='do not run the zmq tests') + args, unknown_args = parser.parse_known_args() - if print_help: - # Only print help of the first script and exit - subprocess.check_call((RPC_TESTS_DIR + test_list[0]).split() + ['-h']) + # Create a set to store arguments and create the passon string + tests = set(arg for arg in unknown_args if arg[:2] != "--") + passon_args = [arg for arg in unknown_args if arg[:2] == "--"] + + # Read config generated by configure. + config = configparser.ConfigParser() + config.read_file(open(os.path.dirname(__file__) + "/tests_config.ini")) + + enable_wallet = config["components"].getboolean("ENABLE_WALLET") + enable_utils = config["components"].getboolean("ENABLE_UTILS") + enable_bitcoind = config["components"].getboolean("ENABLE_BITCOIND") + enable_zmq = config["components"].getboolean("ENABLE_ZMQ") and not args.nozmq + + if config["environment"]["EXEEXT"] == ".exe" and not args.force: + # https://github.com/bitcoin/bitcoin/commit/d52802551752140cf41f0d9a225a43e84404d3e9 + # https://github.com/bitcoin/bitcoin/pull/5677#issuecomment-136646964 + print("Tests currently disabled on Windows by default. Use --force option to enable") sys.exit(0) - coverage = None + if not (enable_wallet and enable_utils and enable_bitcoind): + print("No rpc tests to run. Wallet, utils, and bitcoind must all be enabled") + print("Rerun `configure` with -enable-wallet, -with-utils and -with-daemon and rerun make") + sys.exit(0) - if ENABLE_COVERAGE: + # python3-zmq may not be installed. Handle this gracefully and with some helpful info + if enable_zmq: + try: + import zmq + except ImportError: + print("ERROR: \"import zmq\" failed. Use -nozmq to run without the ZMQ tests." + "To run zmq tests, see dependency info in /qa/README.md.") + raise + + # Build list of tests + if tests: + # Individual tests have been specified. Run specified tests that exist + # in the ALL_SCRIPTS list. Accept the name with or without .py extension. + test_list = [t for t in ALL_SCRIPTS if + (t in tests or re.sub(".py$", "", t) in tests)] + if not test_list: + print("No valid test scripts specified. Check that your test is in one " + "of the test lists in rpc-tests.py or run rpc-tests.py with no arguments to run all tests") + print("Scripts not found:") + print(tests) + sys.exit(0) + + else: + # No individual tests have been specified. Run base tests, and + # optionally ZMQ tests and extended tests. + test_list = BASE_SCRIPTS + if enable_zmq: + test_list += ZMQ_SCRIPTS + if args.extended: + test_list += EXTENDED_SCRIPTS + # TODO: BASE_SCRIPTS and EXTENDED_SCRIPTS are sorted by runtime + # (for parallel running efficiency). This combined list will is no + # longer sorted. + + if args.help: + # Print help for rpc-tests.py, then print help of the first script and exit. + parser.print_help() + subprocess.check_call((config["environment"]["SRCDIR"] + '/qa/rpc-tests/' + test_list[0]).split() + ['-h']) + sys.exit(0) + + run_tests(test_list, config["environment"]["SRCDIR"], config["environment"]["BUILDDIR"], config["environment"]["EXEEXT"], args.jobs, args.coverage, passon_args) + +def run_tests(test_list, src_dir, build_dir, exeext, jobs=1, enable_coverage=False, args=[]): + BOLD = ("","") + if os.name == 'posix': + # primitive formatting on supported + # terminal via ANSI escape sequences: + BOLD = ('\033[0m', '\033[1m') + + #Set env vars + if "BITCOIND" not in os.environ: + os.environ["BITCOIND"] = build_dir + '/src/bitcoind' + exeext + + tests_dir = src_dir + '/qa/rpc-tests/' + + flags = ["--srcdir=" + src_dir] + args + flags.append("--cachedir=%s/qa/cache" % build_dir) + + if enable_coverage: coverage = RPCCoverage() - print("Initializing coverage directory at %s\n" % coverage.dir) - flags = ["--srcdir=%s/src" % BUILDDIR] + passon_args - flags.append("--cachedir=%s/qa/cache" % BUILDDIR) - if coverage: flags.append(coverage.flag) + print("Initializing coverage directory at %s\n" % coverage.dir) + else: + coverage = None - if len(test_list) > 1 and run_parallel > 1: + if len(test_list) > 1 and jobs > 1: # Populate cache - subprocess.check_output([RPC_TESTS_DIR + 'create_cache.py'] + flags) + subprocess.check_output([tests_dir + 'create_cache.py'] + flags) #Run Tests - max_len_name = len(max(test_list, key=len)) + all_passed = True time_sum = 0 time0 = time.time() - job_queue = RPCTestHandler(run_parallel, test_list, flags) + + job_queue = RPCTestHandler(jobs, tests_dir, test_list, flags) + + max_len_name = len(max(test_list, key=len)) results = BOLD[1] + "%s | %s | %s\n\n" % ("TEST".ljust(max_len_name), "PASSED", "DURATION") + BOLD[0] - all_passed = True for _ in range(len(test_list)): (name, stdout, stderr, passed, duration) = job_queue.get_next() all_passed = all_passed and passed @@ -233,8 +250,10 @@ def runtests(): print('\n' + BOLD[1] + name + BOLD[0] + ":") print('' if passed else stdout + '\n', end='') print('' if stderr == '' else 'stderr:\n' + stderr + '\n', end='') - results += "%s | %s | %s s\n" % (name.ljust(max_len_name), str(passed).ljust(6), duration) print("Pass: %s%s%s, Duration: %s s\n" % (BOLD[1], passed, BOLD[0], duration)) + + results += "%s | %s | %s s\n" % (name.ljust(max_len_name), str(passed).ljust(6), duration) + results += BOLD[1] + "\n%s | %s | %s s (accumulated)" % ("ALL".ljust(max_len_name), str(all_passed).ljust(6), time_sum) + BOLD[0] print(results) print("\nRuntime: %s s" % (int(time.time() - time0))) @@ -247,15 +266,15 @@ def runtests(): sys.exit(not all_passed) - class RPCTestHandler: """ Trigger the testscrips passed in via the list. """ - def __init__(self, num_tests_parallel, test_list=None, flags=None): + def __init__(self, num_tests_parallel, tests_dir, test_list=None, flags=None): assert(num_tests_parallel >= 1) self.num_jobs = num_tests_parallel + self.tests_dir = tests_dir self.test_list = test_list self.flags = flags self.num_running = 0 @@ -275,7 +294,7 @@ class RPCTestHandler: 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, + subprocess.Popen((self.tests_dir + t).split() + self.flags + port_seed, universal_newlines=True, stdout=log_stdout, stderr=log_stderr), @@ -340,10 +359,10 @@ class RPCCoverage(object): """ # This is shared from `qa/rpc-tests/test-framework/coverage.py` - REFERENCE_FILENAME = 'rpc_interface.txt' - COVERAGE_FILE_PREFIX = 'coverage.' + reference_filename = 'rpc_interface.txt' + coverage_file_prefix = 'coverage.' - coverage_ref_filename = os.path.join(self.dir, REFERENCE_FILENAME) + coverage_ref_filename = os.path.join(self.dir, reference_filename) coverage_filenames = set() all_cmds = set() covered_cmds = set() @@ -356,7 +375,7 @@ class RPCCoverage(object): for root, dirs, files in os.walk(self.dir): for filename in files: - if filename.startswith(COVERAGE_FILE_PREFIX): + if filename.startswith(coverage_file_prefix): coverage_filenames.add(os.path.join(root, filename)) for filename in coverage_filenames: @@ -367,4 +386,4 @@ class RPCCoverage(object): if __name__ == '__main__': - runtests() + main() diff --git a/qa/pull-tester/tests_config.ini.in b/qa/pull-tester/tests_config.ini.in new file mode 100644 index 000000000..e3e457d0b --- /dev/null +++ b/qa/pull-tester/tests_config.ini.in @@ -0,0 +1,18 @@ +# 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. + +# These environment variables are set by the build process and read by +# rpc-tests.py + +[environment] +SRCDIR=@abs_top_srcdir@ +BUILDDIR=@abs_top_builddir@ +EXEEXT=@EXEEXT@ + +[components] +# Which components are enabled. These are commented out by `configure` if they were disabled when running config. +@ENABLE_WALLET_TRUE@ENABLE_WALLET=true +@BUILD_BITCOIN_UTILS_TRUE@ENABLE_UTILS=true +@BUILD_BITCOIND_TRUE@ENABLE_BITCOIND=true +@ENABLE_ZMQ_TRUE@ENABLE_ZMQ=true diff --git a/qa/pull-tester/tests_config.py.in b/qa/pull-tester/tests_config.py.in deleted file mode 100644 index a0d0a3d98..000000000 --- a/qa/pull-tester/tests_config.py.in +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python3 -# 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. - -SRCDIR="@abs_top_srcdir@" -BUILDDIR="@abs_top_builddir@" -EXEEXT="@EXEEXT@" - -# These will turn into comments if they were disabled when configuring. -@ENABLE_WALLET_TRUE@ENABLE_WALLET=1 -@BUILD_BITCOIN_UTILS_TRUE@ENABLE_UTILS=1 -@BUILD_BITCOIND_TRUE@ENABLE_BITCOIND=1 -@ENABLE_ZMQ_TRUE@ENABLE_ZMQ=1 diff --git a/qa/rpc-tests/bip68-112-113-p2p.py b/qa/rpc-tests/bip68-112-113-p2p.py index c96b746c9..e03bc1c37 100755 --- a/qa/rpc-tests/bip68-112-113-p2p.py +++ b/qa/rpc-tests/bip68-112-113-p2p.py @@ -5,7 +5,7 @@ from test_framework.test_framework import ComparisonTestFramework from test_framework.util import * -from test_framework.mininode import ToHex, CTransaction, NetworkThread +from test_framework.mininode import ToHex, NetworkThread from test_framework.blocktools import create_coinbase, create_block from test_framework.comptool import TestInstance, TestManager from test_framework.script import * diff --git a/qa/rpc-tests/bip68-sequence.py b/qa/rpc-tests/bip68-sequence.py index a12bf10eb..1b099f933 100755 --- a/qa/rpc-tests/bip68-sequence.py +++ b/qa/rpc-tests/bip68-sequence.py @@ -9,8 +9,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -from test_framework.script import * -from test_framework.mininode import * from test_framework.blocktools import * SEQUENCE_LOCKTIME_DISABLE_FLAG = (1<<31) diff --git a/qa/rpc-tests/bumpfee.py b/qa/rpc-tests/bumpfee.py index ac282796c..e02cb4c30 100755 --- a/qa/rpc-tests/bumpfee.py +++ b/qa/rpc-tests/bumpfee.py @@ -8,10 +8,8 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework import blocktools from test_framework.mininode import CTransaction from test_framework.util import * -from test_framework.util import * import io -import time # Sequence number that is BIP 125 opt-in and BIP 68-compliant BIP125_SEQUENCE_NUMBER = 0xfffffffd diff --git a/qa/rpc-tests/import-rescan.py b/qa/rpc-tests/import-rescan.py index e683df26d..54cc6d264 100755 --- a/qa/rpc-tests/import-rescan.py +++ b/qa/rpc-tests/import-rescan.py @@ -2,54 +2,105 @@ # 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. +"""Test rescan behavior of importaddress, importpubkey, importprivkey, and +importmulti RPCs with different types of keys and rescan options. +In the first part of the test, node 0 creates an address for each type of +import RPC call and sends BTC to it. Then other nodes import the addresses, +and the test makes listtransactions and getbalance calls to confirm that the +importing node either did or did not execute rescans picking up the send +transactions. + +In the second part of the test, node 0 sends more BTC to each address, and the +test makes more listtransactions and getbalance calls to confirm that the +importing nodes pick up the new transactions regardless of whether rescans +happened previously. +""" + +from test_framework.authproxy import JSONRPCException from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import (start_nodes, connect_nodes, sync_blocks, assert_equal) +from test_framework.util import (start_nodes, connect_nodes, sync_blocks, assert_equal, set_node_times) from decimal import Decimal import collections import enum import itertools -import functools Call = enum.Enum("Call", "single multi") Data = enum.Enum("Data", "address pub priv") -ImportNode = collections.namedtuple("ImportNode", "rescan") +Rescan = enum.Enum("Rescan", "no yes late_timestamp") -def call_import_rpc(call, data, address, scriptPubKey, pubkey, key, label, node, rescan): - """Helper that calls a wallet import RPC on a bitcoin node.""" - watchonly = data != Data.priv - if call == Call.single: - if data == Data.address: - response = node.importaddress(address, label, rescan) - elif data == Data.pub: - response = node.importpubkey(pubkey, label, rescan) - elif data == Data.priv: - response = node.importprivkey(key, label, rescan) - assert_equal(response, None) - elif call == Call.multi: - response = node.importmulti([{ - "scriptPubKey": { - "address": address - }, - "pubkeys": [pubkey] if data == Data.pub else [], - "keys": [key] if data == Data.priv else [], - "label": label, - "watchonly": watchonly - }], {"rescan": rescan}) - assert_equal(response, [{"success": True}]) - return watchonly +class Variant(collections.namedtuple("Variant", "call data rescan prune")): + """Helper for importing one key and verifying scanned transactions.""" + + def do_import(self, timestamp): + """Call one key import RPC.""" + + if self.call == Call.single: + if self.data == Data.address: + response, error = try_rpc(self.node.importaddress, self.address["address"], self.label, + self.rescan == Rescan.yes) + elif self.data == Data.pub: + response, error = try_rpc(self.node.importpubkey, self.address["pubkey"], self.label, + self.rescan == Rescan.yes) + elif self.data == Data.priv: + response, error = try_rpc(self.node.importprivkey, self.key, self.label, self.rescan == Rescan.yes) + assert_equal(response, None) + assert_equal(error, {'message': 'Rescan is disabled in pruned mode', + 'code': -4} if self.expect_disabled else None) + elif self.call == Call.multi: + response = self.node.importmulti([{ + "scriptPubKey": { + "address": self.address["address"] + }, + "timestamp": timestamp + RESCAN_WINDOW + (1 if self.rescan == Rescan.late_timestamp else 0), + "pubkeys": [self.address["pubkey"]] if self.data == Data.pub else [], + "keys": [self.key] if self.data == Data.priv else [], + "label": self.label, + "watchonly": self.data != Data.priv + }], {"rescan": self.rescan in (Rescan.yes, Rescan.late_timestamp)}) + assert_equal(response, [{"success": True}]) + + def check(self, txid=None, amount=None, confirmations=None): + """Verify that getbalance/listtransactions return expected values.""" + + balance = self.node.getbalance(self.label, 0, True) + assert_equal(balance, self.expected_balance) + + txs = self.node.listtransactions(self.label, 10000, 0, True) + assert_equal(len(txs), self.expected_txs) + + if txid is not None: + tx, = [tx for tx in txs if tx["txid"] == txid] + assert_equal(tx["account"], self.label) + assert_equal(tx["address"], self.address["address"]) + assert_equal(tx["amount"], amount) + assert_equal(tx["category"], "receive") + assert_equal(tx["label"], self.label) + assert_equal(tx["txid"], txid) + assert_equal(tx["confirmations"], confirmations) + assert_equal("trusted" not in tx, True) + if self.data != Data.priv: + assert_equal(tx["involvesWatchonly"], True) + else: + assert_equal("involvesWatchonly" not in tx, True) -# List of RPCs that import a wallet key or address in various ways. -IMPORT_RPCS = [functools.partial(call_import_rpc, call, data) for call, data in itertools.product(Call, Data)] +# List of Variants for each way a key or address could be imported. +IMPORT_VARIANTS = [Variant(*variants) for variants in itertools.product(Call, Data, Rescan, (False, True))] -# List of bitcoind nodes that will import keys. -IMPORT_NODES = [ - ImportNode(rescan=True), - ImportNode(rescan=False), -] +# List of nodes to import keys to. Half the nodes will have pruning disabled, +# half will have it enabled. Different nodes will be used for imports that are +# expected to cause rescans, and imports that are not expected to cause +# rescans, in order to prevent rescans during later imports picking up +# transactions associated with earlier imports. This makes it easier to keep +# track of expected balances and transactions. +ImportNode = collections.namedtuple("ImportNode", "prune rescan") +IMPORT_NODES = [ImportNode(*fields) for fields in itertools.product((False, True), repeat=2)] + +# Rescans start at the earliest block up to 2 hours before the key timestamp. +RESCAN_WINDOW = 2 * 60 * 60 class ImportRescanTest(BitcoinTestFramework): @@ -59,6 +110,10 @@ class ImportRescanTest(BitcoinTestFramework): def setup_network(self): extra_args = [["-debug=1"] for _ in range(self.num_nodes)] + for i, import_node in enumerate(IMPORT_NODES, 1): + if import_node.prune: + extra_args[i] += ["-prune=1"] + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args) for i in range(1, self.num_nodes): connect_nodes(self.nodes[i], 0) @@ -66,89 +121,64 @@ class ImportRescanTest(BitcoinTestFramework): def run_test(self): # Create one transaction on node 0 with a unique amount and label for # each possible type of wallet import RPC. - import_rpc_variants = [] - for i, import_rpc in enumerate(IMPORT_RPCS): - label = "label{}".format(i) - addr = self.nodes[0].validateaddress(self.nodes[0].getnewaddress(label)) - key = self.nodes[0].dumpprivkey(addr["address"]) - amount = 24.9375 - i * .0625 - txid = self.nodes[0].sendtoaddress(addr["address"], amount) - import_rpc = functools.partial(import_rpc, addr["address"], addr["scriptPubKey"], addr["pubkey"], key, - label) - import_rpc_variants.append((import_rpc, label, amount, txid, addr)) + for i, variant in enumerate(IMPORT_VARIANTS): + variant.label = "label {} {}".format(i, variant) + variant.address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress(variant.label)) + variant.key = self.nodes[0].dumpprivkey(variant.address["address"]) + variant.initial_amount = 25 - (i + 1) / 4.0 + variant.initial_txid = self.nodes[0].sendtoaddress(variant.address["address"], variant.initial_amount) + # Generate a block containing the initial transactions, then another + # block further in the future (past the rescan window). self.nodes[0].generate(1) assert_equal(self.nodes[0].getrawmempool(), []) + timestamp = self.nodes[0].getblockheader(self.nodes[0].getbestblockhash())["time"] + set_node_times(self.nodes, timestamp + RESCAN_WINDOW + 1) + self.nodes[0].generate(1) sync_blocks(self.nodes) - # For each importing node and variation of wallet import RPC, invoke - # the RPC and check the results from getbalance and listtransactions. - for node, import_node in zip(self.nodes[1:], IMPORT_NODES): - for import_rpc, label, amount, txid, addr in import_rpc_variants: - watchonly = import_rpc(node, import_node.rescan) + # For each variation of wallet key import, invoke the import RPC and + # check the results from getbalance and listtransactions. + for variant in IMPORT_VARIANTS: + variant.expect_disabled = variant.rescan == Rescan.yes and variant.prune and variant.call == Call.single + expect_rescan = variant.rescan == Rescan.yes and not variant.expect_disabled + variant.node = self.nodes[1 + IMPORT_NODES.index(ImportNode(variant.prune, expect_rescan))] + variant.do_import(timestamp) + if expect_rescan: + variant.expected_balance = variant.initial_amount + variant.expected_txs = 1 + variant.check(variant.initial_txid, variant.initial_amount, 2) + else: + variant.expected_balance = 0 + variant.expected_txs = 0 + variant.check() - balance = node.getbalance(label, 0, True) - if import_node.rescan: - assert_equal(balance, amount) - else: - assert_equal(balance, 0) - - txs = node.listtransactions(label, 10000, 0, True) - if import_node.rescan: - assert_equal(len(txs), 1) - assert_equal(txs[0]["account"], label) - assert_equal(txs[0]["address"], addr["address"]) - assert_equal(txs[0]["amount"], amount) - assert_equal(txs[0]["category"], "receive") - assert_equal(txs[0]["label"], label) - assert_equal(txs[0]["txid"], txid) - assert_equal(txs[0]["confirmations"], 1) - assert_equal("trusted" not in txs[0], True) - if watchonly: - assert_equal(txs[0]["involvesWatchonly"], True) - else: - assert_equal("involvesWatchonly" not in txs[0], True) - else: - assert_equal(len(txs), 0) - - # Create spends for all the imported addresses. - spend_txids = [] + # Create new transactions sending to each address. fee = self.nodes[0].getnetworkinfo()["relayfee"] - for import_rpc, label, amount, txid, addr in import_rpc_variants: - raw_tx = self.nodes[0].getrawtransaction(txid) - decoded_tx = self.nodes[0].decoderawtransaction(raw_tx) - input_vout = next(out["n"] for out in decoded_tx["vout"] - if out["scriptPubKey"]["addresses"] == [addr["address"]]) - inputs = [{"txid": txid, "vout": input_vout}] - outputs = {self.nodes[0].getnewaddress(): Decimal(amount) - fee} - raw_spend_tx = self.nodes[0].createrawtransaction(inputs, outputs) - signed_spend_tx = self.nodes[0].signrawtransaction(raw_spend_tx) - spend_txid = self.nodes[0].sendrawtransaction(signed_spend_tx["hex"]) - spend_txids.append(spend_txid) + for i, variant in enumerate(IMPORT_VARIANTS): + variant.sent_amount = 25 - (2 * i + 1) / 8.0 + variant.sent_txid = self.nodes[0].sendtoaddress(variant.address["address"], variant.sent_amount) + # Generate a block containing the new transactions. self.nodes[0].generate(1) assert_equal(self.nodes[0].getrawmempool(), []) sync_blocks(self.nodes) - # Check the results from getbalance and listtransactions after the spends. - for node, import_node in zip(self.nodes[1:], IMPORT_NODES): - txs = node.listtransactions("*", 10000, 0, True) - for (import_rpc, label, amount, txid, addr), spend_txid in zip(import_rpc_variants, spend_txids): - balance = node.getbalance(label, 0, True) - spend_tx = [tx for tx in txs if tx["txid"] == spend_txid] - if import_node.rescan: - assert_equal(balance, amount) - assert_equal(len(spend_tx), 1) - assert_equal(spend_tx[0]["account"], "") - assert_equal(spend_tx[0]["amount"] + spend_tx[0]["fee"], -amount) - assert_equal(spend_tx[0]["category"], "send") - assert_equal("label" not in spend_tx[0], True) - assert_equal(spend_tx[0]["confirmations"], 1) - assert_equal("trusted" not in spend_tx[0], True) - assert_equal("involvesWatchonly" not in txs[0], True) - else: - assert_equal(balance, 0) - assert_equal(spend_tx, []) + # Check the latest results from getbalance and listtransactions. + for variant in IMPORT_VARIANTS: + if not variant.expect_disabled: + variant.expected_balance += variant.sent_amount + variant.expected_txs += 1 + variant.check(variant.sent_txid, variant.sent_amount, 1) + else: + variant.check() + + +def try_rpc(func, *args, **kwargs): + try: + return func(*args, **kwargs), None + except JSONRPCException as e: + return None, e.error if __name__ == "__main__": diff --git a/qa/rpc-tests/importmulti.py b/qa/rpc-tests/importmulti.py index e100a3af9..1aa4ba2e1 100755 --- a/qa/rpc-tests/importmulti.py +++ b/qa/rpc-tests/importmulti.py @@ -20,6 +20,7 @@ class ImportMultiTest (BitcoinTestFramework): print ("Mining blocks...") self.nodes[0].generate(1) self.nodes[1].generate(1) + timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime'] # keyword definition PRIV_KEY = 'privkey' @@ -52,31 +53,48 @@ class ImportMultiTest (BitcoinTestFramework): result = self.nodes[1].importmulti([{ "scriptPubKey": { "address": address['address'] - } + }, + "timestamp": "now", }]) assert_equal(result[0]['success'], True) address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], True) assert_equal(address_assert['ismine'], False) + assert_equal(address_assert['timestamp'], timestamp) + watchonly_address = address['address'] + watchonly_timestamp = timestamp + print("Should not import an invalid address") + result = self.nodes[1].importmulti([{ + "scriptPubKey": { + "address": "not valid address", + }, + "timestamp": "now", + }]) + assert_equal(result[0]['success'], False) + assert_equal(result[0]['error']['code'], -5) + assert_equal(result[0]['error']['message'], 'Invalid address') # ScriptPubKey + internal print("Should import a scriptPubKey with internal flag") address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) result = self.nodes[1].importmulti([{ "scriptPubKey": address['scriptPubKey'], + "timestamp": "now", "internal": True }]) assert_equal(result[0]['success'], True) address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], True) assert_equal(address_assert['ismine'], False) + assert_equal(address_assert['timestamp'], timestamp) # ScriptPubKey + !internal print("Should not import a scriptPubKey without internal flag") address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) result = self.nodes[1].importmulti([{ - "scriptPubKey": address['scriptPubKey'] + "scriptPubKey": address['scriptPubKey'], + "timestamp": "now", }]) assert_equal(result[0]['success'], False) assert_equal(result[0]['error']['code'], -8) @@ -84,6 +102,7 @@ class ImportMultiTest (BitcoinTestFramework): address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) + assert_equal('timestamp' in address_assert, False) # Address + Public key + !Internal @@ -93,12 +112,14 @@ class ImportMultiTest (BitcoinTestFramework): "scriptPubKey": { "address": address['address'] }, + "timestamp": "now", "pubkeys": [ address['pubkey'] ] }]) assert_equal(result[0]['success'], True) address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], True) assert_equal(address_assert['ismine'], False) + assert_equal(address_assert['timestamp'], timestamp) # ScriptPubKey + Public key + internal @@ -106,6 +127,7 @@ class ImportMultiTest (BitcoinTestFramework): address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) request = [{ "scriptPubKey": address['scriptPubKey'], + "timestamp": "now", "pubkeys": [ address['pubkey'] ], "internal": True }] @@ -114,12 +136,14 @@ class ImportMultiTest (BitcoinTestFramework): address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], True) assert_equal(address_assert['ismine'], False) + assert_equal(address_assert['timestamp'], timestamp) # ScriptPubKey + Public key + !internal print("Should not import a scriptPubKey without internal and with public key") address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) request = [{ "scriptPubKey": address['scriptPubKey'], + "timestamp": "now", "pubkeys": [ address['pubkey'] ] }] result = self.nodes[1].importmulti(request) @@ -129,6 +153,7 @@ class ImportMultiTest (BitcoinTestFramework): address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) + assert_equal('timestamp' in address_assert, False) # Address + Private key + !watchonly print("Should import an address with private key") @@ -137,12 +162,14 @@ class ImportMultiTest (BitcoinTestFramework): "scriptPubKey": { "address": address['address'] }, + "timestamp": "now", "keys": [ self.nodes[0].dumpprivkey(address['address']) ] }]) assert_equal(result[0]['success'], True) address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], True) + assert_equal(address_assert['timestamp'], timestamp) # Address + Private key + watchonly print("Should not import an address with private key and with watchonly") @@ -151,6 +178,7 @@ class ImportMultiTest (BitcoinTestFramework): "scriptPubKey": { "address": address['address'] }, + "timestamp": "now", "keys": [ self.nodes[0].dumpprivkey(address['address']) ], "watchonly": True }]) @@ -160,12 +188,14 @@ class ImportMultiTest (BitcoinTestFramework): address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) + assert_equal('timestamp' in address_assert, False) # ScriptPubKey + Private key + internal print("Should import a scriptPubKey with internal and with private key") address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) result = self.nodes[1].importmulti([{ "scriptPubKey": address['scriptPubKey'], + "timestamp": "now", "keys": [ self.nodes[0].dumpprivkey(address['address']) ], "internal": True }]) @@ -173,12 +203,14 @@ class ImportMultiTest (BitcoinTestFramework): address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], True) + assert_equal(address_assert['timestamp'], timestamp) # ScriptPubKey + Private key + !internal print("Should not import a scriptPubKey without internal and with private key") address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) result = self.nodes[1].importmulti([{ "scriptPubKey": address['scriptPubKey'], + "timestamp": "now", "keys": [ self.nodes[0].dumpprivkey(address['address']) ] }]) assert_equal(result[0]['success'], False) @@ -187,6 +219,7 @@ class ImportMultiTest (BitcoinTestFramework): address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) + assert_equal('timestamp' in address_assert, False) # P2SH address @@ -197,18 +230,21 @@ class ImportMultiTest (BitcoinTestFramework): self.nodes[1].generate(100) transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00) self.nodes[1].generate(1) + timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime'] transaction = self.nodes[1].gettransaction(transactionid) print("Should import a p2sh") result = self.nodes[1].importmulti([{ "scriptPubKey": { "address": multi_sig_script['address'] - } + }, + "timestamp": "now", }]) assert_equal(result[0]['success'], True) address_assert = self.nodes[1].validateaddress(multi_sig_script['address']) assert_equal(address_assert['isscript'], True) assert_equal(address_assert['iswatchonly'], True) + assert_equal(address_assert['timestamp'], timestamp) p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0] assert_equal(p2shunspent['spendable'], False) assert_equal(p2shunspent['solvable'], False) @@ -222,6 +258,7 @@ class ImportMultiTest (BitcoinTestFramework): self.nodes[1].generate(100) transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00) self.nodes[1].generate(1) + timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime'] transaction = self.nodes[1].gettransaction(transactionid) print("Should import a p2sh with respective redeem script") @@ -229,9 +266,12 @@ class ImportMultiTest (BitcoinTestFramework): "scriptPubKey": { "address": multi_sig_script['address'] }, + "timestamp": "now", "redeemscript": multi_sig_script['redeemScript'] }]) assert_equal(result[0]['success'], True) + address_assert = self.nodes[1].validateaddress(multi_sig_script['address']) + assert_equal(address_assert['timestamp'], timestamp) p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0] assert_equal(p2shunspent['spendable'], False) @@ -246,6 +286,7 @@ class ImportMultiTest (BitcoinTestFramework): self.nodes[1].generate(100) transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00) self.nodes[1].generate(1) + timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime'] transaction = self.nodes[1].gettransaction(transactionid) print("Should import a p2sh with respective redeem script and private keys") @@ -253,10 +294,13 @@ class ImportMultiTest (BitcoinTestFramework): "scriptPubKey": { "address": multi_sig_script['address'] }, + "timestamp": "now", "redeemscript": multi_sig_script['redeemScript'], "keys": [ self.nodes[0].dumpprivkey(sig_address_1['address']), self.nodes[0].dumpprivkey(sig_address_2['address'])] }]) assert_equal(result[0]['success'], True) + address_assert = self.nodes[1].validateaddress(multi_sig_script['address']) + assert_equal(address_assert['timestamp'], timestamp) p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0] assert_equal(p2shunspent['spendable'], False) @@ -277,6 +321,7 @@ class ImportMultiTest (BitcoinTestFramework): "scriptPubKey": { "address": multi_sig_script['address'] }, + "timestamp": "now", "redeemscript": multi_sig_script['redeemScript'], "keys": [ self.nodes[0].dumpprivkey(sig_address_1['address']), self.nodes[0].dumpprivkey(sig_address_2['address'])], "watchonly": True @@ -294,6 +339,7 @@ class ImportMultiTest (BitcoinTestFramework): "scriptPubKey": { "address": address['address'] }, + "timestamp": "now", "pubkeys": [ address2['pubkey'] ] }]) assert_equal(result[0]['success'], False) @@ -302,6 +348,7 @@ class ImportMultiTest (BitcoinTestFramework): address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) + assert_equal('timestamp' in address_assert, False) # ScriptPubKey + Public key + internal + Wrong pubkey @@ -310,6 +357,7 @@ class ImportMultiTest (BitcoinTestFramework): address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) request = [{ "scriptPubKey": address['scriptPubKey'], + "timestamp": "now", "pubkeys": [ address2['pubkey'] ], "internal": True }] @@ -320,6 +368,7 @@ class ImportMultiTest (BitcoinTestFramework): address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) + assert_equal('timestamp' in address_assert, False) # Address + Private key + !watchonly + Wrong private key @@ -330,6 +379,7 @@ class ImportMultiTest (BitcoinTestFramework): "scriptPubKey": { "address": address['address'] }, + "timestamp": "now", "keys": [ self.nodes[0].dumpprivkey(address2['address']) ] }]) assert_equal(result[0]['success'], False) @@ -338,6 +388,7 @@ class ImportMultiTest (BitcoinTestFramework): address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) + assert_equal('timestamp' in address_assert, False) # ScriptPubKey + Private key + internal + Wrong private key @@ -346,6 +397,7 @@ class ImportMultiTest (BitcoinTestFramework): address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress()) result = self.nodes[1].importmulti([{ "scriptPubKey": address['scriptPubKey'], + "timestamp": "now", "keys": [ self.nodes[0].dumpprivkey(address2['address']) ], "internal": True }]) @@ -355,6 +407,28 @@ class ImportMultiTest (BitcoinTestFramework): address_assert = self.nodes[1].validateaddress(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) + assert_equal('timestamp' in address_assert, False) + + # restart nodes to check for proper serialization/deserialization of watch only address + stop_nodes(self.nodes) + self.nodes = start_nodes(2, self.options.tmpdir) + address_assert = self.nodes[1].validateaddress(watchonly_address) + assert_equal(address_assert['iswatchonly'], True) + assert_equal(address_assert['ismine'], False) + assert_equal(address_assert['timestamp'], watchonly_timestamp); + + # Bad or missing timestamps + print("Should throw on invalid or missing timestamp values") + assert_raises_message(JSONRPCException, 'Missing required timestamp field for key', + self.nodes[1].importmulti, [{ + "scriptPubKey": address['scriptPubKey'], + }]) + assert_raises_message(JSONRPCException, 'Expected number or "now" timestamp value for key. got type string', + self.nodes[1].importmulti, [{ + "scriptPubKey": address['scriptPubKey'], + "timestamp": "", + }]) + if __name__ == '__main__': ImportMultiTest ().main () diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py index 9151ecf5d..47dfe4f5f 100755 --- a/qa/rpc-tests/p2p-compactblocks.py +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -7,7 +7,6 @@ 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 ''' diff --git a/qa/rpc-tests/p2p-fullblocktest.py b/qa/rpc-tests/p2p-fullblocktest.py index e4b889d76..44e5f1032 100755 --- a/qa/rpc-tests/p2p-fullblocktest.py +++ b/qa/rpc-tests/p2p-fullblocktest.py @@ -398,7 +398,7 @@ class FullBlockTest(ComparisonTestFramework): # Extend the b26 chain to make sure bitcoind isn't accepting b26 b27 = block(27, spend=out[7]) - yield rejected(RejectResult(16, b'bad-prevblk')) + yield rejected(RejectResult(0, b'bad-prevblk')) # Now try a too-large-coinbase script tip(15) @@ -410,7 +410,7 @@ class FullBlockTest(ComparisonTestFramework): # Extend the b28 chain to make sure bitcoind isn't accepting b28 b29 = block(29, spend=out[7]) - yield rejected(RejectResult(16, b'bad-prevblk')) + yield rejected(RejectResult(0, b'bad-prevblk')) # b30 has a max-sized coinbase scriptSig. tip(23) diff --git a/qa/rpc-tests/p2p-leaktests.py b/qa/rpc-tests/p2p-leaktests.py new file mode 100755 index 000000000..41ca84d77 --- /dev/null +++ b/qa/rpc-tests/p2p-leaktests.py @@ -0,0 +1,145 @@ +#!/usr/bin/env python3 +# Copyright (c) 2017 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 * + +''' +Test for message sending before handshake completion + +A node should never send anything other than VERSION/VERACK/REJECT until it's +received a VERACK. + +This test connects to a node and sends it a few messages, trying to intice it +into sending us something it shouldn't. +''' + +banscore = 10 + +class CLazyNode(NodeConnCB): + def __init__(self): + self.connection = None + self.unexpected_msg = False + self.connected = False + super().__init__() + + def add_connection(self, conn): + self.connection = conn + + def send_message(self, message): + self.connection.send_message(message) + + def bad_message(self, message): + self.unexpected_msg = True + print("should not have received message: %s" % message.command) + + def on_open(self, conn): + self.connected = True + + def on_version(self, conn, message): self.bad_message(message) + def on_verack(self, conn, message): self.bad_message(message) + def on_reject(self, conn, message): self.bad_message(message) + def on_inv(self, conn, message): self.bad_message(message) + def on_addr(self, conn, message): self.bad_message(message) + def on_alert(self, conn, message): self.bad_message(message) + def on_getdata(self, conn, message): self.bad_message(message) + def on_getblocks(self, conn, message): self.bad_message(message) + def on_tx(self, conn, message): self.bad_message(message) + def on_block(self, conn, message): self.bad_message(message) + def on_getaddr(self, conn, message): self.bad_message(message) + def on_headers(self, conn, message): self.bad_message(message) + def on_getheaders(self, conn, message): self.bad_message(message) + def on_ping(self, conn, message): self.bad_message(message) + def on_mempool(self, conn): self.bad_message(message) + def on_pong(self, conn, message): self.bad_message(message) + def on_feefilter(self, conn, message): self.bad_message(message) + def on_sendheaders(self, conn, message): self.bad_message(message) + def on_sendcmpct(self, conn, message): self.bad_message(message) + def on_cmpctblock(self, conn, message): self.bad_message(message) + def on_getblocktxn(self, conn, message): self.bad_message(message) + def on_blocktxn(self, conn, message): self.bad_message(message) + +# Node that never sends a version. We'll use this to send a bunch of messages +# anyway, and eventually get disconnected. +class CNodeNoVersionBan(CLazyNode): + def __init__(self): + super().__init__() + + # send a bunch of veracks without sending a message. This should get us disconnected. + # NOTE: implementation-specific check here. Remove if bitcoind ban behavior changes + def on_open(self, conn): + super().on_open(conn) + for i in range(banscore): + self.send_message(msg_verack()) + + def on_reject(self, conn, message): pass + +# Node that never sends a version. This one just sits idle and hopes to receive +# any message (it shouldn't!) +class CNodeNoVersionIdle(CLazyNode): + def __init__(self): + super().__init__() + +# Node that sends a version but not a verack. +class CNodeNoVerackIdle(CLazyNode): + def __init__(self): + self.version_received = False + super().__init__() + + def on_reject(self, conn, message): pass + def on_verack(self, conn, message): pass + # When version is received, don't reply with a verack. Instead, see if the + # node will give us a message that it shouldn't. This is not an exhaustive + # list! + def on_version(self, conn, message): + self.version_received = True + conn.send_message(msg_ping()) + conn.send_message(msg_getaddr()) + +class P2PLeakTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 1 + def setup_network(self): + extra_args = [['-debug', '-banscore='+str(banscore)] + for i in range(self.num_nodes)] + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args) + + def run_test(self): + no_version_bannode = CNodeNoVersionBan() + no_version_idlenode = CNodeNoVersionIdle() + no_verack_idlenode = CNodeNoVerackIdle() + + connections = [] + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], no_version_bannode, send_version=False)) + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], no_version_idlenode, send_version=False)) + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], no_verack_idlenode)) + no_version_bannode.add_connection(connections[0]) + no_version_idlenode.add_connection(connections[1]) + no_verack_idlenode.add_connection(connections[2]) + + NetworkThread().start() # Start up network handling in another thread + + assert(wait_until(lambda: no_version_bannode.connected and no_version_idlenode.connected and no_verack_idlenode.version_received, timeout=10)) + + # Mine a block and make sure that it's not sent to the connected nodes + self.nodes[0].generate(1) + + #Give the node enough time to possibly leak out a message + time.sleep(5) + + #This node should have been banned + assert(no_version_bannode.connection.state == "closed") + + [conn.disconnect_node() for conn in connections] + + # Make sure no unexpected messages came in + assert(no_version_bannode.unexpected_msg == False) + assert(no_version_idlenode.unexpected_msg == False) + assert(no_verack_idlenode.unexpected_msg == False) + +if __name__ == '__main__': + P2PLeakTest().main() diff --git a/qa/rpc-tests/p2p-timeouts.py b/qa/rpc-tests/p2p-timeouts.py new file mode 100755 index 000000000..f1b190587 --- /dev/null +++ b/qa/rpc-tests/p2p-timeouts.py @@ -0,0 +1,103 @@ +#!/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. +""" TimeoutsTest -- test various net timeouts (only in extended tests) + +- Create three bitcoind nodes: + + no_verack_node - we never send a verack in response to their version + no_version_node - we never send a version (only a ping) + no_send_node - we never send any P2P message. + +- Start all three nodes +- Wait 1 second +- Assert that we're connected +- Send a ping to no_verack_node and no_version_node +- Wait 30 seconds +- Assert that we're still connected +- Send a ping to no_verack_node and no_version_node +- Wait 31 seconds +- Assert that we're no longer connected (timeout to receive version/verack is 60 seconds) +""" + +from time import sleep + +from test_framework.mininode import * +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * + +class TestNode(SingleNodeConnCB): + def __init__(self): + SingleNodeConnCB.__init__(self) + self.connected = False + self.received_version = False + + def on_open(self, conn): + self.connected = True + + def on_close(self, conn): + self.connected = False + + def on_version(self, conn, message): + # Don't send a verack in response + self.received_version = True + +class TimeoutsTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 1 + + 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"]]) + + def run_test(self): + # Setup the p2p connections and start up the network thread. + self.no_verack_node = TestNode() # never send verack + self.no_version_node = TestNode() # never send version (just ping) + self.no_send_node = TestNode() # never send anything + + connections = [] + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], self.no_verack_node)) + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], self.no_version_node, send_version=False)) + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], self.no_send_node, send_version=False)) + self.no_verack_node.add_connection(connections[0]) + self.no_version_node.add_connection(connections[1]) + self.no_send_node.add_connection(connections[2]) + + NetworkThread().start() # Start up network handling in another thread + + sleep(1) + + assert(self.no_verack_node.connected) + assert(self.no_version_node.connected) + assert(self.no_send_node.connected) + + ping_msg = msg_ping() + connections[0].send_message(ping_msg) + connections[1].send_message(ping_msg) + + sleep(30) + + assert(self.no_verack_node.received_version) + + assert(self.no_verack_node.connected) + assert(self.no_version_node.connected) + assert(self.no_send_node.connected) + + connections[0].send_message(ping_msg) + connections[1].send_message(ping_msg) + + sleep(31) + + assert(not self.no_verack_node.connected) + assert(not self.no_version_node.connected) + assert(not self.no_send_node.connected) + +if __name__ == '__main__': + TimeoutsTest().main() diff --git a/qa/rpc-tests/rpcnamedargs.py b/qa/rpc-tests/rpcnamedargs.py index da2d8f040..f9a40955c 100755 --- a/qa/rpc-tests/rpcnamedargs.py +++ b/qa/rpc-tests/rpcnamedargs.py @@ -3,17 +3,11 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -from decimal import Decimal - from test_framework.test_framework import BitcoinTestFramework -from test_framework.authproxy import JSONRPCException from test_framework.util import ( assert_equal, assert_raises_jsonrpc, - assert_is_hex_string, - assert_is_hash_string, start_nodes, - connect_nodes_bi, ) diff --git a/qa/rpc-tests/segwit.py b/qa/rpc-tests/segwit.py index 299f5387e..d6831e00e 100755 --- a/qa/rpc-tests/segwit.py +++ b/qa/rpc-tests/segwit.py @@ -130,10 +130,14 @@ class SegWitTest(BitcoinTestFramework): 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['sizelimit'] == 1000000) + assert('weightlimit' not in tmpl) 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['sizelimit'] == 1000000) + assert('weightlimit' not in tmpl) assert(tmpl['sigoplimit'] == 20000) assert(tmpl['transactions'][0]['hash'] == txid) assert(tmpl['transactions'][0]['sigops'] == 2) @@ -241,6 +245,8 @@ class SegWitTest(BitcoinTestFramework): 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['sizelimit'] >= 3999577) # actual maximum size is lower due to minimum mandatory non-witness data + assert(tmpl['weightlimit'] == 4000000) assert(tmpl['sigoplimit'] == 80000) assert(tmpl['transactions'][0]['txid'] == txid) assert(tmpl['transactions'][0]['sigops'] == 8) @@ -250,6 +256,8 @@ class SegWitTest(BitcoinTestFramework): try: tmpl = self.nodes[0].getblocktemplate({}) assert(len(tmpl['transactions']) == 1) # Doesn't include witness tx + assert(tmpl['sizelimit'] == 1000000) + assert('weightlimit' not in tmpl) assert(tmpl['sigoplimit'] == 20000) assert(tmpl['transactions'][0]['hash'] == txid) assert(tmpl['transactions'][0]['sigops'] == 2) diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 91daa4ab1..5b563c58a 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -1540,6 +1540,7 @@ class NodeConnCB(object): if conn.ver_send > BIP0031_VERSION: conn.send_message(msg_pong(message.nonce)) def on_reject(self, conn, message): pass + def on_open(self, conn): pass def on_close(self, conn): pass def on_mempool(self, conn): pass def on_pong(self, conn, message): pass @@ -1614,7 +1615,7 @@ class NodeConn(asyncore.dispatcher): "regtest": b"\xfa\xbf\xb5\xda", # regtest } - def __init__(self, dstaddr, dstport, rpc, callback, net="regtest", services=NODE_NETWORK): + def __init__(self, dstaddr, dstport, rpc, callback, net="regtest", services=NODE_NETWORK, send_version=True): asyncore.dispatcher.__init__(self, map=mininode_socket_map) self.log = logging.getLogger("NodeConn(%s:%d)" % (dstaddr, dstport)) self.dstaddr = dstaddr @@ -1631,14 +1632,16 @@ class NodeConn(asyncore.dispatcher): self.disconnect = False self.nServices = 0 - # stuff version msg into sendbuf - vt = msg_version() - vt.nServices = services - vt.addrTo.ip = self.dstaddr - vt.addrTo.port = self.dstport - vt.addrFrom.ip = "0.0.0.0" - vt.addrFrom.port = 0 - self.send_message(vt, True) + if send_version: + # stuff version msg into sendbuf + vt = msg_version() + vt.nServices = services + vt.addrTo.ip = self.dstaddr + vt.addrTo.port = self.dstport + vt.addrFrom.ip = "0.0.0.0" + vt.addrFrom.port = 0 + self.send_message(vt, True) + print('MiniNode: Connecting to Bitcoin Node IP # ' + dstaddr + ':' \ + str(dstport)) @@ -1652,8 +1655,10 @@ class NodeConn(asyncore.dispatcher): self.log.debug(msg) def handle_connect(self): - self.show_debug_msg("MiniNode: Connected & Listening: \n") - self.state = "connected" + if self.state != "connected": + self.show_debug_msg("MiniNode: Connected & Listening: \n") + self.state = "connected" + self.cb.on_open(self) def handle_close(self): self.show_debug_msg("MiniNode: Closing Connection to %s:%d... " @@ -1681,11 +1686,20 @@ class NodeConn(asyncore.dispatcher): def writable(self): with mininode_lock: + pre_connection = self.state == "connecting" length = len(self.sendbuf) - return (length > 0) + return (length > 0 or pre_connection) def handle_write(self): with mininode_lock: + # asyncore does not expose socket connection, only the first read/write + # event, thus we must check connection manually here to know when we + # actually connect + if self.state == "connecting": + self.handle_connect() + if not self.writable(): + return + try: sent = self.send(self.sendbuf) except: diff --git a/qa/rpc-tests/wallet-accounts.py b/qa/rpc-tests/wallet-accounts.py index c51181e4f..45a9db057 100755 --- a/qa/rpc-tests/wallet-accounts.py +++ b/qa/rpc-tests/wallet-accounts.py @@ -6,9 +6,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( start_nodes, - start_node, assert_equal, - connect_nodes_bi, ) diff --git a/src/addrman.cpp b/src/addrman.cpp index f3c238fbb..b6ab4c630 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -53,11 +53,7 @@ bool CAddrInfo::IsTerrible(int64_t nNow) const double CAddrInfo::GetChance(int64_t nNow) const { double fChance = 1.0; - - int64_t nSinceLastTry = nNow - nLastTry; - - if (nSinceLastTry < 0) - nSinceLastTry = 0; + int64_t nSinceLastTry = std::max(nNow - nLastTry, 0); // deprioritize very recent attempts away if (nSinceLastTry < 60 * 10) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 6c6f677df..383d9849a 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -97,10 +97,10 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1510704000; // November 15th, 2017. // The best chain should have at least this much work. - consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000002cb971dd56d1c583c20f90"); + consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000003f94d1ad391682fe038bf5"); // By default assume that the signatures in ancestors of this block are valid. - consensus.defaultAssumeValid = uint256S("0x0000000000000000030abc968e1bd635736e880b946085c93152969b9a81a6e2"); //447235 + consensus.defaultAssumeValid = uint256S("0x00000000000000000013176bf8d7dfeab4e1db31dc93bc311b436e82ab226b90"); //453354 /** * The message start string is designed to be unlikely to occur in normal data. @@ -201,10 +201,10 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1493596800; // May 1st 2017 // The best chain should have at least this much work. - consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000000198b4def2baa9338d6"); + consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000001f057509eba81aed91"); // By default assume that the signatures in ancestors of this block are valid. - consensus.defaultAssumeValid = uint256S("0x000000000871ee6842d3648317ccc8a435eb8cc3c2429aee94faff9ba26b05a0"); //1043841 + consensus.defaultAssumeValid = uint256S("0x00000000000128796ee387cf110ccb9d2f36cffaf7f73079c995377c65ac0dcc"); //1079274 pchMessageStart[0] = 0x0b; pchMessageStart[1] = 0x11; diff --git a/src/clientversion.h b/src/clientversion.h index 0b27bb1bd..69154d546 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -15,7 +15,7 @@ //! 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 13 +#define CLIENT_VERSION_MINOR 14 #define CLIENT_VERSION_REVISION 99 #define CLIENT_VERSION_BUILD 0 diff --git a/src/hash.h b/src/hash.h index 3b86fcc03..eacb8f04f 100644 --- a/src/hash.h +++ b/src/hash.h @@ -25,9 +25,9 @@ public: static const size_t OUTPUT_SIZE = CSHA256::OUTPUT_SIZE; void Finalize(unsigned char hash[OUTPUT_SIZE]) { - unsigned char buf[sha.OUTPUT_SIZE]; + unsigned char buf[CSHA256::OUTPUT_SIZE]; sha.Finalize(buf); - sha.Reset().Write(buf, sha.OUTPUT_SIZE).Finalize(hash); + sha.Reset().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(hash); } CHash256& Write(const unsigned char *data, size_t len) { @@ -49,9 +49,9 @@ public: static const size_t OUTPUT_SIZE = CRIPEMD160::OUTPUT_SIZE; void Finalize(unsigned char hash[OUTPUT_SIZE]) { - unsigned char buf[sha.OUTPUT_SIZE]; + unsigned char buf[CSHA256::OUTPUT_SIZE]; sha.Finalize(buf); - CRIPEMD160().Write(buf, sha.OUTPUT_SIZE).Finalize(hash); + CRIPEMD160().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(hash); } CHash160& Write(const unsigned char *data, size_t len) { diff --git a/src/httprpc.cpp b/src/httprpc.cpp index daac7a0f1..8ac6925ac 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -112,7 +112,7 @@ static bool multiUserAuthorized(std::string strUserPass) std::string strSalt = vFields[1]; std::string strHash = vFields[2]; - unsigned int KEY_SIZE = 32; + static const unsigned int KEY_SIZE = 32; unsigned char out[KEY_SIZE]; CHMAC_SHA256(reinterpret_cast(strSalt.c_str()), strSalt.size()).Write(reinterpret_cast(strPass.c_str()), strPass.size()).Finalize(out); diff --git a/src/init.cpp b/src/init.cpp index 7c108ac4a..cf265180f 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -934,7 +934,7 @@ bool AppInitParameterInteraction() int64_t nMempoolSizeMin = GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) * 1000 * 40; if (nMempoolSizeMax < 0 || nMempoolSizeMax < nMempoolSizeMin) return InitError(strprintf(_("-maxmempool must be at least %d MB"), std::ceil(nMempoolSizeMin / 1000000.0))); - // incremental relay fee sets the minimimum feerate increase necessary for BIP 125 replacement in the mempool + // incremental relay fee sets the minimum feerate increase necessary for BIP 125 replacement in the mempool // and the amount the mempool min fee increases above the feerate of txs evicted due to mempool limiting. if (IsArgSet("-incrementalrelayfee")) { diff --git a/src/net.cpp b/src/net.cpp index 505eb971c..de5fc2969 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1388,6 +1388,11 @@ void CConnman::ThreadSocketHandler() LogPrintf("ping timeout: %fs\n", 0.000001 * (GetTimeMicros() - pnode->nPingUsecStart)); pnode->fDisconnect = true; } + else if (!pnode->fSuccessfullyConnected) + { + LogPrintf("version handshake timeout from %d\n", pnode->id); + pnode->fDisconnect = true; + } } } { diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 7d76aa0b4..3ec1a1c27 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1190,8 +1190,31 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr } } + if (strCommand == NetMsgType::REJECT) + { + if (fDebug) { + try { + std::string strMsg; unsigned char ccode; std::string strReason; + vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, MAX_REJECT_MESSAGE_LENGTH); - if (strCommand == NetMsgType::VERSION) + std::ostringstream ss; + ss << strMsg << " code " << itostr(ccode) << ": " << strReason; + + if (strMsg == NetMsgType::BLOCK || strMsg == NetMsgType::TX) + { + uint256 hash; + vRecv >> hash; + ss << ": hash " << hash.ToString(); + } + LogPrint("net", "Reject %s\n", SanitizeString(ss.str())); + } catch (const std::ios_base::failure&) { + // Avoid feedback loops by preventing reject messages from triggering a new reject message. + LogPrint("net", "Unparseable reject message received\n"); + } + } + } + + else if (strCommand == NetMsgType::VERSION) { // Each connection can only send one version message if (pfrom->nVersion != 0) @@ -1402,6 +1425,13 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr pfrom->fSuccessfullyConnected = true; } + else if (!pfrom->fSuccessfullyConnected) + { + // Must have a verack message before anything else + LOCK(cs_main); + Misbehaving(pfrom->GetId(), 1); + return false; + } else if (strCommand == NetMsgType::ADDR) { @@ -2549,31 +2579,6 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr pfrom->fRelayTxes = true; } - - else if (strCommand == NetMsgType::REJECT) - { - if (fDebug) { - try { - std::string strMsg; unsigned char ccode; std::string strReason; - vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, MAX_REJECT_MESSAGE_LENGTH); - - std::ostringstream ss; - ss << strMsg << " code " << itostr(ccode) << ": " << strReason; - - if (strMsg == NetMsgType::BLOCK || strMsg == NetMsgType::TX) - { - uint256 hash; - vRecv >> hash; - ss << ": hash " << hash.ToString(); - } - LogPrint("net", "Reject %s\n", SanitizeString(ss.str())); - } catch (const std::ios_base::failure&) { - // Avoid feedback loops by preventing reject messages from triggering a new reject message. - LogPrint("net", "Unparseable reject message received\n"); - } - } - } - else if (strCommand == NetMsgType::FEEFILTER) { CAmount newFeeFilter = 0; vRecv >> newFeeFilter; @@ -2601,6 +2606,36 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr return true; } +static bool SendRejectsAndCheckIfBanned(CNode* pnode, CConnman& connman) +{ + AssertLockHeld(cs_main); + CNodeState &state = *State(pnode->GetId()); + + BOOST_FOREACH(const CBlockReject& reject, state.rejects) { + connman.PushMessage(pnode, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::REJECT, (std::string)NetMsgType::BLOCK, reject.chRejectCode, reject.strRejectReason, reject.hashBlock)); + } + state.rejects.clear(); + + if (state.fShouldBan) { + state.fShouldBan = false; + if (pnode->fWhitelisted) + LogPrintf("Warning: not punishing whitelisted peer %s!\n", pnode->addr.ToString()); + else if (pnode->fAddnode) + LogPrintf("Warning: not punishing addnoded peer %s!\n", pnode->addr.ToString()); + else { + pnode->fDisconnect = true; + if (pnode->addr.IsLocal()) + LogPrintf("Warning: not banning local peer %s!\n", pnode->addr.ToString()); + else + { + connman.Ban(pnode->addr, BanReasonNodeMisbehaving); + } + } + return true; + } + return false; +} + bool ProcessMessages(CNode* pfrom, CConnman& connman, const std::atomic& interruptMsgProc) { const CChainParams& chainparams = Params(); @@ -2711,8 +2746,12 @@ bool ProcessMessages(CNode* pfrom, CConnman& connman, const std::atomic& i PrintExceptionContinue(NULL, "ProcessMessages()"); } - if (!fRet) + if (!fRet) { LogPrintf("%s(%s, %u bytes) FAILED peer=%d\n", __func__, SanitizeString(strCommand), nMessageSize, pfrom->id); + } + + LOCK(cs_main); + SendRejectsAndCheckIfBanned(pfrom, connman); return fMoreWork; } @@ -2778,30 +2817,10 @@ bool SendMessages(CNode* pto, CConnman& connman, const std::atomic& interr if (!lockMain) return true; + if (SendRejectsAndCheckIfBanned(pto, connman)) + return true; CNodeState &state = *State(pto->GetId()); - BOOST_FOREACH(const CBlockReject& reject, state.rejects) - connman.PushMessage(pto, msgMaker.Make(NetMsgType::REJECT, (std::string)NetMsgType::BLOCK, reject.chRejectCode, reject.strRejectReason, reject.hashBlock)); - state.rejects.clear(); - - if (state.fShouldBan) { - state.fShouldBan = false; - if (pto->fWhitelisted) - LogPrintf("Warning: not punishing whitelisted peer %s!\n", pto->addr.ToString()); - else if (pto->fAddnode) - LogPrintf("Warning: not punishing addnoded peer %s!\n", pto->addr.ToString()); - else { - pto->fDisconnect = true; - if (pto->addr.IsLocal()) - LogPrintf("Warning: not banning local peer %s!\n", pto->addr.ToString()); - else - { - connman.Ban(pto->addr, BanReasonNodeMisbehaving); - } - return true; - } - } - // Address refresh broadcast int64_t nNow = GetTimeMicros(); if (!IsInitialBlockDownload() && pto->nNextLocalAddrSend < nNow) { diff --git a/src/netbase.cpp b/src/netbase.cpp index 8fd2a8efd..fc9a6ed0b 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -198,6 +198,14 @@ struct timeval MillisToTimeval(int64_t nTimeout) return timeout; } +enum class IntrRecvError { + OK, + Timeout, + Disconnected, + NetworkError, + Interrupted +}; + /** * Read bytes from socket. This will either read the full number of bytes requested * or return False on error or timeout. @@ -209,7 +217,7 @@ struct timeval MillisToTimeval(int64_t nTimeout) * * @note This function requires that hSocket is in non-blocking mode. */ -bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSocket) +static IntrRecvError InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSocket) { int64_t curTime = GetTimeMillis(); int64_t endTime = curTime + timeout; @@ -222,12 +230,12 @@ bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSock len -= ret; data += ret; } else if (ret == 0) { // Unexpected disconnection - return false; + return IntrRecvError::Disconnected; } else { // Other error or blocking int nErr = WSAGetLastError(); if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL) { if (!IsSelectableSocket(hSocket)) { - return false; + return IntrRecvError::NetworkError; } struct timeval tval = MillisToTimeval(std::min(endTime - curTime, maxWait)); fd_set fdset; @@ -235,17 +243,17 @@ bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSock FD_SET(hSocket, &fdset); int nRet = select(hSocket + 1, &fdset, NULL, NULL, &tval); if (nRet == SOCKET_ERROR) { - return false; + return IntrRecvError::NetworkError; } } else { - return false; + return IntrRecvError::NetworkError; } } if (interruptSocks5Recv) - return false; + return IntrRecvError::Interrupted; curTime = GetTimeMillis(); } - return len == 0; + return len == 0 ? IntrRecvError::OK : IntrRecvError::Timeout; } struct ProxyCredentials @@ -272,6 +280,7 @@ std::string Socks5ErrorString(int err) /** Connect using SOCKS5 (as described in RFC1928) */ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials *auth, SOCKET& hSocket) { + IntrRecvError recvr; LogPrint("net", "SOCKS5 connecting %s\n", strDest); if (strDest.size() > 255) { CloseSocket(hSocket); @@ -294,7 +303,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials return error("Error sending to proxy"); } char pchRet1[2]; - if (!InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket)) { + if ((recvr = InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) { CloseSocket(hSocket); LogPrintf("Socks5() connect to %s:%d failed: InterruptibleRecv() timeout or other failure\n", strDest, port); return false; @@ -320,7 +329,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials } LogPrint("proxy", "SOCKS5 sending proxy authentication %s:%s\n", auth->username, auth->password); char pchRetA[2]; - if (!InterruptibleRecv(pchRetA, 2, SOCKS5_RECV_TIMEOUT, hSocket)) { + if ((recvr = InterruptibleRecv(pchRetA, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) { CloseSocket(hSocket); return error("Error reading proxy authentication response"); } @@ -349,9 +358,16 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials return error("Error sending to proxy"); } char pchRet2[4]; - if (!InterruptibleRecv(pchRet2, 4, SOCKS5_RECV_TIMEOUT, hSocket)) { + if ((recvr = InterruptibleRecv(pchRet2, 4, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) { CloseSocket(hSocket); - return error("Error reading proxy response"); + if (recvr == IntrRecvError::Timeout) { + /* If a timeout happens here, this effectively means we timed out while connecting + * to the remote node. This is very common for Tor, so do not print an + * error message. */ + return false; + } else { + return error("Error while reading proxy response"); + } } if (pchRet2[0] != 0x05) { CloseSocket(hSocket); @@ -370,26 +386,26 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials char pchRet3[256]; switch (pchRet2[3]) { - case 0x01: ret = InterruptibleRecv(pchRet3, 4, SOCKS5_RECV_TIMEOUT, hSocket); break; - case 0x04: ret = InterruptibleRecv(pchRet3, 16, SOCKS5_RECV_TIMEOUT, hSocket); break; + case 0x01: recvr = InterruptibleRecv(pchRet3, 4, SOCKS5_RECV_TIMEOUT, hSocket); break; + case 0x04: recvr = InterruptibleRecv(pchRet3, 16, SOCKS5_RECV_TIMEOUT, hSocket); break; case 0x03: { - ret = InterruptibleRecv(pchRet3, 1, SOCKS5_RECV_TIMEOUT, hSocket); - if (!ret) { + recvr = InterruptibleRecv(pchRet3, 1, SOCKS5_RECV_TIMEOUT, hSocket); + if (recvr != IntrRecvError::OK) { CloseSocket(hSocket); return error("Error reading from proxy"); } int nRecv = pchRet3[0]; - ret = InterruptibleRecv(pchRet3, nRecv, SOCKS5_RECV_TIMEOUT, hSocket); + recvr = InterruptibleRecv(pchRet3, nRecv, SOCKS5_RECV_TIMEOUT, hSocket); break; } default: CloseSocket(hSocket); return error("Error: malformed proxy response"); } - if (!ret) { + if (recvr != IntrRecvError::OK) { CloseSocket(hSocket); return error("Error reading from proxy"); } - if (!InterruptibleRecv(pchRet3, 2, SOCKS5_RECV_TIMEOUT, hSocket)) { + if ((recvr = InterruptibleRecv(pchRet3, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) { CloseSocket(hSocket); return error("Error reading from proxy"); } diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 1c1acb6b1..be79a6799 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -518,7 +518,10 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel) // Propagate cleared model to child objects rpcConsole->setClientModel(nullptr); #ifdef ENABLE_WALLET - walletFrame->setClientModel(nullptr); + if (walletFrame) + { + walletFrame->setClientModel(nullptr); + } #endif // ENABLE_WALLET unitDisplayControl->setOptionsModel(nullptr); } diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index f8aba70d9..d4fd8bd37 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -563,9 +563,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) } // after fee - nAfterFee = nAmount - nPayFee; - if (nAfterFee < 0) - nAfterFee = 0; + nAfterFee = std::max(nAmount - nPayFee, 0); } // actually update labels diff --git a/src/qt/forms/intro.ui b/src/qt/forms/intro.ui index e4ff3da1a..cfdd8482e 100644 --- a/src/qt/forms/intro.ui +++ b/src/qt/forms/intro.ui @@ -7,7 +7,7 @@ 0 0 674 - 363 + 415 @@ -55,9 +55,6 @@ - - %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. - true @@ -203,6 +200,36 @@ + + + + When you click OK, %1 will begin to download and process the full %4 block chain (%2GB) starting with the earliest transactions in %3 when %4 initially launched. + + + true + + + + + + + This initial synchronisation is very demanding, and may expose hardware problems with your computer that had previously gone unnoticed. Each time you run %1, it will continue downloading where it left off. + + + true + + + + + + + If you have chosen to limit block chain storage (pruning), the historical data must still be downloaded and processed, but will be deleted afterward to keep your disk usage low. + + + true + + + diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 5d6c0e2e3..fd3dcac42 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -37,9 +37,7 @@ #include #include -#if BOOST_FILESYSTEM_VERSION >= 3 #include -#endif #include #include @@ -67,9 +65,7 @@ #include #endif -#if BOOST_FILESYSTEM_VERSION >= 3 static boost::filesystem::detail::utf8_codecvt_facet utf8; -#endif #if defined(Q_OS_MAC) extern double NSAppKitVersionNumber; @@ -762,6 +758,8 @@ bool SetStartOnSystemStartup(bool fAutoStart) #elif defined(Q_OS_MAC) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // based on: https://github.com/Mozketo/LaunchAtLoginController/blob/master/LaunchAtLoginController.m #include @@ -824,6 +822,7 @@ bool SetStartOnSystemStartup(bool fAutoStart) } return true; } +#pragma GCC diagnostic pop #else bool GetStartOnSystemStartup() { return false; } @@ -860,7 +859,6 @@ void setClipboard(const QString& str) QApplication::clipboard()->setText(str, QClipboard::Selection); } -#if BOOST_FILESYSTEM_VERSION >= 3 boost::filesystem::path qstringToBoostPath(const QString &path) { return boost::filesystem::path(path.toStdString(), utf8); @@ -870,18 +868,6 @@ QString boostPathToQString(const boost::filesystem::path &path) { return QString::fromStdString(path.string(utf8)); } -#else -#warning Conversion between boost path and QString can use invalid character encoding with boost_filesystem v2 and older -boost::filesystem::path qstringToBoostPath(const QString &path) -{ - return boost::filesystem::path(path.toStdString()); -} - -QString boostPathToQString(const boost::filesystem::path &path) -{ - return QString::fromStdString(path.string()); -} -#endif QString formatDurationStr(int secs) { diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index 6b5ac47f2..4939648ff 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -124,16 +124,34 @@ Intro::Intro(QWidget *parent) : ui->setupUi(this); ui->welcomeLabel->setText(ui->welcomeLabel->text().arg(tr(PACKAGE_NAME))); ui->storageLabel->setText(ui->storageLabel->text().arg(tr(PACKAGE_NAME))); + + ui->lblExplanation1->setText(ui->lblExplanation1->text() + .arg(tr(PACKAGE_NAME)) + .arg(BLOCK_CHAIN_SIZE) + .arg(2009) + .arg(tr("Bitcoin")) + ); + ui->lblExplanation2->setText(ui->lblExplanation2->text().arg(tr(PACKAGE_NAME))); + uint64_t pruneTarget = std::max(0, GetArg("-prune", 0)); requiredSpace = BLOCK_CHAIN_SIZE; + QString storageRequiresMsg = tr("At least %1 GB of data will be stored in this directory, and it will grow over time."); if (pruneTarget) { uint64_t prunedGBs = std::ceil(pruneTarget * 1024 * 1024.0 / GB_BYTES); if (prunedGBs <= requiredSpace) { requiredSpace = prunedGBs; + storageRequiresMsg = tr("Approximately %1 GB of data will be stored in this directory."); } + ui->lblExplanation3->setVisible(true); + } else { + ui->lblExplanation3->setVisible(false); } requiredSpace += CHAIN_STATE_SIZE; - ui->sizeWarningLabel->setText(ui->sizeWarningLabel->text().arg(tr(PACKAGE_NAME)).arg(requiredSpace)); + ui->sizeWarningLabel->setText( + tr("%1 will download and store a copy of the Bitcoin block chain.").arg(tr(PACKAGE_NAME)) + " " + + storageRequiresMsg.arg(requiredSpace) + " " + + tr("The wallet will also be stored in this directory.") + ); startThread(); } diff --git a/src/qt/locale/bitcoin_cs.ts b/src/qt/locale/bitcoin_cs.ts index 67c595ab3..f38c42513 100644 --- a/src/qt/locale/bitcoin_cs.ts +++ b/src/qt/locale/bitcoin_cs.ts @@ -329,6 +329,10 @@ Click to enable network activity again. Kliknutím opět umožníš spojení do sítě. + + Syncing Headers (%1%)... + Synchronizuji záhlaví bloků (%1 %)… + Reindexing blocks on disk... Vytvářím nový index bloků na disku... @@ -481,6 +485,10 @@ %1 client %1 klient + + Connecting to peers... + Připojuji se… + Catching up... Stahuji... @@ -3089,6 +3097,14 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Spustit příkaz, když se objeví transakce týkající se peněženky (%s se v příkazu nahradí za TxID) + + Extra transactions to keep in memory for compact block reconstructions (default: %u) + Počet extra transakcí, které se mají držet v paměti pro účely rekonstrukce kompaktních bloků (výchozí: %u) + + + If this block is in the chain assume that it and its ancestors are valid and potentially skip their script verification (0 to verify all, default: %s, testnet: %s) + Pokud je tenhle blok v řetězci, tak předpokládat, že on i jeho následníci jsou platní, a potenciálně přeskočit ověřování jejich skriptů (0 = ověřovat vše, výchozí: %s, testnet: %s) + 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) Maximální povolené seřizování času mediánem časů protějšků. Místní vnímání času může být ovlivněno protějšky, a to dopředu nebo dozadu až o toto množství. (výchozí: %u vteřin) @@ -3105,6 +3121,14 @@ 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. + + Reduce storage requirements by enabling pruning (deleting) of old blocks. This allows the pruneblockchain RPC to be called to delete specific blocks, and enables automatic pruning of old blocks if a target size in MiB is provided. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, 1 = allow manual pruning via RPC, >%u = automatically prune block files to stay under the specified target size in MiB) + Omezit nároky na úložný prostor prořezáváním (mazáním) starých bloků. Tato volba také umožní použít RPC volání pruneblockchain ke smazání konkrétních bloků a dále automatické prořezávání starých bloků, pokud je zadána cílová velikost souborů s bloky v MiB. Tento režim není slučitelný s -txindex ani -rescan. Upozornění: opětovná změna tohoto nastavení bude vyžadovat nové stažení celého řetězce bloků. (výchozí: 0 = bloky neprořezávat, 1 = povolit ruční prořezávání skrze RPC, >%u = automatické prořezávání bloků tak, aby byla udržena cílová velikost souborů s bloky, v MiB) + + + Set lowest fee rate (in %s/kB) for transactions to be included in block creation. (default: %s) + Nastavit nejnižší akceptovatelný poplatek (v %s/kB) pro transakce, které mají být zahrnuty do nových bloků. (výchozí: %s) + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Nastavení počtu vláken pro verifikaci skriptů (%u až %d, 0 = automaticky, <0 = nechat daný počet jader volný, výchozí: %d) diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index cc834a8b9..f62f1e4a7 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -1083,7 +1083,7 @@ Use a custom data directory: - + Error: Specified data directory "%1" cannot be created. diff --git a/src/qt/locale/bitcoin_et.ts b/src/qt/locale/bitcoin_et.ts index f95b01d33..313d5e3be 100644 --- a/src/qt/locale/bitcoin_et.ts +++ b/src/qt/locale/bitcoin_et.ts @@ -214,6 +214,10 @@ BanTableModel + + IP/Netmask + IP/Võrgumask + BitcoinGUI @@ -787,6 +791,10 @@ &Window &Aken + + Hide tray icon + Peida tegumiriba ikoon + Show only a tray icon after minimizing the window. Minimeeri systray alale. @@ -903,10 +911,30 @@ N/A N/A + + %1 ms + %1 ms + + + %n hour(s) + %n tund%n tundi + + + %n day(s) + %n päev%n päeva + + + %n week(s) + %n nädal%n nädalat + %1 and %2 %1 ja %2 + + %n year(s) + %n aasta%n aastat + QObject::QObject diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts index 92682ff29..218002315 100644 --- a/src/qt/locale/bitcoin_fr.ts +++ b/src/qt/locale/bitcoin_fr.ts @@ -329,6 +329,10 @@ Click to enable network activity again. Cliquer pour réactiver l'activité réseau. + + Syncing Headers (%1%)... + Synchronisation des en-têtes (%1)... + Reindexing blocks on disk... Réindexation des blocs sur le disque... diff --git a/src/qt/locale/bitcoin_it.ts b/src/qt/locale/bitcoin_it.ts index 484e7f86b..9f2c7626d 100644 --- a/src/qt/locale/bitcoin_it.ts +++ b/src/qt/locale/bitcoin_it.ts @@ -702,10 +702,6 @@ Error Errore - - %n GB of free space available - GB di spazio libero disponibile%n GB di spazio disponibile - (of %n GB needed) (di %nGB richiesti)(%n GB richiesti) diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts index c63703530..3202587cb 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 @@ -39,7 +39,7 @@ &Delete - &Excluir + E&xcluir Choose the address to send coins to @@ -102,7 +102,7 @@ AddressTableModel Label - Rótuo + Rótulo Address @@ -110,7 +110,7 @@ (no label) - (sem rótuo) + (sem rótulo) @@ -231,7 +231,7 @@ BitcoinGUI Sign &message... - &Assinar mensagem... + Assinar &mensagem... Synchronizing with network... @@ -375,7 +375,7 @@ &Show / Hide - &Exibir/Ocultar + &Exibir / Ocultar Show or hide the main Window @@ -479,7 +479,7 @@ %1 client - %1 + %1 cliente Connecting to peers... @@ -688,7 +688,7 @@ (no label) - (sem rótuo) + (sem rótulo) change from %1 (%2) @@ -1360,6 +1360,10 @@ Node/Service Nó/Serviço + + NodeId + ID do nó + Ping Ping @@ -1900,7 +1904,7 @@ Label - Rótuo + Rótulo Message @@ -1923,7 +1927,7 @@ Label - Rótuo + Rótulo Message @@ -1931,7 +1935,7 @@ (no label) - (sem rótuo) + (sem rótulo) (no message) @@ -2210,7 +2214,7 @@ (no label) - (sem rótuo) + (sem rótulo) @@ -2665,7 +2669,7 @@ Label - Rótuo + Rótulo Open for %n more block(s) @@ -2741,7 +2745,7 @@ (no label) - (sem rótuo) + (sem rótulo) Transaction status. Hover over this field to show number of confirmations. @@ -2888,7 +2892,7 @@ Label - Rótuo + Rótulo Address @@ -3797,6 +3801,10 @@ Relay non-P2SH multisig (default: %u) Retransmitir P2SH não multisig (padrão: %u) + + Send transactions with full-RBF opt-in enabled (default: %u) + Ativar opção full-RBF nas transações enviadas (padrão: %u) + Set key pool size to <n> (default: %u) Defina o tamanho da chave para piscina<n> (padrão: %u) @@ -3819,7 +3827,7 @@ Specify pid file (default: %s) - Especificar aqrquivo pid (padrão: %s) + Especificar arquivo pid (padrão: %s) Spend unconfirmed change when sending transactions (default: %u) diff --git a/src/qt/locale/bitcoin_tr.ts b/src/qt/locale/bitcoin_tr.ts index c37a51896..2de0d14dd 100644 --- a/src/qt/locale/bitcoin_tr.ts +++ b/src/qt/locale/bitcoin_tr.ts @@ -35,7 +35,7 @@ &Export - &Dışa aktar + &Dışarı aktar &Delete @@ -59,15 +59,23 @@ Receiving addresses - Alınan adresler + Alım adresleri + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Bunlar ödemeleri göndermek için kullanacağınız Bitcoin adreslerinizdir. Bitcoin yollamadan önce tutarı ve alıcının alım adresini her zaman kontrol ediniz. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Bunlar ödemeleri almak için kullanacağınız Bitcoin adreslerinizdir. Her işlem için yeni bir alım adresi kullanmanız tavsiye edilir. &Copy Address - &Adres Kopyala + &Adresi Kopyala Copy &Label - &Etiketi kopyala + &Etiketi Kopyala &Edit @@ -75,13 +83,21 @@ Export Address List - Adres listesini dışarı aktar + Adres Listesini Dışarı Aktar + + + Comma separated file (*.csv) + Virgülle ayrılmış değerler dosyası (*.csv) Exporting Failed - Dışarı aktarmada hata + Dışarı Aktarım Başarısız Oldu - + + There was an error trying to save the address list to %1. Please try again. + Adres listesinin %1 konumuna kaydedilmesi sırasında bir hata meydana geldi. Lütfen tekrar deneyin. + + AddressTableModel @@ -101,7 +117,7 @@ AskPassphraseDialog Passphrase Dialog - Parola diyaloğu + Parola Diyaloğu Enter passphrase @@ -115,9 +131,17 @@ Repeat new passphrase Yeni parolayı tekrarlayınız + + 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>. + Cüzdan için yeni parolayı giriniz.<br/>Lütfen <b>on ya da daha fazla rastgele karakter</b> veya <b>sekiz ya da daha fazla kelime</b> içeren bir parola kullanınız. + Encrypt wallet - Şifrelenmiş cüzdan + Cüzdanı şifrele + + + This operation needs your wallet passphrase to unlock the wallet. + Bu eylem cüzdan kilidini açmak için cüzdan parolanızı gerektirir. Unlock wallet @@ -125,16 +149,28 @@ This operation needs your wallet passphrase to decrypt the wallet. - Bu işlem, cüzdan şifresini çözmek için cüzdan parolanıza ihtiyaç duyuyor. + Bu eylem, cüzdan şifresini çözmek için cüzdan parolanıza ihtiyaç duyuyor. + + + Decrypt wallet + Cüzdanın şifrelemesini aç Change passphrase Parola değiştir + + Enter the old passphrase and new passphrase to the wallet. + Eski ve yeni parolanızı cüzdana giriniz. + Confirm wallet encryption Cüzdan şifrelemesini onayla + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Uyarı: Eğer cüzdanınızı şifreler ve parolanızı kaybederseniz <b>TÜM BİTCOİNLERİNİZİ KAYBEDECEKSİNİZ</b>! + Are you sure you wish to encrypt your wallet? Cüzdanınızı şifrelemek istediğinizden emin misiniz? @@ -143,35 +179,67 @@ Wallet encrypted Cüzdan şifrelendi + + %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. + Şifreleme işleminin bitirilmesi için %1 kapatılacak. Her ne kadar cüzdanınızı şifreleseniz de şifrelemenin bitcoinlerinizi bilgisayarınıza bulaşan zararlılardan tam olarak koruyamayacağını unutmayın. + + + 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. + ÖNEMLİ: Önceden yapmış olduğunuz cüzdan dosyası yedeklemelerinin yeni oluşturulan şifrelenmiş cüzdan dosyası ile değiştirilmeleri gerekir. Güvenlik nedenleriyle yeni, şifrelenmiş cüzdanı kullanmaya başladığınızda eski şifrelenmemiş cüzdan dosyaları işe yaramaz hale gelecektir. + Wallet encryption failed Cüzdan şifreleme başarısız - Wallet unlock failed - Cüzdan kilidi kaldırma hatası + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Dahili bir hata yüzünden cüzdan şifrelemesi başarısız oldu. Cüzdanın şifrelenmedi. - + + The supplied passphrases do not match. + Girilen parolalar birbiriyle eşleşmiyor. + + + Wallet unlock failed + Cüzdan kilidini kaldırma başarısız oldu + + + The passphrase entered for the wallet decryption was incorrect. + Cüzdan şifresinin açılması için girilen parola yanlıştı. + + + Wallet decryption failed + Cüzdan şifresinin açılması başarısız oldu + + + Wallet passphrase was successfully changed. + Cüzdan parolası başarılı bir şekilde değiştirildi. + + + Warning: The Caps Lock key is on! + Uyarı: Caps Lock tuşu etkin durumda! + + BanTableModel IP/Netmask - IP/Ağ maskesi + IP/Ağ Maskesi Banned Until - Şu vakte kadar yasaklı: + Şu zamana kadar yasaklı: BitcoinGUI Sign &message... - &Mesaj imzala... + &İleti imzala... Synchronizing with network... - Şebeke ile senkronizasyon... + Ağ ile senkronize ediliyor... &Overview @@ -187,15 +255,15 @@ &Transactions - &Muameleler + &İşlemler Browse transaction history - Muamele tarihçesini tara + İşlem geçmişine gözat E&xit - &Çık + Ç&ık Quit application @@ -203,7 +271,7 @@ &About %1 - %1 &hakkında + %1 &Hakkında Show information about %1 @@ -211,11 +279,11 @@ About &Qt - &Qt hakkında + &Qt Hakkında Show information about Qt - Qt hakkında bilgi görüntü + Qt hakkında bilgi göster &Options... @@ -227,15 +295,15 @@ &Encrypt Wallet... - Cüzdanı &şifrele... + Cüzdanı &Şifrele... &Backup Wallet... - Cüzdanı &yedekle... + Cüzdanı &Yedekle... &Change Passphrase... - Parolayı &değiştir... + Parolayı &Değiştir... &Sending addresses... @@ -247,15 +315,31 @@ Open &URI... - &URI aç... + &URI Aç... + + + Click to disable network activity. + Ağ etkinliğini devre dışı bırakmak için tıklayın. + + + Network activity disabled. + Ağ etkinliği devre dışı bırakılmış. + + + Click to enable network activity again. + Ağ etkinliğini yeniden etkinleştirmek için tıklayın. + + + Syncing Headers (%1%)... + Üstbilgiler Senkronize Ediliyor (%1%)... Reindexing blocks on disk... - Diskteki bloklar yeniden endeksleniyor... + Diskteki bloklar yeniden indeksleniyor... Send coins to a Bitcoin address - Bir Bitcoin adresine Bitcoin yolla + Bir bitcoin adresine bitcoin gönder Backup wallet to another location @@ -275,7 +359,7 @@ &Verify message... - Mesaj &kontrol et... + İletiyi &kontrol et... Bitcoin @@ -295,23 +379,23 @@ &Show / Hide - &Göster / Sakla + &Göster / Gizle Show or hide the main Window - Ana pencereyi görüntüle ya da sakla + Ana pencereyi göster ya da gizle Encrypt the private keys that belong to your wallet - Cüzdanınızın özel anahtarlarını şifrele + Cüzdanınıza ait özel anahtarları şifreleyin Sign messages with your Bitcoin addresses to prove you own them - Mesajları adreslerin size ait olduğunu ispatlamak için Bitcoin adresleri ile imzala + İletileri adreslerin size ait olduğunu ispatlamak için Bitcoin adresleri ile imzala Verify messages to ensure they were signed with specified Bitcoin addresses - Belirtilen Bitcoin adresleri ile imzalandıklarından emin olmak için mesajları kontrol et + Belirtilen Bitcoin adresleri ile imzalandıklarından emin olmak için iletileri kontrol et &File @@ -351,7 +435,7 @@ %n active connection(s) to Bitcoin network - Bitcoin şebekesine %n faal bağlantıBitcoin şebekesine %n faal bağlantı + Bitcoin şebekesine %n faal bağlantıBitcoin ağına %n etkin bağlantı var Indexing blocks on disk... @@ -359,11 +443,11 @@ Processing blocks on disk... - Bloklar diske yazıdırılıyor... + Bloklar diske işleniyor... Processed %n block(s) of transaction history. - Muamele tarihçesinden %n blok işlendi.Muamele tarihçesinden %n blok işlendi + Muamele tarihçesinden %n blok işlendi.İşlem tarihçesinden %n blok işlendi %1 behind @@ -371,11 +455,11 @@ Last received block was generated %1 ago. - Son alınan blok %1 evvel oluşturulmuştu. + Son alınan blok %1 önce oluşturulmuştu. Transactions after this will not yet be visible. - Bundan sonraki muameleler henüz görüntülenemez. + Bundan sonraki işlemler henüz görüntülenemez. Error @@ -399,7 +483,11 @@ %1 client - %1 istemcisi + %1 istemci + + + Connecting to peers... + Eşlere bağlanılıyor... Catching up... @@ -414,7 +502,7 @@ Amount: %1 - Meblağ: %1 + Tutar: %1 @@ -437,11 +525,19 @@ Sent transaction - Muamele yollandı + İşlem gönderildi Incoming transaction - Gelen muamele + Gelen işlem + + + HD key generation is <b>enabled</b> + HD anahtar oluşturma <b>etkin</b> + + + HD key generation is <b>disabled</b> + HD anahtar oluşturma <b>devre dışı</b> Wallet is <b>encrypted</b> and currently <b>unlocked</b> @@ -451,7 +547,11 @@ Wallet is <b>encrypted</b> and currently <b>locked</b> Cüzdan <b>şifrelenmiştir</b> ve şu anda <b>kilitlidir</b> - + + A fatal error occurred. Bitcoin can no longer continue safely and will quit. + Ölümcül bir hata oluştu. Bitcoin yazılımı artık güvenli bir şekilde çalışmaya devam edemediği için kapatılacaktır. + + CoinControlDialog @@ -468,7 +568,7 @@ Amount: - Meblağ: + Tutar: Fee: @@ -500,7 +600,7 @@ Amount - Meblağ + Tutar Received with label @@ -532,13 +632,77 @@ Copy amount + Tutarı kopyala + + + Copy transaction ID + İşlem ID'sini kopyala + + + Lock unspent + Harcanmamışı kilitle + + + Unlock unspent + Harcanmamışın kilidini aç + + + Copy quantity Miktarı kopyala + + Copy fee + Ücreti kopyala + + + Copy after fee + Ücretten sonrasını kopyala + + + Copy bytes + Baytları kopyala + + + Copy dust + Tozu kopyala + + + Copy change + Para üstünü kopyala + + + (%1 locked) + (%1 kilitlendi) + + + yes + evet + + + no + hayır + + + This label turns red if any recipient receives an amount smaller than the current dust threshold. + Eğer herhangi bir alıcı mevcut toz eşiğinden daha düşük bir tutar alırsa bu etiket kırmızıya dönüşür. + + + Can vary +/- %1 satoshi(s) per input. + Girdi başına +/- %1 satoshi değişebilir. + (no label) (etiket yok) - + + change from %1 (%2) + %1 ögesinden para üstü (%2) + + + (change) + (para üstü) + + EditAddressDialog @@ -561,7 +725,39 @@ &Address &Adres - + + New receiving address + Yeni alım adresi + + + New sending address + Yeni gönderi adresi + + + Edit receiving address + Alım adresini düzenle + + + Edit sending address + Gönderi adresini düzenle + + + The entered address "%1" is not a valid Bitcoin address. + Girilen "%1" adresi geçerli bir Bitcoin adresi değildir. + + + The entered address "%1" is already in the address book. + Girilen "%1" adresi zaten adres defterinde mevcuttur. + + + Could not unlock wallet. + Cüzdan kilidi açılamadı. + + + New key generation failed. + Yeni anahtar oluşturulması başarısız oldu. + + FreespaceChecker @@ -574,7 +770,7 @@ Directory already exists. Add %1 if you intend to create a new directory here. - Klasör hâlihazırda mevcuttur. Burada yeni bir klasör oluşturmak istiyorsanız, %1 ilâve ediniz. + Klasör zaten mevcuttur. Burada yeni bir klasör oluşturmak istiyorsanız, %1 ekleyiniz. Path already exists, and is not a directory. @@ -656,7 +852,7 @@ %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, Bitcoin blok zincirinin bir kopyasını indirecek ve saklayacaktır. Bu klasörde en az %2GB veri saklanacak ve bu zamanla artacaktır. Cüzdan da bu klasörde saklanacaktır. + %1, Bitcoin blok zincirinin bir kopyasını indirecek ve saklayacaktır. Bu klasörde en az %2 GB veri saklanacak ve bu zamanla artacaktır. Cüzdan da bu klasörde saklanacaktır. Use the default data directory @@ -689,20 +885,56 @@ Form Form + + Recent transactions may not yet be visible, and therefore your wallet's balance might be incorrect. This information will be correct once your wallet has finished synchronizing with the bitcoin network, as detailed below. + Son işlemler henüz görünmeyebilir ve bu nedenle cüzdanınızın bakiyesi yanlış olabilir. Bu bilgiler, aşağıda detaylandırıldığı gibi, cüzdanınız bitcoin ağı ile senkronizasyonunu tamamladığında doğru olacaktır. + + + Attempting to spend bitcoins that are affected by not-yet-displayed transactions will not be accepted by the network. + Henüz görüntülenmeyen işlemlerden etkilenen bitcoinleri harcama girişiminde bulunmak ağ tarafından kabul edilmeyecektir. + + + Number of blocks left + Kalan blok sayısı + + + Unknown... + Bilinmiyor... + Last block time Son blok zamanı - Hide - Sakla + Progress + İlerleme - + + Progress increase per hour + Saat başı ilerleme artışı + + + calculating... + hesaplanıyor... + + + Estimated time left until synced + Senkronize edilene kadar kalan tahmini süre + + + Hide + Gizle + + + Unknown. Syncing Headers (%1)... + Bilinmeyen. Üstbilgiler Senkronize Ediliyor (%1)... + + OpenURIDialog Open URI - URI aç + URI Aç Open payment request from URI or file @@ -716,7 +948,11 @@ Select payment request file Ödeme talebi dosyasını seç - + + Select payment request file to open + Açılacak ödeme talebi dosyasını seç + + OptionsDialog @@ -725,7 +961,7 @@ &Main - &Esas ayarlar + &Genel Automatically start %1 after logging in to the system. @@ -737,7 +973,7 @@ Size of &database cache - &Veritabanı tamponunun boyutu + &Veritabanı önbelleğinin boyutu MB @@ -765,15 +1001,15 @@ 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 |. - Muameleler sekmesinde bağlam menüsü unsurları olarak görünen üçüncü taraf bağlantıları (mesela bir blok tarayıcısı). URL'deki %s, muamele hash değeri ile değiştirilecektir. Birden çok bağlantılar düşey çubuklar | ile ayrılacaktır. + İşlemler sekmesinde bağlam menüsü unsurları olarak görünen üçüncü taraf bağlantıları (mesela bir blok tarayıcısı). URL'deki %s, işlem hash değeri ile değiştirilecektir. Birden çok bağlantılar düşey çubuklar | ile ayrılacaktır. Third party transaction URLs - Üçüncü taraf muamele URL'leri + Üçüncü parti işlem URL'leri Active command-line options that override above options: - Yukarıdaki seçeneklerin yerine geçen faal komut satırı seçenekleri: + Yukarıdaki seçeneklerin yerine geçen etkin komut satırı seçenekleri: Reset all client options to default. @@ -781,11 +1017,11 @@ &Reset Options - Seçenekleri Sıfı&rla + Seçenekleri &Sıfırla &Network - &Şebeke + &Ağ (0 = auto, <0 = leave that many cores free) @@ -805,11 +1041,11 @@ 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. - Teyit edilmemiş para üstünü harcamayı devre dışı bırakırsanız, bir muamelenin para üstü bu muamele için en az bir teyit olana dek harcanamaz. Bu, aynı zamanda bakiyenizin nasıl hesaplandığını da etkiler. + Doğrulanmamış para üstünü harcamayı devre dışı bırakırsanız, bir işlemin para üstü bu işlem için en az bir doğrulama olana dek harcanamaz. Bu, aynı zamanda bakiyenizin nasıl hesaplandığını da etkiler. &Spend unconfirmed change - Teyit edilmemiş para üstünü &harca + Doğrulanmamış para üstünü &harca Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. @@ -821,15 +1057,15 @@ Connect to the Bitcoin network through a SOCKS5 proxy. - Bitcoin şebekesine SOCKS5 vekil sunucusu vasıtasıyla bağlan. + Bitcoin ağına bir SOCKS5 vekil sunucusu aracılığıyla bağlan. &Connect through SOCKS5 proxy (default proxy): - SOCKS5 vekil sunucusu vasıtasıyla &bağlan (varsayılan vekil sunucusu): + SOCKS5 vekil sunucusu aracılığıyla &bağlan (varsayılan vekil sunucusu): Proxy &IP: - Vekil &İP: + Vekil &IP: &Port: @@ -841,11 +1077,11 @@ Used for reaching peers via: - Eşlere ulaşmak için kullanılır, şu yoluyla: + Eşlere ulaşmak için kullanılır, şu üzerinden: Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. - Bu şebeke türü yoluyla eşlere bağlanmak için belirtilen varsayılan SOCKS5 vekil sunucusunun kullanılıp kullanılmadığını gösterir. + Bu ağ türü yoluyla eşlere bağlanmak için belirtilen varsayılan SOCKS5 vekil sunucusunun kullanılıp kullanılmadığını gösterir. IPv4 @@ -861,7 +1097,7 @@ Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. - Bitcoin şebekesine gizli Tor servisleri için ayrı bir SOCKS5 vekil sunucusu vasıtasıyla bağlan. + Bitcoin ağına gizli Tor servisleri için ayrı bir SOCKS5 vekil sunucusu aracılığıyla bağlan. Use separate SOCKS5 proxy to reach peers via Tor hidden services: @@ -873,15 +1109,15 @@ &Hide the icon from the system tray. - İkonu sistem çekmecesinden &sakla + Simgeyi görev çubuğundan &gizle Hide tray icon - Sistem çekmecesi ikonunu sakla + Görev çubuğu simgesini gizle Show only a tray icon after minimizing the window. - Küçültüldükten sonra sadece çekmece ikonu göster. + Küçültüldükten sonra sadece tepsi simgesi göster. &Minimize to the tray instead of the taskbar @@ -905,7 +1141,7 @@ &Unit to show amounts in: - Meblağları göstermek için &birim: + Tutarı göstermek için &birim: Choose the default subdivision unit to show in the interface and when sending coins. @@ -960,7 +1196,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. - Görüntülenen veriler zaman aşımına uğramış olabilir. Bağlantı kurulduğunda cüzdanınız otomatik olarak şebeke ile eşleşir ancak bu işlem henüz tamamlanmamıştır. + Görüntülenen bilgiler güncel olmayabilir. Bağlantı kurulduğunda cüzdanınız otomatik olarak Bitcoin ağı ile senkronize olur ancak bu işlem henüz tamamlanmamıştır. Watch-only: @@ -980,7 +1216,7 @@ Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance - Henüz teyit edilmemiş ve harcanabilir bakiyeye eklenmemiş muamelelerin toplamı + Henüz doğrulanmamış ve harcanabilir bakiyeye eklenmemiş işlemlerin toplamı Immature: @@ -1012,11 +1248,11 @@ Recent transactions - Son muameleler + Son işlemler Unconfirmed transactions to watch-only addresses - Sadece izlenen adreslere gelen teyit edilmemiş muameleler + Sadece izlenen adreslere gelen doğrulanmamış işlemler Mined balance in watch-only addresses that has not yet matured @@ -1029,7 +1265,95 @@ PaymentServer - + + Payment request error + Ödeme talebi hatası + + + Cannot start bitcoin: click-to-pay handler + Bitcoin başlatılamadı: tıkla-ve-öde yöneticisi + + + URI handling + URI yönetimi + + + Payment request fetch URL is invalid: %1 + Ödeme talebini alma URL'i geçersiz: %1 + + + Invalid payment address %1 + %1 ödeme adresi geçersizdir + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + URI ayrıştırılamıyor! Bunun nedeni geçersiz bir Bitcoin adresi veya hatalı biçimlendirilmiş URI değişkenleri olabilir. + + + Payment request file handling + Ödeme talebi dosyası yönetimi + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + Ödeme talebi dosyası okunamıyor! Bunun nedeni geçersiz bir ödeme talebi dosyası olabilir. + + + Payment request rejected + Ödeme talebi reddedildi + + + Payment request network doesn't match client network. + Ödeme talebi ağı, istemci ağıyla eşleşmiyor. + + + Payment request expired. + Ödeme talebinin geçerlilik süresi bitti. + + + Payment request is not initialized. + Ödeme talebi başlatılmadı. + + + Unverified payment requests to custom payment scripts are unsupported. + Özel ödeme betiklerine, doğrulanmamış ödeme talepleri desteklenmez. + + + Invalid payment request. + Geçersiz ödeme talebi. + + + Requested payment amount of %1 is too small (considered dust). + Talep edilen %1 ödeme tutarı çok küçüktür (toz olarak kabul edilir). + + + Refund from %1 + %1 adresinden geri ödeme + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + %1 ödeme talebi çok büyük (%2 bayt, üst sınır %3 bayt). + + + Error communicating with %1: %2 + %1 ile iletişimde hata: %2 + + + Payment request cannot be parsed! + Ödeme talebi ayrıştırılamaz! + + + Bad response from server %1 + %1 sunucusundan hatalı yanıt + + + Network request error + Ağ talebi hatası + + + Payment acknowledged + Ödeme kabul edildi + + PeerTableModel @@ -1040,12 +1364,20 @@ Node/Service Düğüm/Servis - + + NodeId + Düğüm ID'si + + + Ping + Ping + + QObject Amount - Meblağ + Tutar Enter a Bitcoin address (e.g. %1) @@ -1079,21 +1411,73 @@ %1 ms %1 ms + + %n second(s) + %n saniye%n saniye + + + %n minute(s) + %n dakika%n dakika + + + %n hour(s) + %n saat%n saat + + + %n day(s) + %n gün%n gün + + + %n week(s) + %n hafta%n hafta + %1 and %2 %1 ve %2 - + + %n year(s) + %n yıl%n yıl + + + %1 didn't yet exit safely... + %1 henüz güvenli bir şekilde çıkış yapmamıştır... + + QObject::QObject - + + Error: Specified data directory "%1" does not exist. + Hata: Belirtilen "%1" veri klasörü yoktur. + + + Error: Cannot parse configuration file: %1. Only use key=value syntax. + Hata: %1 yapılandırma dosyası ayrıştırılamadı. Sadece anahtar=değer dizimini kullanınız. + + + Error: %1 + Hata: %1 + + QRImageWidget &Save Image... Resmi ka&ydet... - + + &Copy Image + Resmi &Kopyala + + + Save QR Code + QR Kodu Kaydet + + + PNG Image (*.png) + PNG Resim (*.png) + + RPCConsole @@ -1106,7 +1490,7 @@ &Information - &Malumat + &Bilgi Debug window @@ -1130,7 +1514,7 @@ Network - Şebeke + Name @@ -1154,7 +1538,7 @@ Current number of transactions - Güncel muamele sayısı + Güncel işlem sayısı Memory usage @@ -1198,7 +1582,7 @@ Synced Headers - Eşleşmiş Başlıklar + Eşleşmiş Üstbilgiler Synced Blocks @@ -1252,6 +1636,10 @@ Ping Wait Ping Beklemesi + + Min Ping + En Düşük Ping + Time Offset Saat Farkı @@ -1270,7 +1658,7 @@ &Network Traffic - &Şebeke trafiği + &Ağ trafiği &Clear @@ -1312,18 +1700,38 @@ 1 &year 1 &yıl + + &Disconnect + &Bağlantıyı Kes + + + Ban for + Yasakla + + + &Unban + &Yasaklamayı Kaldır + Welcome to the %1 RPC console. %1 RPC konsoluna hoş geldiniz. Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. - Tarihçede gezinmek için imleç tuşlarını kullanınız, <b>Ctrl-L</b> ile de ekranı temizleyebilirsiniz. + Tarihçede gezinmek için aşağı ve yukarı ok tuşlarını kullanınız, <b>Ctrl-L</b> ile de ekranı temizleyebilirsiniz. Type <b>help</b> for an overview of available commands. Mevcut komutların listesi için <b>help</b> yazınız. + + WARNING: Scammers have been active, telling users to type commands here, stealing their wallet contents. Do not use this console without fully understanding the ramification of a command. + UYARI: Bitcoin dolandırıcılarının çok fazla etkin olduğu zamanlarda, dolandırıcılar bazı kullanıcılara buraya komutlar yazmalarını söylerek onların cüzdanlarındaki bitcoinleri çalmışlardır. Bir komutun sonuçlarını tam olarak anlamadan bu konsolu kullanmayın. + + + Network activity disabled + Ağ etkinliği devre dışı bırakıldı + %1 B %1 B @@ -1377,7 +1785,7 @@ ReceiveCoinsDialog &Amount: - &Meblağ: + &Tutar: &Label: @@ -1385,7 +1793,7 @@ &Message: - Me&saj: + &İleti: 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. @@ -1397,7 +1805,7 @@ 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. - Talep açıldığında gösterilecek, isteğinize dayalı, ödeme talebi ile ilişkilendirilecek bir mesaj. Not: Bu mesaj ödeme ile birlikte Bitcoin şebekesi üzerinden gönderilmeyecektir. + Talep açıldığında gösterilecek, isteğinize dayalı, ödeme talebi ile ilişkilendirilecek bir ileti. Not: Bu ileti ödeme ile birlikte Bitcoin ağı üzerinden gönderilmeyecektir. An optional label to associate with the new receiving address. @@ -1409,7 +1817,7 @@ An optional amount to request. Leave this empty or zero to not request a specific amount. - Seçiminize dayalı talep edilecek meblağ. Belli bir meblağ talep etmemek için bunu boş bırakın veya sıfır değerini kullanın. + Seçiminize dayalı talep edilecek tutar. Belli bir tutar talep etmemek için bunu boş bırakın veya sıfır değerini kullanın. Clear all fields of the form. @@ -1443,13 +1851,21 @@ Remove Kaldır + + Copy URI + URI'yi kopyala + Copy label Etiket kopyala + + Copy message + İletiyi kopyala + Copy amount - Miktarı kopyala + Tutarı kopyala @@ -1470,26 +1886,74 @@ &Save Image... Resmi ka&ydet... + + Request payment to %1 + %1 unsuruna ödeme talep et + + + Payment information + Ödeme bilgisi + + + URI + URI + Address Adres - Label - Etiket + Amount + Tutar - - - RecentRequestsTableModel Label Etiket + + Message + İleti + + + Resulting URI too long, try to reduce the text for label / message. + Sonuç URI çok uzun, etiket ya da ileti metnini kısaltmayı deneyiniz. + + + Error encoding URI into QR Code. + URI'nin QR koduna kodlanmasında hata oluştu. + + + + RecentRequestsTableModel + + Date + Tarih + + + Label + Etiket + + + Message + İleti + (no label) (etiket yok) - + + (no message) + (ileti yok) + + + (no amount requested) + (tutar talep edilmedi) + + + Requested + Talep edilen + + SendCoinsDialog @@ -1522,7 +1986,7 @@ Amount: - Meblağ: + Tutar: Fee: @@ -1546,7 +2010,7 @@ Transaction Fee: - Muamele ücreti: + İşlem ücreti: Choose... @@ -1562,11 +2026,11 @@ 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. - Eğer özel ücret 1000 satoşi olarak ayarlandıysa ve muamele sadece 250 baytsa, "kilobayt başı" ücret olarak sadece 250 satoşi öder ve "toplam asgari" 1000 satoşi öder. Bir kilobayttan yüksek muameleler için ikisi de kilobayt başı ödeme yapar. + Eğer özel ücret 1000 satoşi olarak ayarlandıysa ve işlem sadece 250 baytsa, "kilobayt başı" ücret olarak sadece 250 satoşi öder ve "toplam asgari" 1000 satoşi öder. Bir kilobayttan yüksek işlemler için ikisi de kilobayt başı ödeme yapar. Hide - Sakla + Gizle total at least @@ -1574,7 +2038,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. - Asgari ücreti ödemek, bloklarda boşluktan daha az muamele hacmi olduğu sürece bir sorun çıkarmaz. Fakat şebekenin işleyecebileceğinden daha çok bitcoin muameleleri talebi olduğunda bunun asla teyit edilmeyen bir muamele olabileceğinin farkında olmalısınız. + Gerekli olan en az ücreti ödemek, bloklarda boşluktan daha az işlem hacmi olduğu sürece bir sorun çıkarmaz. Fakat ağın işleyecebileceğinden daha çok bitcoin işlemi talebi olduğunda bunun asla doğrulanmayan bir işlem olabileceğinin farkında olmalısınız. (read the tooltip) @@ -1616,6 +2080,10 @@ Dust: Toz: + + Confirmation time target: + Doğrulama süresi hedefi: + Clear &All Tümünü &temizle @@ -1633,9 +2101,117 @@ G&önder - Copy amount + Copy quantity Miktarı kopyala + + Copy amount + Tutarı kopyala + + + Copy fee + Ücreti kopyala + + + Copy after fee + Ücretten sonrasını kopyala + + + Copy bytes + Baytları kopyala + + + Copy dust + Tozu kopyala + + + Copy change + Para üstünü kopyala + + + %1 to %2 + %1 ögesinden %2 unsuruna + + + Are you sure you want to send? + Göndermek istediğinizden emin misiniz? + + + added as transaction fee + işlem ücreti olarak eklendi + + + Total Amount %1 + Toplam Tutar %1 + + + or + veya + + + Confirm send coins + Bitcoin gönderimini onaylayın + + + The recipient address is not valid. Please recheck. + Alıcı adresi geçerli değildir. Lütfen tekrar kontrol ediniz. + + + The amount to pay must be larger than 0. + Ödeyeceğiniz tutarın 0'dan yüksek olması gerekir. + + + The amount exceeds your balance. + Tutar bakiyenizden yüksektir. + + + The total exceeds your balance when the %1 transaction fee is included. + Toplam, %1 işlem ücreti eklendiğinde bakiyenizi geçmektedir. + + + Duplicate address found: addresses should only be used once each. + Tekrarlayan adres bulundu: adresler sadece bir kez kullanılmalıdır. + + + Transaction creation failed! + İşlem oluşturma başarısız! + + + The transaction was rejected with the following reason: %1 + İşlem şu nedenden dolayı reddedildi: %1 + + + A fee higher than %1 is considered an absurdly high fee. + %1 tutarından yüksek bir ücret saçma derecede yüksek bir ücret olarak kabul edilir. + + + Payment request expired. + Ödeme talebinin geçerlilik süresi bitti. + + + %n block(s) + %n blok%n blok + + + Pay only the required fee of %1 + Sadece asgari ücret olan %1 tutarını öde + + + Warning: Invalid Bitcoin address + Uyarı: geçersiz Bitcoin adresi + + + Warning: Unknown change address + Uyarı: Bilinmeyen para üstü adresi + + + Confirm custom change address + Özel para üstü adresini onayla + + + The address you selected for change is not part of this wallet. Any or all funds in your wallet may be sent to this address. Are you sure? + Para üstü için seçtiğiniz adres bu cüzdanın bir parçası değil. Cüzdanınızdaki bir miktar veya tüm para bu adrese gönderilebilir. Emin misiniz? + (no label) (etiket yok) @@ -1645,7 +2221,7 @@ SendCoinsEntry A&mount: - Mebla&ğ: + T&utar: Pay &To: @@ -1681,19 +2257,19 @@ Remove this entry - Bu unsuru kaldır + Bu ögeyi kaldır 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. - Ücret yollanan meblağdan alınacaktır. Alıcı meblağ alanında girdiğinizden daha az bitcoin alacaktır. Eğer birden çok alıcı seçiliyse ücret eşit olarak bölünecektir. + Ücret yollanan tutardan alınacaktır. Alıcı tutar alanına girdiğinizden daha az bitcoin alacaktır. Eğer birden çok alıcı seçiliyse ücret eşit olarak bölünecektir. S&ubtract fee from amount - Ücreti meblağdan düş + Ücreti tutardan düş Message: - Mesaj: + İleti: This is an unauthenticated payment request. @@ -1709,7 +2285,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. - Bitcoin: URI'siyle ilişkili ve bilginiz için muameleyle saklanacak bir mesaj. Not: Bu mesaj Bitcoin şebekesi üzerinden gönderilmeyecektir. + Referans için bitcoin: URI'siyle iliştirilmiş işlemle birlikte depolanacak bir ileti. Not: Bu mesaj Bitcoin ağı üzerinden gönderilmeyecektir. Pay To: @@ -1719,10 +2295,18 @@ Memo: Not: - + + Enter a label for this address to add it to your address book + Adres defterinize eklemek için bu adrese bir etiket giriniz + + SendConfirmationDialog - + + Yes + Evet + + ShutdownWindow @@ -1738,19 +2322,19 @@ SignVerifyMessageDialog Signatures - Sign / Verify a Message - İmzalar - Mesaj İmzala / Kontrol et + İmzalar - İleti İmzala / Kontrol et &Sign Message - Mesaj &imzala + İleti &imzala 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. - Adreslerinize yollanan bitcoinleri alabileceğiniz ispatlamak için adreslerinizle mesaj/anlaşma imzalayabilirsiniz. Oltalama saldırılarının kimliğinizi imzanızla elde etmeyi deneyebilecekleri için belirsiz ya da rastgele hiçbir şey imzalamamaya dikkat ediniz. Sadece ayrıntılı açıklaması olan ve tümüne katıldığınız ifadeleri imzalayınız. + Adreslerinize yollanan bitcoinleri alabileceğiniz ispatlamak için adreslerinizle iletiler/anlaşmalar imzalayabilirsiniz. Oltalama saldırılarının kimliğinizi imzanızla elde etmeyi deneyebilecekleri için belirsiz ya da rastgele hiçbir şey imzalamamaya dikkat ediniz. Sadece ayrıntılı açıklaması olan ve tümüne katıldığınız ifadeleri imzalayınız. The Bitcoin address to sign the message with - Mesajın imzalanmasında kullanılacak Bitcoin adresi + İletinin imzalanmasında kullanılacak Bitcoin adresi Choose previously used address @@ -1770,7 +2354,7 @@ Enter the message you want to sign here - İmzalamak istediğiniz mesajı burada giriniz + İmzalamak istediğiniz iletiyi burada giriniz Signature @@ -1782,15 +2366,15 @@ Sign the message to prove you own this Bitcoin address - Bu Bitcoin adresinin sizin olduğunu ispatlamak için mesajı imzalayın + Bu Bitcoin adresinin sizin olduğunu ispatlamak için iletiyi imzalayın Sign &Message - &Mesajı imzala + &İletiyi imzala Reset all sign message fields - Tüm mesaj alanlarını sıfırla + Tüm ileti alanlarını sıfırla Clear &All @@ -1798,29 +2382,81 @@ &Verify Message - Mesaj &kontrol et + İletiyi &kontrol et 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! - Alıcının adresini, mesajı (satır sonları, boşluklar, sekmeler vs. karakterleri tam olarak kopyaladığınızdan emin olunuz) ve imzayı aşağıda giriniz. Bir ortadaki adam saldırısı tarafından kandırılmaya mâni olmak için imzadan, imzalı mesajın içeriğini aşan bir anlam çıkarmamaya dikkat ediniz. Bunun sadece imzalayan tarafın adres ile alım yapabildiğini ispatladığını ve herhangi bir muamelenin gönderi tarafını kanıtlayamayacağını unutmayınız! + Alıcının adresini, iletiyi (satır sonları, boşluklar, sekmeler vs. karakterleri tam olarak kopyaladığınızdan emin olunuz) ve imzayı aşağıya giriniz. Bir ortadaki adam saldırısı tarafından kandırılmaya engel olmak için imzadan, imzalı iletinin içeriğini aşan bir anlam çıkarmamaya dikkat ediniz. Bunun sadece imzalayan tarafın adres ile alım yapabildiğini ispatladığını ve herhangi bir işlemin gönderi tarafını kanıtlayamayacağını unutmayınız! The Bitcoin address the message was signed with - Mesajın imzalanmasında kullanılan Bitcoin adresi + İletinin imzalanmasında kullanılan Bitcoin adresi Verify the message to ensure it was signed with the specified Bitcoin address - Belirtilen Bitcoin adresi ile imzalandığını doğrulamak için mesajı kontrol et + Belirtilen Bitcoin adresi ile imzalandığını doğrulamak için iletiyi kontrol et Verify &Message - &Mesaj kontrol et + &İletiyi kontrol et Reset all verify message fields - Tüm mesaj kontrolü alanlarını sıfırla + Tüm ileti kontrolü alanlarını sıfırla - + + Click "Sign Message" to generate signature + İmzayı oluşturmak için "İletiyi İmzala"ya tıklayın + + + The entered address is invalid. + Girilen adres geçersizdir. + + + Please check the address and try again. + Lütfen adresi kontrol edip tekrar deneyiniz. + + + The entered address does not refer to a key. + Girilen adres herhangi bir anahtara işaret etmemektedir. + + + Wallet unlock was cancelled. + Cüzdan kilidinin açılması iptal edildi. + + + Private key for the entered address is not available. + Girilen adres için özel anahtar mevcut değildir. + + + Message signing failed. + İleti imzalaması başarısız oldu. + + + Message signed. + İleti imzalandı. + + + The signature could not be decoded. + İmzanın kodu çözülemedi. + + + Please check the signature and try again. + Lütfen imzayı kontrol edip tekrar deneyiniz. + + + The signature did not match the message digest. + İmza iletinin özeti ile eşleşmedi. + + + Message verification failed. + İleti doğrulaması başarısız oldu. + + + Message verified. + İleti doğrulandı. + + SplashScreen @@ -1837,27 +2473,367 @@ TransactionDesc - + + Open for %n more block(s) + %n taneden daha fazla blok için açık%n taneden daha fazla blok için açık + + + Open until %1 + %1 değerine dek açık + + + conflicted with a transaction with %1 confirmations + %1 doğrulamalı bir işlem ile çelişti + + + %1/offline + %1/çevrim dışı + + + 0/unconfirmed, %1 + 0/doğrulanmamış, %1 + + + in memory pool + bellek alanında + + + not in memory pool + bellek alanında değil + + + abandoned + terk edilmiş + + + %1/unconfirmed + %1/doğrulanmadı + + + %1 confirmations + %1 doğrulama + + + Status + Durum + + + , has not been successfully broadcast yet + , henüz başarılı bir şekilde yayınlanmadı + + + , broadcast through %n node(s) + , %n düğüm aracılığıyla yayınlandı, %n düğüm aracılığıyla yayınlandı + + + Date + Tarih + + + Source + Kaynak + + + Generated + Oluşturuldu + + + From + Gönderen + + + unknown + bilinmiyor + + + To + Alıcı + + + own address + kendi adresiniz + + + watch-only + sadece-izlenen + + + label + etiket + + + Credit + Alınan Tutar + + + matures in %n more block(s) + %n ek blok sonrasında olgunlaşacak%n ek blok sonrasında olgunlaşacak + + + not accepted + kabul edilmedi + + + Debit + Çekilen Tutar + + + Total debit + Toplam çekilen tutar + + + Total credit + Toplam alınan tutar + + + Transaction fee + İşlem ücreti + + + Net amount + Net tutar + + + Message + İleti + + + Comment + Yorum + + + Transaction ID + İşlem ID'si + + + Transaction total size + İşlemin toplam boyutu + + + Output index + Çıktı indeksi + + + Merchant + Tüccar + + + 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. + Oluşturulan bitcoin'lerin harcanabilmelerinden önce %1 blok beklemeleri gerekmektedir. Bu blok, oluşturduğunuzda, blok zincirine eklenmesi için ağda yayınlandı. Zincire eklenmesi başarısız olursa, durumu "kabul edilmedi" olarak değiştirilecek ve harcanamayacaktır. Bu, bazen başka bir düğüm sizden birkaç saniye önce ya da sonra blok oluşturursa meydana gelebilir. + + + Debug information + Hata ayıklama bilgisi + + + Transaction + İşlem + + + Inputs + Girdiler + + + Amount + Tutar + + + true + doğru + + + false + yanlış + + TransactionDescDialog This pane shows a detailed description of the transaction - Bu pano muamelenin ayrıntılı açıklamasını gösterir + Bu pano işlemin ayrıntılı açıklamasını gösterir - + + Details for %1 + %1 için ayrıntılar + + TransactionTableModel + + Date + Tarih + + + Type + Tür + Label Etiket + + Open for %n more block(s) + %n taneden daha fazla blok için açık%n taneden daha fazla blok için açık + + + Open until %1 + %1 değerine dek açık + + + Offline + Çevrim dışı + + + Unconfirmed + Doğrulanmamış + + + Abandoned + Terk edilmiş + + + Confirming (%1 of %2 recommended confirmations) + Doğrulanıyor (%1 kere doğrulandı, önerilen doğrulama sayısı %2) + + + Confirmed (%1 confirmations) + Doğrulandı (%1 doğrulama) + + + Conflicted + Uyuşmadı + + + Immature (%1 confirmations, will be available after %2) + Olgunlaşmamış (%1 doğrulama, %2 doğrulama sonra kullanılabilir olacaktır) + + + This block was not received by any other nodes and will probably not be accepted! + Bu blok başka hiçbir düğüm tarafından alınmamıştır ve muhtemelen kabul edilmeyecektir! + + + Generated but not accepted + Oluşturuldu ama kabul edilmedi + + + Received with + Şununla alındı + + + Received from + Alındığı kişi + + + Sent to + Gönderildiği adres + + + Payment to yourself + Kendinize ödeme + + + Mined + Madenden çıkarılan + + + watch-only + sadece-izlenen + + + (n/a) + (mevcut değil) + (no label) (etiket yok) - + + Transaction status. Hover over this field to show number of confirmations. + İşlem durumu. Doğrulama sayısını görüntülemek için fare imlecini bu alanın üzerinde tutunuz. + + + Date and time that the transaction was received. + İşlemin alındığı tarih ve zaman. + + + Type of transaction. + İşlemin türü. + + + Whether or not a watch-only address is involved in this transaction. + Bu işleme sadece-izlenen bir adresin dahil edilip, edilmediği. + + + User-defined intent/purpose of the transaction. + İşlemin kullanıcı tanımlı amacı. + + + Amount removed from or added to balance. + Bakiyeden kaldırılan ya da bakiyeye eklenen tutar. + + TransactionView + + All + Hepsi + + + Today + Bugün + + + This week + Bu hafta + + + This month + Bu ay + + + Last month + Geçen ay + + + This year + Bu yıl + + + Range... + Tarih Aralığı + + + Received with + Şununla alındı + + + Sent to + Gönderildiği adres + + + To yourself + Kendinize + + + Mined + Madenden çıkarılan + + + Other + Diğer + + + Enter address or label to search + Aranacak adres ya da etiket giriniz + + + Min amount + En düşük tutar + + + Abandon transaction + İşlemden vazgeç + Copy address Adres kopyala @@ -1868,7 +2844,51 @@ Copy amount - Miktarı kopyala + Tutarı kopyala + + + Copy transaction ID + İşlem ID'sini kopyala + + + Copy raw transaction + Ham işlemi kopyala + + + Copy full transaction details + Tüm işlem ayrıntılarını kopyala + + + Edit label + Etiketi düzenle + + + Show transaction details + İşlem ayrıntılarını göster + + + Export Transaction History + İşlem Tarihçesini Dışarı Aktar + + + Comma separated file (*.csv) + Virgülle ayrılmış değerler dosyası (*.csv) + + + Confirmed + Doğrulandı + + + Watch-only + Sadece izlenen + + + Date + Tarih + + + Type + Tür Label @@ -1878,27 +2898,91 @@ Address Adres + + ID + ID + Exporting Failed Dışarı aktarmada hata - + + There was an error trying to save the transaction history to %1. + İşlem tarihçesinin %1 konumuna kaydedilmeye çalışıldığı sırada bir hata meydana geldi. + + + Exporting Successful + Dışarı Aktarma Başarılı + + + The transaction history was successfully saved to %1. + İşlem tarihçesi %1 konumuna başarıyla kaydedildi. + + + Range: + Tarih Aralığı: + + + to + Alıcı + + UnitDisplayStatusBarControl Unit to show amounts in. Click to select another unit. - Meblağları göstermek için birim. Başka bir birim seçmek için tıklayınız. + Tutarı göstermek için birim. Başka bir birim seçmek için tıklayınız. WalletFrame - + + No wallet has been loaded. + Hiçbir cüzdan yüklenmedi. + + WalletModel - + + Send Coins + Bitcoini Gönder + + WalletView - + + &Export + &Dışarı aktar + + + Export the data in the current tab to a file + Mevcut sekmedeki verileri bir dosyaya aktar + + + Backup Wallet + Cüzdanı Yedekle + + + Wallet Data (*.dat) + Cüzdan Verileri (*.dat) + + + Backup Failed + Yedekleme Başarısız Oldu + + + There was an error trying to save the wallet data to %1. + Cüzdan verilerinin %1 konumuna kaydedilmesi sırasında bir hata meydana geldi. + + + Backup Successful + Yedekleme Başarılı + + + The wallet data was successfully saved to %1. + Cüzdan verileri %1 konumuna başarıyla kaydedildi. + + bitcoin-core @@ -1921,13 +3005,25 @@ Accept command line and JSON-RPC commands Komut satırı ve JSON-RPC komutlarını kabul et + + Accept connections from outside (default: 1 if no -proxy or -connect/-noconnect) + Dışarıdan gelen bağlantıları kabul et (varsayılan: 1 eğer -proxy veya -connect/-noconnect yoksa) + + + Connect only to the specified node(s); -noconnect or -connect=0 alone to disable automatic connections + -noconnect ile yalnızca belirtilen düğümleri bağlayın veya yalnız otomatik bağlantıları devre dışı bırakmak için -connect=0 kullanın. + + + Distributed under the MIT software license, see the accompanying file %s or %s + MIT yazılım lisansı altında dağıtılmıştır, beraberindeki %s ya da %s dosyasına bakınız. + If <category> is not supplied or if <category> = 1, output all debugging information. - Eğer <kategori> belirtilmemişse ya da <kategori> = 1 ise, tüm hata ayıklama verilerini dök. + Eğer <kategori> belirtilmemişse ya da <kategori> = 1 ise, tüm hata ayıklama verilerini çıktı al. Prune configured below the minimum of %d MiB. Please use a higher number. - Budama, asgari değer olan %d MiB'den düşük olarak ayarlanmıştır. Lütfen daha yüksek bir sayı kullanınız. + Budama, en düşük değer olan %d MiB'den düşük olarak ayarlanmıştır. Lütfen daha yüksek bir sayı kullanınız. Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) @@ -1943,7 +3039,7 @@ Fee (in %s/kB) to add to transactions you send (default: %s) - Yolladığınız muamelelere eklenecek ücret (%s/kB olarak) (varsayılan: %s) + Yolladığınız işlemlere eklenecek ücret (%s/kB olarak) (varsayılan: %s) Pruning blockstore... @@ -1971,7 +3067,7 @@ Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d) - Muameleler aktarılmadığında dahi beyaz listedeki eşlerden aktarılan muameleleri kabul et (varsayılan: %d) + İşlemler aktarılmadığında dahi beyaz listedeki eşlerden aktarılan işlemleri kabul et (varsayılan: %d) Bind to given address and always listen on it. Use [host]:port notation for IPv6 @@ -1983,7 +3079,7 @@ Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup - Tüm cüzdan muamelelerini sil ve başlangıçta -rescan ile sadece blok zincirinin parçası olanları geri getir + Tüm cüzdan işlemlerini sil ve başlangıçta -rescan ile sadece blok zincirinin parçası olanları geri getir Error loading %s: You can't enable HD on a already existing non-HD wallet @@ -1991,19 +3087,27 @@ Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - %s dosyasının okunması sırasında bir hata meydana geldi! Tüm anahtarlar doğru bir şekilde okundu, ancak muamele verileri ya da adres defteri unsurları hatalı veya eksik olabilir. + %s dosyasının okunması sırasında bir hata meydana geldi! Tüm anahtarlar doğru bir şekilde okundu, ancak işlem verileri ya da adres defteri ögeleri hatalı veya eksik olabilir. Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) - Bir cüzdan muamelesi değiştiğinde komutu çalıştır (komuttaki %s muamele kimliği ile değiştirilecektir) + Bir cüzdan işlemi değiştiğinde komutu çalıştır (komuttaki %s işlem kimliği ile değiştirilecektir) + + + Extra transactions to keep in memory for compact block reconstructions (default: %u) + Daha küçük boyutlu blok yeniden yapılandırması için fazladan işlemleri bellekte tut. (varsayılan: %u) + + + If this block is in the chain assume that it and its ancestors are valid and potentially skip their script verification (0 to verify all, default: %s, testnet: %s) + Eğer bu blok zincirde yer alıyorsa onun ve atalarının geçerli olduğunu varsay ve potansiyel olarak onların betik doğrulamasını atla. (Tümünü doğrulamak için 0, varsayılan %s, testnet: %s) 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) + İzin verilen edilen en yüksek 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) 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) - Tek cüzdan muamelesinde ya da ham muamelede kullanılacak azami toplam ücret (%s olarak); bunu çok düşük olarak ayarlamak büyük muameleleri iptal edebilir (varsayılan: %s) + Tek bir cüzdan işleminde ya da ham işlemde kullanılacak en yüksek toplam ücret (%s olarak); bunu çok düşük olarak ayarlamak büyük işlemleri iptal edebilir (varsayılan: %s) Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly. @@ -2013,6 +3117,14 @@ Please contribute if you find %s useful. Visit %s for further information about the software. %s programını faydalı buluyorsanız lütfen katkıda bulununuz. Yazılım hakkında daha fazla bilgi için %s adresini ziyaret ediniz. + + Reduce storage requirements by enabling pruning (deleting) of old blocks. This allows the pruneblockchain RPC to be called to delete specific blocks, and enables automatic pruning of old blocks if a target size in MiB is provided. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, 1 = allow manual pruning via RPC, >%u = automatically prune block files to stay under the specified target size in MiB) + Eski blokları budamayı (silme) etkinleştirerek depolama gereksinimlerini azaltın. Bu belirli blokları silmek için pruneblockchain uzak yordam çağrısına (RPC) izin verir. Eğer bloklar hedef mebibyte boyutuna ulaşırsa eski blokların otomatik olarak budanmasını sağlar. Bu kip, -txindex ve -rescan ile uyumsuzdur. Uyarı: Bu ayarı geri almak, blok zincirinin tamamını yeniden yüklemeyi gerektirir. (varsayılan: 0 = blok budaması devre dışı, 1 = RPC üzerinden manuel budamaya izin verir, >%u = mebibyte olarak belirtilen hedef boyutun altında kalması için blok dosyalarını otomatik olarak budar) + + + Set lowest fee rate (in %s/kB) for transactions to be included in block creation. (default: %s) + Blok oluşturmaya dahil olan işlemler için en düşük ücret oranını (%s/kB olarak) ayarla. (varsayılan: %s) + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Betik kontrolü iş parçacıklarının sayısını belirler (%u ilâ %d, 0 = otomatik, <0 = bu sayıda çekirdeği kullanma, varsayılan: %d) @@ -2021,6 +3133,10 @@ 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 Blok veritabanı gelecekten gibi görünen bir blok içermektedir. Bu, bilgisayarınızın saat ve tarihinin yanlış ayarlanmış olmasından kaynaklanabilir. Blok veritabanını sadece bilgisayarınızın tarih ve saatinin doğru olduğundan eminseniz yeniden derleyin. + + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications + Bu kararlı sürümden önceki bir deneme sürümüdür. - risklerini bilerek kullanma sorumluluğu sizdedir - bitcoin oluşturmak ya da ticari uygulamalar için kullanmayınız + Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain Veritabanını çatallama öncesi duruma geri sarmak mümkün değil. Blok zincirini tekrar indirmeniz gerekmektedir @@ -2029,6 +3145,22 @@ Use UPnP to map the listening port (default: 1 when listening and no -proxy) Dinlenecek portu haritalamak için UPnP kullan (varsayılan: dinlenildiğinde ve -proxy olmadığında 1) + + 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. The client then connects normally using the rpcuser=<USERNAME>/rpcpassword=<PASSWORD> pair of arguments. This option can be specified multiple times + JSON-RPC bağlantıları için kullanıcı adı ve karmalanmış parola. <userpw> alanı şu biçimdedir: <KULLANICI ADI>:<SALT>$<HASH>. Kanonik bir Python betiği share/rpcuser klasöründe bulunabilir. Ardından istemci normal şekilde rpcuser=<KULLANICI ADI>/rpcpassword=<PAROLA> argüman çiftini kullanarak bağlanabilir. Bu seçenek birden çok kez belirtilebilir. + + + Wallet will not create transactions that violate mempool chain limits (default: %u) + Cüzdan, zincir bellek alanı limitlerini ihlal eden işlem oluşturmayacak. (varsayılan: %u) + + + Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. + Uyarı: Ağ üyeleri aralarında tamamen anlaşmış gibi gözükmüyor! Bazı madenciler sorun yaşıyor gibi görünmektedir. + + + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. + Uyarı: Ağ eşlerimizle tamamen anlaşamamışız gibi görünüyor! Güncelleme yapmanız gerekebilir ya da diğer düğümlerin güncelleme yapmaları gerekebilir. + You need to rebuild the database using -reindex-chainstate to change -txindex -txindex'i değiştirmek için veritabanını -reindex-chainstate kullanarak tekrar inşa etmeniz gerekmektedir @@ -2039,7 +3171,7 @@ -maxmempool must be at least %d MB - -maxmempool asgari %d MB olmalıdır + -maxmempool en az %d MB olmalıdır <category> can be: @@ -2061,9 +3193,13 @@ Cannot resolve -%s address: '%s' Çözümlenemedi - %s adres: '%s' + + Chain selection options: + Blok zinciri seçim ayarları: + Change index out of range - Aralık dışında değişiklik endeksi + Aralık dışında değişiklik indeksi Connection options: @@ -2095,7 +3231,7 @@ Enable publish hash transaction in <address> - Karma değer muamelesinin <adres>te yayınlanmasını etkinleştir + Karma değer işleminin <adres>te yayınlanmasını etkinleştir Enable publish raw block in <address> @@ -2103,11 +3239,11 @@ Enable publish raw transaction in <address> - Ham muamelenin <adres>te yayınlanmasını etkinleştir + Ham işlemin <adres>te yayınlanmasını etkinleştir Enable transaction replacement in the memory pool (default: %u) - Bellek alanında muamele değiştirmeyi etkinleştir (varsayılan: %u) + Bellek alanında işlem değiştirmeyi etkinleştir (varsayılan: %u) Error initializing block database @@ -2155,7 +3291,7 @@ Incorrect or no genesis block found. Wrong datadir for network? - Yanlış ya da bulunamamış doğuş bloku. Şebeke için yanlış veri klasörü mü? + Yanlış ya da bulunamamış doğuş bloğu. Ağ için yanlış veri klasörü mü? Initialization sanity check failed. %s is shutting down. @@ -2167,15 +3303,15 @@ Invalid amount for -%s=<amount>: '%s' - -%s=<meblağ> için geçersiz meblağ: '%s' + -%s=<tutar> için geçersiz tutar: '%s' Invalid amount for -fallbackfee=<amount>: '%s' - -fallbackfee=<meblağ> için geçersiz meblağ: '%s' + -fallbackfee=<tutar> için geçersiz tutar: '%s' Keep the transaction memory pool below <n> megabytes (default: %u) - Muamele bellek alanını <n> megabayttan düşük tut (varsayılan: %u) + İşlem bellek alanını <n> megabayttan düşük tut (varsayılan: %u) Loading banlist... @@ -2191,7 +3327,7 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) - Sadece <net> şebekesindeki düğümlere bağlan (ipv4, ipv6 veya onion) + Sadece <net> ağındaki düğümlere bağlan (ipv4, ipv6 veya onion) Print this help message and exit @@ -2211,11 +3347,11 @@ Rebuild chain state and block index from the blk*.dat files on disk - Zincir durumu ve blok endeksini diskteki blk*.dat dosyalarından yeniden derle + Zincir durumu ve blok indeksini diskteki blk*.dat dosyalarından yeniden derle Rebuild chain state from the currently indexed blocks - Zincir durumunu güncel olarak endekslenen bloklardan yeniden derle + Zincir durumunu güncel olarak indekslenen bloklardan yeniden derle Rewinding blocks... @@ -2227,7 +3363,7 @@ Set maximum block size in bytes (default: %d) - Azami blok boyutunu bayt olarak ayarla (varsayılan: %d) + En yüksek blok boyutunu bayt olarak ayarla (varsayılan: %d) Specify wallet file (within data directory) @@ -2257,6 +3393,10 @@ Use UPnP to map the listening port (default: %u) Dinleme portunu haritalamak için UPnP kullan (varsayılan: %u) + + Use the test chain + Test blok zincirini kullan + User Agent comment (%s) contains unsafe characters. Kullanıcı Aracı açıklaması (%s) güvensiz karakterler içermektedir. @@ -2287,7 +3427,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 - Belirtilen kaynaktan JSON-RPC bağlantılarını kabul et. Bir <ip> için geçerli olanlar şunlardır: salt IP adresi (mesela 1.2.3.4), bir şebeke/ağ maskesi (örneğin 1.2.3.4/255.255.255.0) ya da bir şebeke/CIDR (mesela 1.2.3.4/24). Bu seçenek birden fazla kez belirtilebilir + Belirtilen kaynaktan JSON-RPC bağlantılarını kabul et. Bir <ip> için geçerli olanlar şunlardır: IP adresi (mesela 1.2.3.4), bir ağ/ağ maskesi (örneğin 1.2.3.4/255.255.255.0) ya da bir ağ/CIDR (mesela 1.2.3.4/24). Bu seçenek birden fazla kez belirtilebilir Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6 @@ -2315,19 +3455,19 @@ Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) - Bundan düşük ücretler (%s/kB olarak) aktarma, oluşturma ve muamele yaratma için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s) + Bundan düşük ücretler (%s/kB olarak) aktarma, oluşturma ve işlem yaratma için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s) If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) - Eğer paytxfee ayarlanmadıysa kafi derecede ücret ekleyin ki muameleler teyite vasati n blok içinde başlasın (varsayılan: %u) + Eğer paytxfee ayarlanmadıysa kafi derecede ücret ekleyin ki işlemler teyite vasati n blok içinde başlasın (varsayılan: %u) Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) - -maxtxfee=<tutar> için geçersiz tutar: '%s' (Sıkışmış muameleleri önlemek için en az %s değerinde asgari aktarım ücretine eşit olmalıdır) + -maxtxfee=<tutar> için geçersiz tutar: '%s' (Sıkışmış işlemleri önlemek için en az %s değerinde en düşük aktarım ücretine eşit olmalıdır) Maximum size of data in data carrier transactions we relay and mine (default: %u) - Aktardığımız ve oluşturduğumuz veri taşıyıcı muamelelerindeki azami veri boyutu (varsayılan: %u) + Aktardığımız ve oluşturduğumuz veri taşıyıcı işlemlerindeki en yüksek veri boyutu (varsayılan: %u) Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u) @@ -2335,11 +3475,11 @@ Set maximum size of high-priority/low-fee transactions in bytes (default: %d) - Yüksek öncelikli/düşük ücretli muamelelerin azami boyutunu bayt olarak ayarla (varsayılan: %d) + Yüksek öncelikli/düşük ücretli işlemlerin en yüksek boyutunu bayt olarak ayarla (varsayılan: %d) The transaction amount is too small to send after the fee has been deducted - Bu muamele, ücret düşüldükten sonra göndermek için çok düşük + Bu işlem, tutar düşüldükten sonra göndermek için çok düşük Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start @@ -2347,7 +3487,7 @@ 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 - Beyaz listeye alınan eşler DoS yasaklamasına uğramazlar ve muameleleri zaten mempool'da olsalar da daima aktarılır, bu mesela bir geçit için kullanışlıdır + Beyaz listeye alınan eşler DoS yasaklamasına uğramazlar ve işlemleri zaten mempool'da olsalar da daima aktarılır, bu mesela bir geçit için kullanışlıdır You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain @@ -2391,7 +3531,7 @@ Keep at most <n> unconnectable transactions in memory (default: %u) - Hafızada en çok <n> bağlanılamaz muamele tut (varsayılan: %u) + Hafızada en çok <n> bağlanılamaz işlem tut (varsayılan: %u) Need to specify a port with -whitebind: '%s' @@ -2399,7 +3539,7 @@ Node relay options: - Düğüm röle seçenekleri: + Düğüm aktarma seçenekleri: RPC server options: @@ -2411,15 +3551,15 @@ Rescan the block chain for missing wallet transactions on startup - Başlangıçta blok zincirini eksik cüzdan muameleleri için tekrar tara + Başlangıçta blok zincirini eksik cüzdan işlemleri için tekrar tara Send trace/debug info to console instead of debug.log file - Trace/hata ayıklama verilerini debug.log dosyası yerine konsola gönder + İzleme/hata ayıklama verilerini debug.log dosyası yerine konsola gönder Send transactions as zero-fee transactions if possible (default: %u) - Muameleleri mümkünse ücretsiz olarak gönder (varsayılan: %u) + İşlemleri mümkünse ücretsiz olarak gönder (varsayılan: %u) Show all debugging options (usage: --help -help-debug) @@ -2431,11 +3571,11 @@ Signing transaction failed - Muamelenin imzalanması başarısız oldu + İşlemin imzalanması başarısız oldu The transaction amount is too small to pay the fee - Muamele meblağı ücreti ödemek için çok düşük + İşlemdeki bitcoin tutarı ücreti ödemek için çok düşük This is experimental software. @@ -2447,23 +3587,23 @@ Tor control port to use if onion listening enabled (default: %s) - Eğer onion dinlenmesi etkinse kullanılacak Tor kontrol portu (varsayılan: %s) + Eğer onion dinlemesi etkinse kullanılacak Tor kontrol portu (varsayılan: %s) Transaction amount too small - Muamele meblağı çok düşük + İşlem tutarı çok düşük Transaction too large for fee policy - Ücret politikası için çok büyük muamele + Ücret politikası için işlem çok büyük Transaction too large - Muamele çok büyük + İşlem çok büyük Unable to bind to %s on this computer (bind returned error %s) - Bu bilgisayarda %s unsuruna bağlanılamadı (bağlanma %s hatasını verdi) + Bu bilgisayarda %s ögesine bağlanılamadı (bağlanma %s hatasını verdi) Upgrade wallet to latest format on startup @@ -2479,15 +3619,15 @@ Warning: unknown new rules activated (versionbit %i) - İkaz: bilinmeyen yeni kurallar etkinleştirilmiştir (versionbit %i) + Uyarı: bilinmeyen yeni kurallar etkinleştirilmiştir (versionbit %i) Whether to operate in a blocks only mode (default: %u) - Salt blok kipinde çalışılıp çalışılmayacağı (varsayılan: %u) + Sadece blok kipinde çalışılıp çalışılmayacağı (varsayılan: %u) Zapping all transactions from wallet... - Cüzdandaki tüm muameleler kaldırılıyor... + Cüzdandaki tüm işlemler kaldırılıyor... ZeroMQ notification options: @@ -2515,19 +3655,23 @@ -maxtxfee is set very high! Fees this large could be paid on a single transaction. - -maxtxfee çok yüksek bir değere ayarlanmış! Bu denli yüksek ücretler tek bir muamelede ödenebilir. + -maxtxfee çok yüksek bir değere ayarlanmış! Bu denli yüksek ücretler tek bir işlemde ödenebilir. Do not keep transactions in the mempool longer than <n> hours (default: %u) - Muameleleri bellek alanında <n> saatten fazla tutma (varsayılan: %u) + İşlemleri bellek alanında <n> saatten fazla tutma (varsayılan: %u) 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) + Oluşturma ve aktarma işlemlerinde sigop başına eşdeğer bayt (varsayılan: %u) Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) - Bundan düşük ücretler (%s/kB olarak) muamele oluşturulması için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s) + Bundan düşük ücretler (%s/kB olarak) işlem oluşturulması için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s) + + + Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d) + Yerel aktarma politikasını ihlal etseler bile beyaz listedeki eşlerden gelen işlemlerin aktarılmasını zorla (varsayılan: %d) How thorough the block verification of -checkblocks is (0-4, default: %u) @@ -2535,7 +3679,7 @@ Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u) - Muamelelerin tamamının indeksini tut, getrawtransaction rpc çağrısı tarafından kullanılır (varsayılan: %u) + İşlemlerin tamamının indeksini tut, getrawtransaction rpc çağrısı tarafından kullanılır (varsayılan: %u) Number of seconds to keep misbehaving peers from reconnecting (default: %u) @@ -2543,15 +3687,31 @@ Output debugging information (default: %u, supplying <category> is optional) - Hata ayıklama bilgisi dök (varsayılan: %u, <kategori> sağlanması seçime dayalıdır) + Hata ayıklama bilgisini dök (varsayılan: %u, <kategori> sağlanması seçime dayalıdır) + + + Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect/-noconnect) + Adres sayısı azaldıysa DNS sorgulamasıyla eş adresleri ara (varsayılan: 1 -connect/-noconnect kullanılmadıysa) + + + Sets the serialization of raw transaction or block hex returned in non-verbose mode, non-segwit(0) or segwit(1) (default: %d) + Ham işlemin serileştirilmesini ayarlar veya blok non-verbose, non-segwit(0) veya segwit(1) kipinde onaltılık değeri döndürür (default: %d) Support filtering of blocks and transaction with bloom filters (default: %u) - Blokların ve muamelelerin bloom filtreleri ile süzülmesini destekle (varsayılan: %u) + Blokların ve işlemlerin bloom filtreleri ile süzülmesini destekle (varsayılan: %u) + + + This is the transaction fee you may pay when fee estimates are not available. + İşlem ücret tahminleri mevcut olmadığında ödeyebileceğiniz işlem ücreti budur. + + + This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit %s and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. + Bu ürün OpenSSL Projesi tarafından geliştirilen OpenSSL araç takımınında kullanılmak üzere yazılan yazılımları %s Eric Young tarafından yazılmış şifreleme yazılımını ve Thomas Bernard tarafından yazılmış UPnP yazılımını içerir. Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. - Şebeke sürümü zincirinin toplam boyutu (%i) azami boyutu geçmektedir (%i). Kullanıcı aracı açıklamasının sayısı veya boyutunu azaltınız. + Ağ sürümü zincirinin toplam boyutu (%i) en yüksek boyutu geçmektedir (%i). Kullanıcı aracı açıklamasının sayısı veya boyutunu azaltınız. Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) @@ -2571,11 +3731,19 @@ Warning: Unknown block versions being mined! It's possible unknown rules are in effect - İkaz: bilinmeyen blok sürümü oluşturulmaya çalışılıyor. Bilinmeyen kuralların işlemesi mümkündür. + Uyarı: Bilinmeyen blok sürümü oluşturulmaya çalışılıyor. Bilinmeyen kuralların işlemesi mümkündür. 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. - Uyarı: wallet.dat bozuk, veriler geri kazanıldı! Özgün %s, %s olarak %s klasörüne kaydedildi; bakiyeniz ya da muameleleriniz yanlışsa bir yedeklemeden tekrar yüklemeniz gerekir. + Uyarı: wallet.dat bozuk, veriler geri kazanıldı! Özgün %s, %s olarak %s klasörüne kaydedildi; bakiyeniz ya da işlemleriniz yanlışsa bir yedeklemeden tekrar yüklemeniz gerekir. + + + 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. + Beyaz listeye eklenen eşler verilen IP adresinden (ör. 1.2.3.4) veya CIDR ağından (ör. 1.2.3.0/24) bağlanabilir. Değerler birden çok kez kullanılabilir. + + + %s is set very high! + %s çok yüksek ayarlanmış! (default: %s) @@ -2597,6 +3765,10 @@ Invalid -proxy address: '%s' Geçersiz -proxy adresi: '%s' + + Keypool ran out, please call keypoolrefill first + Keypool tükendi, lütfen önce keypoolrefill'i çağırın + Listen for JSON-RPC connections on <port> (default: %u or testnet: %u) JSON-RPC bağlantılarını <port> üzerinde dinle (varsayılan: %u veya tesnet: %u) @@ -2611,15 +3783,15 @@ Make the wallet broadcast transactions - Cüzdanın muameleleri yayınlamasını sağla + Cüzdanın işlemleri yayınlamasını sağla Maximum per-connection receive buffer, <n>*1000 bytes (default: %u) - Her bağlantı için azami alım tamponu, <n>*1000 bayt (varsayılan: %u) + Her bağlantı için en yüksek alım tamponu, <n>*1000 bayt (varsayılan: %u) Maximum per-connection send buffer, <n>*1000 bytes (default: %u) - Her bağlantı için azami yollama tamponu, <n>*1000 bayt (varsayılan: %u) + Her bağlantı için çok gönderme tamponu, <n>*1000 bayt (varsayılan: %u) Prepend debug output with timestamp (default: %u) @@ -2627,19 +3799,23 @@ Relay and mine data carrier transactions (default: %u) - Veri taşıyıcı muameleleri oluştur ve aktar (varsayılan: %u) + Veri taşıyıcı işlemleri oluştur ve aktar (varsayılan: %u) Relay non-P2SH multisig (default: %u) P2SH olmayan çoklu imzaları aktar (varsayılan: %u) + + Send transactions with full-RBF opt-in enabled (default: %u) + İşlemleri full-RBF opt-in ile gönder etkinleştirildi (default: %u) + Set key pool size to <n> (default: %u) Anahtar alan boyutunu <n> değerine ayarla (varsayılan: %u) Set maximum BIP141 block weight (default: %d) - Azami BIP141 blok ağırlığını ayarla (varsayılan: %d) + En yüksek BIP141 blok ağırlığını ayarla (varsayılan: %d) Set the number of threads to service RPC calls (default: %d) @@ -2651,7 +3827,7 @@ Specify connection timeout in milliseconds (minimum: 1, default: %d) - Bağlantı zaman aşım süresini milisaniye olarak belirt (asgari: 1, varsayılan: %d) + Bağlantı zaman aşım süresini milisaniye olarak belirt (en düşüki: 1, varsayılan: %d) Specify pid file (default: %s) @@ -2659,15 +3835,43 @@ Spend unconfirmed change when sending transactions (default: %u) - Gönderme muamelelerinde teyit edilmemiş para üstünü harca (varsayılan: %u) + Gönderme işlemlerinde doğrulanmamış para üstünü harca (varsayılan: %u) + + + Starting network threads... + Ağ iş parçacıkları başlatılıyor... + + + The wallet will avoid paying less than the minimum relay fee. + Cüzdan en az aktarma ücretinden daha az ödeme yapmaktan sakınacaktır. + + + This is the minimum transaction fee you pay on every transaction. + Bu her işlemde ödeceğiniz en düşük işlem ücretidir. + + + This is the transaction fee you will pay if you send a transaction. + Eğer bir gönderme işlemi yaparsanız bu ödeyeceğiniz işlem ücretidir. Threshold for disconnecting misbehaving peers (default: %u) Aksaklık gösteren eşlerle bağlantıyı kesme sınırı (varsayılan: %u) + + Transaction amounts must not be negative + İşlem tutarı negatif olmamalıdır + + + Transaction has too long of a mempool chain + İşlem çok uzun bir mempool zincirine sahip + + + Transaction must have at least one recipient + İşlemin en az bir alıcısı olması gerekir + Unknown network specified in -onlynet: '%s' - -onlynet için bilinmeyen bir şebeke belirtildi: '%s' + -onlynet için bilinmeyen bir ağ belirtildi: '%s' Insufficient funds @@ -2679,7 +3883,7 @@ Add a node to connect to and attempt to keep the connection open - Bağlanılacak düğüm ekle ve bağlantıyı zinde tutmaya çalış + Bağlanılacak düğüm ekle ve bağlantıyı sürekli açık tutmaya çalış Loading wallet... @@ -2695,7 +3899,7 @@ Rescanning... - Yeniden tarama... + Yeniden taranıyor... Done loading diff --git a/src/qt/locale/bitcoin_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts index e98bc080e..20875c232 100644 --- a/src/qt/locale/bitcoin_zh_CN.ts +++ b/src/qt/locale/bitcoin_zh_CN.ts @@ -481,6 +481,10 @@ %1 client %1 客戶 + + Connecting to peers... + 正在连接到节点…… + Catching up... 更新中... @@ -1927,7 +1931,11 @@ (no amount requested) (无请求金额) - + + Requested + 总额 + + SendCoinsDialog @@ -2178,6 +2186,10 @@ Warning: Unknown change address 警告:未知的更改地址 + + The address you selected for change is not part of this wallet. Any or all funds in your wallet may be sent to this address. Are you sure? + 你选择的找零地址未被包含在本钱包中,你钱包中的部分或全部金额将被发送至该地址。你确定要这样做吗? + (no label) (无标签) @@ -2459,6 +2471,14 @@ 0/unconfirmed, %1 0/未确认,%1 + + in memory pool + 在内存池中 + + + not in memory pool + 不在内存池中 + abandoned 已抛弃 @@ -3200,6 +3220,10 @@ Use UPnP to map the listening port (default: %u) 使用UPnp映射监听端口 (默认: %u) + + Use the test chain + 使用测试链 + User Agent comment (%s) contains unsafe characters. 用户代理评论(%s)包含不安全的字符。 diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 89f633aa7..7ff00b1e9 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -277,6 +277,9 @@ void OptionsDialog::showRestartWarning(bool fPersistent) void OptionsDialog::clearStatusLabel() { ui->statusLabel->clear(); + if (model && model->isRestartRequired()) { + showRestartWarning(true); + } } void OptionsDialog::updateProxyValidationState() @@ -286,7 +289,7 @@ void OptionsDialog::updateProxyValidationState() if (pUiProxyIp->isValid() && (!ui->proxyPort->isEnabled() || ui->proxyPort->text().toInt() > 0) && (!ui->proxyPortTor->isEnabled() || ui->proxyPortTor->text().toInt() > 0)) { setOkButtonState(otherProxyWidget->isValid()); //only enable ok button if both proxys are valid - ui->statusLabel->clear(); + clearStatusLabel(); } else { diff --git a/src/qt/paymentrequestplus.h b/src/qt/paymentrequestplus.h index ee1a37d83..a2fea3fdc 100644 --- a/src/qt/paymentrequestplus.h +++ b/src/qt/paymentrequestplus.h @@ -5,7 +5,10 @@ #ifndef BITCOIN_QT_PAYMENTREQUESTPLUS_H #define BITCOIN_QT_PAYMENTREQUESTPLUS_H +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #include "paymentrequest.pb.h" +#pragma GCC diagnostic pop #include "base58.h" diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 688e8123a..dd75f1207 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -55,8 +55,6 @@ const char* BIP70_MESSAGE_PAYMENTREQUEST = "PaymentRequest"; const char* BIP71_MIMETYPE_PAYMENT = "application/bitcoin-payment"; const char* BIP71_MIMETYPE_PAYMENTACK = "application/bitcoin-paymentack"; const char* BIP71_MIMETYPE_PAYMENTREQUEST = "application/bitcoin-paymentrequest"; -// BIP70 max payment request size in bytes (DoS protection) -const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE = 50000; struct X509StoreDeleter { void operator()(X509_STORE* b) { diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index 9d46280a3..7c6d4507f 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -53,7 +53,7 @@ class QUrl; QT_END_NAMESPACE // BIP70 max payment request size in bytes (DoS protection) -extern const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE; +static const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE = 50000; class PaymentServer : public QObject { diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 368654bfa..7b69c81ff 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -820,7 +820,8 @@ UniValue pruneblockchain(const JSONRPCRequest& request) throw runtime_error( "pruneblockchain\n" "\nArguments:\n" - "1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or to a unix timestamp to prune based on block time.\n" + "1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or a unix timestamp\n" + " to prune blocks whose block time is at least 2 hours older than the provided timestamp.\n" "\nResult:\n" "n (numeric) Height of the last block pruned.\n" "\nExamples:\n" @@ -839,7 +840,8 @@ UniValue pruneblockchain(const JSONRPCRequest& request) // Height value more than a billion is too high to be a block height, and // too low to be a block time (corresponds to timestamp from Sep 2001). if (heightParam > 1000000000) { - CBlockIndex* pindex = chainActive.FindEarliestAtLeast(heightParam); + // Add a 2 hour buffer to include blocks which might have had old timestamps + CBlockIndex* pindex = chainActive.FindEarliestAtLeast(heightParam - 7200); if (!pindex) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Could not find block with at least the specified timestamp."); } diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 5bdd84e55..29bdb3768 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -24,7 +24,7 @@ public: }; /** - * Specifiy a (method, idx, name) here if the argument is a non-string RPC + * Specify a (method, idx, name) here if the argument is a non-string RPC * argument and needs to be converted from JSON. * * @note Parameter indexes start from 0. diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index c594daca0..77cd282a3 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -676,8 +676,12 @@ UniValue getblocktemplate(const JSONRPCRequest& request) 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("weightlimit", (int64_t)MAX_BLOCK_WEIGHT)); + if (fPreSegWit) { + result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_BASE_SIZE)); + } else { + result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SERIALIZED_SIZE)); + 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))); diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 480c45516..140cb4840 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -167,6 +167,7 @@ UniValue validateaddress(const JSONRPCRequest& request) " \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n" " \"iscompressed\" : true|false, (boolean) If the address is compressed\n" " \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\n" + " \"timestamp\" : timestamp, (number, optional) The creation time of the key if available in seconds since epoch (Jan 1 1970 GMT)\n" " \"hdkeypath\" : \"keypath\" (string, optional) The HD keypath if the key is HD and available\n" " \"hdmasterkeyid\" : \"\" (string, optional) The Hash160 of the HD master pubkey\n" "}\n" @@ -204,10 +205,19 @@ UniValue validateaddress(const JSONRPCRequest& request) if (pwalletMain && pwalletMain->mapAddressBook.count(dest)) ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name)); CKeyID keyID; - if (pwalletMain && address.GetKeyID(keyID) && pwalletMain->mapKeyMetadata.count(keyID) && !pwalletMain->mapKeyMetadata[keyID].hdKeypath.empty()) - { - ret.push_back(Pair("hdkeypath", pwalletMain->mapKeyMetadata[keyID].hdKeypath)); - ret.push_back(Pair("hdmasterkeyid", pwalletMain->mapKeyMetadata[keyID].hdMasterKeyID.GetHex())); + if (pwalletMain) { + const auto& meta = pwalletMain->mapKeyMetadata; + auto it = address.GetKeyID(keyID) ? meta.find(keyID) : meta.end(); + if (it == meta.end()) { + it = meta.find(CScriptID(scriptPubKey)); + } + if (it != meta.end()) { + ret.push_back(Pair("timestamp", it->second.nCreateTime)); + if (!it->second.hdKeypath.empty()) { + ret.push_back(Pair("hdkeypath", it->second.hdKeypath)); + ret.push_back(Pair("hdmasterkeyid", it->second.hdMasterKeyID.GetHex())); + } + } } #endif } @@ -435,7 +445,7 @@ UniValue setmocktime(const JSONRPCRequest& request) // this could have an effect on mempool time-based eviction, as well as // IsCurrentForFeeEstimation() and IsInitialBlockDownload(). // TODO: figure out the right way to synchronize around mocktime, and - // ensure all callsites of GetTime() are accessing this safely. + // ensure all call sites of GetTime() are accessing this safely. LOCK(cs_main); RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VNUM)); diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 283d458c8..0b763acd4 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -18,8 +18,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index 09bedc546..6f364e42d 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -93,8 +93,9 @@ static CSignatureCache signatureCache; // To be called once in AppInit2/TestingSetup to initialize the signatureCache void InitSignatureCache() { - size_t nMaxCacheSize = GetArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20); - if (nMaxCacheSize <= 0) return; + // nMaxCacheSize is unsigned. If -maxsigcachesize is set to zero, + // setup_bytes creates the minimum possible cache (2 elements). + size_t nMaxCacheSize = std::min(std::max((int64_t)0, GetArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE)), MAX_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20); size_t nElems = signatureCache.setup_bytes(nMaxCacheSize); LogPrintf("Using %zu MiB out of %zu requested for signature cache, able to store %zu elements\n", (nElems*sizeof(uint256)) >>20, nMaxCacheSize>>20, nElems); diff --git a/src/script/sigcache.h b/src/script/sigcache.h index c123a9ba0..238952bb9 100644 --- a/src/script/sigcache.h +++ b/src/script/sigcache.h @@ -14,6 +14,8 @@ // systems). Due to how we count cache size, actual memory usage is slightly // more (~32.25 MB) static const unsigned int DEFAULT_MAX_SIG_CACHE_SIZE = 32; +// Maximum sig cache size allowed +static const int64_t MAX_MAX_SIG_CACHE_SIZE = 16384; class CPubKey; diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index a8f09ba6a..c62e6ae83 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -23,7 +23,7 @@ #include #include -// Tests this internal-to-main.cpp method: +// Tests these internal-to-net_processing.cpp methods: extern bool AddOrphanTx(const CTransactionRef& tx, NodeId peer); extern void EraseOrphansFor(NodeId peer); extern unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans); diff --git a/src/test/testutil.cpp b/src/test/testutil.cpp index 304cffb79..e6d862297 100644 --- a/src/test/testutil.cpp +++ b/src/test/testutil.cpp @@ -11,23 +11,5 @@ #include boost::filesystem::path GetTempPath() { -#if BOOST_FILESYSTEM_VERSION == 3 return boost::filesystem::temp_directory_path(); -#else - // TODO: remove when we don't support filesystem v2 anymore - boost::filesystem::path path; -#ifdef WIN32 - char pszPath[MAX_PATH] = ""; - - if (GetTempPathA(MAX_PATH, pszPath)) - path = boost::filesystem::path(pszPath); -#else - path = boost::filesystem::path("/tmp"); -#endif - if (path.empty() || !boost::filesystem::is_directory(path)) { - LogPrintf("GetTempPath(): failed to find temp path\n"); - return boost::filesystem::path(""); - } - return path; -#endif } diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 236527a2b..5842dd88d 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -395,7 +395,7 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, { NotifyEntryAdded(entry.GetSharedTx()); // Add to memory pool without checking anything. - // Used by main.cpp AcceptToMemoryPool(), which DOES do + // Used by AcceptToMemoryPool(), which DOES do // all the appropriate checks. LOCK(cs); indexed_transaction_set::iterator newit = mapTx.insert(entry).first; diff --git a/src/util.cpp b/src/util.cpp index ba157625d..78c353dfe 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -214,12 +214,13 @@ void OpenDebugLog() assert(vMsgsBeforeOpenLog); boost::filesystem::path pathDebug = GetDataDir() / "debug.log"; fileout = fopen(pathDebug.string().c_str(), "a"); - if (fileout) setbuf(fileout, NULL); // unbuffered - - // dump buffered messages from before we opened the log - while (!vMsgsBeforeOpenLog->empty()) { - FileWriteStr(vMsgsBeforeOpenLog->front(), fileout); - vMsgsBeforeOpenLog->pop_front(); + if (fileout) { + setbuf(fileout, NULL); // unbuffered + // dump buffered messages from before we opened the log + while (!vMsgsBeforeOpenLog->empty()) { + FileWriteStr(vMsgsBeforeOpenLog->front(), fileout); + vMsgsBeforeOpenLog->pop_front(); + } } delete vMsgsBeforeOpenLog; @@ -838,4 +839,4 @@ std::string CopyrightHolders(const std::string& strPrefix) strCopyrightHolders += "\n" + strPrefix + "The Bitcoin Core developers"; } return strCopyrightHolders; -} +} \ No newline at end of file diff --git a/src/utiltime.h b/src/utiltime.h index 05c679049..cc3290c63 100644 --- a/src/utiltime.h +++ b/src/utiltime.h @@ -11,7 +11,7 @@ /** * GetTimeMicros() and GetTimeMillis() both return the system time, but in - * different units. GetTime() returns the sytem time in seconds, but also + * different units. GetTime() returns the system time in seconds, but also * supports mocktime, where the time can be specified by the user, eg for * testing (eg with the setmocktime rpc, or -mocktime argument). * diff --git a/src/validation.cpp b/src/validation.cpp index fe8f8365b..cad1c9c16 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1429,7 +1429,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // Helps prevent CPU exhaustion attacks. // Skip script verification when connecting blocks under the - // assumedvalid block. Assuming the assumedvalid block is valid this + // assumevalid block. Assuming the assumevalid block is valid this // is safe because block merkle hashes are still computed and checked, // Of course, if an assumed valid block is invalid due to false scriptSigs // this optimization would allow an invalid chain to be accepted. @@ -1771,7 +1771,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin pindexBestHeader->GetAncestor(pindex->nHeight) == pindex && pindexBestHeader->nChainWork >= UintToArith256(chainparams.GetConsensus().nMinimumChainWork)) { // This block is a member of the assumed verified chain and an ancestor of the best header. - // The equivalent time check discourages hashpower from extorting the network via DOS attack + // The equivalent time check discourages hash power from extorting the network via DOS attack // into accepting an invalid block through telling users they must manually set assumevalid. // Requiring a software change or burying the invalid block, regardless of the setting, makes // it hard to hide the implication of the demand. This also avoids having release candidates @@ -2486,12 +2486,12 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, bool fInitialDownload; { LOCK(cs_main); - { // TODO: Tempoarily ensure that mempool removals are notified before + { // TODO: Temporarily ensure that mempool removals are notified before // connected transactions. This shouldn't matter, but the abandoned // state of transactions in our wallet is currently cleared when we // receive another notification and there is a race condition where // notification of a connected conflict might cause an outside process - // to abandon a transaction and then have it inadvertantly cleared by + // to abandon a transaction and then have it inadvertently cleared by // the notification that the conflicted transaction was evicted. MemPoolConflictRemovalTracker mrt(mempool); CBlockIndex *pindexOldTip = chainActive.Tip(); @@ -2520,7 +2520,7 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, } // MemPoolConflictRemovalTracker destroyed and conflict evictions are notified - // Transactions in the connnected block are notified + // Transactions in the connected block are notified for (const auto& pair : connectTrace.blocksConnected) { assert(pair.second); const CBlock& block = *(pair.second); @@ -3187,7 +3187,7 @@ static bool AcceptBlock(const std::shared_ptr& pblock, CValidation } if (fNewBlock) *fNewBlock = true; - if (!CheckBlock(block, state, chainparams.GetConsensus(), GetAdjustedTime()) || + if (!CheckBlock(block, state, chainparams.GetConsensus()) || !ContextualCheckBlock(block, state, chainparams.GetConsensus(), pindex->pprev)) { if (state.IsInvalid() && !state.CorruptionPossible()) { pindex->nStatus |= BLOCK_FAILED_VALID; @@ -3229,13 +3229,19 @@ static bool AcceptBlock(const std::shared_ptr& pblock, CValidation bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr pblock, bool fForceProcessing, bool *fNewBlock) { { - LOCK(cs_main); - - // Store to disk CBlockIndex *pindex = NULL; if (fNewBlock) *fNewBlock = false; CValidationState state; - bool ret = AcceptBlock(pblock, state, chainparams, &pindex, fForceProcessing, NULL, fNewBlock); + // Ensure that CheckBlock() passes before calling AcceptBlock, as + // belt-and-suspenders. + bool ret = CheckBlock(*pblock, state, chainparams.GetConsensus()); + + LOCK(cs_main); + + if (ret) { + // Store to disk + ret = AcceptBlock(pblock, state, chainparams, &pindex, fForceProcessing, NULL, fNewBlock); + } CheckBlockIndex(chainparams.GetConsensus()); if (!ret) { GetMainSignals().BlockChecked(*pblock, state); @@ -4174,7 +4180,7 @@ static const uint64_t MEMPOOL_DUMP_VERSION = 1; bool LoadMempool(void) { int64_t nExpiryTimeout = GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60; - FILE* filestr = fopen((GetDataDir() / "mempool.dat").string().c_str(), "r"); + FILE* filestr = fopen((GetDataDir() / "mempool.dat").string().c_str(), "rb"); CAutoFile file(filestr, SER_DISK, CLIENT_VERSION); if (file.IsNull()) { LogPrintf("Failed to open mempool file from disk. Continuing anyway.\n"); @@ -4255,7 +4261,7 @@ void DumpMempool(void) int64_t mid = GetTimeMicros(); try { - FILE* filestr = fopen((GetDataDir() / "mempool.dat.new").string().c_str(), "w"); + FILE* filestr = fopen((GetDataDir() / "mempool.dat.new").string().c_str(), "wb"); if (!filestr) { return; } diff --git a/src/validationinterface.h b/src/validationinterface.h index a2e76f203..a494eb699 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -50,7 +50,7 @@ protected: struct CMainSignals { /** Notifies listeners of updated block chain tip */ boost::signals2::signal UpdatedBlockTip; - /** A posInBlock value for SyncTransaction calls for tranactions not + /** A posInBlock value for SyncTransaction calls for transactions not * included in connected blocks such as transactions removed from mempool, * accepted to mempool or appearing in disconnected blocks.*/ static const int SYNC_TRANSACTION_NOT_IN_BLOCK = -1; diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 7d4ed70ed..e95c71ac8 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -143,7 +143,7 @@ UniValue importprivkey(const JSONRPCRequest& request) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); // whenever a key is imported, we need to scan the whole chain - pwalletMain->nTimeFirstKey = 1; // 0 would be considered 'no value' + pwalletMain->UpdateTimeFirstKey(1); if (fRescan) { pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true); @@ -161,7 +161,7 @@ void ImportScript(const CScript& script, const string& strLabel, bool isRedeemSc pwalletMain->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script)) + if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script, 0 /* nCreateTime */)) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); if (isRedeemScript) { @@ -500,8 +500,7 @@ UniValue importwallet(const JSONRPCRequest& request) while (pindex && pindex->pprev && pindex->GetBlockTime() > nTimeBegin - 7200) pindex = pindex->pprev; - if (!pwalletMain->nTimeFirstKey || nTimeBegin < pwalletMain->nTimeFirstKey) - pwalletMain->nTimeFirstKey = nTimeBegin; + pwalletMain->UpdateTimeFirstKey(nTimeBegin); LogPrintf("Rescanning last %i blocks\n", chainActive.Height() - pindex->nHeight + 1); pwalletMain->ScanForWalletTransactions(pindex); @@ -576,15 +575,17 @@ UniValue dumpwallet(const JSONRPCRequest& request) if (!file.is_open()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file"); - std::map mapKeyBirth; + std::map mapKeyBirth; std::set setKeyPool; pwalletMain->GetKeyBirthTimes(mapKeyBirth); pwalletMain->GetAllReserveKeys(setKeyPool); // sort time/key pairs std::vector > vKeyBirth; - for (std::map::const_iterator it = mapKeyBirth.begin(); it != mapKeyBirth.end(); it++) { - vKeyBirth.push_back(std::make_pair(it->second, it->first)); + for (const auto& entry : mapKeyBirth) { + if (const CKeyID* keyID = boost::get(&entry.first)) { // set and test + vKeyBirth.push_back(std::make_pair(entry.second, *keyID)); + } } mapKeyBirth.clear(); std::sort(vKeyBirth.begin(), vKeyBirth.end()); @@ -640,7 +641,8 @@ UniValue dumpwallet(const JSONRPCRequest& request) } -UniValue processImport(const UniValue& data) { +UniValue ProcessImport(const UniValue& data, const int64_t timestamp) +{ try { bool success = false; @@ -659,7 +661,6 @@ UniValue processImport(const UniValue& data) { const bool& internal = data.exists("internal") ? data["internal"].get_bool() : false; const bool& watchOnly = data.exists("watchonly") ? data["watchonly"].get_bool() : false; const string& label = data.exists("label") && !internal ? data["label"].get_str() : ""; - const int64_t& timestamp = data.exists("timestamp") && data["timestamp"].get_int64() > 1 ? data["timestamp"].get_int64() : 1; bool isScript = scriptPubKey.getType() == UniValue::VSTR; bool isP2SH = strRedeemScript.length() > 0; @@ -671,6 +672,9 @@ UniValue processImport(const UniValue& data) { if (!isScript) { address = CBitcoinAddress(output); + if (!address.IsValid()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); + } script = GetScriptForDestination(address.Get()); } else { if (!IsHex(output)) { @@ -721,7 +725,7 @@ UniValue processImport(const UniValue& data) { pwalletMain->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(redeemScript) && !pwalletMain->AddWatchOnly(redeemScript)) { + if (!pwalletMain->HaveWatchOnly(redeemScript) && !pwalletMain->AddWatchOnly(redeemScript, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } @@ -738,7 +742,7 @@ UniValue processImport(const UniValue& data) { pwalletMain->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(redeemDestination) && !pwalletMain->AddWatchOnly(redeemDestination)) { + if (!pwalletMain->HaveWatchOnly(redeemDestination) && !pwalletMain->AddWatchOnly(redeemDestination, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } @@ -782,9 +786,7 @@ UniValue processImport(const UniValue& data) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); } - if (timestamp < pwalletMain->nTimeFirstKey) { - pwalletMain->nTimeFirstKey = timestamp; - } + pwalletMain->UpdateTimeFirstKey(timestamp); } } @@ -833,7 +835,7 @@ UniValue processImport(const UniValue& data) { pwalletMain->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(pubKeyScript) && !pwalletMain->AddWatchOnly(pubKeyScript)) { + if (!pwalletMain->HaveWatchOnly(pubKeyScript) && !pwalletMain->AddWatchOnly(pubKeyScript, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } @@ -851,7 +853,7 @@ UniValue processImport(const UniValue& data) { pwalletMain->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(scriptRawPubKey) && !pwalletMain->AddWatchOnly(scriptRawPubKey)) { + if (!pwalletMain->HaveWatchOnly(scriptRawPubKey) && !pwalletMain->AddWatchOnly(scriptRawPubKey, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } @@ -912,9 +914,7 @@ UniValue processImport(const UniValue& data) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); } - if (timestamp < pwalletMain->nTimeFirstKey) { - pwalletMain->nTimeFirstKey = timestamp; - } + pwalletMain->UpdateTimeFirstKey(timestamp); success = true; } @@ -927,7 +927,7 @@ UniValue processImport(const UniValue& data) { pwalletMain->MarkDirty(); - if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script)) { + if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } @@ -958,6 +958,20 @@ UniValue processImport(const UniValue& data) { } } +int64_t GetImportTimestamp(const UniValue& data, int64_t now) +{ + if (data.exists("timestamp")) { + const UniValue& timestamp = data["timestamp"]; + if (timestamp.isNum()) { + return timestamp.get_int64(); + } else if (timestamp.isStr() && timestamp.get_str() == "now") { + return now; + } + throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Expected number or \"now\" timestamp value for key. got type %s", uvTypeName(timestamp.type()))); + } + throw JSONRPCError(RPC_TYPE_ERROR, "Missing required timestamp field for key"); +} + UniValue importmulti(const JSONRPCRequest& mainRequest) { // clang-format off @@ -970,13 +984,18 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) " [ (array of json objects)\n" " {\n" " \"scriptPubKey\": \"