aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/debian/bitcoind.manpages1
-rw-r--r--contrib/debian/changelog12
-rw-r--r--contrib/debian/control2
-rw-r--r--contrib/debian/manpages/bitcoin-cli.148
-rw-r--r--contrib/gitian-descriptors/gitian-linux.yml2
-rw-r--r--contrib/gitian-descriptors/gitian-osx.yml2
-rw-r--r--contrib/gitian-descriptors/gitian-win.yml2
-rw-r--r--contrib/gitian-downloader/fanquake-key.pgp63
-rw-r--r--contrib/gitian-downloader/jonasschnelli-key.pgpbin0 -> 2230 bytes
-rw-r--r--contrib/gitian-downloader/jonasschnelli.pgpbin4460 -> 0 bytes
-rw-r--r--doc/REST-interface.md14
-rw-r--r--doc/bips.md18
-rw-r--r--doc/release-process.md1
-rw-r--r--doc/unit-tests.md2
-rwxr-xr-xqa/rpc-tests/getblocktemplate_proposals.py1
-rwxr-xr-xqa/rpc-tests/rest.py9
-rw-r--r--src/Makefile.am2
-rw-r--r--src/allocators.h10
-rw-r--r--src/base58.cpp2
-rw-r--r--src/bitcoind.cpp16
-rw-r--r--src/chain.h6
-rw-r--r--src/chainparams.h2
-rw-r--r--src/checkqueue.h12
-rw-r--r--src/crypter.cpp4
-rw-r--r--src/crypter.h4
-rw-r--r--src/db.cpp2
-rw-r--r--src/main.cpp107
-rw-r--r--src/net.cpp2
-rw-r--r--src/pow.cpp8
-rw-r--r--src/qt/forms/helpmessagedialog.ui82
-rw-r--r--src/qt/forms/sendcoinsdialog.ui20
-rw-r--r--src/qt/paymentrequestplus.cpp1
-rw-r--r--src/qt/paymentrequestplus.h2
-rw-r--r--src/qt/paymentserver.cpp26
-rw-r--r--src/qt/paymentserver.h2
-rw-r--r--src/qt/test/paymentrequestdata.h25
-rw-r--r--src/qt/test/paymentservertests.cpp17
-rw-r--r--src/qt/utilitydialog.cpp1
-rw-r--r--src/random.cpp13
-rw-r--r--src/rest.cpp33
-rw-r--r--src/rpcmining.cpp10
-rw-r--r--src/rpcmisc.cpp2
-rw-r--r--src/rpcserver.cpp2
-rw-r--r--src/streams.h1
-rw-r--r--src/support/cleanse.cpp13
-rw-r--r--src/support/cleanse.h13
-rw-r--r--src/test/data/script_invalid.json8
-rw-r--r--src/test/data/script_valid.json8
-rw-r--r--src/test/script_tests.cpp8
-rw-r--r--src/util.cpp7
50 files changed, 518 insertions, 130 deletions
diff --git a/contrib/debian/bitcoind.manpages b/contrib/debian/bitcoind.manpages
index 3e4ca63d4e..6d3e683855 100644
--- a/contrib/debian/bitcoind.manpages
+++ b/contrib/debian/bitcoind.manpages
@@ -1,2 +1,3 @@
debian/manpages/bitcoind.1
debian/manpages/bitcoin.conf.5
+debian/manpages/bitcoin-cli.1
diff --git a/contrib/debian/changelog b/contrib/debian/changelog
index fe910b65a5..7ce3babc1b 100644
--- a/contrib/debian/changelog
+++ b/contrib/debian/changelog
@@ -1,3 +1,15 @@
+bitcoin (0.10.0-precise1) precise; urgency=medium
+
+ * New upstream releases.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Wed, 18 Feb 2015 13:22:00 -1000
+
+bitcoin (0.9.4-precise1) precise; urgency=high
+
+ * New upstream releases.
+
+ -- Matt Corallo (laptop - only while traveling) <matt@mattcorallo.com> Mon, 12 Jan 2015 23:30:00 -1000
+
bitcoin (0.9.3-precise1) precise; urgency=medium
* New upstream releases.
diff --git a/contrib/debian/control b/contrib/debian/control
index a653260ad3..4392bb3385 100644
--- a/contrib/debian/control
+++ b/contrib/debian/control
@@ -12,7 +12,7 @@ Build-Depends: debhelper,
libdb4.8++-dev,
libssl-dev,
pkg-config,
- libminiupnpc8-dev,
+ libminiupnpc8-dev | libminiupnpc-dev (>> 1.6),
libboost-filesystem-dev (>> 1.35) | libboost-filesystem1.35-dev,
libboost-program-options-dev (>> 1.35) | libboost-program-options1.35-dev,
libboost-thread-dev (>> 1.35) | libboost-thread1.35-dev,
diff --git a/contrib/debian/manpages/bitcoin-cli.1 b/contrib/debian/manpages/bitcoin-cli.1
new file mode 100644
index 0000000000..f953ae9db7
--- /dev/null
+++ b/contrib/debian/manpages/bitcoin-cli.1
@@ -0,0 +1,48 @@
+.TH BITCOIN-CLI "1" "February 2015" "bitcoin-cli 0.10"
+.SH NAME
+bitcoin-cli \- a remote procedure call client for Bitcoin Core.
+.SH SYNOPSIS
+bitcoin-cli [options] <command> [params] \- Send command to Bitcoin Core.
+.TP
+bitcoin-cli [options] help \- Asks Bitcoin Core for a list of supported commands.
+.SH DESCRIPTION
+This manual page documents the bitcoin-cli program. bitcoin-cli is an RPC client used to send commands to Bitcoin Core.
+
+.SH OPTIONS
+.TP
+\fB\-?\fR
+Show the help message.
+.TP
+\fB\-conf=\fR<file>
+Specify configuration file (default: bitcoin.conf).
+.TP
+\fB\-datadir=\fR<dir>
+Specify data directory.
+.TP
+\fB\-testnet\fR
+Connect to a Bitcoin Core instance running in testnet mode.
+.TP
+\fB\-regtest\fR
+Connect to a Bitcoin Core instance running in regtest mode (see documentation for -regtest on bitcoind).
+.TP
+\fB\-rpcuser=\fR<user>
+Username for JSON\-RPC connections.
+.TP
+\fB\-rpcpassword=\fR<pw>
+Password for JSON\-RPC connections.
+.TP
+\fB\-rpcport=\fR<port>
+Listen for JSON\-RPC connections on <port> (default: 8332 or testnet: 18332).
+.TP
+\fB\-rpcconnect=\fR<ip>
+Send commands to node running on <ip> (default: 127.0.0.1).
+.TP
+\fB\-rpcssl\fR=\fI1\fR
+Use OpenSSL (https) for JSON\-RPC connections (see the Bitcoin Wiki for SSL setup instructions).
+
+.SH "SEE ALSO"
+\fBbitcoind\fP, \fBbitcoin.conf\fP
+.SH AUTHOR
+This manual page was written by Ciemon Dunville <ciemon@gmail.com>. Permission is granted to copy, distribute and/or modify this document under the terms of the MIT License.
+
+The complete text of the MIT License can be found on the web at \fIhttp://opensource.org/licenses/MIT\fP.
diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml
index 28bd9211ac..80de6770c5 100644
--- a/contrib/gitian-descriptors/gitian-linux.yml
+++ b/contrib/gitian-descriptors/gitian-linux.yml
@@ -99,7 +99,7 @@ script: |
find . -name "lib*.la" -delete
find . -name "lib*.a" -delete
rm -rf ${DISTNAME}/lib/pkgconfig
- find . | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz
+ find ${DISTNAME} | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz
cd ../../
done
mkdir -p $OUTDIR/src
diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml
index 3ca42248d4..43eb79d848 100644
--- a/contrib/gitian-descriptors/gitian-osx.yml
+++ b/contrib/gitian-descriptors/gitian-osx.yml
@@ -126,7 +126,7 @@ script: |
find . -name "lib*.la" -delete
find . -name "lib*.a" -delete
rm -rf ${DISTNAME}/lib/pkgconfig
- find . | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz
+ find ${DISTNAME} | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz
cd ../../
done
mkdir -p $OUTDIR/src
diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml
index 4baa08c88d..f0459ee946 100644
--- a/contrib/gitian-descriptors/gitian-win.yml
+++ b/contrib/gitian-descriptors/gitian-win.yml
@@ -106,7 +106,7 @@ script: |
find . -name "lib*.la" -delete
find . -name "lib*.a" -delete
rm -rf ${DISTNAME}/lib/pkgconfig
- find . -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}.zip
+ find ${DISTNAME} -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}.zip
cd ../..
done
mkdir -p $OUTDIR/src
diff --git a/contrib/gitian-downloader/fanquake-key.pgp b/contrib/gitian-downloader/fanquake-key.pgp
new file mode 100644
index 0000000000..9c03ff4522
--- /dev/null
+++ b/contrib/gitian-downloader/fanquake-key.pgp
@@ -0,0 +1,63 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG/MacGPG2 v2.0.26
+
+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
+XwbdK0Zpx/oDtRHpuDMGKJBV2LWAZYkEbFsmtg==
+=3o2I
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/contrib/gitian-downloader/jonasschnelli-key.pgp b/contrib/gitian-downloader/jonasschnelli-key.pgp
new file mode 100644
index 0000000000..fe44c0fbd4
--- /dev/null
+++ b/contrib/gitian-downloader/jonasschnelli-key.pgp
Binary files differ
diff --git a/contrib/gitian-downloader/jonasschnelli.pgp b/contrib/gitian-downloader/jonasschnelli.pgp
deleted file mode 100644
index 96140fe171..0000000000
--- a/contrib/gitian-downloader/jonasschnelli.pgp
+++ /dev/null
Binary files differ
diff --git a/doc/REST-interface.md b/doc/REST-interface.md
index 0af650b4e8..23154ee903 100644
--- a/doc/REST-interface.md
+++ b/doc/REST-interface.md
@@ -10,6 +10,8 @@ Supported API
Given a transaction hash,
Returns a transaction, in binary, hex-encoded binary or JSON formats.
+For full TX query capability, one must enable the transaction index via "txindex=1" command line / configuration option.
+
`GET /rest/block/BLOCK-HASH.{bin|hex|json}`
`GET /rest/block/notxdetails/BLOCK-HASH.{bin|hex|json}`
@@ -20,7 +22,17 @@ The HTTP request and response are both handled entirely in-memory, thus making m
With the /notxdetails/ option JSON response will only contain the transaction hash instead of the complete transaction details. The option only affects the JSON response.
-For full TX query capability, one must enable the transaction index via "txindex=1" command line / configuration option.
+`GET /rest/chaininfo.json`
+
+Returns various state info regarding block chain processing.
+Only supports JSON as output format.
+* chain : (string) current network name as defined in BIP70 (main, test, regtest)
+* blocks : (numeric) the current number of blocks processed in the server
+* headers : (numeric) the current number of headers we have validated
+* bestblockhash : (string) the hash of the currently best block
+* difficulty : (numeric) the current difficulty
+* verificationprogress : (numeric) estimate of verification progress [0..1]
+* chainwork : (string) total amount of work in active chain, in hexadecimal
Risks
-------------
diff --git a/doc/bips.md b/doc/bips.md
new file mode 100644
index 0000000000..579eadfff3
--- /dev/null
+++ b/doc/bips.md
@@ -0,0 +1,18 @@
+BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.10.0**):
+
+* [`BIP 11`](https://github.com/bitcoin/bips/blob/master/bip-0011.mediawiki): Multisig outputs are standard since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)).
+* [`BIP 13`](https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki): The address format for P2SH addresses has been implemented since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)).
+* [`BIP 14`](https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki): The subversion string is being used as User Agent since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)).
+* [`BIP 16`](https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki): The pay-to-script-hash evaluation rules have been implemented since **v0.6.0**, and took effect on *April 1st 2012* ([PR #748](https://github.com/bitcoin/bitcoin/pull/748)).
+* [`BIP 21`](https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki): The URI format for Bitcoin payments has been implemented since **v0.6.0** ([PR #176](https://github.com/bitcoin/bitcoin/pull/176)).
+* [`BIP 22`](https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki): The 'getblocktemplate' (GBT) RPC protocol for mining has been implemented since **v0.7.0** ([PR #936](https://github.com/bitcoin/bitcoin/pull/936)).
+* [`BIP 23`](https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki): Some extensions to GBT have been implemented since **v0.10.0rc1**, including longpolling and block proposals ([PR #1816](https://github.com/bitcoin/bitcoin/pull/1816)).
+* [`BIP 30`](https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki): The evaluation rules to forbid creating new transactions with the same txid as previous not-fully-spent transactions were implemented since **v0.6.0**, and the rule took effect on *March 15th 2012* ([PR #915](https://github.com/bitcoin/bitcoin/pull/915)).
+* [`BIP 31`](https://github.com/bitcoin/bips/blob/master/bip-0031.mediawiki): The 'pong' protocol message (and the protocol version bump to 60001) has been implemented since **v0.6.1** ([PR #1081](https://github.com/bitcoin/bitcoin/pull/1081)).
+* [`BIP 34`](https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki): The rule that requires blocks to contain their height (number) in the coinbase input, and the introduction of version 2 blocks has been implemented since **v0.7.0**. The rule took effect for version 2 blocks as of *block 224413* (March 5th 2013), and version 1 blocks are no longer allowed since *block 227931* (March 25th 2013) ([PR #1526](https://github.com/bitcoin/bitcoin/pull/1526)).
+* [`BIP 35`](https://github.com/bitcoin/bips/blob/master/bip-0035.mediawiki): The 'mempool' protocol message (and the protocol version bump to 60002) has been implemented since **v0.7.0** ([PR #1641](https://github.com/bitcoin/bitcoin/pull/1641)).
+* [`BIP 37`](https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki): The bloom filtering for transaction relaying, partial merkle trees for blocks , and the protocol version bump to 70001 (enabling low-bandwidth SPV clients) has been implemented since **v0.8.0** ([PR #1795](https://github.com/bitcoin/bitcoin/pull/1795)).
+* [`BIP 42`](https://github.com/bitcoin/bips/blob/master/bip-0042.mediawiki): The bug that would have caused the subsidy schedule to resume after block 13440000 was fixed in **v0.9.2** ([PR #3842](https://github.com/bitcoin/bitcoin/pull/3842)).
+* [`BIP 61`](https://github.com/bitcoin/bips/blob/master/bip-0061.mediawiki): The 'reject' protocol message (and the protocol version bump to 70002) was added in **v0.9.0** ([PR #3185](https://github.com/bitcoin/bitcoin/pull/3185)).
+* [`BIP 66`](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki): The strict DER rules and associated version 3 blocks have been implemented since **v0.10.0** ([PR #5713](https://github.com/bitcoin/bitcoin/pull/5713)).
+* [`BIP 70`](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) [`71`](https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki) [`72`](https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki): Payment Protocol support has been available in Bitcoin Core GUI since **v0.9.0** ([PR #5216](https://github.com/bitcoin/bitcoin/pull/5216)).
diff --git a/doc/release-process.md b/doc/release-process.md
index 363465d827..016090c594 100644
--- a/doc/release-process.md
+++ b/doc/release-process.md
@@ -130,6 +130,7 @@ gpg --digest-algo sha256 --clearsign SHA256SUMS # outputs SHA256SUMS.asc
rm SHA256SUMS
```
(the digest algorithm is forced to sha256 to avoid confusion of the `Hash:` header that GPG adds with the SHA256 used for the files)
+Note: check that SHA256SUMS itself doesn't end up in SHA256SUMS, which is a spurious/nonsensical entry.
- Upload zips and installers, as well as `SHA256SUMS.asc` from last step, to the bitcoin.org server
diff --git a/doc/unit-tests.md b/doc/unit-tests.md
index f1d3a8bc50..72613054b9 100644
--- a/doc/unit-tests.md
+++ b/doc/unit-tests.md
@@ -12,7 +12,7 @@ To add more bitcoind tests, add `BOOST_AUTO_TEST_CASE` functions to the existing
.cpp files in the test/ directory or add new .cpp files that
implement new BOOST_AUTO_TEST_SUITE sections.
-To run the bitcoin-qt tests manually, launch src/qt/test/bitcoin-qt_test
+To run the bitcoin-qt tests manually, launch src/qt/test/test_bitcoin-qt
To add more bitcoin-qt tests, add them to the `src/qt/test/` directory and
the `src/qt/test/test_main.cpp` file.
diff --git a/qa/rpc-tests/getblocktemplate_proposals.py b/qa/rpc-tests/getblocktemplate_proposals.py
index 22fe2ce044..f65162002d 100755
--- a/qa/rpc-tests/getblocktemplate_proposals.py
+++ b/qa/rpc-tests/getblocktemplate_proposals.py
@@ -95,6 +95,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework):
def run_test(self):
node = self.nodes[0]
+ node.setgenerate(True, 1) # Mine a block to leave initial block download
tmpl = node.getblocktemplate()
if 'coinbasetxn' not in tmpl:
rawcoinbase = encodeUNum(tmpl['height'])
diff --git a/qa/rpc-tests/rest.py b/qa/rpc-tests/rest.py
index 704d889739..a9d41cf367 100755
--- a/qa/rpc-tests/rest.py
+++ b/qa/rpc-tests/rest.py
@@ -78,7 +78,7 @@ class RESTTest (BitcoinTestFramework):
# check hex format response
hex_string = http_get_call(url.hostname, url.port, '/rest/tx/'+tx_hash+self.FORMAT_SEPARATOR+"hex", True)
- assert_equal(response.status, 200)
+ assert_equal(hex_string.status, 200)
assert_greater_than(int(response.getheader('content-length')), 10)
# check block tx details
@@ -106,5 +106,12 @@ class RESTTest (BitcoinTestFramework):
for tx in txs:
assert_equal(tx in json_obj['tx'], True)
+ #test rest bestblock
+ bb_hash = self.nodes[0].getbestblockhash()
+
+ json_string = http_get_call(url.hostname, url.port, '/rest/chaininfo.json')
+ json_obj = json.loads(json_string)
+ assert_equal(json_obj['bestblockhash'], bb_hash)
+
if __name__ == '__main__':
RESTTest ().main ()
diff --git a/src/Makefile.am b/src/Makefile.am
index 009c3c5196..7644f6b325 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -123,6 +123,7 @@ BITCOIN_CORE_H = \
script/standard.h \
serialize.h \
streams.h \
+ support/cleanse.h \
sync.h \
threadsafety.h \
timedata.h \
@@ -268,6 +269,7 @@ libbitcoin_util_a_SOURCES = \
compat/strnlen.cpp \
random.cpp \
rpcprotocol.cpp \
+ support/cleanse.cpp \
sync.cpp \
uint256.cpp \
util.cpp \
diff --git a/src/allocators.h b/src/allocators.h
index 6a131c3517..8ffe015b9e 100644
--- a/src/allocators.h
+++ b/src/allocators.h
@@ -6,6 +6,8 @@
#ifndef BITCOIN_ALLOCATORS_H
#define BITCOIN_ALLOCATORS_H
+#include "support/cleanse.h"
+
#include <map>
#include <string>
#include <string.h>
@@ -14,8 +16,6 @@
#include <boost/thread/mutex.hpp>
#include <boost/thread/once.hpp>
-#include <openssl/crypto.h> // for OPENSSL_cleanse()
-
/**
* Thread-safe class to keep track of locked (ie, non-swappable) memory pages.
*
@@ -174,7 +174,7 @@ void LockObject(const T& t)
template <typename T>
void UnlockObject(const T& t)
{
- OPENSSL_cleanse((void*)(&t), sizeof(T));
+ memory_cleanse((void*)(&t), sizeof(T));
LockedPageManager::Instance().UnlockRange((void*)(&t), sizeof(T));
}
@@ -217,7 +217,7 @@ struct secure_allocator : public std::allocator<T> {
void deallocate(T* p, std::size_t n)
{
if (p != NULL) {
- OPENSSL_cleanse(p, sizeof(T) * n);
+ memory_cleanse(p, sizeof(T) * n);
LockedPageManager::Instance().UnlockRange(p, sizeof(T) * n);
}
std::allocator<T>::deallocate(p, n);
@@ -254,7 +254,7 @@ struct zero_after_free_allocator : public std::allocator<T> {
void deallocate(T* p, std::size_t n)
{
if (p != NULL)
- OPENSSL_cleanse(p, sizeof(T) * n);
+ memory_cleanse(p, sizeof(T) * n);
std::allocator<T>::deallocate(p, n);
}
};
diff --git a/src/base58.cpp b/src/base58.cpp
index 980d3cbf42..c809185056 100644
--- a/src/base58.cpp
+++ b/src/base58.cpp
@@ -172,7 +172,7 @@ bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes)
vchData.resize(vchTemp.size() - nVersionBytes);
if (!vchData.empty())
memcpy(&vchData[0], &vchTemp[nVersionBytes], vchData.size());
- OPENSSL_cleanse(&vchTemp[0], vchData.size());
+ memory_cleanse(&vchTemp[0], vchData.size());
return true;
}
diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
index 8a1745b50d..a0a96c2dfa 100644
--- a/src/bitcoind.cpp
+++ b/src/bitcoind.cpp
@@ -33,7 +33,7 @@
static bool fDaemon;
-void DetectShutdownThread(boost::thread_group* threadGroup)
+void WaitForShutdown(boost::thread_group* threadGroup)
{
bool fShutdown = ShutdownRequested();
// Tell the main threads to shutdown.
@@ -56,7 +56,6 @@ void DetectShutdownThread(boost::thread_group* threadGroup)
bool AppInit(int argc, char* argv[])
{
boost::thread_group threadGroup;
- boost::thread* detectShutdownThread = NULL;
bool fRet = false;
@@ -144,7 +143,6 @@ bool AppInit(int argc, char* argv[])
#endif
SoftSetBoolArg("-server", true);
- detectShutdownThread = new boost::thread(boost::bind(&DetectShutdownThread, &threadGroup));
fRet = AppInit2(threadGroup);
}
catch (const std::exception& e) {
@@ -155,20 +153,12 @@ bool AppInit(int argc, char* argv[])
if (!fRet)
{
- if (detectShutdownThread)
- detectShutdownThread->interrupt();
-
threadGroup.interrupt_all();
// threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of
// the startup-failure cases to make sure they don't result in a hang due to some
// thread-blocking-waiting-for-another-thread-during-startup case
- }
-
- if (detectShutdownThread)
- {
- detectShutdownThread->join();
- delete detectShutdownThread;
- detectShutdownThread = NULL;
+ } else {
+ WaitForShutdown(&threadGroup);
}
Shutdown();
diff --git a/src/chain.h b/src/chain.h
index 004e87ab52..02f53cd2f2 100644
--- a/src/chain.h
+++ b/src/chain.h
@@ -48,6 +48,12 @@ struct CDiskBlockPos
void SetNull() { nFile = -1; nPos = 0; }
bool IsNull() const { return (nFile == -1); }
+
+ std::string ToString() const
+ {
+ return strprintf("CBlockDiskPos(nFile=%i, nPos=%i)", nFile, nPos);
+ }
+
};
enum BlockStatus {
diff --git a/src/chainparams.h b/src/chainparams.h
index f52bf4e55f..86b84df667 100644
--- a/src/chainparams.h
+++ b/src/chainparams.h
@@ -68,7 +68,7 @@ public:
bool RequireStandard() const { return fRequireStandard; }
int64_t TargetTimespan() const { return nTargetTimespan; }
int64_t TargetSpacing() const { return nTargetSpacing; }
- int64_t Interval() const { return nTargetTimespan / nTargetSpacing; }
+ int64_t DifficultyAdjustmentInterval() const { return nTargetTimespan / nTargetSpacing; }
/** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */
bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; }
/** In the future use NetworkIDString() for RPC fields */
diff --git a/src/checkqueue.h b/src/checkqueue.h
index 7ca825c16f..6f6b97e3a7 100644
--- a/src/checkqueue.h
+++ b/src/checkqueue.h
@@ -161,7 +161,12 @@ public:
{
}
- friend class CCheckQueueControl<T>;
+ bool IsIdle()
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ return (nTotal == nIdle && nTodo == 0 && fAllOk == true);
+ }
+
};
/**
@@ -180,9 +185,8 @@ public:
{
// passed queue is supposed to be unused, or NULL
if (pqueue != NULL) {
- assert(pqueue->nTotal == pqueue->nIdle);
- assert(pqueue->nTodo == 0);
- assert(pqueue->fAllOk == true);
+ bool isIdle = pqueue->IsIdle();
+ assert(isIdle);
}
}
diff --git a/src/crypter.cpp b/src/crypter.cpp
index 75d84dbf13..c7f7e21679 100644
--- a/src/crypter.cpp
+++ b/src/crypter.cpp
@@ -26,8 +26,8 @@ bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::v
if (i != (int)WALLET_CRYPTO_KEY_SIZE)
{
- OPENSSL_cleanse(chKey, sizeof(chKey));
- OPENSSL_cleanse(chIV, sizeof(chIV));
+ memory_cleanse(chKey, sizeof(chKey));
+ memory_cleanse(chIV, sizeof(chIV));
return false;
}
diff --git a/src/crypter.h b/src/crypter.h
index cbaf1562f0..8a91498e2e 100644
--- a/src/crypter.h
+++ b/src/crypter.h
@@ -82,8 +82,8 @@ public:
void CleanKey()
{
- OPENSSL_cleanse(chKey, sizeof(chKey));
- OPENSSL_cleanse(chIV, sizeof(chIV));
+ memory_cleanse(chKey, sizeof(chKey));
+ memory_cleanse(chIV, sizeof(chIV));
fKeySet = false;
}
diff --git a/src/db.cpp b/src/db.cpp
index a7f885135b..3246e4b67a 100644
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -21,8 +21,6 @@
#include <boost/thread.hpp>
#include <boost/version.hpp>
-#include <openssl/rand.h>
-
using namespace std;
diff --git a/src/main.cpp b/src/main.cpp
index 27c427f7cd..b6a61f7da1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1199,19 +1199,19 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos)
// Open history file to read
CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
if (filein.IsNull())
- return error("ReadBlockFromDisk: OpenBlockFile failed");
+ return error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString());
// Read block
try {
filein >> block;
}
catch (const std::exception& e) {
- return error("%s: Deserialize or I/O error - %s", __func__, e.what());
+ return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
}
// Check the header
if (!CheckProofOfWork(block.GetHash(), block.nBits))
- return error("ReadBlockFromDisk: Errors in block header");
+ return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
return true;
}
@@ -1221,7 +1221,8 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex)
if (!ReadBlockFromDisk(block, pindex->GetBlockPos()))
return false;
if (block.GetHash() != pindex->GetBlockHash())
- return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index");
+ return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
+ pindex->ToString(), pindex->GetBlockPos().ToString());
return true;
}
@@ -1588,6 +1589,39 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uin
} // anon namespace
+/**
+ * Apply the undo operation of a CTxInUndo to the given chain state.
+ * @param undo The undo object.
+ * @param view The coins view to which to apply the changes.
+ * @param out The out point that corresponds to the tx input.
+ * @return True on success.
+ */
+static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const COutPoint& out)
+{
+ bool fClean = true;
+
+ CCoinsModifier coins = view.ModifyCoins(out.hash);
+ if (undo.nHeight != 0) {
+ // undo data contains height: this is the last output of the prevout tx being spent
+ if (!coins->IsPruned())
+ fClean = fClean && error("%s: undo data overwriting existing transaction", __func__);
+ coins->Clear();
+ coins->fCoinBase = undo.fCoinBase;
+ coins->nHeight = undo.nHeight;
+ coins->nVersion = undo.nVersion;
+ } else {
+ if (coins->IsPruned())
+ fClean = fClean && error("%s: undo data adding output to missing transaction", __func__);
+ }
+ if (coins->IsAvailable(out.n))
+ fClean = fClean && error("%s: undo data overwriting existing output", __func__);
+ if (coins->vout.size() < out.n+1)
+ coins->vout.resize(out.n+1);
+ coins->vout[out.n] = undo.txout;
+
+ return fClean;
+}
+
bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
{
assert(pindex->GetBlockHash() == view.GetBestBlock());
@@ -1613,11 +1647,8 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
uint256 hash = tx.GetHash();
// Check that all outputs are available and match the outputs in the block itself
- // exactly. Note that transactions with only provably unspendable outputs won't
- // have outputs available even in the block itself, so we handle that case
- // specially with outsEmpty.
+ // exactly.
{
- CCoins outsEmpty;
CCoinsModifier outs = view.ModifyCoins(hash);
outs->ClearUnspendable();
@@ -1642,24 +1673,8 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
for (unsigned int j = tx.vin.size(); j-- > 0;) {
const COutPoint &out = tx.vin[j].prevout;
const CTxInUndo &undo = txundo.vprevout[j];
- CCoinsModifier coins = view.ModifyCoins(out.hash);
- if (undo.nHeight != 0) {
- // undo data contains height: this is the last output of the prevout tx being spent
- if (!coins->IsPruned())
- fClean = fClean && error("DisconnectBlock(): undo data overwriting existing transaction");
- coins->Clear();
- coins->fCoinBase = undo.fCoinBase;
- coins->nHeight = undo.nHeight;
- coins->nVersion = undo.nVersion;
- } else {
- if (coins->IsPruned())
- fClean = fClean && error("DisconnectBlock(): undo data adding output to missing transaction");
- }
- if (coins->IsAvailable(out.n))
- fClean = fClean && error("DisconnectBlock(): undo data overwriting existing output");
- if (coins->vout.size() < out.n+1)
- coins->vout.resize(out.n+1);
- coins->vout[out.n] = undo.txout;
+ if (!ApplyTxInUndo(undo, view, out))
+ fClean = false;
}
}
}
@@ -1670,9 +1685,9 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
if (pfClean) {
*pfClean = fClean;
return true;
- } else {
- return fClean;
}
+
+ return fClean;
}
void static FlushBlockFile(bool fFinalize = false)
@@ -3340,19 +3355,17 @@ void static ProcessGetData(CNode* pfrom)
BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
if (mi != mapBlockIndex.end())
{
- // If the requested block is at a height below our last
- // checkpoint, only serve it if it's in the checkpointed chain
- int nHeight = mi->second->nHeight;
- CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint();
- if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
- if (!chainActive.Contains(mi->second))
- {
- LogPrintf("ProcessGetData(): ignoring request for old block that isn't in the main chain\n");
- } else {
- send = true;
- }
- } else {
+ if (chainActive.Contains(mi->second)) {
send = true;
+ } else {
+ // To prevent fingerprinting attacks, only send blocks outside of the active
+ // chain if they are valid, and no more than a month older than the best header
+ // chain we know about.
+ send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
+ (mi->second->GetBlockTime() > pindexBestHeader->GetBlockTime() - 30 * 24 * 60 * 60);
+ if (!send) {
+ LogPrintf("ProcessGetData(): ignoring request from peer=%i for old block that isn't in the main chain\n", pfrom->GetId());
+ }
}
}
if (send)
@@ -3450,7 +3463,7 @@ void static ProcessGetData(CNode* pfrom)
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
{
RandAddSeedPerfmon();
- LogPrint("net", "received: %s (%u bytes) peer=%d\n", strCommand, vRecv.size(), pfrom->id);
+ LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
{
LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
@@ -4285,7 +4298,7 @@ bool ProcessMessages(CNode* pfrom)
// Scan for message start
if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
- LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", msg.hdr.GetCommand(), pfrom->id);
+ LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id);
fOk = false;
break;
}
@@ -4294,7 +4307,7 @@ bool ProcessMessages(CNode* pfrom)
CMessageHeader& hdr = msg.hdr;
if (!hdr.IsValid())
{
- LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", hdr.GetCommand(), pfrom->id);
+ LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id);
continue;
}
string strCommand = hdr.GetCommand();
@@ -4310,7 +4323,7 @@ bool ProcessMessages(CNode* pfrom)
if (nChecksum != hdr.nChecksum)
{
LogPrintf("ProcessMessages(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
- strCommand, nMessageSize, nChecksum, hdr.nChecksum);
+ SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum);
continue;
}
@@ -4327,12 +4340,12 @@ bool ProcessMessages(CNode* pfrom)
if (strstr(e.what(), "end of data"))
{
// Allow exceptions from under-length message on vRecv
- LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand, nMessageSize, e.what());
+ LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", SanitizeString(strCommand), nMessageSize, e.what());
}
else if (strstr(e.what(), "size too large"))
{
// Allow exceptions from over-long size
- LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught\n", strCommand, nMessageSize, e.what());
+ LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught\n", SanitizeString(strCommand), nMessageSize, e.what());
}
else
{
@@ -4349,7 +4362,7 @@ bool ProcessMessages(CNode* pfrom)
}
if (!fRet)
- LogPrintf("ProcessMessage(%s, %u bytes) FAILED peer=%d\n", strCommand, nMessageSize, pfrom->id);
+ LogPrintf("ProcessMessage(%s, %u bytes) FAILED peer=%d\n", SanitizeString(strCommand), nMessageSize, pfrom->id);
break;
}
diff --git a/src/net.cpp b/src/net.cpp
index e4ab9d706d..3c3666615e 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -1971,7 +1971,7 @@ void CNode::BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSen
ENTER_CRITICAL_SECTION(cs_vSend);
assert(ssSend.size() == 0);
ssSend << CMessageHeader(pszCommand, 0);
- LogPrint("net", "sending: %s ", pszCommand);
+ LogPrint("net", "sending: %s ", SanitizeString(pszCommand));
}
void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend)
diff --git a/src/pow.cpp b/src/pow.cpp
index e49f0d104c..6dd5c4c12c 100644
--- a/src/pow.cpp
+++ b/src/pow.cpp
@@ -20,8 +20,8 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
if (pindexLast == NULL)
return nProofOfWorkLimit;
- // Only change once per interval
- if ((pindexLast->nHeight+1) % Params().Interval() != 0)
+ // Only change once per difficulty adjustment interval
+ if ((pindexLast->nHeight+1) % Params().DifficultyAdjustmentInterval() != 0)
{
if (Params().AllowMinDifficultyBlocks())
{
@@ -34,7 +34,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
{
// Return the last non-special-min-difficulty-rules-block
const CBlockIndex* pindex = pindexLast;
- while (pindex->pprev && pindex->nHeight % Params().Interval() != 0 && pindex->nBits == nProofOfWorkLimit)
+ while (pindex->pprev && pindex->nHeight % Params().DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit)
pindex = pindex->pprev;
return pindex->nBits;
}
@@ -44,7 +44,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
// Go back by what we want to be 14 days worth of blocks
const CBlockIndex* pindexFirst = pindexLast;
- for (int i = 0; pindexFirst && i < Params().Interval()-1; i++)
+ for (int i = 0; pindexFirst && i < Params().DifficultyAdjustmentInterval()-1; i++)
pindexFirst = pindexFirst->pprev;
assert(pindexFirst);
diff --git a/src/qt/forms/helpmessagedialog.ui b/src/qt/forms/helpmessagedialog.ui
index 37008f047e..dc7df9d6c8 100644
--- a/src/qt/forms/helpmessagedialog.ui
+++ b/src/qt/forms/helpmessagedialog.ui
@@ -14,6 +14,69 @@
<string notr="true">Bitcoin Core - Command-line options</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>12</number>
+ </property>
+ <property name="topMargin">
+ <number>12</number>
+ </property>
+ <property name="rightMargin">
+ <number>12</number>
+ </property>
+ <property name="bottomMargin">
+ <number>12</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayoutLogo" stretch="0,0">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>4</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="aboutLogo">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Ignored">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>100</height>
+ </size>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="../bitcoin.qrc">:/icons/bitcoin</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="frame">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
@@ -25,6 +88,9 @@
</item>
<item>
<widget class="QScrollArea" name="scrollArea">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum>
</property>
@@ -57,6 +123,22 @@
</widget>
</item>
<item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>4</width>
+ <height>4</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
<widget class="QDialogButtonBox" name="okButton">
<property name="orientation">
<enum>Qt::Horizontal</enum>
diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui
index eebb459327..b1ed7a27b5 100644
--- a/src/qt/forms/sendcoinsdialog.ui
+++ b/src/qt/forms/sendcoinsdialog.ui
@@ -771,16 +771,6 @@
</property>
</widget>
</item>
- <item>
- <widget class="QPushButton" name="buttonMinimizeFee">
- <property name="toolTip">
- <string>collapse fee-settings</string>
- </property>
- <property name="text">
- <string>Minimize</string>
- </property>
- </widget>
- </item>
</layout>
</item>
<item>
@@ -811,6 +801,16 @@
</property>
</spacer>
</item>
+ <item>
+ <widget class="QPushButton" name="buttonMinimizeFee">
+ <property name="toolTip">
+ <string>collapse fee-settings</string>
+ </property>
+ <property name="text">
+ <string>Minimize</string>
+ </property>
+ </widget>
+ </item>
</layout>
</item>
<item>
diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp
index 4c1e898020..b69461ad9e 100644
--- a/src/qt/paymentrequestplus.cpp
+++ b/src/qt/paymentrequestplus.cpp
@@ -13,7 +13,6 @@
#include <stdexcept>
-#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include <QDateTime>
diff --git a/src/qt/paymentrequestplus.h b/src/qt/paymentrequestplus.h
index fbc3a09265..61f8a3415d 100644
--- a/src/qt/paymentrequestplus.h
+++ b/src/qt/paymentrequestplus.h
@@ -9,6 +9,8 @@
#include "base58.h"
+#include <openssl/x509.h>
+
#include <QByteArray>
#include <QList>
#include <QString>
diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp
index a00916bf7f..96ceeb18a4 100644
--- a/src/qt/paymentserver.cpp
+++ b/src/qt/paymentserver.cpp
@@ -16,7 +16,6 @@
#include <cstdlib>
-#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include <QApplication>
@@ -569,6 +568,14 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
return false;
}
+ // Bitcoin amounts are stored as (optional) uint64 in the protobuf messages (see paymentrequest.proto),
+ // but CAmount is defined as int64_t. Because of that we need to verify that amounts are in a valid range
+ // and no overflow has happened.
+ if (!verifyAmount(sendingTo.second)) {
+ emit message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR);
+ return false;
+ }
+
// Extract and check amounts
CTxOut txOut(sendingTo.second, sendingTo.first);
if (txOut.IsDust(::minRelayTxFee)) {
@@ -580,6 +587,11 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
}
recipient.amount += sendingTo.second;
+ // Also verify that the final amount is still in a valid range after adding additional amounts.
+ if (!verifyAmount(recipient.amount)) {
+ emit message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR);
+ return false;
+ }
}
// Store addresses and format them to fit nicely into the GUI
recipient.address = addresses.join("<br />");
@@ -768,3 +780,15 @@ bool PaymentServer::verifyExpired(const payments::PaymentDetails& requestDetails
}
return fVerified;
}
+
+bool PaymentServer::verifyAmount(const CAmount& requestAmount)
+{
+ bool fVerified = MoneyRange(requestAmount);
+ if (!fVerified) {
+ qWarning() << QString("PaymentServer::%1: Payment request amount out of allowed range (%2, allowed 0 - %3).")
+ .arg(__func__)
+ .arg(requestAmount)
+ .arg(MAX_MONEY);
+ }
+ return fVerified;
+}
diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h
index db5f44ff1d..6bf5ac2eea 100644
--- a/src/qt/paymentserver.h
+++ b/src/qt/paymentserver.h
@@ -95,6 +95,8 @@ public:
static bool verifyNetwork(const payments::PaymentDetails& requestDetails);
// Verify if the payment request is expired
static bool verifyExpired(const payments::PaymentDetails& requestDetails);
+ // Verify the payment request amount is valid
+ static bool verifyAmount(const CAmount& requestAmount);
signals:
// Fired when a valid payment request is received
diff --git a/src/qt/test/paymentrequestdata.h b/src/qt/test/paymentrequestdata.h
index 50636d7c67..c548ffe429 100644
--- a/src/qt/test/paymentrequestdata.h
+++ b/src/qt/test/paymentrequestdata.h
@@ -433,3 +433,28 @@ dGluZyB0ZXN0bmV0ISqAAXSQG8+GFA18VaKarlYrOz293rNMIub0swKGcQm8jAGX\
HSLaRgHfUDeEPr4hydy4dtfu59KNwe2xsHOHu/SpO4L8SrA4Dm9A7SlNBVWdcLbw\
d2hj739GDLz0b5KuJ2SG6VknMRQM976w/m2qlq0ccVGaaZ2zMIGfpzL3p6adwx/5\
";
+
+//
+// Payment request with amount overflow (amount is set to 21000001 BTC)
+//
+const char* paymentrequest5_cert2_BASE64 =
+"\
+Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\
+BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\
+ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\
+IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\
+mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\
+wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\
+RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\
+KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\
++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\
+3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\
+tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\
+yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\
+dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iTAoEdGVzdBIkCIDC9P+F\
+vt0DEhl2qRQErGqUUwSsaMpDvWIaGnJGNQqi8oisGLzcrKYFKhhUZXN0aW5nIGFt\
+b3VudCBvdmVyZmxvdyEqgAG8S7WEDUC6tCL6q2CTBjop/AitgEy31RL9IqYruytR\
+iEBFUrBDJZU+UEezGwr7/zoECjo5ZY3PmtZcM2sILNjyweJF6XVzGqTxUw6pN6sW\
+XR2T3Gy2LzRvhVA25QgGqpz0/juS2BtmNbsZPkN9gMMwKimgzc+PuCzmEKwPK9cQ\
+YQ==\
+";
diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp
index 04935192c8..e2ec439b2e 100644
--- a/src/qt/test/paymentservertests.cpp
+++ b/src/qt/test/paymentservertests.cpp
@@ -7,7 +7,10 @@
#include "optionsmodel.h"
#include "paymentrequestdata.h"
+#include "amount.h"
#include "random.h"
+#include "script/script.h"
+#include "script/standard.h"
#include "util.h"
#include "utilstrencodings.h"
@@ -184,6 +187,20 @@ void PaymentServerTests::paymentServerTests()
tempFile.close();
QCOMPARE(PaymentServer::readPaymentRequestFromFile(tempFile.fileName(), r.paymentRequest), false);
+ // Payment request with amount overflow (amount is set to 21000001 BTC):
+ data = DecodeBase64(paymentrequest5_cert2_BASE64);
+ byteArray = QByteArray((const char*)&data[0], data.size());
+ r.paymentRequest.parse(byteArray);
+ // Ensure the request is initialized
+ QVERIFY(r.paymentRequest.IsInitialized());
+ // Extract address and amount from the request
+ QList<std::pair<CScript, CAmount> > sendingTos = r.paymentRequest.getPayTo();
+ foreach (const PAIRTYPE(CScript, CAmount)& sendingTo, sendingTos) {
+ CTxDestination dest;
+ if (ExtractDestination(sendingTo.first, dest))
+ QCOMPARE(PaymentServer::verifyAmount(sendingTo.second), false);
+ }
+
delete server;
}
diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp
index 4ef42b927e..63dd6efb52 100644
--- a/src/qt/utilitydialog.cpp
+++ b/src/qt/utilitydialog.cpp
@@ -137,6 +137,7 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
ui->helpMessage->moveCursor(QTextCursor::Start);
ui->scrollArea->setVisible(false);
+ ui->aboutLogo->setVisible(false);
}
}
diff --git a/src/random.cpp b/src/random.cpp
index 663456e962..0ba0de908d 100644
--- a/src/random.cpp
+++ b/src/random.cpp
@@ -5,6 +5,7 @@
#include "random.h"
+#include "support/cleanse.h"
#ifdef WIN32
#include "compat.h" // for Windows API
#endif
@@ -18,7 +19,6 @@
#include <sys/time.h>
#endif
-#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/rand.h>
@@ -40,22 +40,23 @@ void RandAddSeed()
// Seed with CPU performance counter
int64_t nCounter = GetPerformanceCounter();
RAND_add(&nCounter, sizeof(nCounter), 1.5);
- OPENSSL_cleanse((void*)&nCounter, sizeof(nCounter));
+ memory_cleanse((void*)&nCounter, sizeof(nCounter));
}
void RandAddSeedPerfmon()
{
RandAddSeed();
+#ifdef WIN32
+ // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
+ // Seed with the entire set of perfmon data
+
// This can take up to 2 seconds, so only do it every 10 minutes
static int64_t nLastPerfmon;
if (GetTime() < nLastPerfmon + 10 * 60)
return;
nLastPerfmon = GetTime();
-#ifdef WIN32
- // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
- // Seed with the entire set of perfmon data
std::vector<unsigned char> vData(250000, 0);
long ret = 0;
unsigned long nSize = 0;
@@ -70,7 +71,7 @@ void RandAddSeedPerfmon()
RegCloseKey(HKEY_PERFORMANCE_DATA);
if (ret == ERROR_SUCCESS) {
RAND_add(begin_ptr(vData), nSize, nSize / 100.0);
- OPENSSL_cleanse(begin_ptr(vData), nSize);
+ memory_cleanse(begin_ptr(vData), nSize);
LogPrint("rand", "%s: %lu bytes\n", __func__, nSize);
} else {
static bool warned = false; // Warn only once
diff --git a/src/rest.cpp b/src/rest.cpp
index 1ee1d52912..adc2d56284 100644
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -95,7 +95,7 @@ static bool rest_headers(AcceptedConnection* conn,
bool fRun)
{
vector<string> params;
- enum RetFormat rf = ParseDataFormat(params, strReq);
+ const RetFormat rf = ParseDataFormat(params, strReq);
vector<string> path;
boost::split(path, params[0], boost::is_any_of("/"));
@@ -159,7 +159,7 @@ static bool rest_block(AcceptedConnection* conn,
bool showTxDetails)
{
vector<string> params;
- enum RetFormat rf = ParseDataFormat(params, strReq);
+ const RetFormat rf = ParseDataFormat(params, strReq);
string hashStr = params[0];
uint256 hash;
@@ -226,13 +226,39 @@ static bool rest_block_notxdetails(AcceptedConnection* conn,
return rest_block(conn, strReq, mapHeaders, fRun, false);
}
+static bool rest_chaininfo(AcceptedConnection* conn,
+ const std::string& strReq,
+ const std::map<std::string, std::string>& mapHeaders,
+ bool fRun)
+{
+ vector<string> params;
+ const RetFormat rf = ParseDataFormat(params, strReq);
+
+ switch (rf) {
+ case RF_JSON: {
+ Array rpcParams;
+ Value chainInfoObject = getblockchaininfo(rpcParams, false);
+
+ string strJSON = write_string(chainInfoObject, false) + "\n";
+ conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush;
+ return true;
+ }
+ default: {
+ throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: json)");
+ }
+ }
+
+ // not reached
+ return true; // continue to process further HTTP reqs on this cxn
+}
+
static bool rest_tx(AcceptedConnection* conn,
const std::string& strReq,
const std::map<std::string, std::string>& mapHeaders,
bool fRun)
{
vector<string> params;
- enum RetFormat rf = ParseDataFormat(params, strReq);
+ const RetFormat rf = ParseDataFormat(params, strReq);
string hashStr = params[0];
uint256 hash;
@@ -287,6 +313,7 @@ static const struct {
{"/rest/tx/", rest_tx},
{"/rest/block/notxdetails/", rest_block_notxdetails},
{"/rest/block/", rest_block_extended},
+ {"/rest/chaininfo", rest_chaininfo},
{"/rest/headers/", rest_headers},
};
diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp
index 369b3fb4d7..165a9df697 100644
--- a/src/rpcmining.cpp
+++ b/src/rpcmining.cpp
@@ -44,7 +44,7 @@ Value GetNetworkHashPS(int lookup, int height) {
// If lookup is -1, then use blocks since last difficulty change.
if (lookup <= 0)
- lookup = pb->nHeight % 2016 + 1;
+ lookup = pb->nHeight % Params().DifficultyAdjustmentInterval() + 1;
// If lookup is larger than chain, then set it to chain length.
if (lookup > pb->nHeight)
@@ -446,10 +446,6 @@ Value getblocktemplate(const Array& params, bool fHelp)
}
// Release the wallet and main lock while waiting
-#ifdef ENABLE_WALLET
- if(pwalletMain)
- LEAVE_CRITICAL_SECTION(pwalletMain->cs_wallet);
-#endif
LEAVE_CRITICAL_SECTION(cs_main);
{
checktxtime = boost::get_system_time() + boost::posix_time::minutes(1);
@@ -467,10 +463,6 @@ Value getblocktemplate(const Array& params, bool fHelp)
}
}
ENTER_CRITICAL_SECTION(cs_main);
-#ifdef ENABLE_WALLET
- if(pwalletMain)
- ENTER_CRITICAL_SECTION(pwalletMain->cs_wallet);
-#endif
if (!IsRPCRunning())
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down");
diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp
index 8d260b1cc9..2eda4d3355 100644
--- a/src/rpcmisc.cpp
+++ b/src/rpcmisc.cpp
@@ -228,6 +228,8 @@ CScript _createmultisig_redeemScript(const Array& params)
throw runtime_error(
strprintf("not enough keys supplied "
"(got %u keys, but need at least %d to redeem)", keys.size(), nRequired));
+ if (keys.size() > 16)
+ throw runtime_error("Number of addresses involved in the multisignature address creation > 16\nReduce the number");
std::vector<CPubKey> pubkeys;
pubkeys.resize(keys.size());
for (unsigned int i = 0; i < keys.size(); i++)
diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp
index 823b1fcf24..20e9252d7e 100644
--- a/src/rpcserver.cpp
+++ b/src/rpcserver.cpp
@@ -849,7 +849,7 @@ void JSONRequest::parse(const Value& valRequest)
throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string");
strMethod = valMethod.get_str();
if (strMethod != "getblocktemplate")
- LogPrint("rpc", "ThreadRPCServer method=%s\n", strMethod);
+ LogPrint("rpc", "ThreadRPCServer method=%s\n", SanitizeString(strMethod));
// Parse params
Value valParams = find_value(request, "params");
diff --git a/src/streams.h b/src/streams.h
index bd8568b1af..9999c2341f 100644
--- a/src/streams.h
+++ b/src/streams.h
@@ -16,6 +16,7 @@
#include <map>
#include <set>
#include <stdint.h>
+#include <stdio.h>
#include <string>
#include <string.h>
#include <utility>
diff --git a/src/support/cleanse.cpp b/src/support/cleanse.cpp
new file mode 100644
index 0000000000..a2141b2449
--- /dev/null
+++ b/src/support/cleanse.cpp
@@ -0,0 +1,13 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "cleanse.h"
+
+#include <openssl/crypto.h>
+
+void memory_cleanse(void *ptr, size_t len)
+{
+ OPENSSL_cleanse(ptr, len);
+}
diff --git a/src/support/cleanse.h b/src/support/cleanse.h
new file mode 100644
index 0000000000..3e02aa8fd1
--- /dev/null
+++ b/src/support/cleanse.h
@@ -0,0 +1,13 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_SUPPORT_CLEANSE_H
+#define BITCOIN_SUPPORT_CLEANSE_H
+
+#include <stdlib.h>
+
+void memory_cleanse(void *ptr, size_t len);
+
+#endif // BITCOIN_SUPPORT_CLEANSE_H
diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json
index a67c157aff..3c52547a64 100644
--- a/src/test/data/script_invalid.json
+++ b/src/test/data/script_invalid.json
@@ -696,7 +696,13 @@
"BIP66 example 11, with DERSIG"
],
[
- "0x49 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef05101",
+ "0x48 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb12510101",
+ "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
+ "DERSIG",
+ "P2PK with multi-byte hashtype, with DERSIG"
+],
+[
+ "0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001",
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
"LOW_S",
"P2PK with high S"
diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json
index fb81fcb1f5..34e2c8d61a 100644
--- a/src/test/data/script_valid.json
+++ b/src/test/data/script_valid.json
@@ -814,7 +814,13 @@
"BIP66 example 12, with DERSIG"
],
[
- "0x49 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef05101",
+ "0x48 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb12510101",
+ "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
+ "",
+ "P2PK with multi-byte hashtype, without DERSIG"
+],
+[
+ "0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001",
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
"",
"P2PK with high S but no LOW_S"
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 6092afd782..e410b59710 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -107,7 +107,6 @@ void static NegateSignatureS(std::vector<unsigned char>& vchSig) {
std::vector<unsigned char> r, s;
r = std::vector<unsigned char>(vchSig.begin() + 4, vchSig.begin() + 4 + vchSig[3]);
s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]);
- unsigned char hashtype = vchSig.back();
// Really ugly to implement mod-n negation here, but it would be feature creep to expose such functionality from libsecp256k1.
static const unsigned char order[33] = {
@@ -141,7 +140,6 @@ void static NegateSignatureS(std::vector<unsigned char>& vchSig) {
vchSig.push_back(0x02);
vchSig.push_back(s.size());
vchSig.insert(vchSig.end(), s.begin(), s.end());
- vchSig.push_back(hashtype);
}
namespace
@@ -478,6 +476,12 @@ BOOST_AUTO_TEST_CASE(script_build)
good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
"BIP66 example 12, with DERSIG", SCRIPT_VERIFY_DERSIG
).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
+ "P2PK with multi-byte hashtype, without DERSIG", 0
+ ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101"));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
+ "P2PK with multi-byte hashtype, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101"));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
"P2PK with high S but no LOW_S", 0
diff --git a/src/util.cpp b/src/util.cpp
index 0d0f7e5f91..361b3631f5 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -698,13 +698,8 @@ void RenameThread(const char* name)
// removed.
pthread_set_name_np(pthread_self(), name);
-#elif defined(MAC_OSX) && defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
-
-// pthread_setname_np is XCode 10.6-and-later
-#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
+#elif defined(MAC_OSX)
pthread_setname_np(name);
-#endif
-
#else
// Prevent warnings for unused parameters...
(void)name;