diff options
-rw-r--r-- | contrib/README.md | 4 | ||||
-rw-r--r-- | contrib/pyminer/README.md | 8 | ||||
-rw-r--r-- | contrib/pyminer/example-config.cfg | 32 | ||||
-rwxr-xr-x | contrib/pyminer/pyminer.py | 269 | ||||
-rw-r--r-- | contrib/systemd/bitcoind.service | 17 | ||||
-rw-r--r-- | doc/README.md | 3 | ||||
-rw-r--r-- | doc/README_windows.txt | 2 | ||||
-rw-r--r-- | doc/build-msw.md | 83 | ||||
-rw-r--r-- | doc/systemd.md | 47 | ||||
-rw-r--r-- | src/checkpoints.cpp | 5 | ||||
-rw-r--r-- | src/init.cpp | 4 | ||||
-rw-r--r-- | src/net.cpp | 31 | ||||
-rw-r--r-- | src/netbase.cpp | 70 | ||||
-rw-r--r-- | src/netbase.h | 2 | ||||
-rw-r--r-- | src/qt/optionsdialog.cpp | 4 | ||||
-rw-r--r-- | src/qt/optionsmodel.h | 1 | ||||
-rw-r--r-- | src/qt/transactiondesc.cpp | 2 | ||||
-rw-r--r-- | src/qt/transactiontablemodel.cpp | 2 | ||||
-rw-r--r-- | src/qt/transactiontablemodel.h | 4 | ||||
-rw-r--r-- | src/rpcclient.cpp | 2 | ||||
-rw-r--r-- | src/rpcmining.cpp | 23 | ||||
-rw-r--r-- | src/rpcmisc.cpp | 13 |
22 files changed, 174 insertions, 454 deletions
diff --git a/contrib/README.md b/contrib/README.md index 63b1875d30..dae975e9ef 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -19,10 +19,6 @@ Contains the script `github-merge.sh` for merging github pull requests securely ### [Linearize](/contrib/linearize) ### Construct a linear, no-fork, best version of the blockchain. -### [PyMiner](/contrib/pyminer) ### - -This is a 'getwork' CPU mining client for Bitcoin. It is pure-python, and therefore very, very slow. The purpose is to provide a reference implementation of a miner in order to study and develop other mining programs. - ### [Qos](/contrib/qos) ### A Linux bash script that will set up traffic control (tc) to limit the outgoing bandwidth for connections to the Bitcoin network. This means one can have an always-on bitcoind instance running, and another local bitcoind/bitcoin-qt instance which connects to this node and receives blocks from it. diff --git a/contrib/pyminer/README.md b/contrib/pyminer/README.md deleted file mode 100644 index 3b20f2fdea..0000000000 --- a/contrib/pyminer/README.md +++ /dev/null @@ -1,8 +0,0 @@ -### PyMiner ### - -This is a 'getwork' CPU mining client for Bitcoin. It is pure-python, and therefore very, very slow. The purpose is to provide a reference implementation of a miner, for study. - -### Other Resources ### - -- [BitcoinTalk Thread](https://bitcointalk.org/index.php?topic=3546.0) -- [Jgarzik Repo](https://github.com/jgarzik/pyminer)
\ No newline at end of file diff --git a/contrib/pyminer/example-config.cfg b/contrib/pyminer/example-config.cfg deleted file mode 100644 index 103e7c1372..0000000000 --- a/contrib/pyminer/example-config.cfg +++ /dev/null @@ -1,32 +0,0 @@ - -# -# RPC login details -# -host=127.0.0.1 -port=8332 - -rpcuser=myusername -rpcpass=mypass - - -# -# mining details -# - -threads=4 - -# periodic rate for requesting new work, if solution not found -scantime=60 - - -# -# misc. -# - -# not really used right now -logdir=/tmp/pyminer - -# set to 1, to enable hashmeter output -hashmeter=0 - - diff --git a/contrib/pyminer/pyminer.py b/contrib/pyminer/pyminer.py deleted file mode 100755 index 706a10b39d..0000000000 --- a/contrib/pyminer/pyminer.py +++ /dev/null @@ -1,269 +0,0 @@ -#!/usr/bin/python -# -# Copyright (c) 2011 The Bitcoin developers -# Distributed under the MIT/X11 software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -# - -import sys -from multiprocessing import Process -import time -import struct -import hashlib -import base64 -import re -import httplib -import json - -ERR_SLEEP = 15 -MAX_NONCE = 1000000L - -settings = {} - - -class BitcoinRPC: - object_id = 1 - - def __init__(self, host, port, username, password): - authpair = "{0}:{1}".format(username, password) - self.authhdr = "Basic {0}".format(base64.b64encode(authpair)) - self.conn = httplib.HTTPConnection(host, port, strict=False, timeout=30) - - def rpc(self, method, params=None): - self.object_id += 1 - obj = {'version' : '1.1', - 'method' : method, - 'id' : self.object_id, - 'params' : params or []} - - self.conn.request('POST', '/', json.dumps(obj), - { 'Authorization' : self.authhdr, - 'Content-type' : 'application/json' }) - - resp = self.conn.getresponse() - - if resp is None: - print("JSON-RPC: no response") - return None - - body = resp.read() - resp_obj = json.loads(body) - - if resp_obj is None: - print("JSON-RPC: cannot JSON-decode body") - return None - - if 'error' in resp_obj and resp_obj['error'] != None: - return resp_obj['error'] - - if 'result' not in resp_obj: - print("JSON-RPC: no result in object") - return None - - return resp_obj['result'] - - def getblockcount(self): - return self.rpc('getblockcount') - - def getwork(self, data=None): - return self.rpc('getwork', data) - -def uint32(x): - return x & 0xffffffffL - -def bytereverse(x): - return uint32(( ((x) << 24) | (((x) << 8) & 0x00ff0000) | - (((x) >> 8) & 0x0000ff00) | ((x) >> 24) )) - -def bufreverse(in_buf): - out_words = [] - - for i in range(0, len(in_buf), 4): - word = struct.unpack('@I', in_buf[i:i+4])[0] - out_words.append(struct.pack('@I', bytereverse(word))) - - return ''.join(out_words) - -def wordreverse(in_buf): - out_words = [] - - for i in range(0, len(in_buf), 4): - out_words.append(in_buf[i:i+4]) - - out_words.reverse() - - return ''.join(out_words) - - -class Miner: - def __init__(self, id): - self.id = id - self.max_nonce = MAX_NONCE - - def work(self, datastr, targetstr): - # decode work data hex string to binary - static_data = datastr.decode('hex') - static_data = bufreverse(static_data) - - # the first 76b of 80b do not change - blk_hdr = static_data[:76] - - # decode 256-bit target value - targetbin = targetstr.decode('hex') - targetbin = targetbin[::-1] # byte-swap and dword-swap - targetbin_str = targetbin.encode('hex') - target = long(targetbin_str, 16) - - # pre-hash first 76b of block header - static_hash = hashlib.sha256() - static_hash.update(blk_hdr) - - for nonce in xrange(self.max_nonce): - - # encode 32-bit nonce value - nonce_bin = struct.pack("<I", nonce) - - # hash final 4b, the nonce value - hash1_o = static_hash.copy() - hash1_o.update(nonce_bin) - hash1 = hash1_o.digest() - - # sha256 hash of sha256 hash - hash_o = hashlib.sha256() - hash_o.update(hash1) - hash = hash_o.digest() - - # quick test for winning solution: high 32 bits zero? - if hash[-4:] != '\0\0\0\0': - continue - - # convert binary hash to 256-bit Python long - hash = bufreverse(hash) - hash = wordreverse(hash) - - hash_str = hash.encode('hex') - long_hash = long(hash_str, 16) - - # proof-of-work test: hash < target - if long_hash < target: - print(time.asctime(), "PROOF-OF-WORK found: " - "{0:064x}".format(long_hash)) - return (nonce + 1, nonce_bin) - else: - print(time.asctime(), "PROOF-OF-WORK false" - "positive {0:064x}".format(long_hash)) - - return (nonce + 1, None) - - def submit_work(self, rpc, original_data, nonce_bin): - nonce_bin = bufreverse(nonce_bin) - nonce = nonce_bin.encode('hex') - solution = original_data[:152] + nonce + original_data[160:256] - param_arr = [ solution ] - result = rpc.getwork(param_arr) - - print(time.asctime(), "--> Upstream RPC result:", result) - - def iterate(self, rpc): - work = rpc.getwork() - - if work is None: - time.sleep(ERR_SLEEP) - return - - if 'data' not in work or 'target' not in work: - time.sleep(ERR_SLEEP) - return - - time_start = time.time() - - (hashes_done, nonce_bin) = self.work(work['data'], - work['target']) - - time_end = time.time() - time_diff = time_end - time_start - - self.max_nonce = long( - (hashes_done * settings['scantime']) / time_diff) - - if self.max_nonce > 0xfffffffaL: - self.max_nonce = 0xfffffffaL - - if settings['hashmeter']: - print("HashMeter({:d}): {:d} hashes, {:.2f} Khash/sec".format( - self.id, hashes_done, (hashes_done / 1000.0) / time_diff)) - - if nonce_bin is not None: - self.submit_work(rpc, work['data'], nonce_bin) - - def loop(self): - rpc = BitcoinRPC(settings['host'], settings['port'], - settings['rpcuser'], settings['rpcpass']) - - if rpc is not None: - - while True: - self.iterate(rpc) - - self.conn.close() - - -def miner_thread(id): - miner = Miner(id) - miner.loop() - -if __name__ == '__main__': - if len(sys.argv) != 2: - print("Usage: pyminer.py CONFIG-FILE") - sys.exit(1) - - with open(sys.argv[1]) as f: - - for line in f: - # skip comment lines - m = re.search('^\s*#', line) - if m: - continue - - # parse key=value lines - m = re.search('^(\w+)\s*=\s*(\S.*)$', line) - if m is None: - continue - - settings[m.group(1)] = m.group(2) - - settings.setdefault('host', '127.0.0.1') - settings.setdefault('port', 8332) - settings.setdefault('threads', 1) - settings.setdefault('hashmeter', 0) - settings.setdefault('scantime', 30L) - - if 'rpcuser' not in settings or 'rpcpass' not in settings: - print("Missing username and/or password in cfg file") - sys.exit(1) - - settings['port'] = int(settings['port']) - settings['threads'] = int(settings['threads']) - settings['hashmeter'] = int(settings['hashmeter']) - settings['scantime'] = long(settings['scantime']) - - thread_list = [] - - for thread_id in range(settings['threads']): - p = Process(target=miner_thread, args=(thread_id,)) - p.start() - thread_list.append(p) - time.sleep(1) # stagger threads - - print(settings['threads'], "mining threads started") - - print(time.asctime(), "Miner Starts - {0}:{1}".format(settings['host'], - settings['port'])) - try: - for thread_process in thread_list: - thread_process.join() - except KeyboardInterrupt: - pass - - print(time.asctime(), "Miner Stops - {0}:{1}".format(settings['host'], - settings['port'])) diff --git a/contrib/systemd/bitcoind.service b/contrib/systemd/bitcoind.service new file mode 100644 index 0000000000..edc81cc763 --- /dev/null +++ b/contrib/systemd/bitcoind.service @@ -0,0 +1,17 @@ +[Unit] +Description=Bitcoin's distributed currency daemon +After=network.target + +[Service] +User=bitcoind +Group=bitcoind + +Type=forking +PIDFile=/var/lib/bitcoind/bitcoind.pid +ExecStart=/usr/bin/bitcoind -daemon -pid=/var/lib/bitcoind/bitcoind.pid -conf=/etc/bitcoind.conf -datadir=/var/lib/bitcoind + +Restart=always +PrivateTmp=true + +[Install] +WantedBy=multi-user.target diff --git a/doc/README.md b/doc/README.md index f5aeb34a3c..f8bb8020d4 100644 --- a/doc/README.md +++ b/doc/README.md @@ -68,9 +68,10 @@ The Bitcoin repo's [root README](https://github.com/bitcoin/bitcoin/blob/master/ - [Assets Attribution](assets-attribution.md) - [Files](files.md) - [Tor Support](tor.md) +- [Systemd](systemd.md) License --------------------- Distributed under the [MIT/X11 software license](http://www.opensource.org/licenses/mit-license.php). -This product includes software developed by the OpenSSL Project for use in the [OpenSSL Toolkit](http://www.openssl.org/). This product includes +This product includes software developed by the OpenSSL Project for use in the [OpenSSL Toolkit](https://www.openssl.org/). This product includes cryptographic software written by Eric Young ([eay@cryptsoft.com](mailto:eay@cryptsoft.com)), and UPnP software written by Thomas Bernard. diff --git a/doc/README_windows.txt b/doc/README_windows.txt index 18fd4216f9..368f2b45e1 100644 --- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -5,7 +5,7 @@ Copyright (c) 2009-2014 Bitcoin Core Developers Distributed under the MIT/X11 software license, see the accompanying
file COPYING or http://www.opensource.org/licenses/mit-license.php.
This product includes software developed by the OpenSSL Project for use in
-the OpenSSL Toolkit (http://www.openssl.org/). This product includes
+the OpenSSL Toolkit (https://www.openssl.org/). This product includes
cryptographic software written by Eric Young (eay@cryptsoft.com).
diff --git a/doc/build-msw.md b/doc/build-msw.md deleted file mode 100644 index 9e4eaee3f5..0000000000 --- a/doc/build-msw.md +++ /dev/null @@ -1,83 +0,0 @@ -WINDOWS BUILD NOTES -=================== - - -Compilers Supported -------------------- -TODO: What works? -Note: releases are cross-compiled using mingw running on Linux. - - -Dependencies ------------- -Libraries you need to download separately and build: - - name default path download - -------------------------------------------------------------------------------------------------------------------- - OpenSSL \openssl-1.0.1c-mgw http://www.openssl.org/source/ - Berkeley DB \db-4.8.30.NC-mgw http://www.oracle.com/technology/software/products/berkeley-db/index.html - Boost \boost-1.50.0-mgw http://www.boost.org/users/download/ - miniupnpc \miniupnpc-1.6-mgw http://miniupnp.tuxfamily.org/files/ - -Their licenses: - - OpenSSL Old BSD license with the problematic advertising requirement - Berkeley DB New BSD license with additional requirement that linked software must be free open source - Boost MIT-like license - miniupnpc New (3-clause) BSD license - -Versions used in this release: - - OpenSSL 1.0.1c - Berkeley DB 4.8.30.NC - Boost 1.50.0 - miniupnpc 1.6 - - -OpenSSL -------- -MSYS shell: - -un-tar sources with MSYS 'tar xfz' to avoid issue with symlinks (OpenSSL ticket 2377) -change 'MAKE' env. variable from 'C:\MinGW32\bin\mingw32-make.exe' to '/c/MinGW32/bin/mingw32-make.exe' - - cd /c/openssl-1.0.1c-mgw - ./config - make - -Berkeley DB ------------ -MSYS shell: - - cd /c/db-4.8.30.NC-mgw/build_unix - sh ../dist/configure --enable-mingw --enable-cxx - make - -Boost ------ -MSYS shell: - - downloaded boost jam 3.1.18 - cd \boost-1.50.0-mgw - bjam toolset=gcc --build-type=complete stage - -MiniUPnPc ---------- -UPnP support is optional, make with `USE_UPNP=` to disable it. - -MSYS shell: - - cd /c/miniupnpc-1.6-mgw - make -f Makefile.mingw - mkdir miniupnpc - cp *.h miniupnpc/ - -Bitcoin -------- -MSYS shell: - - cd \bitcoin - sh autogen.sh - sh configure - mingw32-make - strip bitcoind.exe diff --git a/doc/systemd.md b/doc/systemd.md new file mode 100644 index 0000000000..96202c1532 --- /dev/null +++ b/doc/systemd.md @@ -0,0 +1,47 @@ +SYSTEMD SUPPORT IN BITCOIN +========================== + +Packagers can find a .service file in this repo in order to integrate bitcoin's +daemon into systemd based distributions. + +bitcoind.service file is located in contrib/systemd/ folder. + +1. Users +--------------------------------- + +This .service file assumes bitcoind user and group exist in the system, so packager +should make sure they are created on installation. + +2. Files +--------------------------------- + +The .service file assumes several paths that might need to be adjusted according +to packager's needs. + +Daemon's config file is assumed to be located at /etc/bitcoind.conf (you can +use contrib/debian/examples/bitcoin.conf as an example). Once installed, users +must edit the file in order to update at least these two +values: rpcuser and rpcpassword . Failing to do so will make the daemon fail +to boot. However, the message written to /var/lib/bitcoind/debug.log file is +very helpful and no default values should be set: + + YYYY-MM-DD HH:MM:DD Error: To use the "-server" option, you must set a rpcpassword in the configuration file: + /etc/bitcoind.conf + It is recommended you use the following random password: + rpcuser=bitcoinrpc + rpcpassword=HdYZ5HGtAF7mx8aTw6uCATtD2maMAK4E12Ysp4YNZQcX + (you do not need to remember this password) + The username and password MUST NOT be the same. + If the file does not exist, create it with owner-readable-only file permissions. + It is also recommended to set alertnotify so you are notified of problems; + for example: alertnotify=echo %s | mail -s "Bitcoin Alert" admin@foo.com + +Daemon's data and pid files will be stored in /var/lib/bitcoind directory, so it +should be created on installation and make bitcoind user/group it's owner. + +3. Installing .service file +--------------------------------- + +Installing this .service file consists on just copying it to /usr/lib/systemd/system +directory, followed by the command "systemctl daemon-reload" in order to update +running systemd configuration. diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index 4cab11db3d..717f0b90fe 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -51,11 +51,12 @@ namespace Checkpoints { (225430, uint256("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")) (250000, uint256("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")) (279000, uint256("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")) + (295000, uint256("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983")) ; static const CCheckpointData data = { &mapCheckpoints, - 1389047471, // * UNIX timestamp of last checkpoint block - 30549816, // * total number of transactions between genesis and last checkpoint + 1397080064, // * UNIX timestamp of last checkpoint block + 36544669, // * total number of transactions between genesis and last checkpoint // (the tx=... number in the SetBestChain debug.log lines) 60000.0 // * estimated number of transactions per day after checkpoint }; diff --git a/src/init.cpp b/src/init.cpp index 8b6567b5c4..b84c233b99 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -240,7 +240,8 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += " -connect=<ip> " + _("Connect only to the specified node(s)") + "\n"; strUsage += " -discover " + _("Discover own IP address (default: 1 when listening and no -externalip)") + "\n"; strUsage += " -dns " + _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + _("(default: 1)") + "\n"; - strUsage += " -dnsseed " + _("Find peers using DNS lookup (default: 1 unless -connect)") + "\n"; + strUsage += " -dnsseed " + _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)") + "\n"; + strUsage += " -forcednsseed " + _("Always query for peer addresses via DNS lookup (default: 0)") + "\n"; strUsage += " -externalip=<ip> " + _("Specify your own public address") + "\n"; strUsage += " -listen " + _("Accept connections from outside (default: 1 if no -proxy or -connect)") + "\n"; strUsage += " -maxconnections=<n> " + _("Maintain at most <n> connections to peers (default: 125)") + "\n"; @@ -262,6 +263,7 @@ std::string HelpMessage(HelpMessageMode mode) #endif strUsage += " -whitebind=<addr> " + _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6") + "\n"; strUsage += " -whitelist=<netmask> " + _("Whitelist peers connecting from the given netmask or ip. Can be specified multiple times.") + "\n"; + strUsage += " " + _("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") + "\n"; #ifdef ENABLE_WALLET strUsage += "\n" + _("Wallet options:") + "\n"; diff --git a/src/net.cpp b/src/net.cpp index 6c636d16b4..62124514c8 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -501,14 +501,8 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest) addrman.Attempt(addrConnect); // Set to non-blocking -#ifdef WIN32 - u_long nOne = 1; - if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) - LogPrintf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %s\n", NetworkErrorString(WSAGetLastError())); -#else - if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR) - LogPrintf("ConnectSocket() : fcntl non-blocking setting failed, error %s\n", NetworkErrorString(errno)); -#endif + if (!SetSocketNonBlocking(hSocket, true)) + LogPrintf("ConnectNode: Setting socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError())); // Add node CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false); @@ -1227,6 +1221,18 @@ void MapPort(bool) void ThreadDNSAddressSeed() { + // goal: only query DNS seeds if address need is acute + if ((addrman.size() > 0) && + (!GetBoolArg("-forcednsseed", false))) { + MilliSleep(11 * 1000); + + LOCK(cs_vNodes); + if (vNodes.size() >= 2) { + LogPrintf("P2P peers available. Skipped DNS seeding.\n"); + return; + } + } + const vector<CDNSSeedData> &vSeeds = Params().DNSSeeds(); int found = 0; @@ -1642,14 +1648,9 @@ bool BindListenPort(const CService &addrBind, string& strError, bool fWhiteliste setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int)); #endif -#ifdef WIN32 // Set to non-blocking, incoming connections will also inherit this - if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR) -#else - if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR) -#endif - { - strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %s)", NetworkErrorString(WSAGetLastError())); + if (!SetSocketNonBlocking(hListenSocket, true)) { + strError = strprintf("BindListenPort: Setting listening socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError())); LogPrintf("%s\n", strError); return false; } diff --git a/src/netbase.cpp b/src/netbase.cpp index e9f3515456..af6d11f0e2 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -7,10 +7,6 @@ #include "bitcoin-config.h" #endif -#ifdef HAVE_GETADDRINFO_A -#include <netdb.h> -#endif - #include "netbase.h" #include "hash.h" @@ -18,6 +14,10 @@ #include "uint256.h" #include "util.h" +#ifdef HAVE_GETADDRINFO_A +#include <netdb.h> +#endif + #ifndef WIN32 #if HAVE_INET_PTON #include <arpa/inet.h> @@ -331,22 +331,15 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe SOCKET hSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP); if (hSocket == INVALID_SOCKET) return false; + #ifdef SO_NOSIGPIPE int set = 1; setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); #endif -#ifdef WIN32 - u_long fNonblock = 1; - if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR) -#else - int fFlags = fcntl(hSocket, F_GETFL, 0); - if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1) -#endif - { - CloseSocket(hSocket); - return false; - } + // Set to non-blocking + if (!SetSocketNonBlocking(hSocket, true)) + return error("ConnectSocketDirectly: Setting socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError())); if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR) { @@ -404,20 +397,10 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe } } - // this isn't even strictly necessary - // CNode::ConnectNode immediately turns the socket back to non-blocking - // but we'll turn it back to blocking just in case -#ifdef WIN32 - fNonblock = 0; - if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR) -#else - fFlags = fcntl(hSocket, F_GETFL, 0); - if (fcntl(hSocket, F_SETFL, fFlags & ~O_NONBLOCK) == SOCKET_ERROR) -#endif - { - CloseSocket(hSocket); - return false; - } + // This is required when using SOCKS5 proxy! + // CNode::ConnectNode turns the socket back to non-blocking. + if (!SetSocketNonBlocking(hSocket, false)) + return error("ConnectSocketDirectly: Setting socket to blocking failed, error %s\n", NetworkErrorString(WSAGetLastError())); hSocketRet = hSocket; return true; @@ -1271,3 +1254,32 @@ bool CloseSocket(SOCKET& hSocket) hSocket = INVALID_SOCKET; return ret != SOCKET_ERROR; } + +bool SetSocketNonBlocking(SOCKET& hSocket, bool fNonBlocking) +{ + if (fNonBlocking) { +#ifdef WIN32 + u_long nOne = 1; + if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) { +#else + int fFlags = fcntl(hSocket, F_GETFL, 0); + if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == SOCKET_ERROR) { +#endif + CloseSocket(hSocket); + return false; + } + } else { +#ifdef WIN32 + u_long nZero = 0; + if (ioctlsocket(hSocket, FIONBIO, &nZero) == SOCKET_ERROR) { +#else + int fFlags = fcntl(hSocket, F_GETFL, 0); + if (fcntl(hSocket, F_SETFL, fFlags & ~O_NONBLOCK) == SOCKET_ERROR) { +#endif + CloseSocket(hSocket); + return false; + } + } + + return true; +} diff --git a/src/netbase.h b/src/netbase.h index 05221a5fde..7d83e35344 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -180,5 +180,7 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest std::string NetworkErrorString(int err); /** Close socket and set hSocket to INVALID_SOCKET */ bool CloseSocket(SOCKET& hSocket); +/** Disable or enable blocking-mode for a socket */ +bool SetSocketNonBlocking(SOCKET& hSocket, bool fNonBlocking); #endif diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 597be40abd..0117d2e633 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -15,11 +15,11 @@ #include "optionsmodel.h" #include "main.h" // for MAX_SCRIPTCHECK_THREADS +#include "netbase.h" +#include "txdb.h" // for -dbcache defaults #ifdef ENABLE_WALLET #include "wallet.h" // for CWallet::minTxFee #endif -#include "netbase.h" -#include "txdb.h" // for -dbcache defaults #include <QDir> #include <QIntValidator> diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index 89c2ec7453..9699f6eea6 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -32,7 +32,6 @@ public: ProxyUse, // bool ProxyIP, // QString ProxyPort, // int - ProxySocksVersion, // int Fee, // qint64 DisplayUnit, // BitcoinUnits::Unit DisplayAddresses, // bool diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index ac1614efd0..4f6e3169f5 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -11,11 +11,11 @@ #include "db.h" #include "main.h" #include "paymentserver.h" +#include "script.h" #include "transactionrecord.h" #include "timedata.h" #include "ui_interface.h" #include "wallet.h" -#include "script.h" #include <stdint.h> #include <string> diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 4825713b69..7acb0e8871 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -577,7 +577,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const case ConfirmedRole: return rec->status.countsForBalance; case FormattedAmountRole: - // Used for copy/export, so don't include separators + // Used for copy/export, so don't include separators return formatTxAmount(rec, false, BitcoinUnits::separatorNever); case StatusRole: return rec->status.status; diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index ad88d14a90..2124d3dd1c 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -5,11 +5,11 @@ #ifndef TRANSACTIONTABLEMODEL_H #define TRANSACTIONTABLEMODEL_H +#include "bitcoinunits.h" + #include <QAbstractTableModel> #include <QStringList> -#include "bitcoinunits.h" - class TransactionRecord; class TransactionTablePriv; class WalletModel; diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 5edeecf933..a0921453cc 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -85,6 +85,8 @@ static const CRPCConvertParam vRPCConvertParams[] = { "getrawmempool", 0 }, { "estimatefee", 0 }, { "estimatepriority", 0 }, + { "prioritisetransaction", 1 }, + { "prioritisetransaction", 2 }, }; class CRPCConvertTable diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 6f72ea7404..cbb4ab2f8b 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -252,11 +252,30 @@ Value prioritisetransaction(const Array& params, bool fHelp) if (fHelp || params.size() != 3) throw runtime_error( "prioritisetransaction <txid> <priority delta> <fee delta>\n" - "Accepts the transaction into mined blocks at a higher (or lower) priority"); + "Accepts the transaction into mined blocks at a higher (or lower) priority\n" + "\nArguments:\n" + "1. \"txid\" (string, required) The transaction id.\n" + "2. priority delta (numeric, required) The priority to add or subtract.\n" + " The transaction selection algorithm considers the tx as it would have a higher priority.\n" + " (priority of a transaction is calculated: coinage * value_in_satoshis / txsize) \n" + "3. fee delta (numeric, required) The absolute fee value to add or subtract in bitcoin.\n" + " The fee is not actually paid, only the algorithm for selecting transactions into a block\n" + " considers the transaction as it would have paid a higher (or lower) fee.\n" + "\nResult\n" + "true (boolean) Returns true\n" + "\nExamples:\n" + + HelpExampleCli("prioritisetransaction", "\"txid\" 0.0 0.00010000") + + HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 0.00010000") + ); uint256 hash; hash.SetHex(params[0].get_str()); - mempool.PrioritiseTransaction(hash, params[0].get_str(), params[1].get_real(), params[2].get_int64()); + + int64_t nAmount = 0; + if (params[2].get_real() != 0.0) + nAmount = AmountFromValue(params[2]); + + mempool.PrioritiseTransaction(hash, params[0].get_str(), params[1].get_real(), nAmount); return true; } diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index cff795bdf4..bd992397b8 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -27,6 +27,19 @@ using namespace boost::assign; using namespace json_spirit; using namespace std; +/** + * @note Do not add or change anything in the information returned by this + * method. `getinfo` exists for backwards-compatibilty only. It combines + * information from wildly different sources in the program, which is a mess, + * and is thus planned to be deprecated eventually. + * + * Based on the source of the information, new information should be added to: + * - `getblockchaininfo`, + * - `getnetworkinfo` or + * - `getwalletinfo` + * + * Or alternatively, create a specific query method for the information. + **/ Value getinfo(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) |