aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/gitian-descriptors/gitian-linux.yml43
-rw-r--r--contrib/gitian-descriptors/gitian-osx-signer.yml3
-rw-r--r--contrib/gitian-descriptors/gitian-osx.yml28
-rw-r--r--contrib/gitian-descriptors/gitian-win-signer.yml1
-rw-r--r--contrib/gitian-descriptors/gitian-win.yml50
-rw-r--r--contrib/gitian-keys/luke-jr-key.pgpbin6518 -> 6518 bytes
-rwxr-xr-xdepends/config.guess37
-rw-r--r--depends/config.site.in32
-rwxr-xr-xdepends/config.sub6
-rw-r--r--depends/packages/expat.mk8
-rw-r--r--depends/packages/freetype.mk6
-rw-r--r--depends/packages/miniupnpc.mk4
-rw-r--r--depends/packages/native_ccache.mk4
-rw-r--r--depends/packages/zeromq.mk10
-rw-r--r--doc/build-osx.md136
-rw-r--r--doc/developer-notes.md50
-rw-r--r--doc/release-notes.md7
-rwxr-xr-xqa/rpc-tests/bip9-softforks.py32
-rwxr-xr-xqa/rpc-tests/fundrawtransaction.py8
-rwxr-xr-xqa/rpc-tests/mempool_packages.py28
-rwxr-xr-xqa/rpc-tests/p2p-mempool.py99
-rwxr-xr-xqa/rpc-tests/rawtransactions.py6
-rw-r--r--qa/rpc-tests/test_framework/authproxy.py5
-rwxr-xr-xshare/genbuild.sh7
-rw-r--r--src/Makefile.am1
-rw-r--r--src/Makefile.test.include4
-rw-r--r--src/addrman.cpp10
-rw-r--r--src/addrman.h14
-rw-r--r--src/bitcoin-tx.cpp21
-rw-r--r--src/chain.cpp1
-rw-r--r--src/chainparams.cpp10
-rw-r--r--src/chainparams.h7
-rw-r--r--src/clientversion.cpp9
-rw-r--r--src/clientversion.h1
-rw-r--r--src/coincontrol.h6
-rw-r--r--src/coins.cpp6
-rw-r--r--src/coins.h2
-rw-r--r--src/consensus/params.h1
-rw-r--r--src/hash.cpp39
-rw-r--r--src/hash.h21
-rw-r--r--src/indirectmap.h52
-rw-r--r--src/init.cpp5
-rw-r--r--src/main.cpp150
-rw-r--r--src/main.h2
-rw-r--r--src/memusage.h40
-rw-r--r--src/net.cpp93
-rw-r--r--src/net.h8
-rw-r--r--src/qt/bitcoinstrings.cpp108
-rw-r--r--src/qt/locale/bitcoin_en.ts1004
-rw-r--r--src/qt/rpcconsole.cpp12
-rw-r--r--src/rpc/blockchain.cpp260
-rw-r--r--src/rpc/client.cpp2
-rw-r--r--src/rpc/mining.cpp105
-rw-r--r--src/rpc/net.cpp2
-rw-r--r--src/rpc/rawtransaction.cpp29
-rw-r--r--src/rpc/server.cpp14
-rw-r--r--src/rpc/server.h15
-rw-r--r--src/test/base58_tests.cpp4
-rw-r--r--src/test/data/bitcoin-util-test.json13
-rw-r--r--src/test/data/txcreatedata_seq0.hex1
-rw-r--r--src/test/data/txcreatedata_seq1.hex1
-rw-r--r--src/test/dbwrapper_tests.cpp122
-rw-r--r--src/test/hash_tests.cpp65
-rw-r--r--src/test/miner_tests.cpp4
-rw-r--r--src/test/pmt_tests.cpp4
-rw-r--r--src/test/policyestimator_tests.cpp18
-rw-r--r--src/test/prevector_tests.cpp4
-rw-r--r--src/test/util_tests.cpp63
-rw-r--r--src/torcontrol.cpp18
-rw-r--r--src/txmempool.cpp132
-rw-r--r--src/txmempool.h40
-rw-r--r--src/utilstrencodings.cpp34
-rw-r--r--src/utilstrencodings.h14
-rw-r--r--src/versionbits.cpp13
-rw-r--r--src/versionbits.h9
-rw-r--r--src/wallet/rpcdump.cpp2
-rw-r--r--src/wallet/rpcwallet.cpp138
-rw-r--r--src/wallet/wallet.cpp81
-rw-r--r--src/wallet/wallet.h4
79 files changed, 2346 insertions, 1102 deletions
diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml
index 13941f5d55..cd289b2f6e 100644
--- a/contrib/gitian-descriptors/gitian-linux.yml
+++ b/contrib/gitian-descriptors/gitian-linux.yml
@@ -5,7 +5,7 @@ suites:
- "trusty"
architectures:
- "amd64"
-packages:
+packages:
- "curl"
- "g++-multilib"
- "git-core"
@@ -18,7 +18,6 @@ packages:
- "binutils-gold"
- "ca-certificates"
- "python"
-reference_datetime: "2016-01-01 00:00:00"
remotes:
- "url": "https://github.com/bitcoin/bitcoin.git"
"dir": "bitcoin"
@@ -26,9 +25,12 @@ files: []
script: |
WRAP_DIR=$HOME/wrapped
HOSTS="i686-pc-linux-gnu x86_64-unknown-linux-gnu"
- CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports --disable-bench --disable-gui-tests LDFLAGS=-static-libstdc++"
+ CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports --disable-bench --disable-gui-tests"
FAKETIME_HOST_PROGS=""
- FAKETIME_PROGS="date ar ranlib nm strip"
+ FAKETIME_PROGS="date ar ranlib nm strip objcopy"
+ HOST_CFLAGS="-O2 -g"
+ HOST_CXXFLAGS="-O2 -g"
+ HOST_LDFLAGS=-static-libstdc++
export QT_RCC_TEST=1
export GZIP="-9n"
@@ -42,29 +44,36 @@ script: |
mkdir -p ${BASE_CACHE} ${SOURCES_PATH}
fi
- # Create global faketime wrappers
+ function create_global_faketime_wrappers {
for prog in ${FAKETIME_PROGS}; do
echo '#!/bin/bash' > ${WRAP_DIR}/${prog}
echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog}
echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog}
- echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog}
+ echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog}
echo "\$REAL \$@" >> $WRAP_DIR/${prog}
chmod +x ${WRAP_DIR}/${prog}
done
+ }
- # Create per-host faketime wrappers
+ function create_per-host_faketime_wrappers {
for i in $HOSTS; do
for prog in ${FAKETIME_HOST_PROGS}; do
echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog}
echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog}
echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog}
- echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${i}-${prog}
+ echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog}
echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog}
chmod +x ${WRAP_DIR}/${i}-${prog}
done
done
+ }
+
export PATH=${WRAP_DIR}:${PATH}
+ # Faketime for depends so intermediate results are comparable
+ create_global_faketime_wrappers "2000-01-01 12:00:00"
+ create_per-host_faketime_wrappers "2000-01-01 12:00:00"
+
cd bitcoin
BASEPREFIX=`pwd`/depends
# Build dependencies for each host
@@ -72,9 +81,13 @@ script: |
make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}"
done
+ # Faketime for binaries
+ create_global_faketime_wrappers "${REFERENCE_DATETIME}"
+ create_per-host_faketime_wrappers "${REFERENCE_DATETIME}"
+
# Create the release tarball using (arbitrarily) the first host
./autogen.sh
- ./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`
+ CONFIG_SITE=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`/share/config.site ./configure --prefix=/
make dist
SOURCEDIST=`echo bitcoin-*.tar.gz`
DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'`
@@ -95,20 +108,26 @@ script: |
mkdir -p ${INSTALLPATH}
tar --strip-components=1 -xf ../$SOURCEDIST
- ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS}
+ CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}"
make ${MAKEOPTS}
make ${MAKEOPTS} -C src check-security
make ${MAKEOPTS} -C src check-symbols
- make install-strip
+ make install DESTDIR=${INSTALLPATH}
cd installed
find . -name "lib*.la" -delete
find . -name "lib*.a" -delete
rm -rf ${DISTNAME}/lib/pkgconfig
- 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
+ find ${DISTNAME}/bin -type f -executable -exec objcopy --only-keep-debug {} {}.dbg \; -exec strip -s {} \; -exec objcopy --add-gnu-debuglink={}.dbg {} \;
+ find ${DISTNAME}/lib -type f -exec objcopy --only-keep-debug {} {}.dbg \; -exec strip -s {} \; -exec objcopy --add-gnu-debuglink={}.dbg {} \;
+ find ${DISTNAME} -not -name "*.dbg" | 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} -name "*.dbg" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}-debug.tar.gz
cd ../../
+ rm -rf distsrc-${i}
done
mkdir -p $OUTDIR/src
mv $SOURCEDIST $OUTDIR/src
+ mv ${OUTDIR}/${DISTNAME}-x86_64-*-debug.tar.gz ${OUTDIR}/${DISTNAME}-linux64-debug.tar.gz
+ mv ${OUTDIR}/${DISTNAME}-i686-*-debug.tar.gz ${OUTDIR}/${DISTNAME}-linux32-debug.tar.gz
mv ${OUTDIR}/${DISTNAME}-x86_64-*.tar.gz ${OUTDIR}/${DISTNAME}-linux64.tar.gz
mv ${OUTDIR}/${DISTNAME}-i686-*.tar.gz ${OUTDIR}/${DISTNAME}-linux32.tar.gz
diff --git a/contrib/gitian-descriptors/gitian-osx-signer.yml b/contrib/gitian-descriptors/gitian-osx-signer.yml
index fac61aa3de..f6e9414ab1 100644
--- a/contrib/gitian-descriptors/gitian-osx-signer.yml
+++ b/contrib/gitian-descriptors/gitian-osx-signer.yml
@@ -6,7 +6,6 @@ architectures:
- "amd64"
packages:
- "faketime"
-reference_datetime: "2016-01-01 00:00:00"
remotes:
- "url": "https://github.com/bitcoin-core/bitcoin-detached-sigs.git"
"dir": "signature"
@@ -34,5 +33,5 @@ script: |
tar -xf ${UNSIGNED}
OSX_VOLNAME="$(cat osx_volname)"
./detached-sig-apply.sh ${UNSIGNED} signature/osx
- ${WRAP_DIR}/genisoimage -no-cache-inodes -D -l -probe -V "${OSX_VOLNAME}" -no-pad -r -apple -o uncompressed.dmg signed-app
+ ${WRAP_DIR}/genisoimage -no-cache-inodes -D -l -probe -V "${OSX_VOLNAME}" -no-pad -r -dir-mode 0755 -apple -o uncompressed.dmg signed-app
${WRAP_DIR}/dmg dmg uncompressed.dmg ${OUTDIR}/${SIGNED}
diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml
index c430932f9d..8436cd612a 100644
--- a/contrib/gitian-descriptors/gitian-osx.yml
+++ b/contrib/gitian-descriptors/gitian-osx.yml
@@ -5,7 +5,7 @@ suites:
- "trusty"
architectures:
- "amd64"
-packages:
+packages:
- "ca-certificates"
- "curl"
- "g++"
@@ -27,7 +27,6 @@ packages:
- "python-dev"
- "python-setuptools"
- "fonts-tuffy"
-reference_datetime: "2016-01-01 00:00:00"
remotes:
- "url": "https://github.com/bitcoin/bitcoin.git"
"dir": "bitcoin"
@@ -54,29 +53,36 @@ script: |
export ZERO_AR_DATE=1
- # Create global faketime wrappers
+ function create_global_faketime_wrappers {
for prog in ${FAKETIME_PROGS}; do
echo '#!/bin/bash' > ${WRAP_DIR}/${prog}
echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog}
echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog}
- echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog}
+ echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog}
echo "\$REAL \$@" >> $WRAP_DIR/${prog}
chmod +x ${WRAP_DIR}/${prog}
done
+ }
- # Create per-host faketime wrappers
+ function create_per-host_faketime_wrappers {
for i in $HOSTS; do
for prog in ${FAKETIME_HOST_PROGS}; do
echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog}
echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog}
echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog}
- echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${i}-${prog}
+ echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog}
echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog}
chmod +x ${WRAP_DIR}/${i}-${prog}
done
done
+ }
+
export PATH=${WRAP_DIR}:${PATH}
+ # Faketime for depends so intermediate results are comparable
+ create_global_faketime_wrappers "2000-01-01 12:00:00"
+ create_per-host_faketime_wrappers "2000-01-01 12:00:00"
+
cd bitcoin
BASEPREFIX=`pwd`/depends
@@ -88,9 +94,13 @@ script: |
make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}"
done
+ # Faketime for binaries
+ create_global_faketime_wrappers "${REFERENCE_DATETIME}"
+ create_per-host_faketime_wrappers "${REFERENCE_DATETIME}"
+
# Create the release tarball using (arbitrarily) the first host
./autogen.sh
- ./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`
+ CONFIG_SITE=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`/share/config.site ./configure --prefix=/
make dist
SOURCEDIST=`echo bitcoin-*.tar.gz`
DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'`
@@ -112,9 +122,9 @@ script: |
mkdir -p ${INSTALLPATH}
tar --strip-components=1 -xf ../$SOURCEDIST
- ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS}
+ CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS}
make ${MAKEOPTS}
- make install-strip
+ make install-strip DESTDIR=${INSTALLPATH}
make osx_volname
make deploydir
diff --git a/contrib/gitian-descriptors/gitian-win-signer.yml b/contrib/gitian-descriptors/gitian-win-signer.yml
index 88edb96627..3c1e0214a0 100644
--- a/contrib/gitian-descriptors/gitian-win-signer.yml
+++ b/contrib/gitian-descriptors/gitian-win-signer.yml
@@ -7,7 +7,6 @@ architectures:
packages:
- "libssl-dev"
- "autoconf"
-reference_datetime: "2016-01-01 00:00:00"
remotes:
- "url": "https://github.com/bitcoin-core/bitcoin-detached-sigs.git"
"dir": "signature"
diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml
index 9f7322f0b5..1d3a876dfb 100644
--- a/contrib/gitian-descriptors/gitian-win.yml
+++ b/contrib/gitian-descriptors/gitian-win.yml
@@ -5,7 +5,7 @@ suites:
- "trusty"
architectures:
- "amd64"
-packages:
+packages:
- "curl"
- "g++"
- "git-core"
@@ -21,7 +21,6 @@ packages:
- "zip"
- "ca-certificates"
- "python"
-reference_datetime: "2016-01-01 00:00:00"
remotes:
- "url": "https://github.com/bitcoin/bitcoin.git"
"dir": "bitcoin"
@@ -29,9 +28,11 @@ files: []
script: |
WRAP_DIR=$HOME/wrapped
HOSTS="x86_64-w64-mingw32 i686-w64-mingw32"
- CONFIGFLAGS="--enable-reduce-exports --disable-gui-tests"
- FAKETIME_HOST_PROGS="g++ ar ranlib nm windres strip"
+ CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests"
+ FAKETIME_HOST_PROGS="g++ ar ranlib nm windres strip objcopy"
FAKETIME_PROGS="date makensis zip"
+ HOST_CFLAGS="-O2 -g"
+ HOST_CXXFLAGS="-O2 -g"
export QT_RCC_TEST=1
export GZIP="-9n"
@@ -45,29 +46,31 @@ script: |
mkdir -p ${BASE_CACHE} ${SOURCES_PATH}
fi
- # Create global faketime wrappers
+ function create_global_faketime_wrappers {
for prog in ${FAKETIME_PROGS}; do
echo '#!/bin/bash' > ${WRAP_DIR}/${prog}
echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog}
echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog}
- echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog}
+ echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog}
echo "\$REAL \$@" >> $WRAP_DIR/${prog}
chmod +x ${WRAP_DIR}/${prog}
done
+ }
- # Create per-host faketime wrappers
+ function create_per-host_faketime_wrappers {
for i in $HOSTS; do
for prog in ${FAKETIME_HOST_PROGS}; do
echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog}
echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog}
echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog}
- echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${i}-${prog}
+ echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog}
echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog}
chmod +x ${WRAP_DIR}/${i}-${prog}
done
done
+ }
- # Create per-host linker wrapper
+ function create_per-host_linker_wrapper {
# This is only needed for trusty, as the mingw linker leaks a few bytes of
# heap, causing non-determinism. See discussion in https://github.com/bitcoin/bitcoin/pull/6900
for i in $HOSTS; do
@@ -83,15 +86,21 @@ script: |
echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog}
echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog}
echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog}
- echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${i}-${prog}
+ echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog}
echo "export COMPILER_PATH=${WRAP_DIR}/${i}" >> ${WRAP_DIR}/${i}-${prog}
echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog}
chmod +x ${WRAP_DIR}/${i}-${prog}
done
done
+ }
export PATH=${WRAP_DIR}:${PATH}
+ # Faketime for depends so intermediate results are comparable
+ create_global_faketime_wrappers "2000-01-01 12:00:00"
+ create_per-host_faketime_wrappers "2000-01-01 12:00:00"
+ create_per-host_linker_wrapper "2000-01-01 12:00:00"
+
cd bitcoin
BASEPREFIX=`pwd`/depends
# Build dependencies for each host
@@ -99,9 +108,14 @@ script: |
make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}"
done
+ # Faketime for binaries
+ create_global_faketime_wrappers "${REFERENCE_DATETIME}"
+ create_per-host_faketime_wrappers "${REFERENCE_DATETIME}"
+ create_per-host_linker_wrapper "${REFERENCE_DATETIME}"
+
# Create the release tarball using (arbitrarily) the first host
./autogen.sh
- ./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`
+ CONFIG_SITE=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`/share/config.site ./configure --prefix=/
make dist
SOURCEDIST=`echo bitcoin-*.tar.gz`
DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'`
@@ -125,22 +139,28 @@ script: |
mkdir -p ${INSTALLPATH}
tar --strip-components=1 -xf ../$SOURCEDIST
- ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS}
+ CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}"
make ${MAKEOPTS}
make ${MAKEOPTS} -C src check-security
make deploy
- make install-strip
+ make install DESTDIR=${INSTALLPATH}
cp -f bitcoin-*setup*.exe $OUTDIR/
cd installed
mv ${DISTNAME}/bin/*.dll ${DISTNAME}/lib/
find . -name "lib*.la" -delete
find . -name "lib*.a" -delete
rm -rf ${DISTNAME}/lib/pkgconfig
- find ${DISTNAME} -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}.zip
- cd ../..
+ find ${DISTNAME}/bin -type f -executable -exec ${i}-objcopy --only-keep-debug {} {}.dbg \; -exec ${i}-strip -s {} \; -exec ${i}-objcopy --add-gnu-debuglink={}.dbg {} \;
+ find ${DISTNAME}/lib -type f -exec ${i}-objcopy --only-keep-debug {} {}.dbg \; -exec ${i}-strip -s {} \; -exec ${i}-objcopy --add-gnu-debuglink={}.dbg {} \;
+ find ${DISTNAME} -not -name "*.dbg" -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}.zip
+ find ${DISTNAME} -name "*.dbg" -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}-debug.zip
+ cd ../../
+ rm -rf distsrc-${i}
done
cd $OUTDIR
rename 's/-setup\.exe$/-setup-unsigned.exe/' *-setup.exe
find . -name "*-setup-unsigned.exe" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-win-unsigned.tar.gz
+ mv ${OUTDIR}/${DISTNAME}-x86_64-*-debug.zip ${OUTDIR}/${DISTNAME}-win64-debug.zip
+ mv ${OUTDIR}/${DISTNAME}-i686-*-debug.zip ${OUTDIR}/${DISTNAME}-win32-debug.zip
mv ${OUTDIR}/${DISTNAME}-x86_64-*.zip ${OUTDIR}/${DISTNAME}-win64.zip
mv ${OUTDIR}/${DISTNAME}-i686-*.zip ${OUTDIR}/${DISTNAME}-win32.zip
diff --git a/contrib/gitian-keys/luke-jr-key.pgp b/contrib/gitian-keys/luke-jr-key.pgp
index 4406e6d5be..a2d34e75e1 100644
--- a/contrib/gitian-keys/luke-jr-key.pgp
+++ b/contrib/gitian-keys/luke-jr-key.pgp
Binary files differ
diff --git a/depends/config.guess b/depends/config.guess
index 373a659a06..c4bd827a7b 100755
--- a/depends/config.guess
+++ b/depends/config.guess
@@ -2,7 +2,7 @@
# Attempt to guess a canonical system name.
# Copyright 1992-2016 Free Software Foundation, Inc.
-timestamp='2016-02-11'
+timestamp='2016-05-15'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -186,9 +186,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
- # to ELF recently, or will in the future.
+ # to ELF recently (or will in the future) and ABI.
case "${UNAME_MACHINE_ARCH}" in
- arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ earm*)
+ os=netbsdelf
+ ;;
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ELF__
@@ -386,7 +389,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# This test works for both compilers.
if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
SUN_ARCH=x86_64
@@ -684,7 +687,7 @@ EOF
exit (0);
}
EOF
- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
@@ -701,7 +704,7 @@ EOF
# $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
# => hppa64-hp-hpux11.23
- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
grep -q __LP64__
then
HP_ARCH=hppa2.0w
@@ -900,7 +903,7 @@ EOF
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
@@ -1276,6 +1279,9 @@ EOF
SX-8R:SUPER-UX:*:*)
echo sx8r-nec-superux${UNAME_RELEASE}
exit ;;
+ SX-ACE:SUPER-UX:*:*)
+ echo sxace-nec-superux${UNAME_RELEASE}
+ exit ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit ;;
@@ -1291,7 +1297,7 @@ EOF
if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
case $UNAME_PROCESSOR in
@@ -1386,7 +1392,7 @@ EOF
echo i386-pc-xenix
exit ;;
i*86:skyos:*:*)
- echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'`
exit ;;
i*86:rdos:*:*)
echo ${UNAME_MACHINE}-pc-rdos
@@ -1405,18 +1411,17 @@ esac
cat >&2 <<EOF
$0: unable to guess system type
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
+This script (version $timestamp), has failed to recognize the
+operating system you are using. If your script is old, overwrite
+config.guess and config.sub with the latest versions from:
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
and
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <config-patches@gnu.org> in order to provide the needed
-information to handle your system.
+If $0 has already been updated, send the following data and any
+information you think might be pertinent to config-patches@gnu.org to
+provide the necessary information to handle your system.
config.guess timestamp = $timestamp
diff --git a/depends/config.site.in b/depends/config.site.in
index 984ddb1e62..e731537bf7 100644
--- a/depends/config.site.in
+++ b/depends/config.site.in
@@ -1,24 +1,26 @@
+depends_prefix="`dirname ${ac_site_file}`/.."
+
cross_compiling=maybe
host_alias=@HOST@
ac_tool_prefix=${host_alias}-
if test -z $with_boost; then
- with_boost=$prefix
+ with_boost=$depends_prefix
fi
if test -z $with_qt_plugindir; then
- with_qt_plugindir=$prefix/plugins
+ with_qt_plugindir=$depends_prefix/plugins
fi
if test -z $with_qt_translationdir; then
- with_qt_translationdir=$prefix/translations
+ with_qt_translationdir=$depends_prefix/translations
fi
if test -z $with_qt_bindir; then
- with_qt_bindir=$prefix/native/bin
+ with_qt_bindir=$depends_prefix/native/bin
fi
if test -z $with_protoc_bindir; then
- with_protoc_bindir=$prefix/native/bin
+ with_protoc_bindir=$depends_prefix/native/bin
fi
if test -z $with_comparison_tool; then
- with_comparison_tool=$prefix/native/share/BitcoindComparisonTool_jar/BitcoindComparisonTool.jar
+ with_comparison_tool=$depends_prefix/native/share/BitcoindComparisonTool_jar/BitcoindComparisonTool.jar
fi
@@ -41,32 +43,32 @@ fi
if test x@host_os@ = xmingw32; then
if test -z $with_qt_incdir; then
- with_qt_incdir=$prefix/include
+ with_qt_incdir=$depends_prefix/include
fi
if test -z $with_qt_libdir; then
- with_qt_libdir=$prefix/lib
+ with_qt_libdir=$depends_prefix/lib
fi
fi
-PATH=$prefix/native/bin:$PATH
+PATH=$depends_prefix/native/bin:$PATH
PKG_CONFIG="`which pkg-config` --static"
# These two need to remain exported because pkg-config does not see them
# otherwise. That means they must be unexported at the end of configure.ac to
# avoid ruining the cache. Sigh.
-export PKG_CONFIG_LIBDIR=$prefix/lib/pkgconfig
-export PKG_CONFIG_PATH=$prefix/share/pkgconfig
+export PKG_CONFIG_LIBDIR=$depends_prefix/lib/pkgconfig
+export PKG_CONFIG_PATH=$depends_prefix/share/pkgconfig
-CPPFLAGS="-I$prefix/include/ $CPPFLAGS"
-LDFLAGS="-L$prefix/lib $LDFLAGS"
+CPPFLAGS="-I$depends_prefix/include/ $CPPFLAGS"
+LDFLAGS="-L$depends_prefix/lib $LDFLAGS"
CC="@CC@"
CXX="@CXX@"
OBJC="${CC}"
OBJCXX="${CXX}"
-CCACHE=$prefix/native/bin/ccache
-PYTHONPATH=$prefix/native/lib/python/dist-packages:$PYTHONPATH
+CCACHE=$depends_prefix/native/bin/ccache
+PYTHONPATH=$depends_prefix/native/lib/python/dist-packages:$PYTHONPATH
if test -n "@AR@"; then
AR=@AR@
diff --git a/depends/config.sub b/depends/config.sub
index 6223dde931..6d86a1e2f7 100755
--- a/depends/config.sub
+++ b/depends/config.sub
@@ -2,7 +2,7 @@
# Configuration validation subroutine script.
# Copyright 1992-2016 Free Software Foundation, Inc.
-timestamp='2016-01-01'
+timestamp='2016-05-10'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -1399,7 +1399,7 @@ case $os in
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
- | -onefs* | -tirtos*)
+ | -onefs* | -tirtos* | -phoenix*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1531,6 +1531,8 @@ case $os in
;;
-nacl*)
;;
+ -ios)
+ ;;
-none)
;;
*)
diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk
index 1ac4435374..bd29275638 100644
--- a/depends/packages/expat.mk
+++ b/depends/packages/expat.mk
@@ -1,8 +1,8 @@
package=expat
-$(package)_version=2.1.0
-$(package)_download_path=http://sourceforge.net/projects/expat/files/expat/$($(package)_version)
-$(package)_file_name=$(package)-$($(package)_version).tar.gz
-$(package)_sha256_hash=823705472f816df21c8f6aa026dd162b280806838bb55b3432b0fb1fcca7eb86
+$(package)_version=2.1.1
+$(package)_download_path=https://downloads.sourceforge.net/project/expat/expat/$($(package)_version)
+$(package)_file_name=$(package)-$($(package)_version).tar.bz2
+$(package)_sha256_hash=aff584e5a2f759dcfc6d48671e9529f6afe1e30b0cd6a4cec200cbe3f793de67
define $(package)_set_vars
$(package)_config_opts=--disable-static
diff --git a/depends/packages/freetype.mk b/depends/packages/freetype.mk
index f7d6e0f9fc..7cea28ff0b 100644
--- a/depends/packages/freetype.mk
+++ b/depends/packages/freetype.mk
@@ -1,8 +1,8 @@
package=freetype
-$(package)_version=2.5.3
-$(package)_download_path=http://downloads.sourceforge.net/$(package)
+$(package)_version=2.6.3
+$(package)_download_path=http://download.savannah.gnu.org/releases/$(package)
$(package)_file_name=$(package)-$($(package)_version).tar.bz2
-$(package)_sha256_hash=c0848b29d52ef3ca27ad92e08351f023c5e24ce8cea7d8fe69fc96358e65f75e
+$(package)_sha256_hash=371e707aa522acf5b15ce93f11183c725b8ed1ee8546d7b3af549863045863a2
define $(package)_set_vars
$(package)_config_opts=--without-zlib --without-png --disable-static
diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk
index 45fa03631f..e34cf7be2f 100644
--- a/depends/packages/miniupnpc.mk
+++ b/depends/packages/miniupnpc.mk
@@ -1,8 +1,8 @@
package=miniupnpc
-$(package)_version=1.9.20160209
+$(package)_version=2.0
$(package)_download_path=http://miniupnp.free.fr/files
$(package)_file_name=$(package)-$($(package)_version).tar.gz
-$(package)_sha256_hash=572171eacc1d72537ce47b6f4571260757ab7bcfdaf54c3a55c7f88594d94b6f
+$(package)_sha256_hash=d434ceb8986efbe199c5ca53f90ed53eab290b1e6d0530b717eb6fa49d61f93b
define $(package)_set_vars
$(package)_build_opts=CC="$($(package)_cc)"
diff --git a/depends/packages/native_ccache.mk b/depends/packages/native_ccache.mk
index cc76f9a794..9216e17598 100644
--- a/depends/packages/native_ccache.mk
+++ b/depends/packages/native_ccache.mk
@@ -1,8 +1,8 @@
package=native_ccache
-$(package)_version=3.2.4
+$(package)_version=3.2.5
$(package)_download_path=http://samba.org/ftp/ccache
$(package)_file_name=ccache-$($(package)_version).tar.bz2
-$(package)_sha256_hash=ffeb967edb549e67da0bd5f44f729a2022de9fdde65dfd80d2a7204d7f75332e
+$(package)_sha256_hash=7a553809e90faf9de3a23ee9c5b5f786cfd4836bf502744bedb824a24bee1097
define $(package)_set_vars
$(package)_config_opts=
diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk
index b3f18db056..f8901f72c2 100644
--- a/depends/packages/zeromq.mk
+++ b/depends/packages/zeromq.mk
@@ -1,11 +1,11 @@
package=zeromq
-$(package)_version=4.0.7
+$(package)_version=4.1.4
$(package)_download_path=http://download.zeromq.org
$(package)_file_name=$(package)-$($(package)_version).tar.gz
-$(package)_sha256_hash=e00b2967e074990d0538361cc79084a0a92892df2c6e7585da34e4c61ee47b03
+$(package)_sha256_hash=e99f44fde25c2e4cb84ce440f87ca7d3fe3271c2b8cfbc67d55e4de25e6fe378
define $(package)_set_vars
- $(package)_config_opts=--without-documentation --disable-shared
+ $(package)_config_opts=--without-documentation --disable-shared --without-libsodium
$(package)_config_opts_linux=--with-pic
$(package)_cxxflags=-std=c++11
endef
@@ -15,11 +15,11 @@ define $(package)_config_cmds
endef
define $(package)_build_cmds
- $(MAKE) -C src
+ $(MAKE) libzmq.la
endef
define $(package)_stage_cmds
- $(MAKE) -C src DESTDIR=$($(package)_staging_dir) install
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install-libLTLIBRARIES install-includeHEADERS install-pkgconfigDATA
endef
define $(package)_postprocess_cmds
diff --git a/doc/build-osx.md b/doc/build-osx.md
index 296e0aa1f0..89d7816c9a 100644
--- a/doc/build-osx.md
+++ b/doc/build-osx.md
@@ -1,129 +1,93 @@
Mac OS X Build Instructions and Notes
====================================
-This guide will show you how to build Bitcoin Core for OS X.
-
-Notes
------
-
-* Tested on OS X 10.7 through 10.11 on 64-bit Intel processors only.
-
-* All of the commands should be executed in a Terminal application. The
-built-in one is located in `/Applications/Utilities`.
+The commands in this guide should be executed in a Terminal application.
+The built-in one is located in `/Applications/Utilities/Terminal.app`.
Preparation
-----------
+Download and install [Xcode](https://developer.apple.com/xcode/download).
-You need to install Xcode with all the options checked so that the compiler
-and everything is available in /usr not just /Developer. Xcode should be
-available on your OS X installation media, but if not, you can get the
-current version from https://developer.apple.com/xcode/. If you install
-Xcode 4.3 or later, you'll need to install its command line tools. This can
-be done in `Xcode > Preferences > Downloads > Components` and generally must
-be re-done or updated every time Xcode is updated.
-
-You will also need to install [Homebrew](http://brew.sh) in order to install library
-dependencies.
+Once installed, run `xcode-select --install` to install the OS X command line tools.
-The installation of the actual dependencies is covered in the instructions
-sections below.
+Install [Homebrew](http://brew.sh).
-Instructions: Homebrew
+Dependencies
----------------------
-#### Install dependencies using Homebrew
+ brew install automake berkeley-db4 libtool boost --c++11 miniupnpc openssl pkg-config protobuf --c++11 qt5 libevent
- brew install autoconf automake berkeley-db4 libtool boost miniupnpc openssl pkg-config protobuf qt5 libevent
+NOTE: Building with Qt4 is still supported, however, could result in a broken UI. Building with Qt5 is recommended.
-NOTE: Building with Qt4 is still supported, however, could result in a broken UI. As such, building with Qt5 is recommended.
-
-### Building `bitcoin`
+Build Bitcoin Core
+------------------------
-1. Clone the GitHub tree to get the source code and go into the directory.
+1. Clone the bitcoin source code and cd into `bitcoin`
- git clone https://github.com/bitcoin/bitcoin.git
+ git clone https://github.com/bitcoin/bitcoin
cd bitcoin
2. Build bitcoin-core:
- This will configure and build the headless bitcoin binaries as well as the gui (if Qt is found).
- You can disable the gui build by passing `--without-gui` to configure.
+
+ Configure and build the headless bitcoin binaries as well as the GUI (if Qt is found).
+
+ You can disable the GUI build by passing `--without-gui` to configure.
./autogen.sh
./configure
make
-3. It is also a good idea to build and run the unit tests:
+3. It is recommended to build and run the unit tests:
make check
-4. (Optional) You can also install bitcoind to your path:
-
- make install
-
-Use Qt Creator as IDE
-------------------------
-You can use Qt Creator as IDE, for debugging and for manipulating forms, etc.
-Download Qt Creator from https://www.qt.io/download/. Download the "community edition" and only install Qt Creator (uncheck the rest during the installation process).
-
-1. Make sure you installed everything through Homebrew mentioned above
-2. Do a proper ./configure --enable-debug
-3. In Qt Creator do "New Project" -> Import Project -> Import Existing Project
-4. Enter "bitcoin-qt" as project name, enter src/qt as location
-5. Leave the file selection as it is
-6. Confirm the "summary page"
-7. In the "Projects" tab select "Manage Kits..."
-8. Select the default "Desktop" kit and select "Clang (x86 64bit in /usr/bin)" as compiler
-9. Select LLDB as debugger (you might need to set the path to your installation)
-10. Start debugging with Qt Creator
-
-Creating a release build
-------------------------
-You can ignore this section if you are building `bitcoind` for your own use.
-
-bitcoind/bitcoin-cli binaries are not included in the Bitcoin-Qt.app bundle.
-
-If you are building `bitcoind` or `Bitcoin Core` for others, your build machine should be set up
-as follows for maximum compatibility:
+4. You can also create a .dmg that contains the .app bundle (optional):
-All dependencies should be compiled with these flags:
-
- -mmacosx-version-min=10.7
- -arch x86_64
- -isysroot $(xcode-select --print-path)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk
-
-Once dependencies are compiled, see [doc/release-process.md](release-process.md) for how the Bitcoin Core
-bundle is packaged and signed to create the .dmg disk image that is distributed.
+ make deploy
Running
-------
-It's now available at `./bitcoind`, provided that you are still in the `src`
-directory. We have to first create the RPC configuration file, though.
+Bitcoin Core is now available at `./src/bitcoind`
-Run `./bitcoind` to get the filename where it should be put, or just try these
-commands:
+Before running, it's recommended you create an RPC configuration file.
echo -e "rpcuser=bitcoinrpc\nrpcpassword=$(xxd -l 16 -p /dev/urandom)" > "/Users/${USER}/Library/Application Support/Bitcoin/bitcoin.conf"
+
chmod 600 "/Users/${USER}/Library/Application Support/Bitcoin/bitcoin.conf"
-The next time you run it, it will start downloading the blockchain, but it won't
-output anything while it's doing this. This process may take several hours;
-you can monitor its process by looking at the debug.log file, like this:
+The first time you run bitcoind, it will start downloading the blockchain. This process could take several hours.
+
+You can monitor the download process by looking at the debug.log file:
tail -f $HOME/Library/Application\ Support/Bitcoin/debug.log
Other commands:
-------
- ./bitcoind -daemon # to start the bitcoin daemon.
- ./bitcoin-cli --help # for a list of command-line options.
- ./bitcoin-cli help # When the daemon is running, to get a list of RPC commands
+ ./src/bitcoind -daemon # Starts the bitcoin daemon.
+ ./src/bitcoin-cli --help # Outputs a list of command-line options.
+ ./src/bitcoin-cli help # Outputs a list of RPC commands when the daemon is running.
+
+Using Qt Creator as IDE
+------------------------
+You can use Qt Creator as an IDE, for bitcoin development.
+Download and install the community edition of [Qt Creator](https://www.qt.io/download/).
+Uncheck everything except Qt Creator during the installation process.
-Using Qt official installer while building
-------------------------------------------
+1. Make sure you installed everything through Homebrew mentioned above
+2. Do a proper ./configure --enable-debug
+3. In Qt Creator do "New Project" -> Import Project -> Import Existing Project
+4. Enter "bitcoin-qt" as project name, enter src/qt as location
+5. Leave the file selection as it is
+6. Confirm the "summary page"
+7. In the "Projects" tab select "Manage Kits..."
+8. Select the default "Desktop" kit and select "Clang (x86 64bit in /usr/bin)" as compiler
+9. Select LLDB as debugger (you might need to set the path to your installation)
+10. Start debugging with Qt Creator
+
+Notes
+-----
+
+* Tested on OS X 10.7 through 10.11 on 64-bit Intel processors only.
-If you prefer to use the latest Qt installed from the official binary
-installer over the brew version, you have to make several changes to
-the installed tree and its binaries (all these changes are contained
-in the brew version already). The changes needed are described in
-[#7714](https://github.com/bitcoin/bitcoin/issues/7714). We do not
-support building Bitcoin Core this way though.
+* Building with downloaded Qt binaries is not officially supported. See the notes in [#7714](https://github.com/bitcoin/bitcoin/issues/7714)
diff --git a/doc/developer-notes.md b/doc/developer-notes.md
index add2fb5004..abed15c370 100644
--- a/doc/developer-notes.md
+++ b/doc/developer-notes.md
@@ -323,7 +323,7 @@ Strings and formatting
buffer overflows and surprises with `\0` characters. Also some C string manipulations
tend to act differently depending on platform, or even the user locale
-- Use `ParseInt32`, `ParseInt64`, `ParseDouble` from `utilstrencodings.h` for number parsing
+- Use `ParseInt32`, `ParseInt64`, `ParseUInt32`, `ParseUInt64`, `ParseDouble` from `utilstrencodings.h` for number parsing
- *Rationale*: These functions do overflow checking, and avoid pesky locale issues
@@ -381,3 +381,51 @@ GUI
- *Rationale*: Model classes pass through events and data from the core, they
should not interact with the user. That's where View classes come in. The converse also
holds: try to not directly access core data structures from Views.
+
+Git and github tips
+---------------------
+
+- For resolving merge/rebase conflicts, it can be useful to enable diff3 style using
+ `git config merge.conflictstyle diff3`. Instead of
+
+ <<<
+ yours
+ ===
+ theirs
+ >>>
+
+ you will see
+
+ <<<
+ yours
+ |||
+ original
+ ===
+ theirs
+ >>>
+
+ This may make it much clearer what caused the conflict. In this style, you can often just look
+ at what changed between *original* and *theirs*, and mechanically apply that to *yours* (or the other way around).
+
+- When reviewing patches which change indentation in C++ files, use `git diff -w` and `git show -w`. This makes
+ the diff algorithm ignore whitespace changes. This feature is also available on github.com, by adding `?w=1`
+ at the end of any URL which shows a diff.
+
+- When reviewing patches that change symbol names in many places, use `git diff --word-diff`. This will instead
+ of showing the patch as deleted/added *lines*, show deleted/added *words*.
+
+- When reviewing patches that move code around, try using
+ `git diff --patience commit~:old/file.cpp commit:new/file/name.cpp`, and ignoring everything except the
+ moved body of code which should show up as neither `+` or `-` lines. In case it was not a pure move, this may
+ even work when combined with the `-w` or `--word-diff` options described above.
+
+- When looking at other's pull requests, it may make sense to add the following section to your `.git/config`
+ file:
+
+ [remote "upstream-pull"]
+ fetch = +refs/pull/*:refs/remotes/upstream-pull/*
+ url = git@github.com:bitcoin/bitcoin.git
+
+ This will add an `upstream-pull` remote to your git repository, which can be fetched using `git fetch --all`
+ or `git fetch upstream-pull`. Afterwards, you can use `upstream-pull/NUMBER/head` in arguments to `git show`,
+ `git checkout` and anywhere a commit id would be acceptable to see the changes from pull request NUMBER.
diff --git a/doc/release-notes.md b/doc/release-notes.md
index 7d44b8cda9..be619e41c6 100644
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -80,6 +80,13 @@ The following outputs are affected by this change:
- REST `/rest/block/` (JSON format when including extended tx details)
- `bitcoin-tx -json`
+New mempool information RPC calls
+---------------------------------
+
+RPC calls have been added to output detailed statistics for individual mempool
+entries, as well as to calculate the in-mempool ancestors or descendants of a
+transaction: see `getmempoolentry`, `getmempoolancestors`, `getmempooldescendants`.
+
### ZMQ
Each ZMQ notification now contains an up-counting sequence number that allows
diff --git a/qa/rpc-tests/bip9-softforks.py b/qa/rpc-tests/bip9-softforks.py
index aae258315e..d7e8e5e5a5 100755
--- a/qa/rpc-tests/bip9-softforks.py
+++ b/qa/rpc-tests/bip9-softforks.py
@@ -80,7 +80,7 @@ class BIP9SoftForksTest(ComparisonTestFramework):
info = self.nodes[0].getblockchaininfo()
return info['bip9_softforks'][key]
- def test_BIP(self, bipName, activated_version, invalidate, invalidatePostSignature):
+ def test_BIP(self, bipName, activated_version, invalidate, invalidatePostSignature, bitno):
# generate some coins for later
self.coinbase_blocks = self.nodes[0].generate(2)
self.height = 3 # height of the next block to build
@@ -89,6 +89,11 @@ class BIP9SoftForksTest(ComparisonTestFramework):
self.last_block_time = int(time.time())
assert_equal(self.get_bip9_status(bipName)['status'], 'defined')
+ tmpl = self.nodes[0].getblocktemplate({})
+ assert(bipName not in tmpl['rules'])
+ assert(bipName not in tmpl['vbavailable'])
+ assert_equal(tmpl['vbrequired'], 0)
+ assert_equal(tmpl['version'], 0x20000000)
# Test 1
# Advance from DEFINED to STARTED
@@ -96,6 +101,11 @@ class BIP9SoftForksTest(ComparisonTestFramework):
yield TestInstance(test_blocks, sync_every_block=False)
assert_equal(self.get_bip9_status(bipName)['status'], 'started')
+ tmpl = self.nodes[0].getblocktemplate({})
+ assert(bipName not in tmpl['rules'])
+ assert_equal(tmpl['vbavailable'][bipName], bitno)
+ assert_equal(tmpl['vbrequired'], 0)
+ assert(tmpl['version'] & activated_version)
# Test 2
# Fail to achieve LOCKED_IN 100 out of 144 signal bit 1
@@ -107,6 +117,11 @@ class BIP9SoftForksTest(ComparisonTestFramework):
yield TestInstance(test_blocks, sync_every_block=False)
assert_equal(self.get_bip9_status(bipName)['status'], 'started')
+ tmpl = self.nodes[0].getblocktemplate({})
+ assert(bipName not in tmpl['rules'])
+ assert_equal(tmpl['vbavailable'][bipName], bitno)
+ assert_equal(tmpl['vbrequired'], 0)
+ assert(tmpl['version'] & activated_version)
# Test 3
# 108 out of 144 signal bit 1 to achieve LOCKED_IN
@@ -118,6 +133,8 @@ class BIP9SoftForksTest(ComparisonTestFramework):
yield TestInstance(test_blocks, sync_every_block=False)
assert_equal(self.get_bip9_status(bipName)['status'], 'locked_in')
+ tmpl = self.nodes[0].getblocktemplate({})
+ assert(bipName not in tmpl['rules'])
# Test 4
# 143 more version 536870913 blocks (waiting period-1)
@@ -125,6 +142,8 @@ class BIP9SoftForksTest(ComparisonTestFramework):
yield TestInstance(test_blocks, sync_every_block=False)
assert_equal(self.get_bip9_status(bipName)['status'], 'locked_in')
+ tmpl = self.nodes[0].getblocktemplate({})
+ assert(bipName not in tmpl['rules'])
# Test 5
# Check that the new rule is enforced
@@ -148,6 +167,11 @@ class BIP9SoftForksTest(ComparisonTestFramework):
yield TestInstance([[block, True]])
assert_equal(self.get_bip9_status(bipName)['status'], 'active')
+ tmpl = self.nodes[0].getblocktemplate({})
+ assert(bipName in tmpl['rules'])
+ assert(bipName not in tmpl['vbavailable'])
+ assert_equal(tmpl['vbrequired'], 0)
+ assert(not (tmpl['version'] & (1 << bitno)))
# Test 6
# Check that the new sequence lock rules are enforced
@@ -183,9 +207,9 @@ class BIP9SoftForksTest(ComparisonTestFramework):
def get_tests(self):
for test in itertools.chain(
- self.test_BIP('csv', 536870913, self.sequence_lock_invalidate, self.donothing),
- self.test_BIP('csv', 536870913, self.mtp_invalidate, self.donothing),
- self.test_BIP('csv', 536870913, self.donothing, self.csv_invalidate)
+ self.test_BIP('csv', 0x20000001, self.sequence_lock_invalidate, self.donothing, 0),
+ self.test_BIP('csv', 0x20000001, self.mtp_invalidate, self.donothing, 0),
+ self.test_BIP('csv', 0x20000001, self.donothing, self.csv_invalidate, 0)
):
yield test
diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py
index 57b850a6a9..998f822afe 100755
--- a/qa/rpc-tests/fundrawtransaction.py
+++ b/qa/rpc-tests/fundrawtransaction.py
@@ -678,6 +678,14 @@ class RawTransactionsTest(BitcoinTestFramework):
assert(signedtx["complete"])
self.nodes[0].sendrawtransaction(signedtx["hex"])
+ inputs = []
+ outputs = {self.nodes[2].getnewaddress() : 1}
+ rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
+ result = self.nodes[3].fundrawtransaction(rawtx) # uses min_relay_tx_fee (set by settxfee)
+ result2 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2*min_relay_tx_fee})
+ result3 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 10*min_relay_tx_fee})
+ assert_equal(result['fee']*2, result2['fee'])
+ assert_equal(result['fee']*10, result3['fee'])
if __name__ == '__main__':
RawTransactionsTest().main()
diff --git a/qa/rpc-tests/mempool_packages.py b/qa/rpc-tests/mempool_packages.py
index 693ff593b3..45dc0e65c4 100755
--- a/qa/rpc-tests/mempool_packages.py
+++ b/qa/rpc-tests/mempool_packages.py
@@ -65,7 +65,14 @@ class MempoolPackagesTest(BitcoinTestFramework):
descendant_fees = 0
descendant_size = 0
+ descendants = []
+ ancestors = list(chain)
for x in reversed(chain):
+ # Check that getmempoolentry is consistent with getrawmempool
+ entry = self.nodes[0].getmempoolentry(x)
+ assert_equal(entry, mempool[x])
+
+ # Check that the descendant calculations are correct
assert_equal(mempool[x]['descendantcount'], descendant_count)
descendant_fees += mempool[x]['fee']
assert_equal(mempool[x]['modifiedfee'], mempool[x]['fee'])
@@ -74,6 +81,27 @@ class MempoolPackagesTest(BitcoinTestFramework):
assert_equal(mempool[x]['descendantsize'], descendant_size)
descendant_count += 1
+ # Check that getmempooldescendants is correct
+ assert_equal(sorted(descendants), sorted(self.nodes[0].getmempooldescendants(x)))
+ descendants.append(x)
+
+ # Check that getmempoolancestors is correct
+ ancestors.remove(x)
+ assert_equal(sorted(ancestors), sorted(self.nodes[0].getmempoolancestors(x)))
+
+ # Check that getmempoolancestors/getmempooldescendants correctly handle verbose=true
+ v_ancestors = self.nodes[0].getmempoolancestors(chain[-1], True)
+ assert_equal(len(v_ancestors), len(chain)-1)
+ for x in v_ancestors.keys():
+ assert_equal(mempool[x], v_ancestors[x])
+ assert(chain[-1] not in v_ancestors.keys())
+
+ v_descendants = self.nodes[0].getmempooldescendants(chain[0], True)
+ assert_equal(len(v_descendants), len(chain)-1)
+ for x in v_descendants.keys():
+ assert_equal(mempool[x], v_descendants[x])
+ assert(chain[0] not in v_descendants.keys())
+
# Check that descendant modified fees includes fee deltas from
# prioritisetransaction
self.nodes[0].prioritisetransaction(chain[-1], 0, 1000)
diff --git a/qa/rpc-tests/p2p-mempool.py b/qa/rpc-tests/p2p-mempool.py
new file mode 100755
index 0000000000..5d2daf39f8
--- /dev/null
+++ b/qa/rpc-tests/p2p-mempool.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python3
+# Copyright (c) 2015-2016 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+from test_framework.mininode import *
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+import time
+
+class TestNode(NodeConnCB):
+ def __init__(self):
+ NodeConnCB.__init__(self)
+ self.connection = None
+ self.ping_counter = 1
+ self.last_pong = msg_pong()
+ self.block_receive_map = {}
+
+ def add_connection(self, conn):
+ self.connection = conn
+ self.peer_disconnected = False
+
+ def on_inv(self, conn, message):
+ pass
+
+ # Track the last getdata message we receive (used in the test)
+ def on_getdata(self, conn, message):
+ self.last_getdata = message
+
+ def on_block(self, conn, message):
+ message.block.calc_sha256()
+ try:
+ self.block_receive_map[message.block.sha256] += 1
+ except KeyError as e:
+ self.block_receive_map[message.block.sha256] = 1
+
+ # Spin until verack message is received from the node.
+ # We use this to signal that our test can begin. This
+ # is called from the testing thread, so it needs to acquire
+ # the global lock.
+ def wait_for_verack(self):
+ def veracked():
+ return self.verack_received
+ return wait_until(veracked, timeout=10)
+
+ def wait_for_disconnect(self):
+ def disconnected():
+ return self.peer_disconnected
+ return wait_until(disconnected, timeout=10)
+
+ # Wrapper for the NodeConn's send_message function
+ def send_message(self, message):
+ self.connection.send_message(message)
+
+ def on_pong(self, conn, message):
+ self.last_pong = message
+
+ def on_close(self, conn):
+ self.peer_disconnected = True
+
+ # Sync up with the node after delivery of a block
+ def sync_with_ping(self, timeout=30):
+ def received_pong():
+ return (self.last_pong.nonce == self.ping_counter)
+ self.connection.send_message(msg_ping(nonce=self.ping_counter))
+ success = wait_until(received_pong, timeout)
+ self.ping_counter += 1
+ return success
+
+ def send_mempool(self):
+ self.lastInv = []
+ self.send_message(msg_mempool())
+
+class P2PMempoolTests(BitcoinTestFramework):
+ def setup_chain(self):
+ initialize_chain_clean(self.options.tmpdir, 2)
+
+ def setup_network(self):
+ # Start a node with maxuploadtarget of 200 MB (/24h)
+ self.nodes = []
+ self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-peerbloomfilters=0"]))
+
+ def run_test(self):
+ #connect a mininode
+ aTestNode = TestNode()
+ node = NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], aTestNode)
+ aTestNode.add_connection(node)
+ NetworkThread().start()
+ aTestNode.wait_for_verack()
+
+ #request mempool
+ aTestNode.send_mempool()
+ aTestNode.wait_for_disconnect()
+
+ #mininode must be disconnected at this point
+ assert_equal(len(self.nodes[0].getpeerinfo()), 0)
+
+if __name__ == '__main__':
+ P2PMempoolTests().main()
diff --git a/qa/rpc-tests/rawtransactions.py b/qa/rpc-tests/rawtransactions.py
index df02c1697f..aa403f058c 100755
--- a/qa/rpc-tests/rawtransactions.py
+++ b/qa/rpc-tests/rawtransactions.py
@@ -138,5 +138,11 @@ class RawTransactionsTest(BitcoinTestFramework):
self.sync_all()
assert_equal(self.nodes[0].getbalance(), bal+Decimal('50.00000000')+Decimal('2.19000000')) #block reward + tx
+ inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : 1000}]
+ outputs = { self.nodes[0].getnewaddress() : 1 }
+ rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
+ decrawtx= self.nodes[0].decoderawtransaction(rawtx)
+ assert_equal(decrawtx['vin'][0]['sequence'], 1000)
+
if __name__ == '__main__':
RawTransactionsTest().main()
diff --git a/qa/rpc-tests/test_framework/authproxy.py b/qa/rpc-tests/test_framework/authproxy.py
index e5f7ab3656..95b2be658c 100644
--- a/qa/rpc-tests/test_framework/authproxy.py
+++ b/qa/rpc-tests/test_framework/authproxy.py
@@ -124,6 +124,11 @@ class AuthServiceProxy(object):
return self._get_response()
else:
raise
+ except BrokenPipeError:
+ # Python 3.5+ raises this instead of BadStatusLine when the connection was reset
+ self.__conn.close()
+ self.__conn.request(method, path, postdata, headers)
+ return self._get_response()
def __call__(self, *args):
AuthServiceProxy.__id_count += 1
diff --git a/share/genbuild.sh b/share/genbuild.sh
index a15cb34e47..1ef77d706f 100755
--- a/share/genbuild.sh
+++ b/share/genbuild.sh
@@ -15,7 +15,6 @@ fi
DESC=""
SUFFIX=""
-LAST_COMMIT_DATE=""
if [ -e "$(which git 2>/dev/null)" -a "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = "true" ]; then
# clean 'dirty' status of touched files that haven't been modified
git diff >/dev/null 2>/dev/null
@@ -29,9 +28,6 @@ if [ -e "$(which git 2>/dev/null)" -a "$(git rev-parse --is-inside-work-tree 2>/
# otherwise generate suffix from git, i.e. string like "59887e8-dirty"
SUFFIX=$(git rev-parse --short HEAD)
git diff-index --quiet HEAD -- || SUFFIX="$SUFFIX-dirty"
-
- # get a string like "2012-04-10 16:27:19 +0200"
- LAST_COMMIT_DATE="$(git log -n 1 --format="%ci")"
fi
if [ -n "$DESC" ]; then
@@ -45,7 +41,4 @@ fi
# only update build.h if necessary
if [ "$INFO" != "$NEWINFO" ]; then
echo "$NEWINFO" >"$FILE"
- if [ -n "$LAST_COMMIT_DATE" ]; then
- echo "#define BUILD_DATE \"$LAST_COMMIT_DATE\"" >> "$FILE"
- fi
fi
diff --git a/src/Makefile.am b/src/Makefile.am
index 5e33c6a869..3df8e267bb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -93,6 +93,7 @@ BITCOIN_CORE_H = \
core_memusage.h \
httprpc.h \
httpserver.h \
+ indirectmap.h \
init.h \
key.h \
keystore.h \
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index ff3351fe72..41d811fb54 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -17,7 +17,9 @@ EXTRA_DIST += \
test/data/txcreate2.hex \
test/data/txcreatedata1.hex \
test/data/txcreatedata2.hex \
- test/data/txcreatesign.hex
+ test/data/txcreatesign.hex \
+ test/data/txcreatedata_seq0.hex \
+ test/data/txcreatedata_seq1.hex
JSON_TEST_FILES = \
test/data/script_tests.json \
diff --git a/src/addrman.cpp b/src/addrman.cpp
index 6c54cfa4cd..00f6fe99e0 100644
--- a/src/addrman.cpp
+++ b/src/addrman.cpp
@@ -197,6 +197,9 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId)
void CAddrMan::Good_(const CService& addr, int64_t nTime)
{
int nId;
+
+ nLastGood = nTime;
+
CAddrInfo* pinfo = Find(addr, &nId);
// if not found, bail out
@@ -311,7 +314,7 @@ bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimeP
return fNew;
}
-void CAddrMan::Attempt_(const CService& addr, int64_t nTime)
+void CAddrMan::Attempt_(const CService& addr, bool fCountFailure, int64_t nTime)
{
CAddrInfo* pinfo = Find(addr);
@@ -327,7 +330,10 @@ void CAddrMan::Attempt_(const CService& addr, int64_t nTime)
// update info
info.nLastTry = nTime;
- info.nAttempts++;
+ if (fCountFailure && info.nLastCountAttempt < nLastGood) {
+ info.nLastCountAttempt = nTime;
+ info.nAttempts++;
+ }
}
CAddrInfo CAddrMan::Select_(bool newOnly)
diff --git a/src/addrman.h b/src/addrman.h
index 3085450450..c5923e9417 100644
--- a/src/addrman.h
+++ b/src/addrman.h
@@ -29,6 +29,9 @@ public:
//! last try whatsoever by us (memory only)
int64_t nLastTry;
+ //! last counted attempt (memory only)
+ int64_t nLastCountAttempt;
+
private:
//! where knowledge about this address first came from
CNetAddr source;
@@ -66,6 +69,7 @@ public:
{
nLastSuccess = 0;
nLastTry = 0;
+ nLastCountAttempt = 0;
nAttempts = 0;
nRefCount = 0;
fInTried = false;
@@ -200,6 +204,9 @@ private:
//! list of "new" buckets
int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE];
+ //! last time Good was called (memory only)
+ int64_t nLastGood;
+
protected:
//! secret key to randomize bucket select with
uint256 nKey;
@@ -230,7 +237,7 @@ protected:
bool Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty);
//! Mark an entry as attempted to connect.
- void Attempt_(const CService &addr, int64_t nTime);
+ void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime);
//! Select an address to connect to, if newOnly is set to true, only the new table is selected from.
CAddrInfo Select_(bool newOnly);
@@ -458,6 +465,7 @@ public:
nIdCount = 0;
nTried = 0;
nNew = 0;
+ nLastGood = 1; //Initially at 1 so that "never" is strictly worse.
}
CAddrMan()
@@ -532,12 +540,12 @@ public:
}
//! Mark an entry as connection attempted to.
- void Attempt(const CService &addr, int64_t nTime = GetAdjustedTime())
+ void Attempt(const CService &addr, bool fCountFailure, int64_t nTime = GetAdjustedTime())
{
{
LOCK(cs);
Check();
- Attempt_(addr, nTime);
+ Attempt_(addr, fCountFailure, nTime);
Check();
}
}
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index 95d7a085a0..f9ea94b9f4 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -71,7 +71,7 @@ static bool AppInitRawTx(int argc, char* argv[])
strUsage = HelpMessageGroup(_("Commands:"));
strUsage += HelpMessageOpt("delin=N", _("Delete input N from TX"));
strUsage += HelpMessageOpt("delout=N", _("Delete output N from TX"));
- strUsage += HelpMessageOpt("in=TXID:VOUT", _("Add input to TX"));
+ strUsage += HelpMessageOpt("in=TXID:VOUT(:SEQUENCE_NUMBER)", _("Add input to TX"));
strUsage += HelpMessageOpt("locktime=N", _("Set TX lock time to N"));
strUsage += HelpMessageOpt("nversion=N", _("Set TX version to N"));
strUsage += HelpMessageOpt("outaddr=VALUE:ADDRESS", _("Add address-based output to TX"));
@@ -181,15 +181,15 @@ static void MutateTxLocktime(CMutableTransaction& tx, const string& cmdVal)
static void MutateTxAddInput(CMutableTransaction& tx, const string& strInput)
{
+ std::vector<std::string> vStrInputParts;
+ boost::split(vStrInputParts, strInput, boost::is_any_of(":"));
+
// separate TXID:VOUT in string
- size_t pos = strInput.find(':');
- if ((pos == string::npos) ||
- (pos == 0) ||
- (pos == (strInput.size() - 1)))
+ if (vStrInputParts.size()<2)
throw runtime_error("TX input missing separator");
// extract and validate TXID
- string strTxid = strInput.substr(0, pos);
+ string strTxid = vStrInputParts[0];
if ((strTxid.size() != 64) || !IsHex(strTxid))
throw runtime_error("invalid TX input txid");
uint256 txid(uint256S(strTxid));
@@ -198,13 +198,18 @@ static void MutateTxAddInput(CMutableTransaction& tx, const string& strInput)
static const unsigned int maxVout = MAX_BLOCK_SIZE / minTxOutSz;
// extract and validate vout
- string strVout = strInput.substr(pos + 1, string::npos);
+ string strVout = vStrInputParts[1];
int vout = atoi(strVout);
if ((vout < 0) || (vout > (int)maxVout))
throw runtime_error("invalid TX input vout");
+ // extract the optional sequence number
+ uint32_t nSequenceIn=std::numeric_limits<unsigned int>::max();
+ if (vStrInputParts.size() > 2)
+ nSequenceIn = std::stoul(vStrInputParts[2]);
+
// append to transaction input list
- CTxIn txin(txid, vout);
+ CTxIn txin(txid, vout, CScript(), nSequenceIn);
tx.vin.push_back(txin);
}
diff --git a/src/chain.cpp b/src/chain.cpp
index 32f6480f84..77e924e703 100644
--- a/src/chain.cpp
+++ b/src/chain.cpp
@@ -93,6 +93,7 @@ CBlockIndex* CBlockIndex::GetAncestor(int height)
pindexWalk = pindexWalk->pskip;
heightWalk = heightSkip;
} else {
+ assert(pindexWalk->pprev);
pindexWalk = pindexWalk->pprev;
heightWalk--;
}
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index 5c7d190125..0005115671 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -16,6 +16,14 @@
#include "chainparamsseeds.h"
+std::string CDNSSeedData::getHost(uint64_t requiredServiceBits) const {
+ //use default host for non-filter-capable seeds or if we use the default service bits (NODE_NETWORK)
+ if (!supportsServiceBitsFiltering || requiredServiceBits == NODE_NETWORK)
+ return host;
+
+ return strprintf("x%x.%s", requiredServiceBits, host);
+}
+
static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
{
CMutableTransaction txNew;
@@ -197,6 +205,8 @@ public:
vFixedSeeds.clear();
vSeeds.clear();
+ // nodes with support for servicebits filtering should be at the top
+ vSeeds.push_back(CDNSSeedData("testnetbitcoin.jonasschnelli.ch", "testnet-seed.bitcoin.jonasschnelli.ch", true));
vSeeds.push_back(CDNSSeedData("bitcoin.petertodd.org", "testnet-seed.bitcoin.petertodd.org"));
vSeeds.push_back(CDNSSeedData("bluematt.me", "testnet-seed.bluematt.me"));
vSeeds.push_back(CDNSSeedData("bitcoin.schildbach.de", "testnet-seed.bitcoin.schildbach.de"));
diff --git a/src/chainparams.h b/src/chainparams.h
index 59202f548a..7168daaf43 100644
--- a/src/chainparams.h
+++ b/src/chainparams.h
@@ -13,9 +13,12 @@
#include <vector>
-struct CDNSSeedData {
+class CDNSSeedData {
+public:
std::string name, host;
- CDNSSeedData(const std::string &strName, const std::string &strHost) : name(strName), host(strHost) {}
+ bool supportsServiceBitsFiltering;
+ std::string getHost(uint64_t requiredServiceBits) const;
+ CDNSSeedData(const std::string &strName, const std::string &strHost, bool supportsServiceBitsFilteringIn = false) : name(strName), host(strHost), supportsServiceBitsFiltering(supportsServiceBitsFilteringIn) {}
};
struct SeedSpec6 {
diff --git a/src/clientversion.cpp b/src/clientversion.cpp
index aae0569bba..bfe9e16f80 100644
--- a/src/clientversion.cpp
+++ b/src/clientversion.cpp
@@ -67,16 +67,7 @@ const std::string CLIENT_NAME("Satoshi");
#endif
#endif
-#ifndef BUILD_DATE
-#ifdef GIT_COMMIT_DATE
-#define BUILD_DATE GIT_COMMIT_DATE
-#else
-#define BUILD_DATE __DATE__ ", " __TIME__
-#endif
-#endif
-
const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX);
-const std::string CLIENT_DATE(BUILD_DATE);
static std::string FormatVersion(int nVersion)
{
diff --git a/src/clientversion.h b/src/clientversion.h
index 6f255d69c9..47263d5344 100644
--- a/src/clientversion.h
+++ b/src/clientversion.h
@@ -59,7 +59,6 @@ static const int CLIENT_VERSION =
extern const std::string CLIENT_NAME;
extern const std::string CLIENT_BUILD;
-extern const std::string CLIENT_DATE;
std::string FormatFullVersion();
diff --git a/src/coincontrol.h b/src/coincontrol.h
index 12fe9ce219..e33adc4d2b 100644
--- a/src/coincontrol.h
+++ b/src/coincontrol.h
@@ -18,6 +18,10 @@ public:
bool fAllowWatchOnly;
//! Minimum absolute fee (not per kilobyte)
CAmount nMinimumTotalFee;
+ //! Override estimated feerate
+ bool fOverrideFeeRate;
+ //! Feerate to use if overrideFeeRate is true
+ CFeeRate nFeeRate;
CCoinControl()
{
@@ -31,6 +35,8 @@ public:
fAllowWatchOnly = false;
setSelected.clear();
nMinimumTotalFee = 0;
+ nFeeRate = CFeeRate(0);
+ fOverrideFeeRate = false;
}
bool HasSelected() const
diff --git a/src/coins.cpp b/src/coins.cpp
index b7dd293d69..39db7dedfb 100644
--- a/src/coins.cpp
+++ b/src/coins.cpp
@@ -56,11 +56,7 @@ void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
CCoinsViewCursor *CCoinsViewBacked::Cursor() const { return base->Cursor(); }
-SaltedTxidHasher::SaltedTxidHasher()
-{
- GetRandBytes((unsigned char*)&k0, sizeof(k0));
- GetRandBytes((unsigned char*)&k1, sizeof(k1));
-}
+SaltedTxidHasher::SaltedTxidHasher() : k0(GetRand(std::numeric_limits<uint64_t>::max())), k1(GetRand(std::numeric_limits<uint64_t>::max())) {}
CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false), cachedCoinsUsage(0) { }
diff --git a/src/coins.h b/src/coins.h
index 1dd908700b..033651a435 100644
--- a/src/coins.h
+++ b/src/coins.h
@@ -269,7 +269,7 @@ class SaltedTxidHasher
{
private:
/** Salt */
- uint64_t k0, k1;
+ const uint64_t k0, k1;
public:
SaltedTxidHasher();
diff --git a/src/consensus/params.h b/src/consensus/params.h
index 4f3480b89b..6c4cc49479 100644
--- a/src/consensus/params.h
+++ b/src/consensus/params.h
@@ -16,6 +16,7 @@ enum DeploymentPos
{
DEPLOYMENT_TESTDUMMY,
DEPLOYMENT_CSV, // Deployment of BIP68, BIP112, and BIP113.
+ // NOTE: Also add new deployments to VersionBitsDeploymentInfo in versionbits.cpp
MAX_VERSION_BITS_DEPLOYMENTS
};
diff --git a/src/hash.cpp b/src/hash.cpp
index a518314a53..20a83342db 100644
--- a/src/hash.cpp
+++ b/src/hash.cpp
@@ -100,12 +100,15 @@ CSipHasher::CSipHasher(uint64_t k0, uint64_t k1)
v[2] = 0x6c7967656e657261ULL ^ k0;
v[3] = 0x7465646279746573ULL ^ k1;
count = 0;
+ tmp = 0;
}
CSipHasher& CSipHasher::Write(uint64_t data)
{
uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
+ assert(count % 8 == 0);
+
v3 ^= data;
SIPROUND;
SIPROUND;
@@ -116,7 +119,35 @@ CSipHasher& CSipHasher::Write(uint64_t data)
v[2] = v2;
v[3] = v3;
- count++;
+ count += 8;
+ return *this;
+}
+
+CSipHasher& CSipHasher::Write(const unsigned char* data, size_t size)
+{
+ uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
+ uint64_t t = tmp;
+ int c = count;
+
+ while (size--) {
+ t |= ((uint64_t)(*(data++))) << (8 * (c % 8));
+ c++;
+ if ((c & 7) == 0) {
+ v3 ^= t;
+ SIPROUND;
+ SIPROUND;
+ v0 ^= t;
+ t = 0;
+ }
+ }
+
+ v[0] = v0;
+ v[1] = v1;
+ v[2] = v2;
+ v[3] = v3;
+ count = c;
+ tmp = t;
+
return *this;
}
@@ -124,10 +155,12 @@ uint64_t CSipHasher::Finalize() const
{
uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
- v3 ^= ((uint64_t)count) << 59;
+ uint64_t t = tmp | (((uint64_t)count) << 56);
+
+ v3 ^= t;
SIPROUND;
SIPROUND;
- v0 ^= ((uint64_t)count) << 59;
+ v0 ^= t;
v2 ^= 0xFF;
SIPROUND;
SIPROUND;
diff --git a/src/hash.h b/src/hash.h
index 600dabec56..db4e130ae7 100644
--- a/src/hash.h
+++ b/src/hash.h
@@ -171,19 +171,38 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char
void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]);
-/** SipHash-2-4, using a uint64_t-based (rather than byte-based) interface */
+/** SipHash-2-4 */
class CSipHasher
{
private:
uint64_t v[4];
+ uint64_t tmp;
int count;
public:
+ /** Construct a SipHash calculator initialized with 128-bit key (k0, k1) */
CSipHasher(uint64_t k0, uint64_t k1);
+ /** Hash a 64-bit integer worth of data
+ * It is treated as if this was the little-endian interpretation of 8 bytes.
+ * This function can only be used when a multiple of 8 bytes have been written so far.
+ */
CSipHasher& Write(uint64_t data);
+ /** Hash arbitrary bytes. */
+ CSipHasher& Write(const unsigned char* data, size_t size);
+ /** Compute the 64-bit SipHash-2-4 of the data written so far. The object remains untouched. */
uint64_t Finalize() const;
};
+/** Optimized SipHash-2-4 implementation for uint256.
+ *
+ * It is identical to:
+ * SipHasher(k0, k1)
+ * .Write(val.GetUint64(0))
+ * .Write(val.GetUint64(1))
+ * .Write(val.GetUint64(2))
+ * .Write(val.GetUint64(3))
+ * .Finalize()
+ */
uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256& val);
#endif // BITCOIN_HASH_H
diff --git a/src/indirectmap.h b/src/indirectmap.h
new file mode 100644
index 0000000000..28e1e8dedd
--- /dev/null
+++ b/src/indirectmap.h
@@ -0,0 +1,52 @@
+#ifndef BITCOIN_INDIRECTMAP_H
+#define BITCOIN_INDIRECTMAP_H
+
+template <class T>
+struct DereferencingComparator { bool operator()(const T a, const T b) const { return *a < *b; } };
+
+/* Map whose keys are pointers, but are compared by their dereferenced values.
+ *
+ * Differs from a plain std::map<const K*, T, DereferencingComparator<K*> > in
+ * that methods that take a key for comparison take a K rather than taking a K*
+ * (taking a K* would be confusing, since it's the value rather than the address
+ * of the object for comparison that matters due to the dereferencing comparator).
+ *
+ * Objects pointed to by keys must not be modified in any way that changes the
+ * result of DereferencingComparator.
+ */
+template <class K, class T>
+class indirectmap {
+private:
+ typedef std::map<const K*, T, DereferencingComparator<const K*> > base;
+ base m;
+public:
+ typedef typename base::iterator iterator;
+ typedef typename base::const_iterator const_iterator;
+ typedef typename base::size_type size_type;
+ typedef typename base::value_type value_type;
+
+ // passthrough (pointer interface)
+ std::pair<iterator, bool> insert(const value_type& value) { return m.insert(value); }
+
+ // pass address (value interface)
+ iterator find(const K& key) { return m.find(&key); }
+ const_iterator find(const K& key) const { return m.find(&key); }
+ iterator lower_bound(const K& key) { return m.lower_bound(&key); }
+ const_iterator lower_bound(const K& key) const { return m.lower_bound(&key); }
+ size_type erase(const K& key) { return m.erase(&key); }
+ size_type count(const K& key) const { return m.count(&key); }
+
+ // passthrough
+ bool empty() const { return m.empty(); }
+ size_type size() const { return m.size(); }
+ size_type max_size() const { return m.max_size(); }
+ void clear() { m.clear(); }
+ iterator begin() { return m.begin(); }
+ iterator end() { return m.end(); }
+ const_iterator begin() const { return m.begin(); }
+ const_iterator end() const { return m.end(); }
+ const_iterator cbegin() const { return m.cbegin(); }
+ const_iterator cend() const { return m.cend(); }
+};
+
+#endif // BITCOIN_INDIRECTMAP_H
diff --git a/src/init.cpp b/src/init.cpp
index 9a22501859..ec4ce6b6da 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -319,7 +319,8 @@ std::string HelpMessage(HelpMessageMode mode)
}
strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory"));
strUsage += HelpMessageOpt("-dbcache=<n>", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache));
- strUsage += HelpMessageOpt("-feefilter", strprintf(_("Tell other nodes to filter invs to us by our mempool min fee (default: %u)"), DEFAULT_FEEFILTER));
+ if (showDebug)
+ strUsage += HelpMessageOpt("-feefilter", strprintf("Tell other nodes to filter invs to us by our mempool min fee (default: %u)", DEFAULT_FEEFILTER));
strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file on startup"));
strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS));
strUsage += HelpMessageOpt("-maxmempool=<n>", strprintf(_("Keep the transaction memory pool below <n> megabytes (default: %u)"), DEFAULT_MAX_MEMPOOL_SIZE));
@@ -747,7 +748,7 @@ void InitLogging()
fLogIPs = GetBoolArg("-logips", DEFAULT_LOGIPS);
LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
- LogPrintf("Bitcoin version %s (%s)\n", FormatFullVersion(), CLIENT_DATE);
+ LogPrintf("Bitcoin version %s\n", FormatFullVersion());
}
/** Initialize bitcoin.
diff --git a/src/main.cpp b/src/main.cpp
index 162c8b986c..6d006e8789 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -37,6 +37,7 @@
#include "validationinterface.h"
#include "versionbits.h"
+#include <atomic>
#include <sstream>
#include <boost/algorithm/string/replace.hpp>
@@ -80,9 +81,6 @@ uint64_t nPruneTarget = 0;
int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
bool fEnableReplacement = DEFAULT_ENABLE_REPLACEMENT;
-std::map<uint256, CTransaction> mapRelay;
-std::deque<std::pair<int64_t, uint256> > vRelayExpiration;
-CCriticalSection cs_mapRelay;
CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE;
@@ -215,6 +213,12 @@ namespace {
/** Number of peers from which we're downloading blocks. */
int nPeersWithValidatedDownloads = 0;
+
+ /** Relay map, protected by cs_main. */
+ typedef std::map<uint256, std::shared_ptr<const CTransaction>> MapRelay;
+ MapRelay mapRelay;
+ /** Expiration-time ordered list of (expire time, relay map entry) pairs, protected by cs_main). */
+ std::deque<std::pair<int64_t, MapRelay::iterator>> vRelayExpiration;
} // anon namespace
//////////////////////////////////////////////////////////////////////////////
@@ -1054,9 +1058,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
LOCK(pool.cs); // protect pool.mapNextTx
BOOST_FOREACH(const CTxIn &txin, tx.vin)
{
- if (pool.mapNextTx.count(txin.prevout))
+ auto itConflicting = pool.mapNextTx.find(txin.prevout);
+ if (itConflicting != pool.mapNextTx.end())
{
- const CTransaction *ptxConflicting = pool.mapNextTx[txin.prevout].ptx;
+ const CTransaction *ptxConflicting = itConflicting->second;
if (!setConflicts.count(ptxConflicting->GetHash()))
{
// Allow opt-out of transaction replacement by setting
@@ -1441,8 +1446,10 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::P
LOCK(cs_main);
- if (mempool.lookup(hash, txOut))
+ std::shared_ptr<const CTransaction> ptx = mempool.get(hash);
+ if (ptx)
{
+ txOut = *ptx;
return true;
}
@@ -1576,18 +1583,24 @@ CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
bool IsInitialBlockDownload()
{
const CChainParams& chainParams = Params();
+
+ // Once this function has returned false, it must remain false.
+ static std::atomic<bool> latchToFalse{false};
+ // Optimization: pre-test latch before taking the lock.
+ if (latchToFalse.load(std::memory_order_relaxed))
+ return false;
+
LOCK(cs_main);
+ if (latchToFalse.load(std::memory_order_relaxed))
+ return false;
if (fImporting || fReindex)
return true;
if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()))
return true;
- static bool lockIBDState = false;
- if (lockIBDState)
- return false;
bool state = (chainActive.Height() < pindexBestHeader->nHeight - 24 * 6 ||
std::max(chainActive.Tip()->GetBlockTime(), pindexBestHeader->GetBlockTime()) < GetTime() - nMaxTipAge);
if (!state)
- lockIBDState = true;
+ latchToFalse.store(true, std::memory_order_relaxed);
return state;
}
@@ -1885,8 +1898,8 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
// such nodes as they are not following the protocol. That
// said during an upgrade careful thought should be taken
// as to the correct behavior - we may want to continue
- // peering with non-upgraded nodes even after a soft-fork
- // super-majority vote has passed.
+ // peering with non-upgraded nodes even after soft-fork
+ // super-majority signaling has occurred.
return state.DoS(100,false, REJECT_INVALID, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError())));
}
}
@@ -2168,7 +2181,7 @@ void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const
}
// Protected by cs_main
-static VersionBitsCache versionbitscache;
+VersionBitsCache versionbitscache;
int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params)
{
@@ -2921,14 +2934,15 @@ static void NotifyHeaderTip() {
*/
bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, const CBlock *pblock) {
CBlockIndex *pindexMostWork = NULL;
+ CBlockIndex *pindexNewTip = NULL;
do {
boost::this_thread::interruption_point();
if (ShutdownRequested())
break;
- CBlockIndex *pindexNewTip = NULL;
const CBlockIndex *pindexFork;
bool fInitialDownload;
+ int nNewHeight;
{
LOCK(cs_main);
CBlockIndex *pindexOldTip = chainActive.Tip();
@@ -2951,6 +2965,7 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
pindexNewTip = chainActive.Tip();
pindexFork = chainActive.FindFork(pindexOldTip);
fInitialDownload = IsInitialBlockDownload();
+ nNewHeight = chainActive.Height();
}
// When we reach this point, we switched to a new tip (stored in pindexNewTip).
@@ -2979,7 +2994,7 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
{
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes) {
- if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) {
+ if (nNewHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) {
BOOST_REVERSE_FOREACH(const uint256& hash, vHashes) {
pnode->PushBlockHash(hash);
}
@@ -2992,7 +3007,7 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
}
}
}
- } while(pindexMostWork != chainActive.Tip());
+ } while (pindexNewTip != pindexMostWork);
CheckBlockIndex(chainparams.GetConsensus());
// Write changes periodically to disk, after relay.
@@ -3873,10 +3888,18 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview,
CBlockIndex* pindexFailure = NULL;
int nGoodTransactions = 0;
CValidationState state;
+ int reportDone = 0;
+ LogPrintf("[0%]...");
for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev)
{
boost::this_thread::interruption_point();
- uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100)))));
+ int percentageDone = std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
+ if (reportDone < percentageDone/10) {
+ // report every 10% step
+ LogPrintf("[%d%%]...", percentageDone);
+ reportDone = percentageDone/10;
+ }
+ uiInterface.ShowProgress(_("Verifying blocks..."), percentageDone);
if (pindex->nHeight < chainActive.Height()-nCheckDepth)
break;
if (fPruneMode && !(pindex->nStatus & BLOCK_HAVE_DATA)) {
@@ -3934,6 +3957,7 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview,
}
}
+ LogPrintf("[DONE].\n");
LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.Height() - pindexState->nHeight, nGoodTransactions);
return true;
@@ -4502,30 +4526,24 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
}
}
}
- else if (inv.IsKnownType())
+ else if (inv.type == MSG_TX)
{
- CTransaction tx;
// Send stream from relay memory
bool push = false;
- {
- LOCK(cs_mapRelay);
- map<uint256, CTransaction>::iterator mi = mapRelay.find(inv.hash);
- if (mi != mapRelay.end()) {
- tx = (*mi).second;
- push = true;
- }
- }
- if (!push && inv.type == MSG_TX) {
- int64_t txtime;
+ auto mi = mapRelay.find(inv.hash);
+ if (mi != mapRelay.end()) {
+ pfrom->PushMessage(NetMsgType::TX, *mi->second);
+ push = true;
+ } else if (pfrom->timeLastMempoolReq) {
+ auto txinfo = mempool.info(inv.hash);
// To protect privacy, do not answer getdata using the mempool when
// that TX couldn't have been INVed in reply to a MEMPOOL request.
- if (mempool.lookup(inv.hash, tx, txtime) && txtime <= pfrom->timeLastMempoolReq) {
+ if (txinfo.tx && txinfo.nTime <= pfrom->timeLastMempoolReq) {
+ pfrom->PushMessage(NetMsgType::TX, *txinfo.tx);
push = true;
}
}
- if (push) {
- pfrom->PushMessage(inv.GetCommand(), tx);
- } else {
+ if (!push) {
vNotFound.push_back(inv);
}
}
@@ -4568,6 +4586,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
strCommand == NetMsgType::FILTERCLEAR))
{
if (pfrom->nVersion >= NO_BLOOM_VERSION) {
+ LOCK(cs_main);
Misbehaving(pfrom->GetId(), 100);
return false;
} else {
@@ -4583,6 +4602,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
if (pfrom->nVersion != 0)
{
pfrom->PushMessage(NetMsgType::REJECT, strCommand, REJECT_DUPLICATE, string("Duplicate version message"));
+ LOCK(cs_main);
Misbehaving(pfrom->GetId(), 1);
return false;
}
@@ -4642,7 +4662,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
// Potentially mark this peer as a preferred download peer.
+ {
+ LOCK(cs_main);
UpdatePreferredDownload(pfrom, State(pfrom->GetId()));
+ }
// Change version
pfrom->PushMessage(NetMsgType::VERACK);
@@ -4700,6 +4723,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
else if (pfrom->nVersion == 0)
{
// Must have a version message before anything else
+ LOCK(cs_main);
Misbehaving(pfrom->GetId(), 1);
return false;
}
@@ -4735,6 +4759,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
return true;
if (vAddr.size() > 1000)
{
+ LOCK(cs_main);
Misbehaving(pfrom->GetId(), 20);
return error("message addr size() = %u", vAddr.size());
}
@@ -4758,11 +4783,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
LOCK(cs_vNodes);
// Use deterministic randomness to send to the same nodes for 24 hours
// at a time so the addrKnowns of the chosen nodes prevent repeats
- static uint64_t salt0 = 0, salt1 = 0;
- while (salt0 == 0 && salt1 == 0) {
- GetRandBytes((unsigned char*)&salt0, sizeof(salt0));
- GetRandBytes((unsigned char*)&salt1, sizeof(salt1));
- }
+ static const uint64_t salt0 = GetRand(std::numeric_limits<uint64_t>::max());
+ static const uint64_t salt1 = GetRand(std::numeric_limits<uint64_t>::max());
uint64_t hashAddr = addr.GetHash();
multimap<uint64_t, CNode*> mapMix;
const CSipHasher hasher = CSipHasher(salt0, salt1).Write(hashAddr << 32).Write((GetTime() + hashAddr) / (24*60*60));
@@ -4802,6 +4824,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
vRecv >> vInv;
if (vInv.size() > MAX_INV_SZ)
{
+ LOCK(cs_main);
Misbehaving(pfrom->GetId(), 20);
return error("message inv size() = %u", vInv.size());
}
@@ -4877,6 +4900,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
vRecv >> vInv;
if (vInv.size() > MAX_INV_SZ)
{
+ LOCK(cs_main);
Misbehaving(pfrom->GetId(), 20);
return error("message getdata size() = %u", vInv.size());
}
@@ -5128,6 +5152,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
// Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
unsigned int nCount = ReadCompactSize(vRecv);
if (nCount > MAX_HEADERS_RESULTS) {
+ LOCK(cs_main);
Misbehaving(pfrom->GetId(), 20);
return error("headers message size = %u", nCount);
}
@@ -5290,6 +5315,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
else if (strCommand == NetMsgType::MEMPOOL)
{
+ if (!(nLocalServices & NODE_BLOOM) && !pfrom->fWhitelisted)
+ {
+ LogPrint("net", "mempool request with bloom filters disabled, disconnect peer=%d\n", pfrom->GetId());
+ pfrom->fDisconnect = true;
+ return true;
+ }
+
if (CNode::OutboundTargetReached(false) && !pfrom->fWhitelisted)
{
LogPrint("net", "mempool request with bandwidth limit reached, disconnect peer=%d\n", pfrom->GetId());
@@ -5389,8 +5421,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
LOCK(pfrom->cs_filter);
if (!filter.IsWithinSizeConstraints())
+ {
// There is no excuse for sending a too-large filter
+ LOCK(cs_main);
Misbehaving(pfrom->GetId(), 100);
+ }
else
{
delete pfrom->pfilter;
@@ -5410,13 +5445,17 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
// and thus, the maximum size any matched object can have) in a filteradd message
if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE)
{
+ LOCK(cs_main);
Misbehaving(pfrom->GetId(), 100);
} else {
LOCK(pfrom->cs_filter);
if (pfrom->pfilter)
pfrom->pfilter->insert(vData);
else
+ {
+ LOCK(cs_main);
Misbehaving(pfrom->GetId(), 100);
+ }
}
}
@@ -5686,6 +5725,9 @@ bool SendMessages(CNode* pto)
pto->vAddrToSend.clear();
if (!vAddr.empty())
pto->PushMessage(NetMsgType::ADDR, vAddr);
+ // we only send the big addr message once
+ if (pto->vAddrToSend.capacity() > 40)
+ pto->vAddrToSend.shrink_to_fit();
}
CNodeState &state = *State(pto->GetId());
@@ -5880,8 +5922,7 @@ bool SendMessages(CNode* pto)
// Respond to BIP35 mempool requests
if (fSendTrickle && pto->fSendMempool) {
- std::vector<uint256> vtxid;
- mempool.queryHashes(vtxid);
+ auto vtxinfo = mempool.infoAll();
pto->fSendMempool = false;
CAmount filterrate = 0;
{
@@ -5891,20 +5932,16 @@ bool SendMessages(CNode* pto)
LOCK(pto->cs_filter);
- BOOST_FOREACH(const uint256& hash, vtxid) {
+ for (const auto& txinfo : vtxinfo) {
+ const uint256& hash = txinfo.tx->GetHash();
CInv inv(MSG_TX, hash);
pto->setInventoryTxToSend.erase(hash);
if (filterrate) {
- CFeeRate feeRate;
- mempool.lookupFeeRate(hash, feeRate);
- if (feeRate.GetFeePerK() < filterrate)
+ if (txinfo.feeRate.GetFeePerK() < filterrate)
continue;
}
if (pto->pfilter) {
- CTransaction tx;
- bool fInMemPool = mempool.lookup(hash, tx);
- if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
- if (!pto->pfilter->IsRelevantAndUpdate(tx)) continue;
+ if (!pto->pfilter->IsRelevantAndUpdate(*txinfo.tx)) continue;
}
pto->filterInventoryKnown.insert(hash);
vInv.push_back(inv);
@@ -5950,31 +5987,28 @@ bool SendMessages(CNode* pto)
continue;
}
// Not in the mempool anymore? don't bother sending it.
- CFeeRate feeRate;
- if (!mempool.lookupFeeRate(hash, feeRate)) {
+ auto txinfo = mempool.info(hash);
+ if (!txinfo.tx) {
continue;
}
- if (filterrate && feeRate.GetFeePerK() < filterrate) {
+ if (filterrate && txinfo.feeRate.GetFeePerK() < filterrate) {
continue;
}
- CTransaction tx;
- if (!mempool.lookup(hash, tx)) continue;
- if (pto->pfilter && !pto->pfilter->IsRelevantAndUpdate(tx)) continue;
+ if (pto->pfilter && !pto->pfilter->IsRelevantAndUpdate(*txinfo.tx)) continue;
// Send
vInv.push_back(CInv(MSG_TX, hash));
nRelayedTransactions++;
{
- LOCK(cs_mapRelay);
// Expire old relay messages
- while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
+ while (!vRelayExpiration.empty() && vRelayExpiration.front().first < nNow)
{
mapRelay.erase(vRelayExpiration.front().second);
vRelayExpiration.pop_front();
}
- auto ret = mapRelay.insert(std::make_pair(hash, tx));
+ auto ret = mapRelay.insert(std::make_pair(hash, std::move(txinfo.tx)));
if (ret.second) {
- vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, hash));
+ vRelayExpiration.push_back(std::make_pair(nNow + 15 * 60 * 1000000, ret.first));
}
}
if (vInv.size() == MAX_INV_SZ) {
diff --git a/src/main.h b/src/main.h
index 4e93c084f4..9b99ae7c87 100644
--- a/src/main.h
+++ b/src/main.h
@@ -482,6 +482,8 @@ extern CBlockTreeDB *pblocktree;
*/
int GetSpendHeight(const CCoinsViewCache& inputs);
+extern VersionBitsCache versionbitscache;
+
/**
* Determine what nVersion a new block should use.
*/
diff --git a/src/memusage.h b/src/memusage.h
index 49760e64c7..3810bfad07 100644
--- a/src/memusage.h
+++ b/src/memusage.h
@@ -5,6 +5,8 @@
#ifndef BITCOIN_MEMUSAGE_H
#define BITCOIN_MEMUSAGE_H
+#include "indirectmap.h"
+
#include <stdlib.h>
#include <map>
@@ -70,6 +72,15 @@ private:
X x;
};
+struct stl_shared_counter
+{
+ /* Various platforms use different sized counters here.
+ * Conservatively assume that they won't be larger than size_t. */
+ void* class_type;
+ size_t use_count;
+ size_t weak_count;
+};
+
template<typename X>
static inline size_t DynamicUsage(const std::vector<X>& v)
{
@@ -106,6 +117,35 @@ static inline size_t IncrementalDynamicUsage(const std::map<X, Y, Z>& m)
return MallocUsage(sizeof(stl_tree_node<std::pair<const X, Y> >));
}
+// indirectmap has underlying map with pointer as key
+
+template<typename X, typename Y>
+static inline size_t DynamicUsage(const indirectmap<X, Y>& m)
+{
+ return MallocUsage(sizeof(stl_tree_node<std::pair<const X*, Y> >)) * m.size();
+}
+
+template<typename X, typename Y>
+static inline size_t IncrementalDynamicUsage(const indirectmap<X, Y>& m)
+{
+ return MallocUsage(sizeof(stl_tree_node<std::pair<const X*, Y> >));
+}
+
+template<typename X>
+static inline size_t DynamicUsage(const std::unique_ptr<X>& p)
+{
+ return p ? MallocUsage(sizeof(X)) : 0;
+}
+
+template<typename X>
+static inline size_t DynamicUsage(const std::shared_ptr<X>& p)
+{
+ // A shared_ptr can either use a single continuous memory block for both
+ // the counter and the storage (when using std::make_shared), or separate.
+ // We can't observe the difference, however, so assume the worst.
+ return p ? MallocUsage(sizeof(X)) + MallocUsage(sizeof(stl_shared_counter)) : 0;
+}
+
// Boost data structures
template<typename X>
diff --git a/src/net.cpp b/src/net.cpp
index c09e3aedb6..173eba57c8 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -14,6 +14,7 @@
#include "clientversion.h"
#include "consensus/consensus.h"
#include "crypto/common.h"
+#include "crypto/sha256.h"
#include "hash.h"
#include "primitives/transaction.h"
#include "scheduler.h"
@@ -365,7 +366,7 @@ CNode* FindNode(const CService& addr)
return NULL;
}
-CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
+CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure)
{
if (pszDest == NULL) {
if (IsLocal(addrConnect))
@@ -397,7 +398,7 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
return NULL;
}
- addrman.Attempt(addrConnect);
+ addrman.Attempt(addrConnect, fCountFailure);
// Add node
CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false);
@@ -414,7 +415,7 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
} else if (!proxyConnectionFailed) {
// If connecting to the node failed, and failure is not caused by a problem connecting to
// the proxy, mark this as an attempt.
- addrman.Attempt(addrConnect);
+ addrman.Attempt(addrConnect, fCountFailure);
}
return NULL;
@@ -838,6 +839,7 @@ struct NodeEvictionCandidate
int64_t nTimeConnected;
int64_t nMinPingUsecTime;
CAddress addr;
+ uint64_t nKeyedNetGroup;
};
static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
@@ -850,36 +852,8 @@ static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, cons
return a.nTimeConnected > b.nTimeConnected;
}
-class CompareNetGroupKeyed
-{
- std::vector<unsigned char> vchSecretKey;
-public:
- CompareNetGroupKeyed()
- {
- vchSecretKey.resize(32, 0);
- GetRandBytes(vchSecretKey.data(), vchSecretKey.size());
- }
-
- bool operator()(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
- {
- std::vector<unsigned char> vchGroupA, vchGroupB;
- CSHA256 hashA, hashB;
- std::vector<unsigned char> vchA(32), vchB(32);
-
- vchGroupA = a.addr.GetGroup();
- vchGroupB = b.addr.GetGroup();
-
- hashA.Write(begin_ptr(vchGroupA), vchGroupA.size());
- hashB.Write(begin_ptr(vchGroupB), vchGroupB.size());
-
- hashA.Write(begin_ptr(vchSecretKey), vchSecretKey.size());
- hashB.Write(begin_ptr(vchSecretKey), vchSecretKey.size());
-
- hashA.Finalize(begin_ptr(vchA));
- hashB.Finalize(begin_ptr(vchB));
-
- return vchA < vchB;
- }
+static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) {
+ return a.nKeyedNetGroup < b.nKeyedNetGroup;
};
/** Try to find a connection to evict when the node is full.
@@ -902,7 +876,7 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) {
continue;
if (node->fDisconnect)
continue;
- NodeEvictionCandidate candidate = {node->id, node->nTimeConnected, node->nMinPingUsecTime, node->addr};
+ NodeEvictionCandidate candidate = {node->id, node->nTimeConnected, node->nMinPingUsecTime, node->addr, node->nKeyedNetGroup};
vEvictionCandidates.push_back(candidate);
}
}
@@ -912,9 +886,8 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) {
// Protect connections with certain characteristics
// Deterministically select 4 peers to protect by netgroup.
- // An attacker cannot predict which netgroups will be protected.
- static CompareNetGroupKeyed comparerNetGroupKeyed;
- std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), comparerNetGroupKeyed);
+ // An attacker cannot predict which netgroups will be protected
+ std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNetGroupKeyed);
vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
if (vEvictionCandidates.empty()) return false;
@@ -935,24 +908,24 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) {
// Identify the network group with the most connections and youngest member.
// (vEvictionCandidates is already sorted by reverse connect time)
- std::vector<unsigned char> naMostConnections;
+ uint64_t naMostConnections;
unsigned int nMostConnections = 0;
int64_t nMostConnectionsTime = 0;
- std::map<std::vector<unsigned char>, std::vector<NodeEvictionCandidate> > mapAddrCounts;
+ std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapAddrCounts;
BOOST_FOREACH(const NodeEvictionCandidate &node, vEvictionCandidates) {
- mapAddrCounts[node.addr.GetGroup()].push_back(node);
- int64_t grouptime = mapAddrCounts[node.addr.GetGroup()][0].nTimeConnected;
- size_t groupsize = mapAddrCounts[node.addr.GetGroup()].size();
+ mapAddrCounts[node.nKeyedNetGroup].push_back(node);
+ int64_t grouptime = mapAddrCounts[node.nKeyedNetGroup][0].nTimeConnected;
+ size_t groupsize = mapAddrCounts[node.nKeyedNetGroup].size();
if (groupsize > nMostConnections || (groupsize == nMostConnections && grouptime > nMostConnectionsTime)) {
nMostConnections = groupsize;
nMostConnectionsTime = grouptime;
- naMostConnections = node.addr.GetGroup();
+ naMostConnections = node.nKeyedNetGroup;
}
}
// Reduce to the network group with the most connections
- vEvictionCandidates = mapAddrCounts[naMostConnections];
+ vEvictionCandidates = std::move(mapAddrCounts[naMostConnections]);
// Do not disconnect peers if there is only one unprotected connection from their network group.
// This step excessively favors netgroup diversity, and should be removed once more protective criteria are established.
@@ -1464,12 +1437,13 @@ void ThreadDNSAddressSeed()
} else {
std::vector<CNetAddr> vIPs;
std::vector<CAddress> vAdd;
- if (LookupHost(seed.host.c_str(), vIPs, 0, true))
+ uint64_t requiredServiceBits = NODE_NETWORK;
+ if (LookupHost(seed.getHost(requiredServiceBits).c_str(), vIPs, 0, true))
{
BOOST_FOREACH(const CNetAddr& ip, vIPs)
{
int nOneDay = 24*3600;
- CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()));
+ CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()), requiredServiceBits);
addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
vAdd.push_back(addr);
found++;
@@ -1531,7 +1505,7 @@ void static ProcessOneShot()
CAddress addr;
CSemaphoreGrant grant(*semOutbound, true);
if (grant) {
- if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
+ if (!OpenNetworkConnection(addr, false, &grant, strDest.c_str(), true))
AddOneShot(strDest);
}
}
@@ -1547,7 +1521,7 @@ void ThreadOpenConnections()
BOOST_FOREACH(const std::string& strAddr, mapMultiArgs["-connect"])
{
CAddress addr;
- OpenNetworkConnection(addr, NULL, strAddr.c_str());
+ OpenNetworkConnection(addr, false, NULL, strAddr.c_str());
for (int i = 0; i < 10 && i < nLoop; i++)
{
MilliSleep(500);
@@ -1631,7 +1605,7 @@ void ThreadOpenConnections()
}
if (addrConnect.IsValid())
- OpenNetworkConnection(addrConnect, &grant);
+ OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant);
}
}
@@ -1653,7 +1627,7 @@ void ThreadOpenAddedConnections()
BOOST_FOREACH(const std::string& strAddNode, lAddresses) {
CAddress addr;
CSemaphoreGrant grant(*semOutbound);
- OpenNetworkConnection(addr, &grant, strAddNode.c_str());
+ OpenNetworkConnection(addr, false, &grant, strAddNode.c_str());
MilliSleep(500);
}
MilliSleep(120000); // Retry every 2 minutes
@@ -1692,7 +1666,7 @@ void ThreadOpenAddedConnections()
BOOST_FOREACH(std::vector<CService>& vserv, lservAddressesToAdd)
{
CSemaphoreGrant grant(*semOutbound);
- OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant);
+ OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), false, &grant);
MilliSleep(500);
}
MilliSleep(120000); // Retry every 2 minutes
@@ -1700,7 +1674,7 @@ void ThreadOpenAddedConnections()
}
// if successful, this moves the passed grant to the constructed node
-bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot)
+bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot)
{
//
// Initiate outbound network connection
@@ -1714,7 +1688,7 @@ bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOu
} else if (FindNode(std::string(pszDest)))
return false;
- CNode* pnode = ConnectNode(addrConnect, pszDest);
+ CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure);
boost::this_thread::interruption_point();
if (!pnode)
@@ -2345,6 +2319,8 @@ unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", DEFAULT_MAX
CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) :
ssSend(SER_NETWORK, INIT_PROTO_VERSION),
+ addr(addrIn),
+ nKeyedNetGroup(CalculateKeyedNetGroup(addrIn)),
addrKnown(5000, 0.001),
filterInventoryKnown(50000, 0.000001)
{
@@ -2357,7 +2333,6 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa
nRecvBytes = 0;
nTimeConnected = GetTime();
nTimeOffset = 0;
- addr = addrIn;
addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
nVersion = 0;
strSubVer = "";
@@ -2624,3 +2599,13 @@ bool CBanDB::Read(banmap_t& banSet)
int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) {
return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
}
+
+/* static */ uint64_t CNode::CalculateKeyedNetGroup(const CAddress& ad)
+{
+ static const uint64_t k0 = GetRand(std::numeric_limits<uint64_t>::max());
+ static const uint64_t k1 = GetRand(std::numeric_limits<uint64_t>::max());
+
+ std::vector<unsigned char> vchNetGroup(ad.GetGroup());
+
+ return CSipHasher(k0, k1).Write(&vchNetGroup[0], vchNetGroup.size()).Finalize();
+}
diff --git a/src/net.h b/src/net.h
index 403653e8c8..5c1f7e3e89 100644
--- a/src/net.h
+++ b/src/net.h
@@ -84,7 +84,7 @@ CNode* FindNode(const CNetAddr& ip);
CNode* FindNode(const CSubNet& subNet);
CNode* FindNode(const std::string& addrName);
CNode* FindNode(const CService& ip);
-bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
+bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
void MapPort(bool fUseUPnP);
unsigned short GetListenPort();
bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false);
@@ -335,7 +335,7 @@ public:
int64_t nLastRecv;
int64_t nTimeConnected;
int64_t nTimeOffset;
- CAddress addr;
+ const CAddress addr;
std::string addrName;
CService addrLocal;
int nVersion;
@@ -362,6 +362,8 @@ public:
CBloomFilter* pfilter;
int nRefCount;
NodeId id;
+
+ const uint64_t nKeyedNetGroup;
protected:
// Denial-of-service detection/prevention
@@ -450,6 +452,8 @@ private:
CNode(const CNode&);
void operator=(const CNode&);
+ static uint64_t CalculateKeyedNetGroup(const CAddress& ad);
+
public:
NodeId GetId() const {
diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp
index 41f1d5841a..23be8e016b 100644
--- a/src/qt/bitcoinstrings.cpp
+++ b/src/qt/bitcoinstrings.cpp
@@ -1,26 +1,35 @@
-// Copyright (c) 2013-2015 The Bitcoin Core developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
#include <QtGlobal>
-// Automatically generated by extract_strings.py
+// Automatically generated by extract_strings_qt.py
#ifdef __GNUC__
#define UNUSED __attribute__((unused))
#else
#define UNUSED
#endif
static const char UNUSED *bitcoin_strings[] = {
+QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin Core"),
+QT_TRANSLATE_NOOP("bitcoin-core", "The %s developers"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"(1 = keep tx meta data e.g. account owner and payment request information, 2 "
"= drop tx meta data)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"-fallbackfee is set very high! This is the transaction fee you may pay when "
+"fee estimates are not available."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
"-maxtxfee is set very high! Fees this large could be paid on a single "
"transaction."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"-paytxfee is set very high! This is the transaction fee you will pay if you "
"send a transaction."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"A fee rate (in %s/kB) that will be used when fee estimation has insufficient "
+"data (default: %s)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Accept relayed transactions received from whitelisted peers even when not "
+"relaying transactions (default: %d)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
"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"),
@@ -35,8 +44,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"notation for IPv6. This option can be specified multiple times (default: "
"bind to all interfaces)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Cannot obtain a lock on data directory %s. Bitcoin Core is probably already "
-"running."),
+"Cannot obtain a lock on data directory %s. %s is probably already running."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Create new files with system default permissions, instead of umask 077 (only "
"effective with disabled wallet functionality)"),
@@ -52,8 +60,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Do not keep transactions in the mempool longer than <n> hours (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Error reading wallet.dat! All keys read correctly, but transaction data or "
-"address book entries might be missing or incorrect."),
+"Error reading %s! All keys read correctly, but transaction data or address "
+"book entries might be missing or incorrect."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Error: Listening for incoming connections failed (listen returned error %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
@@ -72,6 +80,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Fees (in %s/kB) smaller than this are considered zero fee for transaction "
"creation (default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Force relay of transactions from whitelisted peers even they violate local "
+"relay policy (default: %d)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
"How thorough the block verification of -checkblocks is (0-4, default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"If <category> is not supplied or if <category> = 1, output all debugging "
@@ -86,18 +97,22 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Maintain a full transaction index, used by the getrawtransaction rpc call "
"(default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"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)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
"Maximum size of data in data carrier transactions we relay and mine "
"(default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Maximum total fees (in %s) to use in a single wallet transaction; setting "
-"this too low may abort large transactions (default: %s)"),
+"Maximum total fees (in %s) to use in a single wallet transaction or raw "
+"transaction; setting this too low may abort large transactions (default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Number of seconds to keep misbehaving peers from reconnecting (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Output debugging information (default: %u, supplying <category> is optional)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Please check that your computer's date and time are correct! If your clock "
-"is wrong Bitcoin Core will not work properly."),
+"is wrong, %s will not work properly."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Prune configured below the minimum of %d MiB. Please use a higher number."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
@@ -123,11 +138,10 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Set the number of script verification threads (%u to %d, 0 = auto, <0 = "
"leave that many cores free, default: %d)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Set the number of threads for coin generation if enabled (-1 = all cores, "
-"default: %d)"),
-QT_TRANSLATE_NOOP("bitcoin-core", ""
"Support filtering of blocks and transaction with bloom filters (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Tell other nodes to filter invs to us by our mempool min fee (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
"The block database contains a block which appears to be from the future. "
"This may be due to your computer's date and time being set incorrectly. Only "
"rebuild the block database if you are sure that your computer's date and "
@@ -148,12 +162,12 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = "
"no limit (default: %d)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Unable to bind to %s on this computer. Bitcoin Core is probably already "
-"running."),
-QT_TRANSLATE_NOOP("bitcoin-core", ""
"Unsupported argument -socks found. Setting SOCKS version isn't possible "
"anymore, only SOCKS5 proxies are supported."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/"
+"or -whitelistforcerelay."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
"Use UPnP to map the listening port (default: 1 when listening and no -proxy)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: "
@@ -172,13 +186,16 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: The network does not appear to fully agree! Some miners appear to "
"be experiencing issues."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Warning: Unknown block versions being mined! It's possible unknown rules are "
+"in effect"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"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."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: We do not appear to fully agree with our peers! You may need to "
"upgrade, or other nodes may need to upgrade."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as "
-"wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect "
-"you should restore from a backup."),
-QT_TRANSLATE_NOOP("bitcoin-core", ""
"Whitelist peers connecting from the given netmask or IP address. Can be "
"specified multiple times."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
@@ -187,6 +204,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
QT_TRANSLATE_NOOP("bitcoin-core", ""
"You need to rebuild the database using -reindex to go back to unpruned "
"mode. This will redownload the entire blockchain"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"You need to rebuild the database using -reindex-chainstate to change -txindex"),
+QT_TRANSLATE_NOOP("bitcoin-core", "%s corrupt, salvage failed"),
QT_TRANSLATE_NOOP("bitcoin-core", "(default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "(default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "-maxmempool must be at least %d MB"),
@@ -194,24 +214,22 @@ QT_TRANSLATE_NOOP("bitcoin-core", "<category> can be:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands"),
QT_TRANSLATE_NOOP("bitcoin-core", "Accept connections from outside (default: 1 if no -proxy or -connect)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Accept public REST requests (default: %u)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Activating best chain..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Add a node to connect to and attempt to keep the connection open"),
QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for -addnode, -seednode and -connect"),
QT_TRANSLATE_NOOP("bitcoin-core", "Always query for peer addresses via DNS lookup (default: %u)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Always relay transactions received from whitelisted peers (default: %d)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Attempt to recover private keys from a corrupt wallet.dat on startup"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Append comment to the user agent string"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Attempt to recover private keys from a corrupt wallet on startup"),
QT_TRANSLATE_NOOP("bitcoin-core", "Automatically create Tor hidden service (default: %d)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Block creation options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot downgrade wallet"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -bind address: '%s'"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -externalip address: '%s'"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -whitebind address: '%s'"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -%s address: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot write default address"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Change index out of range"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connect only to the specified node(s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connect through SOCKS5 proxy"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connect to a node to retrieve peer addresses, and disconnect"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connection options:"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Copyright (C) 2009-%i The Bitcoin Core Developers"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Copyright (C) %i-%i"),
QT_TRANSLATE_NOOP("bitcoin-core", "Corrupted block database detected"),
QT_TRANSLATE_NOOP("bitcoin-core", "Debugging/Testing options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Do not load the wallet and disable wallet RPC calls"),
@@ -221,12 +239,13 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Enable publish hash block in <address>"),
QT_TRANSLATE_NOOP("bitcoin-core", "Enable publish hash transaction in <address>"),
QT_TRANSLATE_NOOP("bitcoin-core", "Enable publish raw block in <address>"),
QT_TRANSLATE_NOOP("bitcoin-core", "Enable publish raw transaction in <address>"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Enable transaction replacement in the memory pool (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error initializing block database"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error initializing wallet database environment %s!"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error loading %s"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error loading %s: Wallet corrupted"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error loading %s: Wallet requires newer version of %s"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading block database"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet corrupted"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet requires newer version of Bitcoin Core"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error opening block database"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error reading from database, shutting down."),
QT_TRANSLATE_NOOP("bitcoin-core", "Error"),
@@ -234,34 +253,34 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Error: A fatal internal error occurred, see d
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Disk space is low!"),
QT_TRANSLATE_NOOP("bitcoin-core", "Failed to listen on any port. Use -listen=0 if you want this."),
QT_TRANSLATE_NOOP("bitcoin-core", "Fee (in %s/kB) to add to transactions you send (default: %s)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "How many blocks to check at startup (default: %u, 0 = all)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Importing..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Imports blocks from external blk000??.dat file on startup"),
QT_TRANSLATE_NOOP("bitcoin-core", "Include IP addresses in debug output (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Incorrect or no genesis block found. Wrong datadir for network?"),
QT_TRANSLATE_NOOP("bitcoin-core", "Information"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Initialization sanity check failed. Bitcoin Core is shutting down."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Initialization sanity check failed. %s is shutting down."),
QT_TRANSLATE_NOOP("bitcoin-core", "Insufficient funds"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -onion address: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -proxy address: '%s'"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -maxtxfee=<amount>: '%s'"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -minrelaytxfee=<amount>: '%s'"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -mintxfee=<amount>: '%s'"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -%s=<amount>: '%s'"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -fallbackfee=<amount>: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid netmask specified in -whitelist: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most <n> unconnectable transactions in memory (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Keep the transaction memory pool below <n> megabytes (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on <port> (default: %u or testnet: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Loading banlist..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading block index..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading wallet..."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Location of the auth cookie (default: data dir)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Maintain at most <n> connections to peers (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Make the wallet broadcast transactions"),
QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Minimum bytes per sigop in transactions we relay and mine (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Need to specify a port with -whitebind: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Node relay options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Not enough file descriptors available."),
@@ -269,12 +288,14 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network <net> (ipv4,
QT_TRANSLATE_NOOP("bitcoin-core", "Options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Password for JSON-RPC connections"),
QT_TRANSLATE_NOOP("bitcoin-core", "Prepend debug output with timestamp (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Print this help message and exit"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Print version and exit"),
QT_TRANSLATE_NOOP("bitcoin-core", "Prune cannot be configured with a negative value."),
QT_TRANSLATE_NOOP("bitcoin-core", "Prune mode is incompatible with -txindex."),
QT_TRANSLATE_NOOP("bitcoin-core", "Pruning blockstore..."),
QT_TRANSLATE_NOOP("bitcoin-core", "RPC server options:"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Rebuild block chain index from current blk000??.dat files on startup"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Receive and display P2P network alerts (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Rebuild chain state and block index from the blk*.dat files on disk"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Rebuild chain state from the currently indexed blocks"),
QT_TRANSLATE_NOOP("bitcoin-core", "Reducing -maxconnections from %d to %d, because of system limitations."),
QT_TRANSLATE_NOOP("bitcoin-core", "Relay and mine data carrier transactions (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Relay non-P2SH multisig (default: %u)"),
@@ -299,7 +320,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Specify wallet file (within data directory)")
QT_TRANSLATE_NOOP("bitcoin-core", "Specify your own public address"),
QT_TRANSLATE_NOOP("bitcoin-core", "Spend unconfirmed change when sending transactions (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "The transaction amount is too small to pay the fee"),
-QT_TRANSLATE_NOOP("bitcoin-core", "This help message"),
QT_TRANSLATE_NOOP("bitcoin-core", "This is experimental software."),
QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Tor control port password (default: empty)"),
@@ -309,6 +329,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amounts must be positive"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large for fee policy"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large"),
QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer (bind returned error %s)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer. %s is probably already running."),
QT_TRANSLATE_NOOP("bitcoin-core", "Unable to start HTTP server. See debug log for details."),
QT_TRANSLATE_NOOP("bitcoin-core", "Unknown network specified in -onlynet: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Unsupported argument -benchmark ignored, use -debug=bench."),
@@ -321,13 +342,12 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections"),
QT_TRANSLATE_NOOP("bitcoin-core", "Verifying blocks..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Verifying wallet..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Wallet %s resides outside data directory %s"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Wallet needed to be rewritten: restart Bitcoin Core to complete"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Wallet debugging/testing options:"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Wallet needed to be rewritten: restart %s to complete"),
QT_TRANSLATE_NOOP("bitcoin-core", "Wallet options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Warning"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Warning: This version is obsolete; upgrade required!"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Warning: unknown new rules activated (versionbit %i)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Whether to operate in a blocks only mode (default: %u)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "You need to rebuild the database using -reindex to change -txindex"),
QT_TRANSLATE_NOOP("bitcoin-core", "Zapping all transactions from wallet..."),
QT_TRANSLATE_NOOP("bitcoin-core", "ZeroMQ notification options:"),
-QT_TRANSLATE_NOOP("bitcoin-core", "wallet.dat corrupt, salvage failed"),
};
diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts
index 00411741f1..5549ccd4f8 100644
--- a/src/qt/locale/bitcoin_en.ts
+++ b/src/qt/locale/bitcoin_en.ts
@@ -165,7 +165,7 @@
<translation>Repeat new passphrase</translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="+45"/>
+ <location filename="../askpassphrasedialog.cpp" line="+49"/>
<source>Encrypt wallet</source>
<translation>Encrypt wallet</translation>
</message>
@@ -195,7 +195,7 @@
<translation>Change passphrase</translation>
</message>
<message>
- <location line="+46"/>
+ <location line="+45"/>
<source>Confirm wallet encryption</source>
<translation>Confirm wallet encryption</translation>
</message>
@@ -210,12 +210,7 @@
<translation>Are you sure you wish to encrypt your wallet?</translation>
</message>
<message>
- <location line="+11"/>
- <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+4"/>
+ <location line="+15"/>
<source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
<translation>IMPORTANT: 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.</translation>
</message>
@@ -232,7 +227,7 @@
<translation>Wallet encrypted</translation>
</message>
<message>
- <location line="-136"/>
+ <location line="-135"/>
<source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
<translation type="unfinished"></translation>
</message>
@@ -242,7 +237,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+70"/>
+ <location line="+56"/>
+ <source>%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.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+13"/>
<location line="+7"/>
<location line="+42"/>
<location line="+6"/>
@@ -299,17 +299,17 @@
<context>
<name>BitcoinGUI</name>
<message>
- <location filename="../bitcoingui.cpp" line="+335"/>
+ <location filename="../bitcoingui.cpp" line="+341"/>
<source>Sign &amp;message...</source>
<translation>Sign &amp;message...</translation>
</message>
<message>
- <location line="+362"/>
+ <location line="+377"/>
<source>Synchronizing with network...</source>
<translation>Synchronizing with network...</translation>
</message>
<message>
- <location line="-438"/>
+ <location line="-455"/>
<source>&amp;Overview</source>
<translation>&amp;Overview</translation>
</message>
@@ -344,7 +344,17 @@
<translation>Quit application</translation>
</message>
<message>
- <location line="+6"/>
+ <location line="+3"/>
+ <source>&amp;About %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Show information about %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
<source>About &amp;Qt</source>
<translation>About &amp;Qt</translation>
</message>
@@ -359,6 +369,11 @@
<translation>&amp;Options...</translation>
</message>
<message>
+ <location line="+1"/>
+ <source>Modify configuration options for %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<location line="+6"/>
<source>&amp;Encrypt Wallet...</source>
<translation>&amp;Encrypt Wallet...</translation>
@@ -374,7 +389,7 @@
<translation>&amp;Change Passphrase...</translation>
</message>
<message>
- <location line="+10"/>
+ <location line="+12"/>
<source>&amp;Sending addresses...</source>
<translation type="unfinished"></translation>
</message>
@@ -389,27 +404,17 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+183"/>
- <source>Bitcoin Core client</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+169"/>
- <source>Importing blocks from disk...</source>
- <translation>Importing blocks from disk...</translation>
- </message>
- <message>
- <location line="+3"/>
+ <location line="+372"/>
<source>Reindexing blocks on disk...</source>
<translation>Reindexing blocks on disk...</translation>
</message>
<message>
- <location line="-436"/>
+ <location line="-457"/>
<source>Send coins to a Bitcoin address</source>
<translation>Send coins to a Bitcoin address</translation>
</message>
<message>
- <location line="+65"/>
+ <location line="+67"/>
<source>Backup wallet to another location</source>
<translation>Backup wallet to another location</translation>
</message>
@@ -434,12 +439,12 @@
<translation>&amp;Verify message...</translation>
</message>
<message>
- <location line="+459"/>
+ <location line="+481"/>
<source>Bitcoin</source>
<translation>Bitcoin</translation>
</message>
<message>
- <location line="-669"/>
+ <location line="-693"/>
<source>Wallet</source>
<translation>Wallet</translation>
</message>
@@ -454,12 +459,7 @@
<translation>&amp;Receive</translation>
</message>
<message>
- <location line="+40"/>
- <source>Show information about Bitcoin Core</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+8"/>
+ <location line="+50"/>
<source>&amp;Show / Hide</source>
<translation>&amp;Show / Hide</translation>
</message>
@@ -484,7 +484,7 @@
<translation>Verify messages to ensure they were signed with specified Bitcoin addresses</translation>
</message>
<message>
- <location line="+56"/>
+ <location line="+58"/>
<source>&amp;File</source>
<translation>&amp;File</translation>
</message>
@@ -504,27 +504,12 @@
<translation>Tabs toolbar</translation>
</message>
<message>
- <location line="-314"/>
- <source>Bitcoin Core</source>
- <translation type="unfinished">Bitcoin Core</translation>
- </message>
- <message>
- <location line="+160"/>
+ <location line="-158"/>
<source>Request payments (generates QR codes and bitcoin: URIs)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+38"/>
- <source>&amp;About Bitcoin Core</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+7"/>
- <source>Modify configuration options for Bitcoin Core</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+21"/>
+ <location line="+70"/>
<source>Show the list of used sending addresses and labels</source>
<translation type="unfinished"></translation>
</message>
@@ -543,13 +528,8 @@
<source>&amp;Command-line options</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <location line="+2"/>
- <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
- <translation type="unfinished"></translation>
- </message>
<message numerus="yes">
- <location line="+329"/>
+ <location line="+341"/>
<source>%n active connection(s) to Bitcoin network</source>
<translation>
<numerusform>%n active connection to Bitcoin network</numerusform>
@@ -557,7 +537,17 @@
</translation>
</message>
<message>
- <location line="+25"/>
+ <location line="+22"/>
+ <source>Indexing blocks on disk...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Processing blocks on disk...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+11"/>
<source>No block source available...</source>
<translation>No block source available...</translation>
</message>
@@ -643,12 +633,22 @@
<translation>Up to date</translation>
</message>
<message>
- <location line="+44"/>
+ <location line="-388"/>
+ <source>Show the %1 help message to get a list with possible Bitcoin command-line options</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+188"/>
+ <source>%1 client</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+244"/>
<source>Catching up...</source>
<translation>Catching up...</translation>
</message>
<message>
- <location line="+129"/>
+ <location line="+137"/>
<source>Date: %1
</source>
<translation type="unfinished"></translation>
@@ -699,14 +699,6 @@
</message>
</context>
<context>
- <name>ClientModel</name>
- <message>
- <location filename="../clientmodel.cpp" line="+135"/>
- <source>Network Alert</source>
- <translation>Network Alert</translation>
- </message>
-</context>
-<context>
<name>CoinControlDialog</name>
<message>
<location filename="../forms/coincontroldialog.ui" line="+14"/>
@@ -870,7 +862,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+351"/>
+ <location line="+349"/>
<source>highest</source>
<translation type="unfinished"></translation>
</message>
@@ -935,12 +927,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
- <source>This label turns red if any recipient receives an amount smaller than %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+9"/>
+ <location line="+12"/>
<source>Can vary +/- %1 satoshi(s) per input.</source>
<translation type="unfinished"></translation>
</message>
@@ -971,7 +958,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+59"/>
+ <location line="+4"/>
+ <source>This label turns red if any recipient receives an amount smaller than the current dust threshold.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+55"/>
<location line="+60"/>
<source>(no label)</source>
<translation type="unfinished">(no label)</translation>
@@ -1058,7 +1050,7 @@
<context>
<name>FreespaceChecker</name>
<message>
- <location filename="../intro.cpp" line="+68"/>
+ <location filename="../intro.cpp" line="+78"/>
<source>A new data directory will be created.</source>
<translation>A new data directory will be created.</translation>
</message>
@@ -1086,12 +1078,7 @@
<context>
<name>HelpMessageDialog</name>
<message>
- <location filename="../utilitydialog.cpp" line="+36"/>
- <source>Bitcoin Core</source>
- <translation type="unfinished">Bitcoin Core</translation>
- </message>
- <message>
- <location line="+0"/>
+ <location filename="../utilitydialog.cpp" line="+40"/>
<source>version</source>
<translation type="unfinished">version</translation>
</message>
@@ -1103,7 +1090,7 @@
</message>
<message>
<location line="+5"/>
- <source>About Bitcoin Core</source>
+ <source>About %1</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1166,17 +1153,17 @@
</message>
<message>
<location line="+9"/>
- <source>Welcome to Bitcoin Core.</source>
+ <source>Welcome to %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+26"/>
- <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <source>As this is the first time the program is launched, you can choose where %1 will store its data.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+10"/>
- <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <source>%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.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1190,12 +1177,7 @@
<translation>Use a custom data directory:</translation>
</message>
<message>
- <location filename="../intro.cpp" line="+82"/>
- <source>Bitcoin Core</source>
- <translation type="unfinished">Bitcoin Core</translation>
- </message>
- <message>
- <location line="+1"/>
+ <location filename="../intro.cpp" line="+89"/>
<source>Error: Specified data directory &quot;%1&quot; cannot be created.</source>
<translation type="unfinished"></translation>
</message>
@@ -1262,7 +1244,17 @@
<translation>&amp;Main</translation>
</message>
<message>
- <location line="+18"/>
+ <location line="+6"/>
+ <source>Automatically start %1 after logging in to the system.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>&amp;Start %1 on system login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+9"/>
<source>Size of &amp;database cache</source>
<translation type="unfinished"></translation>
</message>
@@ -1293,17 +1285,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+84"/>
+ <location line="+94"/>
<source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+45"/>
- <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+35"/>
+ <location line="+80"/>
<location line="+13"/>
<source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
<translation type="unfinished"></translation>
@@ -1329,22 +1316,12 @@
<translation>&amp;Reset Options</translation>
</message>
<message>
- <location line="-504"/>
+ <location line="-514"/>
<source>&amp;Network</source>
<translation>&amp;Network</translation>
</message>
<message>
- <location line="-153"/>
- <source>Automatically start Bitcoin Core after logging in to the system.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+3"/>
- <source>&amp;Start Bitcoin Core on system login</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+65"/>
+ <location line="-85"/>
<source>(0 = auto, &lt;0 = leave that many cores free)</source>
<translation type="unfinished"></translation>
</message>
@@ -1455,6 +1432,16 @@
</message>
<message>
<location line="+6"/>
+ <source>&amp;Hide the icon from the system tray.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Hide tray icon</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
<source>Show only a tray icon after minimizing the window.</source>
<translation>Show only a tray icon after minimizing the window.</translation>
</message>
@@ -1479,7 +1466,12 @@
<translation>User Interface &amp;language:</translation>
</message>
<message>
- <location line="+24"/>
+ <location line="+13"/>
+ <source>The user interface language can be set here. This setting will take effect after restarting %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+11"/>
<source>&amp;Unit to show amounts in:</source>
<translation>&amp;Unit to show amounts in:</translation>
</message>
@@ -1489,12 +1481,12 @@
<translation>Choose the default subdivision unit to show in the interface and when sending coins.</translation>
</message>
<message>
- <location line="-440"/>
+ <location line="-450"/>
<source>Whether to show coin control features or not.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+602"/>
+ <location line="+612"/>
<source>&amp;OK</source>
<translation>&amp;OK</translation>
</message>
@@ -1504,7 +1496,7 @@
<translation>&amp;Cancel</translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="+81"/>
+ <location filename="../optionsdialog.cpp" line="+86"/>
<source>default</source>
<translation>default</translation>
</message>
@@ -1514,23 +1506,23 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+71"/>
+ <location line="+72"/>
<source>Confirm options reset</source>
<translation>Confirm options reset</translation>
</message>
<message>
<location line="+1"/>
- <location line="+30"/>
+ <location line="+43"/>
<source>Client restart required to activate changes.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-30"/>
+ <location line="-43"/>
<source>Client will be shut down. Do you want to proceed?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+34"/>
+ <location line="+47"/>
<source>This change would require a client restart.</source>
<translation type="unfinished"></translation>
</message>
@@ -1781,12 +1773,12 @@
<context>
<name>QObject</name>
<message>
- <location filename="../bitcoinunits.cpp" line="+183"/>
+ <location filename="../bitcoinunits.cpp" line="+176"/>
<source>Amount</source>
<translation type="unfinished">Amount</translation>
</message>
<message>
- <location filename="../guiutil.cpp" line="+110"/>
+ <location filename="../guiutil.cpp" line="+118"/>
<source>Enter a Bitcoin address (e.g. %1)</source>
<translation type="unfinished"></translation>
</message>
@@ -1807,7 +1799,7 @@
</message>
<message>
<location line="+2"/>
- <location line="+41"/>
+ <location line="+44"/>
<source>%1 s</source>
<translation type="unfinished"></translation>
</message>
@@ -1862,16 +1854,15 @@
<location line="+23"/>
<location line="+26"/>
<location line="+26"/>
- <location line="+26"/>
- <location line="+23"/>
- <location line="+23"/>
- <location line="+23"/>
<location line="+23"/>
+ <location line="+26"/>
<location line="+36"/>
<location line="+23"/>
<location line="+36"/>
+ <location line="+23"/>
<location line="+36"/>
- <location line="+534"/>
+ <location line="+23"/>
+ <location line="+663"/>
<location line="+23"/>
<location line="+23"/>
<location line="+23"/>
@@ -1892,7 +1883,7 @@
<translation>N/A</translation>
</message>
<message>
- <location line="-1216"/>
+ <location line="-1322"/>
<source>Client version</source>
<translation>Client version</translation>
</message>
@@ -1913,26 +1904,26 @@
</message>
<message>
<location line="+79"/>
- <source>Using OpenSSL version</source>
- <translation>Using OpenSSL version</translation>
+ <source>Using BerkeleyDB version</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<location line="+26"/>
- <source>Using BerkeleyDB version</source>
+ <source>Datadir</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+49"/>
+ <location line="+26"/>
<source>Startup time</source>
<translation>Startup time</translation>
</message>
<message>
- <location line="+170"/>
+ <location line="+29"/>
<source>Network</source>
<translation>Network</translation>
</message>
<message>
- <location line="-147"/>
+ <location line="+7"/>
<source>Name</source>
<translation type="unfinished"></translation>
</message>
@@ -1962,41 +1953,36 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+36"/>
+ <location line="+23"/>
<source>Memory usage</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+48"/>
- <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+233"/>
- <location line="+552"/>
+ <location line="+404"/>
+ <location line="+558"/>
<source>Received</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-472"/>
- <location line="+449"/>
+ <location line="-478"/>
+ <location line="+455"/>
<source>Sent</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-408"/>
+ <location line="-414"/>
<source>&amp;Peers</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+50"/>
+ <location line="+53"/>
<source>Banned peers</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+57"/>
- <location filename="../rpcconsole.cpp" line="+287"/>
- <location line="+578"/>
+ <location line="+60"/>
+ <location filename="../rpcconsole.cpp" line="+295"/>
+ <location line="+635"/>
<source>Select a peer to view detailed information.</source>
<translation type="unfinished"></translation>
</message>
@@ -2031,13 +2017,28 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-973"/>
- <location line="+881"/>
+ <location line="-1079"/>
+ <location line="+987"/>
<source>User Agent</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+23"/>
+ <location line="-684"/>
+ <source>Open the %1 debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+68"/>
+ <source>Decrease font size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+29"/>
+ <source>Increase font size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+610"/>
<source>Services</source>
<translation type="unfinished"></translation>
</message>
@@ -2082,12 +2083,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-977"/>
+ <location line="-1093"/>
<source>Last block time</source>
<translation>Last block time</translation>
</message>
<message>
- <location line="+123"/>
+ <location line="+110"/>
<source>&amp;Open</source>
<translation>&amp;Open</translation>
</message>
@@ -2097,7 +2098,7 @@
<translation>&amp;Console</translation>
</message>
<message>
- <location line="+72"/>
+ <location line="+195"/>
<source>&amp;Network Traffic</source>
<translation type="unfinished"></translation>
</message>
@@ -2112,7 +2113,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../rpcconsole.cpp" line="-343"/>
+ <location filename="../rpcconsole.cpp" line="-342"/>
<source>In:</source>
<translation type="unfinished"></translation>
</message>
@@ -2122,22 +2123,17 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/debugwindow.ui" line="-417"/>
- <source>Build date</source>
- <translation>Build date</translation>
- </message>
- <message>
- <location line="+241"/>
+ <location filename="../forms/debugwindow.ui" line="-299"/>
<source>Debug log file</source>
<translation>Debug log file</translation>
</message>
<message>
- <location line="+85"/>
+ <location line="+136"/>
<source>Clear console</source>
<translation>Clear console</translation>
</message>
<message>
- <location filename="../rpcconsole.cpp" line="-156"/>
+ <location filename="../rpcconsole.cpp" line="-204"/>
<source>&amp;Disconnect Node</source>
<translation type="unfinished"></translation>
</message>
@@ -2175,8 +2171,8 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+70"/>
- <source>Welcome to the Bitcoin Core RPC console.</source>
+ <location line="+118"/>
+ <source>Welcome to the %1 RPC console.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2190,7 +2186,7 @@
<translation>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</translation>
</message>
<message>
- <location line="+144"/>
+ <location line="+146"/>
<source>%1 B</source>
<translation type="unfinished"></translation>
</message>
@@ -2444,9 +2440,14 @@
<translation type="unfinished">Message</translation>
</message>
<message>
- <location line="+99"/>
- <source>Amount</source>
- <translation type="unfinished">Amount</translation>
+ <location line="+57"/>
+ <source>(no amount requested)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+42"/>
+ <source>Requested</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<location line="-59"/>
@@ -2458,17 +2459,12 @@
<source>(no message)</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <location line="+8"/>
- <source>(no amount)</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>SendCoinsDialog</name>
<message>
<location filename="../forms/sendcoinsdialog.ui" line="+14"/>
- <location filename="../sendcoinsdialog.cpp" line="+546"/>
+ <location filename="../sendcoinsdialog.cpp" line="+543"/>
<source>Send Coins</source>
<translation>Send Coins</translation>
</message>
@@ -2615,17 +2611,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+38"/>
- <source>Send as zero-fee transaction if possible</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+7"/>
- <source>(confirmation may take longer)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+110"/>
+ <location line="+102"/>
<source>Send to multiple recipients at once</source>
<translation>Send to multiple recipients at once</translation>
</message>
@@ -2640,12 +2626,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-858"/>
+ <location line="-805"/>
<source>Dust:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+861"/>
+ <location line="+808"/>
<source>Clear &amp;All</source>
<translation>Clear &amp;All</translation>
</message>
@@ -2678,7 +2664,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-221"/>
+ <location line="-215"/>
<source>Copy quantity</source>
<translation type="unfinished"></translation>
</message>
@@ -2713,7 +2699,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+244"/>
+ <location line="+238"/>
<source>Total Amount %1</source>
<translation type="unfinished"></translation>
</message>
@@ -2758,12 +2744,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+91"/>
+ <location line="+89"/>
<source>Pay only the required fee of %1</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
- <location line="+23"/>
+ <location line="+25"/>
<source>Estimated to begin confirmation within %n block(s).</source>
<translation type="unfinished">
<numerusform>Estimated to begin confirmation within %n block.</numerusform>
@@ -2796,12 +2782,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-695"/>
+ <location line="-689"/>
<source>Copy dust</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+221"/>
+ <location line="+215"/>
<source>Are you sure you want to send?</source>
<translation type="unfinished"></translation>
</message>
@@ -2921,10 +2907,19 @@
</message>
</context>
<context>
+ <name>SendConfirmationDialog</name>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="+571"/>
+ <location line="+5"/>
+ <source>Yes</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ShutdownWindow</name>
<message>
<location filename="../utilitydialog.cpp" line="+78"/>
- <source>Bitcoin Core is shutting down...</source>
+ <source>%1 is shutting down...</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3118,16 +3113,6 @@
<context>
<name>SplashScreen</name>
<message>
- <location filename="../splashscreen.cpp" line="+41"/>
- <source>Bitcoin Core</source>
- <translation type="unfinished">Bitcoin Core</translation>
- </message>
- <message>
- <location line="+2"/>
- <source>The Bitcoin Core developers</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<location filename="../networkstyle.cpp" line="+19"/>
<source>[testnet]</source>
<translation>[testnet]</translation>
@@ -3149,14 +3134,29 @@
<translation>Open until %1</translation>
</message>
<message>
- <location line="+6"/>
- <source>conflicted</source>
- <translation type="unfinished"></translation>
+ <location line="+8"/>
+ <source>%1/offline</source>
+ <translation>%1/offline</translation>
</message>
<message>
<location line="+2"/>
- <source>%1/offline</source>
- <translation>%1/offline</translation>
+ <source>0/unconfirmed, %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>in memory pool</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>not in memory pool</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>abandoned</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<location line="+2"/>
@@ -3231,12 +3231,12 @@
<location line="+12"/>
<location line="+53"/>
<location line="+26"/>
- <location line="+53"/>
+ <location line="+54"/>
<source>Credit</source>
<translation>Credit</translation>
</message>
<message numerus="yes">
- <location line="-142"/>
+ <location line="-143"/>
<source>matures in %n more block(s)</source>
<translation>
<numerusform>matures in %n more block</numerusform>
@@ -3251,12 +3251,12 @@
<message>
<location line="+59"/>
<location line="+25"/>
- <location line="+53"/>
+ <location line="+54"/>
<source>Debit</source>
<translation>Debit</translation>
</message>
<message>
- <location line="-68"/>
+ <location line="-69"/>
<source>Total debit</source>
<translation type="unfinished"></translation>
</message>
@@ -3277,12 +3277,12 @@
</message>
<message>
<location line="+6"/>
- <location line="+9"/>
+ <location line="+10"/>
<source>Message</source>
<translation>Message</translation>
</message>
<message>
- <location line="-7"/>
+ <location line="-8"/>
<source>Comment</source>
<translation>Comment</translation>
</message>
@@ -3292,6 +3292,11 @@
<translation>Transaction ID</translation>
</message>
<message>
+ <location line="+1"/>
+ <source>Output index</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<location line="+18"/>
<source>Merchant</source>
<translation type="unfinished"></translation>
@@ -3334,12 +3339,12 @@
<translation>false</translation>
</message>
<message>
- <location line="-242"/>
+ <location line="-243"/>
<source>, has not been successfully broadcast yet</source>
<translation>, has not been successfully broadcast yet</translation>
</message>
<message numerus="yes">
- <location line="-36"/>
+ <location line="-38"/>
<source>Open for %n more block(s)</source>
<translation>
<numerusform>Open for %n more block</numerusform>
@@ -3347,7 +3352,12 @@
</translation>
</message>
<message>
- <location line="+67"/>
+ <location line="+8"/>
+ <source>conflicted with a transaction with %1 confirmations</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+61"/>
<source>unknown</source>
<translation>unknown</translation>
</message>
@@ -3355,15 +3365,15 @@
<context>
<name>TransactionDescDialog</name>
<message>
- <location filename="../forms/transactiondescdialog.ui" line="+14"/>
- <source>Transaction details</source>
- <translation>Transaction details</translation>
- </message>
- <message>
- <location line="+6"/>
+ <location filename="../forms/transactiondescdialog.ui" line="+20"/>
<source>This pane shows a detailed description of the transaction</source>
<translation>This pane shows a detailed description of the transaction</translation>
</message>
+ <message>
+ <location filename="../transactiondescdialog.cpp" line="+17"/>
+ <source>Details for %1</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>TransactionTableModel</name>
@@ -3378,12 +3388,12 @@
<translation>Type</translation>
</message>
<message>
- <location line="+79"/>
+ <location line="+82"/>
<source>Immature (%1 confirmations, will be available after %2)</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
- <location line="-21"/>
+ <location line="-24"/>
<source>Open for %n more block(s)</source>
<translation>
<numerusform>Open for %n more block</numerusform>
@@ -3396,7 +3406,7 @@
<translation>Open until %1</translation>
</message>
<message>
- <location line="+12"/>
+ <location line="+15"/>
<source>Confirmed (%1 confirmations)</source>
<translation>Confirmed (%1 confirmations)</translation>
</message>
@@ -3411,7 +3421,7 @@
<translation>Generated but not accepted</translation>
</message>
<message>
- <location line="-21"/>
+ <location line="-24"/>
<source>Offline</source>
<translation type="unfinished"></translation>
</message>
@@ -3427,6 +3437,11 @@
</message>
<message>
<location line="+3"/>
+ <source>Abandoned</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
<source>Confirming (%1 of %2 recommended confirmations)</source>
<translation type="unfinished"></translation>
</message>
@@ -3471,7 +3486,12 @@
<translation>(n/a)</translation>
</message>
<message>
- <location line="+217"/>
+ <location line="+213"/>
+ <source>(no label)</source>
+ <translation type="unfinished">(no label)</translation>
+ </message>
+ <message>
+ <location line="+39"/>
<source>Transaction status. Hover over this field to show number of confirmations.</source>
<translation>Transaction status. Hover over this field to show number of confirmations.</translation>
</message>
@@ -3576,6 +3596,11 @@
</message>
<message>
<location line="+36"/>
+ <source>Abandon transaction</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>Copy address</source>
<translation>Copy address</translation>
</message>
@@ -3601,6 +3626,11 @@
</message>
<message>
<location line="+1"/>
+ <source>Copy full transaction details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>Edit label</source>
<translation>Edit label</translation>
</message>
@@ -3610,7 +3640,7 @@
<translation>Show transaction details</translation>
</message>
<message>
- <location line="+181"/>
+ <location line="+186"/>
<source>Export Transaction History</source>
<translation type="unfinished"></translation>
</message>
@@ -3675,7 +3705,7 @@
<translation>ID</translation>
</message>
<message>
- <location line="+121"/>
+ <location line="+152"/>
<source>Range:</source>
<translation>Range:</translation>
</message>
@@ -3688,7 +3718,7 @@
<context>
<name>UnitDisplayStatusBarControl</name>
<message>
- <location filename="../bitcoingui.cpp" line="+106"/>
+ <location filename="../bitcoingui.cpp" line="+114"/>
<source>Unit to show amounts in. Click to select another unit.</source>
<translation type="unfinished"></translation>
</message>
@@ -3755,47 +3785,37 @@
<context>
<name>bitcoin-core</name>
<message>
- <location filename="../bitcoinstrings.cpp" line="+267"/>
+ <location filename="../bitcoinstrings.cpp" line="+288"/>
<source>Options:</source>
<translation>Options:</translation>
</message>
<message>
- <location line="+27"/>
+ <location line="+29"/>
<source>Specify data directory</source>
<translation>Specify data directory</translation>
</message>
<message>
- <location line="-84"/>
+ <location line="-87"/>
<source>Connect to a node to retrieve peer addresses, and disconnect</source>
<translation>Connect to a node to retrieve peer addresses, and disconnect</translation>
</message>
<message>
- <location line="+87"/>
+ <location line="+90"/>
<source>Specify your own public address</source>
<translation>Specify your own public address</translation>
</message>
<message>
- <location line="-105"/>
+ <location line="-106"/>
<source>Accept command line and JSON-RPC commands</source>
<translation>Accept command line and JSON-RPC commands</translation>
</message>
<message>
- <location line="-118"/>
+ <location line="-127"/>
<source>If &lt;category&gt; is not supplied or if &lt;category&gt; = 1, output all debugging information.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+15"/>
- <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+7"/>
- <source>Please check that your computer&apos;s date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+3"/>
+ <location line="+29"/>
<source>Prune configured below the minimum of %d MiB. Please use a higher number.</source>
<translation type="unfinished"></translation>
</message>
@@ -3815,7 +3835,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+116"/>
+ <location line="+120"/>
<source>Error: A fatal internal error occurred, see debug.log for details</source>
<translation type="unfinished"></translation>
</message>
@@ -3825,7 +3845,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+38"/>
+ <location line="+40"/>
<source>Pruning blockstore...</source>
<translation type="unfinished"></translation>
</message>
@@ -3840,17 +3860,47 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-117"/>
+ <location line="-118"/>
<source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
<translation>Accept connections from outside (default: 1 if no -proxy or -connect)</translation>
</message>
<message>
- <location line="-168"/>
+ <location line="-203"/>
+ <source>Bitcoin Core</source>
+ <translation type="unfinished">Bitcoin Core</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>The %s developers</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>-fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
<source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
<translation>Bind to given address and always listen on it. Use [host]:port notation for IPv6</translation>
</message>
<message>
- <location line="+16"/>
+ <location line="+10"/>
+ <source>Cannot obtain a lock on data directory %s. %s is probably already running.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation type="unfinished"></translation>
</message>
@@ -3860,17 +3910,47 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+13"/>
+ <location line="+5"/>
+ <source>Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+8"/>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</translation>
</message>
<message>
- <location line="+60"/>
+ <location line="+12"/>
+ <source>Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <source>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)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>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)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Please check that your computer&apos;s date and time are correct! If your clock is wrong, %s will not work properly.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+24"/>
<source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+8"/>
+ <location line="+5"/>
+ <source>Tell other nodes to filter invs to us by our mempool min fee (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
<source>The block database contains a block which appears to be from the future. This may be due to your computer&apos;s date and time being set incorrectly. Only rebuild the block database if you are sure that your computer&apos;s date and time are correct</source>
<translation type="unfinished"></translation>
</message>
@@ -3880,12 +3960,7 @@
<translation>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</translation>
</message>
<message>
- <location line="+13"/>
- <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+6"/>
+ <location line="+19"/>
<source>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</source>
<translation type="unfinished"></translation>
</message>
@@ -3905,22 +3980,27 @@
<translation>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</translation>
</message>
<message>
- <location line="+3"/>
+ <location line="+10"/>
<source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
<translation>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</translation>
</message>
<message>
<location line="+3"/>
- <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
- <translation>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</translation>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <location line="+4"/>
- <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <location line="+9"/>
+ <source>You need to rebuild the database using -reindex-chainstate to change -txindex</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+11"/>
+ <location line="+2"/>
+ <source>%s corrupt, salvage failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
<source>-maxmempool must be at least %d MB</source>
<translation type="unfinished"></translation>
</message>
@@ -3930,12 +4010,32 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+11"/>
+ <location line="+7"/>
+ <source>Append comment to the user agent string</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Attempt to recover private keys from a corrupt wallet on startup</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
<source>Block creation options:</source>
<translation>Block creation options:</translation>
</message>
<message>
- <location line="+6"/>
+ <location line="+2"/>
+ <source>Cannot resolve -%s address: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Change index out of range</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>Connect only to the specified node(s)</source>
<translation>Connect only to the specified node(s)</translation>
</message>
@@ -3945,7 +4045,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+2"/>
+ <location line="+1"/>
+ <source>Copyright (C) %i-%i</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>Corrupted block database detected</source>
<translation>Corrupted block database detected</translation>
</message>
@@ -3986,6 +4091,11 @@
</message>
<message>
<location line="+1"/>
+ <source>Enable transaction replacement in the memory pool (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>Error initializing block database</source>
<translation>Error initializing block database</translation>
</message>
@@ -3996,11 +4106,26 @@
</message>
<message>
<location line="+1"/>
+ <source>Error loading %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Error loading %s: Wallet corrupted</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Error loading %s: Wallet requires newer version of %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>Error loading block database</source>
<translation>Error loading block database</translation>
</message>
<message>
- <location line="+4"/>
+ <location line="+1"/>
<source>Error opening block database</source>
<translation>Error opening block database</translation>
</message>
@@ -4015,7 +4140,7 @@
<translation>Failed to listen on any port. Use -listen=0 if you want this.</translation>
</message>
<message>
- <location line="+4"/>
+ <location line="+3"/>
<source>Importing...</source>
<translation type="unfinished"></translation>
</message>
@@ -4025,17 +4150,47 @@
<translation>Incorrect or no genesis block found. Wrong datadir for network?</translation>
</message>
<message>
- <location line="+4"/>
+ <location line="+2"/>
+ <source>Initialization sanity check failed. %s is shutting down.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
<source>Invalid -onion address: &apos;%s&apos;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+9"/>
+ <location line="+2"/>
+ <source>Invalid amount for -%s=&lt;amount&gt;: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Invalid amount for -fallbackfee=&lt;amount&gt;: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
<source>Keep the transaction memory pool below &lt;n&gt; megabytes (default: %u)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+12"/>
+ <location line="+4"/>
+ <source>Loading banlist...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Location of the auth cookie (default: data dir)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Minimum bytes per sigop in transactions we relay and mine (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
<source>Not enough file descriptors available.</source>
<translation>Not enough file descriptors available.</translation>
</message>
@@ -4046,6 +4201,16 @@
</message>
<message>
<location line="+4"/>
+ <source>Print this help message and exit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Print version and exit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>Prune cannot be configured with a negative value.</source>
<translation type="unfinished"></translation>
</message>
@@ -4055,7 +4220,17 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+13"/>
+ <location line="+3"/>
+ <source>Rebuild chain state and block index from the blk*.dat files on disk</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Rebuild chain state from the currently indexed blocks</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+9"/>
<source>Set database cache size in megabytes (%d to %d, default: %d)</source>
<translation type="unfinished"></translation>
</message>
@@ -4070,7 +4245,12 @@
<translation>Specify wallet file (within data directory)</translation>
</message>
<message>
- <location line="+16"/>
+ <location line="+13"/>
+ <source>Unable to bind to %s on this computer. %s is probably already running.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
<source>Unsupported argument -benchmark ignored, use -debug=bench.</source>
<translation type="unfinished"></translation>
</message>
@@ -4110,22 +4290,22 @@
<translation>Wallet %s resides outside data directory %s</translation>
</message>
<message>
- <location line="+2"/>
- <source>Wallet options:</source>
+ <location line="+1"/>
+ <source>Wallet debugging/testing options:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+2"/>
- <source>Warning: This version is obsolete; upgrade required!</source>
+ <location line="+1"/>
+ <source>Wallet needed to be rewritten: restart %s to complete</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+2"/>
- <source>You need to rebuild the database using -reindex to change -txindex</source>
- <translation>You need to rebuild the database using -reindex to change -txindex</translation>
+ <location line="+1"/>
+ <source>Wallet options:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <location line="-306"/>
+ <location line="-315"/>
<source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
<translation type="unfinished"></translation>
</message>
@@ -4140,12 +4320,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+4"/>
- <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+3"/>
+ <location line="+6"/>
<source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
<translation type="unfinished"></translation>
</message>
@@ -4170,7 +4345,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+11"/>
+ <location line="+14"/>
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4180,7 +4355,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+6"/>
+ <location line="+10"/>
<source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4200,12 +4375,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+5"/>
- <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+10"/>
+ <location line="+14"/>
<source>The transaction amount is too small to send after the fee has been deducted</source>
<translation type="unfinished"></translation>
</message>
@@ -4215,7 +4385,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+44"/>
+ <location line="+47"/>
<source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
<translation type="unfinished"></translation>
</message>
@@ -4225,7 +4395,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+4"/>
+ <location line="+7"/>
<source>(default: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4235,52 +4405,22 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+1"/>
- <source>Activating best chain...</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+4"/>
- <source>Always relay transactions received from whitelisted peers (default: %d)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Attempt to recover private keys from a corrupt wallet.dat on startup</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
+ <location line="+6"/>
<source>Automatically create Tor hidden service (default: %d)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+5"/>
- <source>Cannot resolve -whitebind address: &apos;%s&apos;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+3"/>
+ <location line="+7"/>
<source>Connect through SOCKS5 proxy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
- <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+15"/>
- <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+2"/>
+ <location line="+21"/>
<source>Error reading from database, shutting down.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+9"/>
+ <location line="+8"/>
<source>Imports blocks from external blk000??.dat file on startup</source>
<translation type="unfinished"></translation>
</message>
@@ -4290,32 +4430,12 @@
<translation>Information</translation>
</message>
<message>
- <location line="+1"/>
- <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+4"/>
- <source>Invalid amount for -maxtxfee=&lt;amount&gt;: &apos;%s&apos;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: &apos;%s&apos;</source>
- <translation>Invalid amount for -minrelaytxfee=&lt;amount&gt;: &apos;%s&apos;</translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Invalid amount for -mintxfee=&lt;amount&gt;: &apos;%s&apos;</source>
- <translation>Invalid amount for -mintxfee=&lt;amount&gt;: &apos;%s&apos;</translation>
- </message>
- <message>
- <location line="+1"/>
+ <location line="+7"/>
<source>Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos; (must be at least %s)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+2"/>
+ <location line="+1"/>
<source>Invalid netmask specified in -whitelist: &apos;%s&apos;</source>
<translation type="unfinished"></translation>
</message>
@@ -4325,7 +4445,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+11"/>
+ <location line="+14"/>
<source>Need to specify a port with -whitebind: &apos;%s&apos;</source>
<translation type="unfinished"></translation>
</message>
@@ -4335,22 +4455,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+9"/>
+ <location line="+11"/>
<source>RPC server options:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+1"/>
- <source>Rebuild block chain index from current blk000??.dat files on startup</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Receive and display P2P network alerts (default: %u)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
+ <location line="+3"/>
<source>Reducing -maxconnections from %d to %d, because of system limitations.</source>
<translation type="unfinished"></translation>
</message>
@@ -4390,7 +4500,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+2"/>
+ <location line="+1"/>
<source>This is experimental software.</source>
<translation type="unfinished"></translation>
</message>
@@ -4430,7 +4540,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+6"/>
+ <location line="+7"/>
<source>Upgrade wallet to latest format on startup</source>
<translation type="unfinished"></translation>
</message>
@@ -4440,72 +4550,57 @@
<translation>Username for JSON-RPC connections</translation>
</message>
<message>
- <location line="+4"/>
- <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+2"/>
+ <location line="+7"/>
<source>Warning</source>
<translation>Warning</translation>
</message>
<message>
- <location line="+2"/>
- <source>Whether to operate in a blocks only mode (default: %u)</source>
+ <location line="+1"/>
+ <source>Warning: unknown new rules activated (versionbit %i)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+2"/>
- <source>Zapping all transactions from wallet...</source>
+ <location line="+1"/>
+ <source>Whether to operate in a blocks only mode (default: %u)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>ZeroMQ notification options:</source>
+ <source>Zapping all transactions from wallet...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>wallet.dat corrupt, salvage failed</source>
- <translation>wallet.dat corrupt, salvage failed</translation>
+ <source>ZeroMQ notification options:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <location line="-62"/>
+ <location line="-63"/>
<source>Password for JSON-RPC connections</source>
<translation>Password for JSON-RPC connections</translation>
</message>
<message>
- <location line="-205"/>
+ <location line="-216"/>
<source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
<translation>Execute command when the best block changes (%s in cmd is replaced by block hash)</translation>
</message>
<message>
- <location line="+237"/>
- <source>This help message</source>
- <translation>This help message</translation>
- </message>
- <message>
- <location line="-103"/>
+ <location line="+145"/>
<source>Allow DNS lookups for -addnode, -seednode and -connect</source>
<translation>Allow DNS lookups for -addnode, -seednode and -connect</translation>
</message>
<message>
- <location line="+59"/>
+ <location line="+56"/>
<source>Loading addresses...</source>
<translation>Loading addresses...</translation>
</message>
<message>
- <location line="-30"/>
- <source>Error loading wallet.dat: Wallet corrupted</source>
- <translation>Error loading wallet.dat: Wallet corrupted</translation>
- </message>
- <message>
- <location line="-214"/>
+ <location line="-260"/>
<source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
+ <location line="+6"/>
<source>-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
<translation type="unfinished"></translation>
</message>
@@ -4515,22 +4610,17 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+32"/>
+ <location line="+37"/>
<source>Do not keep transactions in the mempool longer than &lt;n&gt; hours (default: %u)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+2"/>
- <source>Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+17"/>
+ <location line="+19"/>
<source>Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
+ <location line="+6"/>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4540,7 +4630,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+9"/>
+ <location line="+13"/>
<source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4550,12 +4640,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+32"/>
+ <location line="+29"/>
<source>Support filtering of blocks and transaction with bloom filters (default: %u)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+16"/>
+ <location line="+18"/>
<source>Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</source>
<translation type="unfinished"></translation>
</message>
@@ -4565,11 +4655,16 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+6"/>
+ <location line="+3"/>
<source>Unsupported argument -socks found. Setting SOCKS version isn&apos;t possible anymore, only SOCKS5 proxies are supported.</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+3"/>
+ <source>Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<location line="+5"/>
<source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
<translation type="unfinished"></translation>
@@ -4580,27 +4675,27 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+29"/>
- <source>(default: %s)</source>
+ <location line="+13"/>
+ <source>Warning: Unknown block versions being mined! It&apos;s possible unknown rules are in effect</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+10"/>
- <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <location line="+3"/>
+ <source>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.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+27"/>
- <source>Error loading wallet.dat</source>
- <translation>Error loading wallet.dat</translation>
+ <location line="+19"/>
+ <source>(default: %s)</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <location line="+10"/>
- <source>Generate coins (default: %u)</source>
+ <location line="+9"/>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+1"/>
+ <location line="+37"/>
<source>How many blocks to check at startup (default: %u, 0 = all)</source>
<translation type="unfinished"></translation>
</message>
@@ -4615,7 +4710,7 @@
<translation>Invalid -proxy address: &apos;%s&apos;</translation>
</message>
<message>
- <location line="+9"/>
+ <location line="+7"/>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4625,7 +4720,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+4"/>
+ <location line="+6"/>
<source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4645,12 +4740,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+7"/>
+ <location line="+8"/>
<source>Prepend debug output with timestamp (default: %u)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+8"/>
+ <location line="+10"/>
<source>Relay and mine data carrier transactions (default: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4695,72 +4790,57 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+4"/>
+ <location line="+3"/>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+9"/>
+ <location line="+10"/>
<source>Unknown network specified in -onlynet: &apos;%s&apos;</source>
<translation>Unknown network specified in -onlynet: &apos;%s&apos;</translation>
</message>
<message>
- <location line="-107"/>
- <source>Cannot resolve -bind address: &apos;%s&apos;</source>
- <translation>Cannot resolve -bind address: &apos;%s&apos;</translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Cannot resolve -externalip address: &apos;%s&apos;</source>
- <translation>Cannot resolve -externalip address: &apos;%s&apos;</translation>
- </message>
- <message>
- <location line="+45"/>
- <source>Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos;</source>
- <translation>Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos;</translation>
- </message>
- <message>
- <location line="-7"/>
+ <location line="-71"/>
<source>Insufficient funds</source>
<translation>Insufficient funds</translation>
</message>
<message>
- <location line="+14"/>
+ <location line="+13"/>
<source>Loading block index...</source>
<translation>Loading block index...</translation>
</message>
<message>
- <location line="-61"/>
+ <location line="-59"/>
<source>Add a node to connect to and attempt to keep the connection open</source>
<translation>Add a node to connect to and attempt to keep the connection open</translation>
</message>
<message>
- <location line="+62"/>
+ <location line="+60"/>
<source>Loading wallet...</source>
<translation>Loading wallet...</translation>
</message>
<message>
- <location line="-55"/>
+ <location line="-53"/>
<source>Cannot downgrade wallet</source>
<translation>Cannot downgrade wallet</translation>
</message>
<message>
- <location line="+4"/>
+ <location line="+2"/>
<source>Cannot write default address</source>
<translation>Cannot write default address</translation>
</message>
<message>
- <location line="+73"/>
+ <location line="+77"/>
<source>Rescanning...</source>
<translation>Rescanning...</translation>
</message>
<message>
- <location line="-63"/>
+ <location line="-66"/>
<source>Done loading</source>
<translation>Done loading</translation>
</message>
<message>
- <location line="+13"/>
+ <location line="+14"/>
<source>Error</source>
<translation>Error</translation>
</message>
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index b11648e46f..11f3e49a06 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -327,6 +327,14 @@ bool RPCConsole::eventFilter(QObject* obj, QEvent *event)
return true;
}
break;
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ // forward these events to lineEdit
+ if(obj == autoCompleter->popup()) {
+ QApplication::postEvent(ui->lineEdit, new QKeyEvent(*keyevt));
+ return true;
+ }
+ break;
default:
// Typing in messages widget brings focus to line edit, and redirects key there
// Exclude most combinations and keys that emit no text, except paste shortcuts
@@ -458,9 +466,7 @@ void RPCConsole::setClientModel(ClientModel *model)
autoCompleter = new QCompleter(wordList, this);
ui->lineEdit->setCompleter(autoCompleter);
-
- // clear the lineEdit after activating from QCompleter
- connect(autoCompleter, SIGNAL(activated(const QString&)), ui->lineEdit, SLOT(clear()), Qt::QueuedConnection);
+ autoCompleter->popup()->installEventFilter(this);
}
}
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index cf3c73c4df..1bb365d36c 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -183,6 +183,60 @@ UniValue getdifficulty(const UniValue& params, bool fHelp)
return GetDifficulty();
}
+std::string EntryDescriptionString()
+{
+ return " \"size\" : n, (numeric) transaction size in bytes\n"
+ " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n"
+ " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n"
+ " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n"
+ " \"height\" : n, (numeric) block height when transaction entered pool\n"
+ " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n"
+ " \"currentpriority\" : n, (numeric) transaction priority now\n"
+ " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n"
+ " \"descendantsize\" : n, (numeric) size of in-mempool descendants (including this one)\n"
+ " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n"
+ " \"ancestorcount\" : n, (numeric) number of in-mempool ancestor transactions (including this one)\n"
+ " \"ancestorsize\" : n, (numeric) size of in-mempool ancestors (including this one)\n"
+ " \"ancestorfees\" : n, (numeric) modified fees (see above) of in-mempool ancestors (including this one)\n"
+ " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
+ " \"transactionid\", (string) parent transaction id\n"
+ " ... ]\n";
+}
+
+void entryToJSON(UniValue &info, const CTxMemPoolEntry &e)
+{
+ AssertLockHeld(mempool.cs);
+
+ info.push_back(Pair("size", (int)e.GetTxSize()));
+ info.push_back(Pair("fee", ValueFromAmount(e.GetFee())));
+ info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee())));
+ info.push_back(Pair("time", e.GetTime()));
+ info.push_back(Pair("height", (int)e.GetHeight()));
+ info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight())));
+ info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height())));
+ info.push_back(Pair("descendantcount", e.GetCountWithDescendants()));
+ info.push_back(Pair("descendantsize", e.GetSizeWithDescendants()));
+ info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants()));
+ info.push_back(Pair("ancestorcount", e.GetCountWithAncestors()));
+ info.push_back(Pair("ancestorsize", e.GetSizeWithAncestors()));
+ info.push_back(Pair("ancestorfees", e.GetModFeesWithAncestors()));
+ const CTransaction& tx = e.GetTx();
+ set<string> setDepends;
+ BOOST_FOREACH(const CTxIn& txin, tx.vin)
+ {
+ if (mempool.exists(txin.prevout.hash))
+ setDepends.insert(txin.prevout.hash.ToString());
+ }
+
+ UniValue depends(UniValue::VARR);
+ BOOST_FOREACH(const string& dep, setDepends)
+ {
+ depends.push_back(dep);
+ }
+
+ info.push_back(Pair("depends", depends));
+}
+
UniValue mempoolToJSON(bool fVerbose = false)
{
if (fVerbose)
@@ -193,31 +247,7 @@ UniValue mempoolToJSON(bool fVerbose = false)
{
const uint256& hash = e.GetTx().GetHash();
UniValue info(UniValue::VOBJ);
- info.push_back(Pair("size", (int)e.GetTxSize()));
- info.push_back(Pair("fee", ValueFromAmount(e.GetFee())));
- info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee())));
- info.push_back(Pair("time", e.GetTime()));
- info.push_back(Pair("height", (int)e.GetHeight()));
- info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight())));
- info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height())));
- info.push_back(Pair("descendantcount", e.GetCountWithDescendants()));
- info.push_back(Pair("descendantsize", e.GetSizeWithDescendants()));
- info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants()));
- const CTransaction& tx = e.GetTx();
- set<string> setDepends;
- BOOST_FOREACH(const CTxIn& txin, tx.vin)
- {
- if (mempool.exists(txin.prevout.hash))
- setDepends.insert(txin.prevout.hash.ToString());
- }
-
- UniValue depends(UniValue::VARR);
- BOOST_FOREACH(const string& dep, setDepends)
- {
- depends.push_back(dep);
- }
-
- info.push_back(Pair("depends", depends));
+ entryToJSON(info, e);
o.push_back(Pair(hash.ToString(), info));
}
return o;
@@ -251,20 +281,8 @@ UniValue getrawmempool(const UniValue& params, bool fHelp)
"\nResult: (for verbose = true):\n"
"{ (json object)\n"
" \"transactionid\" : { (json object)\n"
- " \"size\" : n, (numeric) transaction size in bytes\n"
- " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n"
- " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n"
- " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n"
- " \"height\" : n, (numeric) block height when transaction entered pool\n"
- " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n"
- " \"currentpriority\" : n, (numeric) transaction priority now\n"
- " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n"
- " \"descendantsize\" : n, (numeric) size of in-mempool descendants (including this one)\n"
- " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n"
- " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
- " \"transactionid\", (string) parent transaction id\n"
- " ... ]\n"
- " }, ...\n"
+ + EntryDescriptionString()
+ + " }, ...\n"
"}\n"
"\nExamples\n"
+ HelpExampleCli("getrawmempool", "true")
@@ -280,6 +298,167 @@ UniValue getrawmempool(const UniValue& params, bool fHelp)
return mempoolToJSON(fVerbose);
}
+UniValue getmempoolancestors(const UniValue& params, bool fHelp)
+{
+ if (fHelp || params.size() < 1 || params.size() > 2) {
+ throw runtime_error(
+ "getmempoolancestors txid (verbose)\n"
+ "\nIf txid is in the mempool, returns all in-mempool ancestors.\n"
+ "\nArguments:\n"
+ "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
+ "2. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n"
+ "\nResult (for verbose=false):\n"
+ "[ (json array of strings)\n"
+ " \"transactionid\" (string) The transaction id of an in-mempool ancestor transaction\n"
+ " ,...\n"
+ "]\n"
+ "\nResult (for verbose=true):\n"
+ "{ (json object)\n"
+ " \"transactionid\" : { (json object)\n"
+ + EntryDescriptionString()
+ + " }, ...\n"
+ "}\n"
+ "\nExamples\n"
+ + HelpExampleCli("getmempoolancestors", "\"mytxid\"")
+ + HelpExampleRpc("getmempoolancestors", "\"mytxid\"")
+ );
+ }
+
+ bool fVerbose = false;
+ if (params.size() > 1)
+ fVerbose = params[1].get_bool();
+
+ uint256 hash = ParseHashV(params[0], "parameter 1");
+
+ LOCK(mempool.cs);
+
+ CTxMemPool::txiter it = mempool.mapTx.find(hash);
+ if (it == mempool.mapTx.end()) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
+ }
+
+ CTxMemPool::setEntries setAncestors;
+ uint64_t noLimit = std::numeric_limits<uint64_t>::max();
+ std::string dummy;
+ mempool.CalculateMemPoolAncestors(*it, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false);
+
+ if (!fVerbose) {
+ UniValue o(UniValue::VARR);
+ BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) {
+ o.push_back(ancestorIt->GetTx().GetHash().ToString());
+ }
+
+ return o;
+ } else {
+ UniValue o(UniValue::VOBJ);
+ BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) {
+ const CTxMemPoolEntry &e = *ancestorIt;
+ const uint256& hash = e.GetTx().GetHash();
+ UniValue info(UniValue::VOBJ);
+ entryToJSON(info, e);
+ o.push_back(Pair(hash.ToString(), info));
+ }
+ return o;
+ }
+}
+
+UniValue getmempooldescendants(const UniValue& params, bool fHelp)
+{
+ if (fHelp || params.size() < 1 || params.size() > 2) {
+ throw runtime_error(
+ "getmempooldescendants txid (verbose)\n"
+ "\nIf txid is in the mempool, returns all in-mempool descendants.\n"
+ "\nArguments:\n"
+ "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
+ "2. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n"
+ "\nResult (for verbose=false):\n"
+ "[ (json array of strings)\n"
+ " \"transactionid\" (string) The transaction id of an in-mempool descendant transaction\n"
+ " ,...\n"
+ "]\n"
+ "\nResult (for verbose=true):\n"
+ "{ (json object)\n"
+ " \"transactionid\" : { (json object)\n"
+ + EntryDescriptionString()
+ + " }, ...\n"
+ "}\n"
+ "\nExamples\n"
+ + HelpExampleCli("getmempooldescendants", "\"mytxid\"")
+ + HelpExampleRpc("getmempooldescendants", "\"mytxid\"")
+ );
+ }
+
+ bool fVerbose = false;
+ if (params.size() > 1)
+ fVerbose = params[1].get_bool();
+
+ uint256 hash = ParseHashV(params[0], "parameter 1");
+
+ LOCK(mempool.cs);
+
+ CTxMemPool::txiter it = mempool.mapTx.find(hash);
+ if (it == mempool.mapTx.end()) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
+ }
+
+ CTxMemPool::setEntries setDescendants;
+ mempool.CalculateDescendants(it, setDescendants);
+ // CTxMemPool::CalculateDescendants will include the given tx
+ setDescendants.erase(it);
+
+ if (!fVerbose) {
+ UniValue o(UniValue::VARR);
+ BOOST_FOREACH(CTxMemPool::txiter descendantIt, setDescendants) {
+ o.push_back(descendantIt->GetTx().GetHash().ToString());
+ }
+
+ return o;
+ } else {
+ UniValue o(UniValue::VOBJ);
+ BOOST_FOREACH(CTxMemPool::txiter descendantIt, setDescendants) {
+ const CTxMemPoolEntry &e = *descendantIt;
+ const uint256& hash = e.GetTx().GetHash();
+ UniValue info(UniValue::VOBJ);
+ entryToJSON(info, e);
+ o.push_back(Pair(hash.ToString(), info));
+ }
+ return o;
+ }
+}
+
+UniValue getmempoolentry(const UniValue& params, bool fHelp)
+{
+ if (fHelp || params.size() != 1) {
+ throw runtime_error(
+ "getmempoolentry txid\n"
+ "\nReturns mempool data for given transaction\n"
+ "\nArguments:\n"
+ "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
+ "\nResult:\n"
+ "{ (json object)\n"
+ + EntryDescriptionString()
+ + "}\n"
+ "\nExamples\n"
+ + HelpExampleCli("getmempoolentry", "\"mytxid\"")
+ + HelpExampleRpc("getmempoolentry", "\"mytxid\"")
+ );
+ }
+
+ uint256 hash = ParseHashV(params[0], "parameter 1");
+
+ LOCK(mempool.cs);
+
+ CTxMemPool::txiter it = mempool.mapTx.find(hash);
+ if (it == mempool.mapTx.end()) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool");
+ }
+
+ const CTxMemPoolEntry &e = *it;
+ UniValue info(UniValue::VOBJ);
+ entryToJSON(info, e);
+ return info;
+}
+
UniValue getblockhash(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() != 1)
@@ -1004,6 +1183,9 @@ static const CRPCCommand commands[] =
{ "blockchain", "getblockheader", &getblockheader, true },
{ "blockchain", "getchaintips", &getchaintips, true },
{ "blockchain", "getdifficulty", &getdifficulty, true },
+ { "blockchain", "getmempoolancestors", &getmempoolancestors, true },
+ { "blockchain", "getmempooldescendants", &getmempooldescendants, true },
+ { "blockchain", "getmempoolentry", &getmempoolentry, true },
{ "blockchain", "getmempoolinfo", &getmempoolinfo, true },
{ "blockchain", "getrawmempool", &getrawmempool, true },
{ "blockchain", "gettxout", &gettxout, true },
diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp
index c89af6bfa7..d0675fdb49 100644
--- a/src/rpc/client.cpp
+++ b/src/rpc/client.cpp
@@ -102,6 +102,8 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "prioritisetransaction", 2 },
{ "setban", 2 },
{ "setban", 3 },
+ { "getmempoolancestors", 1 },
+ { "getmempooldescendants", 1 },
};
class CRPCConvertTable
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index 9a7d9d53a0..2bd52eadbc 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -8,6 +8,7 @@
#include "chain.h"
#include "chainparams.h"
#include "consensus/consensus.h"
+#include "consensus/params.h"
#include "consensus/validation.h"
#include "core_io.h"
#include "init.h"
@@ -303,6 +304,15 @@ static UniValue BIP22ValidationResult(const CValidationState& state)
return "valid?";
}
+std::string gbt_vb_name(const Consensus::DeploymentPos pos) {
+ const struct BIP9DeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos];
+ std::string s = vbinfo.name;
+ if (!vbinfo.gbt_force) {
+ s.insert(s.begin(), '!');
+ }
+ return s;
+}
+
UniValue getblocktemplate(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() > 1)
@@ -310,7 +320,9 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
"getblocktemplate ( \"jsonrequestobject\" )\n"
"\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n"
"It returns data needed to construct a block to work on.\n"
- "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n"
+ "For full specification, see BIPs 22 and 9:\n"
+ " https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki\n"
+ " https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki#getblocktemplate_changes\n"
"\nArguments:\n"
"1. \"jsonrequestobject\" (string, optional) A json object in the following spec\n"
@@ -326,6 +338,12 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
"\nResult:\n"
"{\n"
" \"version\" : n, (numeric) The block version\n"
+ " \"rules\" : [ \"rulename\", ... ], (array of strings) specific block rules that are to be enforced\n"
+ " \"vbavailable\" : { (json object) set of pending, supported versionbit (BIP 9) softfork deployments\n"
+ " \"rulename\" : bitnumber (numeric) identifies the bit number as indicating acceptance and readiness for the named softfork rule\n"
+ " ,...\n"
+ " },\n"
+ " \"vbrequired\" : n, (numeric) bit mask of versionbits the server requires set in submissions\n"
" \"previousblockhash\" : \"xxxx\", (string) The hash of current highest block\n"
" \"transactions\" : [ (array) contents of non-coinbase transactions that should be included in the next block\n"
" {\n"
@@ -369,6 +387,8 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
std::string strMode = "template";
UniValue lpval = NullUniValue;
+ std::set<std::string> setClientRules;
+ int64_t nMaxVersionPreVB = -1;
if (params.size() > 0)
{
const UniValue& oparam = params[0].get_obj();
@@ -412,6 +432,20 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
TestBlockValidity(state, Params(), block, pindexPrev, false, true);
return BIP22ValidationResult(state);
}
+
+ const UniValue& aClientRules = find_value(oparam, "rules");
+ if (aClientRules.isArray()) {
+ for (unsigned int i = 0; i < aClientRules.size(); ++i) {
+ const UniValue& v = aClientRules[i];
+ setClientRules.insert(v.get_str());
+ }
+ } else {
+ // NOTE: It is important that this NOT be read if versionbits is supported
+ const UniValue& uvMaxVersion = find_value(oparam, "maxversion");
+ if (uvMaxVersion.isNum()) {
+ nMaxVersionPreVB = uvMaxVersion.get_int64();
+ }
+ }
}
if (strMode != "template")
@@ -501,9 +535,10 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
pindexPrev = pindexPrevNew;
}
CBlock* pblock = &pblocktemplate->block; // pointer for convenience
+ const Consensus::Params& consensusParams = Params().GetConsensus();
// Update nTime
- UpdateTime(pblock, Params().GetConsensus(), pindexPrev);
+ UpdateTime(pblock, consensusParams, pindexPrev);
pblock->nNonce = 0;
UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal");
@@ -544,17 +579,69 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
- static UniValue aMutable(UniValue::VARR);
- if (aMutable.empty())
- {
- aMutable.push_back("time");
- aMutable.push_back("transactions");
- aMutable.push_back("prevblock");
- }
+ UniValue aMutable(UniValue::VARR);
+ aMutable.push_back("time");
+ aMutable.push_back("transactions");
+ aMutable.push_back("prevblock");
UniValue result(UniValue::VOBJ);
result.push_back(Pair("capabilities", aCaps));
+
+ UniValue aRules(UniValue::VARR);
+ UniValue vbavailable(UniValue::VOBJ);
+ for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++i) {
+ Consensus::DeploymentPos pos = Consensus::DeploymentPos(i);
+ ThresholdState state = VersionBitsState(pindexPrev, consensusParams, pos, versionbitscache);
+ switch (state) {
+ case THRESHOLD_DEFINED:
+ case THRESHOLD_FAILED:
+ // Not exposed to GBT at all
+ break;
+ case THRESHOLD_LOCKED_IN:
+ // Ensure bit is set in block version
+ pblock->nVersion |= VersionBitsMask(consensusParams, pos);
+ // FALL THROUGH to get vbavailable set...
+ case THRESHOLD_STARTED:
+ {
+ const struct BIP9DeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos];
+ vbavailable.push_back(Pair(gbt_vb_name(pos), consensusParams.vDeployments[pos].bit));
+ if (setClientRules.find(vbinfo.name) == setClientRules.end()) {
+ if (!vbinfo.gbt_force) {
+ // If the client doesn't support this, don't indicate it in the [default] version
+ pblock->nVersion &= ~VersionBitsMask(consensusParams, pos);
+ }
+ }
+ break;
+ }
+ case THRESHOLD_ACTIVE:
+ {
+ // Add to rules only
+ const struct BIP9DeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos];
+ aRules.push_back(gbt_vb_name(pos));
+ if (setClientRules.find(vbinfo.name) == setClientRules.end()) {
+ // Not supported by the client; make sure it's safe to proceed
+ if (!vbinfo.gbt_force) {
+ // If we do anything other than throw an exception here, be sure version/force isn't sent to old clients
+ throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Support for '%s' rule requires explicit client support", vbinfo.name));
+ }
+ }
+ break;
+ }
+ }
+ }
result.push_back(Pair("version", pblock->nVersion));
+ result.push_back(Pair("rules", aRules));
+ result.push_back(Pair("vbavailable", vbavailable));
+ result.push_back(Pair("vbrequired", int(0)));
+
+ if (nMaxVersionPreVB >= 2) {
+ // If VB is supported by the client, nMaxVersionPreVB is -1, so we won't get here
+ // Because BIP 34 changed how the generation transaction is serialised, we can only use version/force back to v2 blocks
+ // This is safe to do [otherwise-]unconditionally only because we are throwing an exception above if a non-force deployment gets activated
+ // Note that this can probably also be removed entirely after the first BIP9 non-force deployment (ie, probably segwit) gets activated
+ aMutable.push_back("version/force");
+ }
+
result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex()));
result.push_back(Pair("transactions", transactions));
result.push_back(Pair("coinbaseaux", aux));
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index 36178bfb4c..cae964e46d 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -219,7 +219,7 @@ UniValue addnode(const UniValue& params, bool fHelp)
if (strCommand == "onetry")
{
CAddress addr;
- OpenNetworkConnection(addr, NULL, strNode.c_str());
+ OpenNetworkConnection(addr, false, NULL, strNode.c_str());
return NullUniValue;
}
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index 483fe746ca..992914f88c 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -334,6 +334,7 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp)
" {\n"
" \"txid\":\"id\", (string, required) The transaction id\n"
" \"vout\":n (numeric, required) The output number\n"
+ " \"sequence\":n (numeric, optional) The sequence number\n"
" }\n"
" ,...\n"
" ]\n"
@@ -384,6 +385,12 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
uint32_t nSequence = (rawTx.nLockTime ? std::numeric_limits<uint32_t>::max() - 1 : std::numeric_limits<uint32_t>::max());
+
+ // set the sequence number if passed in the parameters object
+ const UniValue& sequenceObj = find_value(o, "sequence");
+ if (sequenceObj.isNum())
+ nSequence = sequenceObj.get_int();
+
CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence);
rawTx.vin.push_back(in);
@@ -675,7 +682,12 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp)
UniValue prevOut = p.get_obj();
- RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR));
+ RPCTypeCheckObj(prevOut,
+ {
+ {"txid", UniValueType(UniValue::VSTR)},
+ {"vout", UniValueType(UniValue::VNUM)},
+ {"scriptPubKey", UniValueType(UniValue::VSTR)},
+ });
uint256 txid = ParseHashO(prevOut, "txid");
@@ -703,7 +715,13 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp)
// if redeemScript given and not using the local wallet (private keys
// given), add redeemScript to the tempKeystore so it can be signed:
if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) {
- RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR)("redeemScript",UniValue::VSTR));
+ RPCTypeCheckObj(prevOut,
+ {
+ {"txid", UniValueType(UniValue::VSTR)},
+ {"vout", UniValueType(UniValue::VNUM)},
+ {"scriptPubKey", UniValueType(UniValue::VSTR)},
+ {"redeemScript", UniValueType(UniValue::VSTR)},
+ });
UniValue v = find_value(prevOut, "redeemScript");
if (!v.isNull()) {
vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
@@ -743,6 +761,9 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp)
// Script verification errors
UniValue vErrors(UniValue::VARR);
+ // Use CTransaction for the constant parts of the
+ // transaction to avoid rehashing.
+ const CTransaction txConst(mergedTx);
// Sign what we can:
for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
CTxIn& txin = mergedTx.vin[i];
@@ -760,10 +781,10 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp)
// ... and merge in other signatures:
BOOST_FOREACH(const CMutableTransaction& txv, txVariants) {
- txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig);
+ txin.scriptSig = CombineSignatures(prevPubKey, txConst, i, txin.scriptSig, txv.vin[i].scriptSig);
}
ScriptError serror = SCRIPT_ERR_OK;
- if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i), &serror)) {
+ if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i), &serror)) {
TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror));
}
}
diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp
index d06a9142b6..23149baa6d 100644
--- a/src/rpc/server.cpp
+++ b/src/rpc/server.cpp
@@ -88,20 +88,18 @@ void RPCTypeCheck(const UniValue& params,
}
void RPCTypeCheckObj(const UniValue& o,
- const map<string, UniValue::VType>& typesExpected,
- bool fAllowNull,
- bool fStrict)
+ const map<string, UniValueType>& typesExpected,
+ bool fAllowNull,
+ bool fStrict)
{
- BOOST_FOREACH(const PAIRTYPE(string, UniValue::VType)& t, typesExpected)
- {
+ for (const auto& t : typesExpected) {
const UniValue& v = find_value(o, t.first);
if (!fAllowNull && v.isNull())
throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first));
- if (!((v.type() == t.second) || (fAllowNull && (v.isNull()))))
- {
+ if (!(t.second.typeAny || v.type() == t.second.type || (fAllowNull && v.isNull()))) {
string err = strprintf("Expected type %s for %s, got %s",
- uvTypeName(t.second), t.first, uvTypeName(v.type()));
+ uvTypeName(t.second.type), t.first, uvTypeName(v.type()));
throw JSONRPCError(RPC_TYPE_ERROR, err);
}
}
diff --git a/src/rpc/server.h b/src/rpc/server.h
index b471336617..b5ccc153d0 100644
--- a/src/rpc/server.h
+++ b/src/rpc/server.h
@@ -32,6 +32,15 @@ namespace RPCServer
class CBlockIndex;
class CNetAddr;
+/** Wrapper for UniValue::VType, which includes typeAny:
+ * Used to denote don't care type. Only used by RPCTypeCheckObj */
+struct UniValueType {
+ UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {}
+ UniValueType() : typeAny(true) {}
+ bool typeAny;
+ UniValue::VType type;
+};
+
class JSONRequest
{
public:
@@ -60,17 +69,17 @@ bool RPCIsInWarmup(std::string *statusOut);
/**
* Type-check arguments; throws JSONRPCError if wrong type given. Does not check that
* the right number of arguments are passed, just that any passed are the correct type.
- * Use like: RPCTypeCheck(params, boost::assign::list_of(str_type)(int_type)(obj_type));
*/
void RPCTypeCheck(const UniValue& params,
const std::list<UniValue::VType>& typesExpected, bool fAllowNull=false);
/*
Check for expected keys/value types in an Object.
- Use like: RPCTypeCheckObj(object, boost::assign::map_list_of("name", str_type)("value", int_type));
*/
void RPCTypeCheckObj(const UniValue& o,
- const std::map<std::string, UniValue::VType>& typesExpected, bool fAllowNull=false, bool fStrict=false);
+ const std::map<std::string, UniValueType>& typesExpected,
+ bool fAllowNull = false,
+ bool fStrict = false);
/** Opaque base class for timers returned by NewTimerFunc.
* This provides no methods at the moment, but makes sure that delete
diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp
index e5a2e28b2e..01eb2aee9e 100644
--- a/src/test/base58_tests.cpp
+++ b/src/test/base58_tests.cpp
@@ -79,7 +79,7 @@ class TestAddrTypeVisitor : public boost::static_visitor<bool>
private:
std::string exp_addrType;
public:
- TestAddrTypeVisitor(const std::string &exp_addrType) : exp_addrType(exp_addrType) { }
+ TestAddrTypeVisitor(const std::string &_exp_addrType) : exp_addrType(_exp_addrType) { }
bool operator()(const CKeyID &id) const
{
return (exp_addrType == "pubkey");
@@ -100,7 +100,7 @@ class TestPayloadVisitor : public boost::static_visitor<bool>
private:
std::vector<unsigned char> exp_payload;
public:
- TestPayloadVisitor(std::vector<unsigned char> &exp_payload) : exp_payload(exp_payload) { }
+ TestPayloadVisitor(std::vector<unsigned char> &_exp_payload) : exp_payload(_exp_payload) { }
bool operator()(const CKeyID &id) const
{
uint160 exp_key(exp_payload);
diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json
index 3bf80ca434..5cb383de85 100644
--- a/src/test/data/bitcoin-util-test.json
+++ b/src/test/data/bitcoin-util-test.json
@@ -86,5 +86,18 @@
"outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
"outdata=54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"],
"output_cmp": "txcreatedata2.hex"
+ },
+ { "exec": "./bitcoin-tx",
+ "args":
+ ["-create",
+ "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:4294967293",
+ "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"],
+ "output_cmp": "txcreatedata_seq0.hex"
+ },
+ { "exec": "./bitcoin-tx",
+ "args":
+ ["01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff0180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000",
+ "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:1"],
+ "output_cmp": "txcreatedata_seq1.hex"
}
]
diff --git a/src/test/data/txcreatedata_seq0.hex b/src/test/data/txcreatedata_seq0.hex
new file mode 100644
index 0000000000..db02b5e4a4
--- /dev/null
+++ b/src/test/data/txcreatedata_seq0.hex
@@ -0,0 +1 @@
+01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff0180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000
diff --git a/src/test/data/txcreatedata_seq1.hex b/src/test/data/txcreatedata_seq1.hex
new file mode 100644
index 0000000000..4cedcd975c
--- /dev/null
+++ b/src/test/data/txcreatedata_seq1.hex
@@ -0,0 +1 @@
+01000000021f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff1f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000010000000180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000
diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp
index 081d57831d..a0bdcf4afb 100644
--- a/src/test/dbwrapper_tests.cpp
+++ b/src/test/dbwrapper_tests.cpp
@@ -203,5 +203,125 @@ BOOST_AUTO_TEST_CASE(existing_data_reindex)
BOOST_CHECK(odbw.Read(key, res3));
BOOST_CHECK_EQUAL(res3.ToString(), in2.ToString());
}
-
+
+BOOST_AUTO_TEST_CASE(iterator_ordering)
+{
+ path ph = temp_directory_path() / unique_path();
+ CDBWrapper dbw(ph, (1 << 20), true, false, false);
+ for (int x=0x00; x<256; ++x) {
+ uint8_t key = x;
+ uint32_t value = x*x;
+ BOOST_CHECK(dbw.Write(key, value));
+ }
+
+ boost::scoped_ptr<CDBIterator> it(const_cast<CDBWrapper*>(&dbw)->NewIterator());
+ for (int c=0; c<2; ++c) {
+ int seek_start;
+ if (c == 0)
+ seek_start = 0x00;
+ else
+ seek_start = 0x80;
+ it->Seek((uint8_t)seek_start);
+ for (int x=seek_start; x<256; ++x) {
+ uint8_t key;
+ uint32_t value;
+ BOOST_CHECK(it->Valid());
+ if (!it->Valid()) // Avoid spurious errors about invalid iterator's key and value in case of failure
+ break;
+ BOOST_CHECK(it->GetKey(key));
+ BOOST_CHECK(it->GetValue(value));
+ BOOST_CHECK_EQUAL(key, x);
+ BOOST_CHECK_EQUAL(value, x*x);
+ it->Next();
+ }
+ BOOST_CHECK(!it->Valid());
+ }
+}
+
+struct StringContentsSerializer {
+ // Used to make two serialized objects the same while letting them have a different lengths
+ // This is a terrible idea
+ string str;
+ StringContentsSerializer() {}
+ StringContentsSerializer(const string& inp) : str(inp) {}
+
+ StringContentsSerializer& operator+=(const string& s) {
+ str += s;
+ return *this;
+ }
+ StringContentsSerializer& operator+=(const StringContentsSerializer& s) { return *this += s.str; }
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ if (ser_action.ForRead()) {
+ str.clear();
+ char c = 0;
+ while (true) {
+ try {
+ READWRITE(c);
+ str.push_back(c);
+ } catch (const std::ios_base::failure& e) {
+ break;
+ }
+ }
+ } else {
+ for (size_t i = 0; i < str.size(); i++)
+ READWRITE(str[i]);
+ }
+ }
+};
+
+BOOST_AUTO_TEST_CASE(iterator_string_ordering)
+{
+ char buf[10];
+
+ path ph = temp_directory_path() / unique_path();
+ CDBWrapper dbw(ph, (1 << 20), true, false, false);
+ for (int x=0x00; x<10; ++x) {
+ for (int y = 0; y < 10; y++) {
+ sprintf(buf, "%d", x);
+ StringContentsSerializer key(buf);
+ for (int z = 0; z < y; z++)
+ key += key;
+ uint32_t value = x*x;
+ BOOST_CHECK(dbw.Write(key, value));
+ }
+ }
+
+ boost::scoped_ptr<CDBIterator> it(const_cast<CDBWrapper*>(&dbw)->NewIterator());
+ for (int c=0; c<2; ++c) {
+ int seek_start;
+ if (c == 0)
+ seek_start = 0;
+ else
+ seek_start = 5;
+ sprintf(buf, "%d", seek_start);
+ StringContentsSerializer seek_key(buf);
+ it->Seek(seek_key);
+ for (int x=seek_start; x<10; ++x) {
+ for (int y = 0; y < 10; y++) {
+ sprintf(buf, "%d", x);
+ string exp_key(buf);
+ for (int z = 0; z < y; z++)
+ exp_key += exp_key;
+ StringContentsSerializer key;
+ uint32_t value;
+ BOOST_CHECK(it->Valid());
+ if (!it->Valid()) // Avoid spurious errors about invalid iterator's key and value in case of failure
+ break;
+ BOOST_CHECK(it->GetKey(key));
+ BOOST_CHECK(it->GetValue(value));
+ BOOST_CHECK_EQUAL(key.str, exp_key);
+ BOOST_CHECK_EQUAL(value, x*x);
+ it->Next();
+ }
+ }
+ BOOST_CHECK(!it->Valid());
+ }
+}
+
+
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp
index 8baaf3645f..82d61209b5 100644
--- a/src/test/hash_tests.cpp
+++ b/src/test/hash_tests.cpp
@@ -47,17 +47,58 @@ BOOST_AUTO_TEST_CASE(murmurhash3)
#undef T
}
+/*
+ SipHash-2-4 output with
+ k = 00 01 02 ...
+ and
+ in = (empty string)
+ in = 00 (1 byte)
+ in = 00 01 (2 bytes)
+ in = 00 01 02 (3 bytes)
+ ...
+ in = 00 01 02 ... 3e (63 bytes)
+
+ from: https://131002.net/siphash/siphash24.c
+*/
+uint64_t siphash_4_2_testvec[] = {
+ 0x726fdb47dd0e0e31, 0x74f839c593dc67fd, 0x0d6c8009d9a94f5a, 0x85676696d7fb7e2d,
+ 0xcf2794e0277187b7, 0x18765564cd99a68d, 0xcbc9466e58fee3ce, 0xab0200f58b01d137,
+ 0x93f5f5799a932462, 0x9e0082df0ba9e4b0, 0x7a5dbbc594ddb9f3, 0xf4b32f46226bada7,
+ 0x751e8fbc860ee5fb, 0x14ea5627c0843d90, 0xf723ca908e7af2ee, 0xa129ca6149be45e5,
+ 0x3f2acc7f57c29bdb, 0x699ae9f52cbe4794, 0x4bc1b3f0968dd39c, 0xbb6dc91da77961bd,
+ 0xbed65cf21aa2ee98, 0xd0f2cbb02e3b67c7, 0x93536795e3a33e88, 0xa80c038ccd5ccec8,
+ 0xb8ad50c6f649af94, 0xbce192de8a85b8ea, 0x17d835b85bbb15f3, 0x2f2e6163076bcfad,
+ 0xde4daaaca71dc9a5, 0xa6a2506687956571, 0xad87a3535c49ef28, 0x32d892fad841c342,
+ 0x7127512f72f27cce, 0xa7f32346f95978e3, 0x12e0b01abb051238, 0x15e034d40fa197ae,
+ 0x314dffbe0815a3b4, 0x027990f029623981, 0xcadcd4e59ef40c4d, 0x9abfd8766a33735c,
+ 0x0e3ea96b5304a7d0, 0xad0c42d6fc585992, 0x187306c89bc215a9, 0xd4a60abcf3792b95,
+ 0xf935451de4f21df2, 0xa9538f0419755787, 0xdb9acddff56ca510, 0xd06c98cd5c0975eb,
+ 0xe612a3cb9ecba951, 0xc766e62cfcadaf96, 0xee64435a9752fe72, 0xa192d576b245165a,
+ 0x0a8787bf8ecb74b2, 0x81b3e73d20b49b6f, 0x7fa8220ba3b2ecea, 0x245731c13ca42499,
+ 0xb78dbfaf3a8d83bd, 0xea1ad565322a1a0b, 0x60e61c23a3795013, 0x6606d7e446282b93,
+ 0x6ca4ecb15c5f91e1, 0x9f626da15c9625f3, 0xe51b38608ef25f57, 0x958a324ceb064572
+};
+
BOOST_AUTO_TEST_CASE(siphash)
{
CSipHasher hasher(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL);
BOOST_CHECK_EQUAL(hasher.Finalize(), 0x726fdb47dd0e0e31ull);
- hasher.Write(0x0706050403020100ULL);
+ static const unsigned char t0[1] = {0};
+ hasher.Write(t0, 1);
+ BOOST_CHECK_EQUAL(hasher.Finalize(), 0x74f839c593dc67fdull);
+ static const unsigned char t1[7] = {1,2,3,4,5,6,7};
+ hasher.Write(t1, 7);
BOOST_CHECK_EQUAL(hasher.Finalize(), 0x93f5f5799a932462ull);
hasher.Write(0x0F0E0D0C0B0A0908ULL);
BOOST_CHECK_EQUAL(hasher.Finalize(), 0x3f2acc7f57c29bdbull);
- hasher.Write(0x1716151413121110ULL);
- BOOST_CHECK_EQUAL(hasher.Finalize(), 0xb8ad50c6f649af94ull);
- hasher.Write(0x1F1E1D1C1B1A1918ULL);
+ static const unsigned char t2[2] = {16,17};
+ hasher.Write(t2, 2);
+ BOOST_CHECK_EQUAL(hasher.Finalize(), 0x4bc1b3f0968dd39cull);
+ static const unsigned char t3[9] = {18,19,20,21,22,23,24,25,26};
+ hasher.Write(t3, 9);
+ BOOST_CHECK_EQUAL(hasher.Finalize(), 0x2f2e6163076bcfadull);
+ static const unsigned char t4[5] = {27,28,29,30,31};
+ hasher.Write(t4, 5);
BOOST_CHECK_EQUAL(hasher.Finalize(), 0x7127512f72f27cceull);
hasher.Write(0x2726252423222120ULL);
BOOST_CHECK_EQUAL(hasher.Finalize(), 0x0e3ea96b5304a7d0ull);
@@ -65,6 +106,22 @@ BOOST_AUTO_TEST_CASE(siphash)
BOOST_CHECK_EQUAL(hasher.Finalize(), 0xe612a3cb9ecba951ull);
BOOST_CHECK_EQUAL(SipHashUint256(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL, uint256S("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100")), 0x7127512f72f27cceull);
+
+ // Check test vectors from spec, one byte at a time
+ CSipHasher hasher2(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL);
+ for (uint8_t x=0; x<ARRAYLEN(siphash_4_2_testvec); ++x)
+ {
+ BOOST_CHECK_EQUAL(hasher2.Finalize(), siphash_4_2_testvec[x]);
+ hasher2.Write(&x, 1);
+ }
+ // Check test vectors from spec, eight bytes at a time
+ CSipHasher hasher3(0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL);
+ for (uint8_t x=0; x<ARRAYLEN(siphash_4_2_testvec); x+=8)
+ {
+ BOOST_CHECK_EQUAL(hasher3.Finalize(), siphash_4_2_testvec[x]);
+ hasher3.Write(uint64_t(x)|(uint64_t(x+1)<<8)|(uint64_t(x+2)<<16)|(uint64_t(x+3)<<24)|
+ (uint64_t(x+4)<<32)|(uint64_t(x+5)<<40)|(uint64_t(x+6)<<48)|(uint64_t(x+7)<<56));
+ }
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
index 469862518c..3f5f0ee98b 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -385,8 +385,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
SetMockTime(0);
mempool.clear();
- BOOST_FOREACH(CTransaction *tx, txFirst)
- delete tx;
+ BOOST_FOREACH(CTransaction *_tx, txFirst)
+ delete _tx;
fCheckpointsEnabled = true;
}
diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp
index 2f3f607889..74ffe0cc74 100644
--- a/src/test/pmt_tests.cpp
+++ b/src/test/pmt_tests.cpp
@@ -37,8 +37,8 @@ BOOST_AUTO_TEST_CASE(pmt_test1)
seed_insecure_rand(false);
static const unsigned int nTxCounts[] = {1, 4, 7, 17, 56, 100, 127, 256, 312, 513, 1000, 4095};
- for (int n = 0; n < 12; n++) {
- unsigned int nTx = nTxCounts[n];
+ for (int i = 0; i < 12; i++) {
+ unsigned int nTx = nTxCounts[i];
// build a block with some dummy transactions
CBlock block;
diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp
index 644c3da213..2b00e6f567 100644
--- a/src/test/policyestimator_tests.cpp
+++ b/src/test/policyestimator_tests.cpp
@@ -74,9 +74,9 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
// 9/10 blocks add 2nd highest and so on until ...
// 1/10 blocks add lowest fee/pri transactions
while (txHashes[9-h].size()) {
- CTransaction btx;
- if (mpool.lookup(txHashes[9-h].back(), btx))
- block.push_back(btx);
+ std::shared_ptr<const CTransaction> ptx = mpool.get(txHashes[9-h].back());
+ if (ptx)
+ block.push_back(*ptx);
txHashes[9-h].pop_back();
}
}
@@ -160,9 +160,9 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
// Estimates should still not be below original
for (int j = 0; j < 10; j++) {
while(txHashes[j].size()) {
- CTransaction btx;
- if (mpool.lookup(txHashes[j].back(), btx))
- block.push_back(btx);
+ std::shared_ptr<const CTransaction> ptx = mpool.get(txHashes[j].back());
+ if (ptx)
+ block.push_back(*ptx);
txHashes[j].pop_back();
}
}
@@ -181,9 +181,9 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
tx.vin[0].prevout.n = 10000*blocknum+100*j+k;
uint256 hash = tx.GetHash();
mpool.addUnchecked(hash, entry.Fee(feeV[k/4][j]).Time(GetTime()).Priority(priV[k/4][j]).Height(blocknum).FromTx(tx, &mpool));
- CTransaction btx;
- if (mpool.lookup(hash, btx))
- block.push_back(btx);
+ std::shared_ptr<const CTransaction> ptx = mpool.get(hash);
+ if (ptx)
+ block.push_back(*ptx);
}
}
mpool.removeForBlock(block, ++blocknum, dummyConflicted);
diff --git a/src/test/prevector_tests.cpp b/src/test/prevector_tests.cpp
index b39b903530..d1407c1da9 100644
--- a/src/test/prevector_tests.cpp
+++ b/src/test/prevector_tests.cpp
@@ -192,8 +192,8 @@ BOOST_AUTO_TEST_CASE(PrevectorTestInt)
if (((r >> 21) % 32) == 7) {
int values[4];
int num = 1 + (insecure_rand() % 4);
- for (int i = 0; i < num; i++) {
- values[i] = insecure_rand();
+ for (int k = 0; k < num; k++) {
+ values[k] = insecure_rand();
}
test.insert_range(insecure_rand() % (test.size() + 1), values, values + num);
}
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index b99f952a0d..e467a4171d 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -376,6 +376,69 @@ BOOST_AUTO_TEST_CASE(test_ParseInt64)
BOOST_CHECK(!ParseInt64("32482348723847471234", NULL));
}
+BOOST_AUTO_TEST_CASE(test_ParseUInt32)
+{
+ uint32_t n;
+ // Valid values
+ BOOST_CHECK(ParseUInt32("1234", NULL));
+ BOOST_CHECK(ParseUInt32("0", &n) && n == 0);
+ BOOST_CHECK(ParseUInt32("1234", &n) && n == 1234);
+ BOOST_CHECK(ParseUInt32("01234", &n) && n == 1234); // no octal
+ BOOST_CHECK(ParseUInt32("2147483647", &n) && n == 2147483647);
+ BOOST_CHECK(ParseUInt32("2147483648", &n) && n == (uint32_t)2147483648);
+ BOOST_CHECK(ParseUInt32("4294967295", &n) && n == (uint32_t)4294967295);
+ // Invalid values
+ BOOST_CHECK(!ParseUInt32("", &n));
+ BOOST_CHECK(!ParseUInt32(" 1", &n)); // no padding inside
+ BOOST_CHECK(!ParseUInt32(" -1", &n));
+ BOOST_CHECK(!ParseUInt32("1 ", &n));
+ BOOST_CHECK(!ParseUInt32("1a", &n));
+ BOOST_CHECK(!ParseUInt32("aap", &n));
+ BOOST_CHECK(!ParseUInt32("0x1", &n)); // no hex
+ BOOST_CHECK(!ParseUInt32("0x1", &n)); // no hex
+ const char test_bytes[] = {'1', 0, '1'};
+ std::string teststr(test_bytes, sizeof(test_bytes));
+ BOOST_CHECK(!ParseUInt32(teststr, &n)); // no embedded NULs
+ // Overflow and underflow
+ BOOST_CHECK(!ParseUInt32("-2147483648", &n));
+ BOOST_CHECK(!ParseUInt32("4294967296", &n));
+ BOOST_CHECK(!ParseUInt32("-1234", &n));
+ BOOST_CHECK(!ParseUInt32("-32482348723847471234", NULL));
+ BOOST_CHECK(!ParseUInt32("32482348723847471234", NULL));
+}
+
+BOOST_AUTO_TEST_CASE(test_ParseUInt64)
+{
+ uint64_t n;
+ // Valid values
+ BOOST_CHECK(ParseUInt64("1234", NULL));
+ BOOST_CHECK(ParseUInt64("0", &n) && n == 0LL);
+ BOOST_CHECK(ParseUInt64("1234", &n) && n == 1234LL);
+ BOOST_CHECK(ParseUInt64("01234", &n) && n == 1234LL); // no octal
+ BOOST_CHECK(ParseUInt64("2147483647", &n) && n == 2147483647LL);
+ BOOST_CHECK(ParseUInt64("9223372036854775807", &n) && n == 9223372036854775807ULL);
+ BOOST_CHECK(ParseUInt64("9223372036854775808", &n) && n == 9223372036854775808ULL);
+ BOOST_CHECK(ParseUInt64("18446744073709551615", &n) && n == 18446744073709551615ULL);
+ // Invalid values
+ BOOST_CHECK(!ParseUInt64("", &n));
+ BOOST_CHECK(!ParseUInt64(" 1", &n)); // no padding inside
+ BOOST_CHECK(!ParseUInt64(" -1", &n));
+ BOOST_CHECK(!ParseUInt64("1 ", &n));
+ BOOST_CHECK(!ParseUInt64("1a", &n));
+ BOOST_CHECK(!ParseUInt64("aap", &n));
+ BOOST_CHECK(!ParseUInt64("0x1", &n)); // no hex
+ const char test_bytes[] = {'1', 0, '1'};
+ std::string teststr(test_bytes, sizeof(test_bytes));
+ BOOST_CHECK(!ParseUInt64(teststr, &n)); // no embedded NULs
+ // Overflow and underflow
+ BOOST_CHECK(!ParseUInt64("-9223372036854775809", NULL));
+ BOOST_CHECK(!ParseUInt64("18446744073709551616", NULL));
+ BOOST_CHECK(!ParseUInt64("-32482348723847471234", NULL));
+ BOOST_CHECK(!ParseUInt64("-2147483648", &n));
+ BOOST_CHECK(!ParseUInt64("-9223372036854775808", &n));
+ BOOST_CHECK(!ParseUInt64("-1234", &n));
+}
+
BOOST_AUTO_TEST_CASE(test_ParseDouble)
{
double n;
diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp
index 47d834c7b4..0d6b655675 100644
--- a/src/torcontrol.cpp
+++ b/src/torcontrol.cpp
@@ -574,7 +574,15 @@ void TorController::protocolinfo_cb(TorControlConnection& conn, const TorControl
* password: "password"
*/
std::string torpassword = GetArg("-torpassword", "");
- if (methods.count("NULL")) {
+ if (!torpassword.empty()) {
+ if (methods.count("HASHEDPASSWORD")) {
+ LogPrint("tor", "tor: Using HASHEDPASSWORD authentication\n");
+ boost::replace_all(torpassword, "\"", "\\\"");
+ conn.Command("AUTHENTICATE \"" + torpassword + "\"", boost::bind(&TorController::auth_cb, this, _1, _2));
+ } else {
+ LogPrintf("tor: Password provided with -torpassword, but HASHEDPASSWORD authentication is not available\n");
+ }
+ } else if (methods.count("NULL")) {
LogPrint("tor", "tor: Using NULL authentication\n");
conn.Command("AUTHENTICATE", boost::bind(&TorController::auth_cb, this, _1, _2));
} else if (methods.count("SAFECOOKIE")) {
@@ -595,13 +603,7 @@ void TorController::protocolinfo_cb(TorControlConnection& conn, const TorControl
}
}
} else if (methods.count("HASHEDPASSWORD")) {
- if (!torpassword.empty()) {
- LogPrint("tor", "tor: Using HASHEDPASSWORD authentication\n");
- boost::replace_all(torpassword, "\"", "\\\"");
- conn.Command("AUTHENTICATE \"" + torpassword + "\"", boost::bind(&TorController::auth_cb, this, _1, _2));
- } else {
- LogPrintf("tor: Password authentication required, but no password provided with -torpassword\n");
- }
+ LogPrintf("tor: The only supported authentication mechanism left is password, but no password provided with -torpassword\n");
} else {
LogPrintf("tor: No supported authentication method\n");
}
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 4f17e7f8ca..205ffd6379 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -23,18 +23,18 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
int64_t _nTime, double _entryPriority, unsigned int _entryHeight,
bool poolHasNoInputsOf, CAmount _inChainInputValue,
bool _spendsCoinbase, unsigned int _sigOps, LockPoints lp):
- tx(_tx), nFee(_nFee), nTime(_nTime), entryPriority(_entryPriority), entryHeight(_entryHeight),
+ tx(std::make_shared<CTransaction>(_tx)), nFee(_nFee), nTime(_nTime), entryPriority(_entryPriority), entryHeight(_entryHeight),
hadNoDependencies(poolHasNoInputsOf), inChainInputValue(_inChainInputValue),
spendsCoinbase(_spendsCoinbase), sigOpCount(_sigOps), lockPoints(lp)
{
- nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
- nModSize = tx.CalculateModifiedSize(nTxSize);
- nUsageSize = RecursiveDynamicUsage(tx);
+ nTxSize = ::GetSerializeSize(_tx, SER_NETWORK, PROTOCOL_VERSION);
+ nModSize = _tx.CalculateModifiedSize(nTxSize);
+ nUsageSize = RecursiveDynamicUsage(*tx) + memusage::DynamicUsage(tx);
nCountWithDescendants = 1;
nSizeWithDescendants = nTxSize;
nModFeesWithDescendants = nFee;
- CAmount nValueIn = tx.GetValueOut()+nFee;
+ CAmount nValueIn = _tx.GetValueOut()+nFee;
assert(inChainInputValue <= nValueIn);
feeDelta = 0;
@@ -147,11 +147,11 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<uint256> &vHashes
if (it == mapTx.end()) {
continue;
}
- std::map<COutPoint, CInPoint>::iterator iter = mapNextTx.lower_bound(COutPoint(hash, 0));
+ auto iter = mapNextTx.lower_bound(COutPoint(hash, 0));
// First calculate the children, and update setMemPoolChildren to
// include them, and update their setMemPoolParents to include this tx.
- for (; iter != mapNextTx.end() && iter->first.hash == hash; ++iter) {
- const uint256 &childHash = iter->second.ptx->GetHash();
+ for (; iter != mapNextTx.end() && iter->first->hash == hash; ++iter) {
+ const uint256 &childHash = iter->second->GetHash();
txiter childIter = mapTx.find(childHash);
assert(childIter != mapTx.end());
// We can skip updating entries we've encountered before or that
@@ -365,11 +365,11 @@ void CTxMemPool::pruneSpent(const uint256 &hashTx, CCoins &coins)
{
LOCK(cs);
- std::map<COutPoint, CInPoint>::iterator it = mapNextTx.lower_bound(COutPoint(hashTx, 0));
+ auto it = mapNextTx.lower_bound(COutPoint(hashTx, 0));
// iterate over all COutPoints in mapNextTx whose hash equals the provided hashTx
- while (it != mapNextTx.end() && it->first.hash == hashTx) {
- coins.Spend(it->first.n); // and remove those outputs from coins
+ while (it != mapNextTx.end() && it->first->hash == hashTx) {
+ coins.Spend(it->first->n); // and remove those outputs from coins
it++;
}
}
@@ -414,7 +414,7 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry,
const CTransaction& tx = newit->GetTx();
std::set<uint256> setParentTransactions;
for (unsigned int i = 0; i < tx.vin.size(); i++) {
- mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i);
+ mapNextTx.insert(std::make_pair(&tx.vin[i].prevout, &tx));
setParentTransactions.insert(tx.vin[i].prevout.hash);
}
// Don't bother worrying about child transactions of this one.
@@ -500,10 +500,10 @@ void CTxMemPool::removeRecursive(const CTransaction &origTx, std::list<CTransact
// happen during chain re-orgs if origTx isn't re-accepted into
// the mempool for any reason.
for (unsigned int i = 0; i < origTx.vout.size(); i++) {
- std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(origTx.GetHash(), i));
+ auto it = mapNextTx.find(COutPoint(origTx.GetHash(), i));
if (it == mapNextTx.end())
continue;
- txiter nextit = mapTx.find(it->second.ptx->GetHash());
+ txiter nextit = mapTx.find(it->second->GetHash());
assert(nextit != mapTx.end());
txToRemove.insert(nextit);
}
@@ -561,9 +561,9 @@ void CTxMemPool::removeConflicts(const CTransaction &tx, std::list<CTransaction>
list<CTransaction> result;
LOCK(cs);
BOOST_FOREACH(const CTxIn &txin, tx.vin) {
- std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(txin.prevout);
+ auto it = mapNextTx.find(txin.prevout);
if (it != mapNextTx.end()) {
- const CTransaction &txConflict = *it->second.ptx;
+ const CTransaction &txConflict = *it->second;
if (txConflict != tx)
{
removeRecursive(txConflict, removed);
@@ -671,10 +671,10 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
assert(coins && coins->IsAvailable(txin.prevout.n));
}
// Check whether its inputs are marked in mapNextTx.
- std::map<COutPoint, CInPoint>::const_iterator it3 = mapNextTx.find(txin.prevout);
+ auto it3 = mapNextTx.find(txin.prevout);
assert(it3 != mapNextTx.end());
- assert(it3->second.ptx == &tx);
- assert(it3->second.n == i);
+ assert(it3->first == &txin.prevout);
+ assert(it3->second == &tx);
i++;
}
assert(setParentCheck == GetMemPoolParents(it));
@@ -701,10 +701,10 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
// Check children against mapNextTx
CTxMemPool::setEntries setChildrenCheck;
- std::map<COutPoint, CInPoint>::const_iterator iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetHash(), 0));
+ auto iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetHash(), 0));
int64_t childSizes = 0;
- for (; iter != mapNextTx.end() && iter->first.hash == it->GetTx().GetHash(); ++iter) {
- txiter childit = mapTx.find(iter->second.ptx->GetHash());
+ for (; iter != mapNextTx.end() && iter->first->hash == it->GetTx().GetHash(); ++iter) {
+ txiter childit = mapTx.find(iter->second->GetHash());
assert(childit != mapTx.end()); // mapNextTx points to in-mempool transactions
if (setChildrenCheck.insert(childit).second) {
childSizes += childit->GetTxSize();
@@ -738,14 +738,12 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
stepsSinceLastRemove = 0;
}
}
- for (std::map<COutPoint, CInPoint>::const_iterator it = mapNextTx.begin(); it != mapNextTx.end(); it++) {
- uint256 hash = it->second.ptx->GetHash();
+ for (auto it = mapNextTx.cbegin(); it != mapNextTx.cend(); it++) {
+ uint256 hash = it->second->GetHash();
indexed_transaction_set::const_iterator it2 = mapTx.find(hash);
const CTransaction& tx = it2->GetTx();
assert(it2 != mapTx.end());
- assert(&tx == it->second.ptx);
- assert(tx.vin.size() > it->second.n);
- assert(it->first == it->second.ptx->vin[it->second.n].prevout);
+ assert(&tx == it->second);
}
assert(totalTxSize == checkTotal);
@@ -770,50 +768,76 @@ bool CTxMemPool::CompareDepthAndScore(const uint256& hasha, const uint256& hashb
namespace {
class DepthAndScoreComparator
{
- CTxMemPool *mp;
public:
- DepthAndScoreComparator(CTxMemPool *mempool) : mp(mempool) {}
- bool operator()(const uint256& a, const uint256& b) { return mp->CompareDepthAndScore(a, b); }
+ bool operator()(const CTxMemPool::indexed_transaction_set::const_iterator& a, const CTxMemPool::indexed_transaction_set::const_iterator& b)
+ {
+ uint64_t counta = a->GetCountWithAncestors();
+ uint64_t countb = b->GetCountWithAncestors();
+ if (counta == countb) {
+ return CompareTxMemPoolEntryByScore()(*a, *b);
+ }
+ return counta < countb;
+ }
};
}
-void CTxMemPool::queryHashes(vector<uint256>& vtxid)
+std::vector<CTxMemPool::indexed_transaction_set::const_iterator> CTxMemPool::GetSortedDepthAndScore() const
{
- vtxid.clear();
+ std::vector<indexed_transaction_set::const_iterator> iters;
+ AssertLockHeld(cs);
+
+ iters.reserve(mapTx.size());
+ for (indexed_transaction_set::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) {
+ iters.push_back(mi);
+ }
+ std::sort(iters.begin(), iters.end(), DepthAndScoreComparator());
+ return iters;
+}
+
+void CTxMemPool::queryHashes(vector<uint256>& vtxid)
+{
LOCK(cs);
+ auto iters = GetSortedDepthAndScore();
+
+ vtxid.clear();
vtxid.reserve(mapTx.size());
- for (indexed_transaction_set::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi)
- vtxid.push_back(mi->GetTx().GetHash());
- std::sort(vtxid.begin(), vtxid.end(), DepthAndScoreComparator(this));
+ for (auto it : iters) {
+ vtxid.push_back(it->GetTx().GetHash());
+ }
}
-
-bool CTxMemPool::lookup(uint256 hash, CTransaction& result, int64_t& time) const
+std::vector<TxMempoolInfo> CTxMemPool::infoAll() const
{
LOCK(cs);
- indexed_transaction_set::const_iterator i = mapTx.find(hash);
- if (i == mapTx.end()) return false;
- result = i->GetTx();
- time = i->GetTime();
- return true;
+ auto iters = GetSortedDepthAndScore();
+
+ std::vector<TxMempoolInfo> ret;
+ ret.reserve(mapTx.size());
+ for (auto it : iters) {
+ ret.push_back(TxMempoolInfo{it->GetSharedTx(), it->GetTime(), CFeeRate(it->GetFee(), it->GetTxSize())});
+ }
+
+ return ret;
}
-bool CTxMemPool::lookup(uint256 hash, CTransaction& result) const
+std::shared_ptr<const CTransaction> CTxMemPool::get(const uint256& hash) const
{
- int64_t time;
- return CTxMemPool::lookup(hash, result, time);
+ LOCK(cs);
+ indexed_transaction_set::const_iterator i = mapTx.find(hash);
+ if (i == mapTx.end())
+ return nullptr;
+ return i->GetSharedTx();
}
-bool CTxMemPool::lookupFeeRate(const uint256& hash, CFeeRate& feeRate) const
+TxMempoolInfo CTxMemPool::info(const uint256& hash) const
{
LOCK(cs);
indexed_transaction_set::const_iterator i = mapTx.find(hash);
if (i == mapTx.end())
- return false;
- feeRate = CFeeRate(i->GetFee(), i->GetTxSize());
- return true;
+ return TxMempoolInfo();
+ return TxMempoolInfo{i->GetSharedTx(), i->GetTime(), CFeeRate(i->GetFee(), i->GetTxSize())};
}
CFeeRate CTxMemPool::estimateFee(int nBlocks) const
@@ -926,9 +950,9 @@ bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) const {
// If an entry in the mempool exists, always return that one, as it's guaranteed to never
// conflict with the underlying cache, and it cannot have pruned entries (as it contains full)
// transactions. First checking the underlying cache risks returning a pruned entry instead.
- CTransaction tx;
- if (mempool.lookup(txid, tx)) {
- coins = CCoins(tx, MEMPOOL_HEIGHT);
+ shared_ptr<const CTransaction> ptx = mempool.get(txid);
+ if (ptx) {
+ coins = CCoins(*ptx, MEMPOOL_HEIGHT);
return true;
}
return (base->GetCoins(txid, coins) && !coins.IsPruned());
@@ -1079,8 +1103,8 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<uint256>* pvNoSpendsRe
BOOST_FOREACH(const CTxIn& txin, tx.vin) {
if (exists(txin.prevout.hash))
continue;
- std::map<COutPoint, CInPoint>::iterator it = mapNextTx.lower_bound(COutPoint(txin.prevout.hash, 0));
- if (it == mapNextTx.end() || it->first.hash != txin.prevout.hash)
+ auto it = mapNextTx.lower_bound(COutPoint(txin.prevout.hash, 0));
+ if (it == mapNextTx.end() || it->first->hash != txin.prevout.hash)
pvNoSpendsRemaining->push_back(txin.prevout.hash);
}
}
diff --git a/src/txmempool.h b/src/txmempool.h
index 75cf0f4c12..f0e9b2e2c6 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -7,10 +7,12 @@
#define BITCOIN_TXMEMPOOL_H
#include <list>
+#include <memory>
#include <set>
#include "amount.h"
#include "coins.h"
+#include "indirectmap.h"
#include "primitives/transaction.h"
#include "sync.h"
@@ -74,7 +76,7 @@ class CTxMemPool;
class CTxMemPoolEntry
{
private:
- CTransaction tx;
+ std::shared_ptr<const CTransaction> tx;
CAmount nFee; //!< Cached to avoid expensive parent-transaction lookups
size_t nTxSize; //!< ... and avoid recomputing tx size
size_t nModSize; //!< ... and modified size for priority
@@ -111,7 +113,8 @@ public:
unsigned int nSigOps, LockPoints lp);
CTxMemPoolEntry(const CTxMemPoolEntry& other);
- const CTransaction& GetTx() const { return this->tx; }
+ const CTransaction& GetTx() const { return *this->tx; }
+ std::shared_ptr<const CTransaction> GetSharedTx() const { return this->tx; }
/**
* Fast calculation of lower bound of current priority as update
* from entry priority. Only inputs that were originally in-chain will age.
@@ -306,18 +309,19 @@ struct ancestor_score {};
class CBlockPolicyEstimator;
-/** An inpoint - a combination of a transaction and an index n into its vin */
-class CInPoint
+/**
+ * Information about a mempool transaction.
+ */
+struct TxMempoolInfo
{
-public:
- const CTransaction* ptx;
- uint32_t n;
-
- CInPoint() { SetNull(); }
- CInPoint(const CTransaction* ptxIn, uint32_t nIn) { ptx = ptxIn; n = nIn; }
- void SetNull() { ptx = NULL; n = (uint32_t) -1; }
- bool IsNull() const { return (ptx == NULL && n == (uint32_t) -1); }
- size_t DynamicMemoryUsage() const { return 0; }
+ /** The transaction itself */
+ std::shared_ptr<const CTransaction> tx;
+
+ /** Time the transaction entered the mempool. */
+ int64_t nTime;
+
+ /** Feerate of the transaction. */
+ CFeeRate feeRate;
};
/**
@@ -477,8 +481,10 @@ private:
void UpdateParent(txiter entry, txiter parent, bool add);
void UpdateChild(txiter entry, txiter child, bool add);
+ std::vector<indexed_transaction_set::const_iterator> GetSortedDepthAndScore() const;
+
public:
- std::map<COutPoint, CInPoint> mapNextTx;
+ indirectmap<COutPoint, const CTransaction*> mapNextTx;
std::map<uint256, std::pair<double, CAmount> > mapDeltas;
/** Create a new CTxMemPool.
@@ -601,9 +607,9 @@ public:
return (mapTx.count(hash) != 0);
}
- bool lookup(uint256 hash, CTransaction& result) const;
- bool lookup(uint256 hash, CTransaction& result, int64_t& time) const;
- bool lookupFeeRate(const uint256& hash, CFeeRate& feeRate) const;
+ std::shared_ptr<const CTransaction> get(const uint256& hash) const;
+ TxMempoolInfo info(const uint256& hash) const;
+ std::vector<TxMempoolInfo> infoAll() const;
/** Estimate fee rate needed to get into the next nBlocks
* If no answer can be given at nBlocks, return an estimate
diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp
index 0f9334cbe3..5ffdb3be15 100644
--- a/src/utilstrencodings.cpp
+++ b/src/utilstrencodings.cpp
@@ -461,6 +461,40 @@ bool ParseInt64(const std::string& str, int64_t *out)
n <= std::numeric_limits<int64_t>::max();
}
+bool ParseUInt32(const std::string& str, uint32_t *out)
+{
+ if (!ParsePrechecks(str))
+ return false;
+ if (str.size() >= 1 && str[0] == '-') // Reject negative values, unfortunately strtoul accepts these by default if they fit in the range
+ return false;
+ char *endp = NULL;
+ errno = 0; // strtoul will not set errno if valid
+ unsigned long int n = strtoul(str.c_str(), &endp, 10);
+ if(out) *out = (uint32_t)n;
+ // Note that strtoul returns a *unsigned long int*, so even if it doesn't report a over/underflow
+ // we still have to check that the returned value is within the range of an *uint32_t*. On 64-bit
+ // platforms the size of these types may be different.
+ return endp && *endp == 0 && !errno &&
+ n <= std::numeric_limits<uint32_t>::max();
+}
+
+bool ParseUInt64(const std::string& str, uint64_t *out)
+{
+ if (!ParsePrechecks(str))
+ return false;
+ if (str.size() >= 1 && str[0] == '-') // Reject negative values, unfortunately strtoull accepts these by default if they fit in the range
+ return false;
+ char *endp = NULL;
+ errno = 0; // strtoull will not set errno if valid
+ unsigned long long int n = strtoull(str.c_str(), &endp, 10);
+ if(out) *out = (uint64_t)n;
+ // Note that strtoull returns a *unsigned long long int*, so even if it doesn't report a over/underflow
+ // we still have to check that the returned value is within the range of an *uint64_t*.
+ return endp && *endp == 0 && !errno &&
+ n <= std::numeric_limits<uint64_t>::max();
+}
+
+
bool ParseDouble(const std::string& str, double *out)
{
if (!ParsePrechecks(str))
diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h
index d40613cfc4..5744f78c6e 100644
--- a/src/utilstrencodings.h
+++ b/src/utilstrencodings.h
@@ -71,6 +71,20 @@ bool ParseInt32(const std::string& str, int32_t *out);
bool ParseInt64(const std::string& str, int64_t *out);
/**
+ * Convert decimal string to unsigned 32-bit integer with strict parse error feedback.
+ * @returns true if the entire string could be parsed as valid integer,
+ * false if not the entire string could be parsed or when overflow or underflow occurred.
+ */
+bool ParseUInt32(const std::string& str, uint32_t *out);
+
+/**
+ * Convert decimal string to unsigned 64-bit integer with strict parse error feedback.
+ * @returns true if the entire string could be parsed as valid integer,
+ * false if not the entire string could be parsed or when overflow or underflow occurred.
+ */
+bool ParseUInt64(const std::string& str, uint64_t *out);
+
+/**
* Convert string to double with strict parse error feedback.
* @returns true if the entire string could be parsed as valid double,
* false if not the entire string could be parsed or when overflow or underflow occurred.
diff --git a/src/versionbits.cpp b/src/versionbits.cpp
index 78feb8ab0c..043819c654 100644
--- a/src/versionbits.cpp
+++ b/src/versionbits.cpp
@@ -4,6 +4,19 @@
#include "versionbits.h"
+#include "consensus/params.h"
+
+const struct BIP9DeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_BITS_DEPLOYMENTS] = {
+ {
+ /*.name =*/ "testdummy",
+ /*.gbt_force =*/ true,
+ },
+ {
+ /*.name =*/ "csv",
+ /*.gbt_force =*/ true,
+ }
+};
+
ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const
{
int nPeriod = Period(params);
diff --git a/src/versionbits.h b/src/versionbits.h
index 04f4738272..ede2dcdda8 100644
--- a/src/versionbits.h
+++ b/src/versionbits.h
@@ -30,6 +30,15 @@ enum ThresholdState {
// will either be NULL or a block with (height + 1) % Period() == 0.
typedef std::map<const CBlockIndex*, ThresholdState> ThresholdConditionCache;
+struct BIP9DeploymentInfo {
+ /** Deployment name */
+ const char *name;
+ /** Whether GBT clients can safely ignore this rule in simplified usage */
+ bool gbt_force;
+};
+
+extern const struct BIP9DeploymentInfo VersionBitsDeploymentInfo[];
+
/**
* Abstract class that implements BIP9-style threshold logic, and caches results.
*/
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
index bb40cf7245..14c2e31d95 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -590,7 +590,7 @@ UniValue dumpwallet(const UniValue& params, bool fHelp)
std::sort(vKeyBirth.begin(), vKeyBirth.end());
// produce output
- file << strprintf("# Wallet dump created by Bitcoin %s (%s)\n", CLIENT_BUILD, CLIENT_DATE);
+ file << strprintf("# Wallet dump created by Bitcoin %s\n", CLIENT_BUILD);
file << strprintf("# * Created on %s\n", EncodeDumpTime(GetTime()));
file << strprintf("# * Best block at time of backup was %i (%s),\n", chainActive.Height(), chainActive.Tip()->GetBlockHash().ToString());
file << strprintf("# mined on %s\n", EncodeDumpTime(chainActive.Tip()->GetBlockTime()));
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index b9f086b092..2d4e95911d 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -146,38 +146,12 @@ UniValue getnewaddress(const UniValue& params, bool fHelp)
CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
{
- CWalletDB walletdb(pwalletMain->strWalletFile);
-
- CAccount account;
- walletdb.ReadAccount(strAccount, account);
-
- if (!bForceNew) {
- if (!account.vchPubKey.IsValid())
- bForceNew = true;
- else {
- // Check if the current key has been used
- CScript scriptPubKey = GetScriptForDestination(account.vchPubKey.GetID());
- for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
- it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid();
- ++it)
- BOOST_FOREACH(const CTxOut& txout, (*it).second.vout)
- if (txout.scriptPubKey == scriptPubKey) {
- bForceNew = true;
- break;
- }
- }
- }
-
- // Generate a new key
- if (bForceNew) {
- if (!pwalletMain->GetKeyFromPool(account.vchPubKey))
- throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
-
- pwalletMain->SetAddressBook(account.vchPubKey.GetID(), strAccount, "receive");
- walletdb.WriteAccount(strAccount, account);
+ CPubKey pubKey;
+ if (!pwalletMain->GetAccountPubkey(pubKey, strAccount, bForceNew)) {
+ throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
}
- return CBitcoinAddress(account.vchPubKey.GetID());
+ return CBitcoinAddress(pubKey.GetID());
}
UniValue getaccountaddress(const UniValue& params, bool fHelp)
@@ -804,33 +778,7 @@ UniValue movecmd(const UniValue& params, bool fHelp)
if (params.size() > 4)
strComment = params[4].get_str();
- CWalletDB walletdb(pwalletMain->strWalletFile);
- if (!walletdb.TxnBegin())
- throw JSONRPCError(RPC_DATABASE_ERROR, "database error");
-
- int64_t nNow = GetAdjustedTime();
-
- // Debit
- CAccountingEntry debit;
- debit.nOrderPos = pwalletMain->IncOrderPosNext(&walletdb);
- debit.strAccount = strFrom;
- debit.nCreditDebit = -nAmount;
- debit.nTime = nNow;
- debit.strOtherAccount = strTo;
- debit.strComment = strComment;
- pwalletMain->AddAccountingEntry(debit, walletdb);
-
- // Credit
- CAccountingEntry credit;
- credit.nOrderPos = pwalletMain->IncOrderPosNext(&walletdb);
- credit.strAccount = strTo;
- credit.nCreditDebit = nAmount;
- credit.nTime = nNow;
- credit.strOtherAccount = strFrom;
- credit.strComment = strComment;
- pwalletMain->AddAccountingEntry(credit, walletdb);
-
- if (!walletdb.TxnCommit())
+ if (!pwalletMain->AccountMove(strFrom, strTo, nAmount, strComment))
throw JSONRPCError(RPC_DATABASE_ERROR, "database error");
return true;
@@ -2121,7 +2069,11 @@ UniValue lockunspent(const UniValue& params, bool fHelp)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object");
const UniValue& o = output.get_obj();
- RPCTypeCheckObj(o, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM));
+ RPCTypeCheckObj(o,
+ {
+ {"txid", UniValueType(UniValue::VSTR)},
+ {"vout", UniValueType(UniValue::VNUM)},
+ });
string txid = find_value(o, "txid").get_str();
if (!IsHex(txid))
@@ -2307,13 +2259,14 @@ UniValue listunspent(const UniValue& params, bool fHelp)
"\nResult\n"
"[ (array of json object)\n"
" {\n"
- " \"txid\" : \"txid\", (string) the transaction id \n"
+ " \"txid\" : \"txid\", (string) the transaction id \n"
" \"vout\" : n, (numeric) the vout value\n"
- " \"address\" : \"address\", (string) the bitcoin address\n"
- " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n"
- " \"scriptPubKey\" : \"key\", (string) the script key\n"
+ " \"address\" : \"address\", (string) the bitcoin address\n"
+ " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n"
+ " \"scriptPubKey\" : \"key\", (string) the script key\n"
" \"amount\" : x.xxx, (numeric) the transaction amount in " + CURRENCY_UNIT + "\n"
" \"confirmations\" : n, (numeric) The number of confirmations\n"
+ " \"redeemScript\" : n (string) The redeemScript if scriptPubKey is P2SH\n"
" \"spendable\" : xxx, (bool) Whether we have the private keys to spend this output\n"
" \"solvable\" : xxx (bool) Whether we know how to spend this output, ignoring the lack of keys\n"
" }\n"
@@ -2359,38 +2312,34 @@ UniValue listunspent(const UniValue& params, bool fHelp)
if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth)
continue;
- if (setAddress.size()) {
- CTxDestination address;
- if (!ExtractDestination(out.tx->vout[out.i].scriptPubKey, address))
- continue;
+ CTxDestination address;
+ const CScript& scriptPubKey = out.tx->vout[out.i].scriptPubKey;
+ bool fValidAddress = ExtractDestination(scriptPubKey, address);
- if (!setAddress.count(address))
- continue;
- }
+ if (setAddress.size() && (!fValidAddress || !setAddress.count(address)))
+ continue;
- CAmount nValue = out.tx->vout[out.i].nValue;
- const CScript& pk = out.tx->vout[out.i].scriptPubKey;
UniValue entry(UniValue::VOBJ);
entry.push_back(Pair("txid", out.tx->GetHash().GetHex()));
entry.push_back(Pair("vout", out.i));
- CTxDestination address;
- if (ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) {
+
+ if (fValidAddress) {
entry.push_back(Pair("address", CBitcoinAddress(address).ToString()));
+
if (pwalletMain->mapAddressBook.count(address))
entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name));
- }
- entry.push_back(Pair("scriptPubKey", HexStr(pk.begin(), pk.end())));
- if (pk.IsPayToScriptHash()) {
- CTxDestination address;
- if (ExtractDestination(pk, address)) {
+
+ if (scriptPubKey.IsPayToScriptHash()) {
const CScriptID& hash = boost::get<CScriptID>(address);
CScript redeemScript;
if (pwalletMain->GetCScript(hash, redeemScript))
entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end())));
}
}
- entry.push_back(Pair("amount",ValueFromAmount(nValue)));
- entry.push_back(Pair("confirmations",out.nDepth));
+
+ entry.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
+ entry.push_back(Pair("amount", ValueFromAmount(out.tx->vout[out.i].nValue)));
+ entry.push_back(Pair("confirmations", out.nDepth));
entry.push_back(Pair("spendable", out.fSpendable));
entry.push_back(Pair("solvable", out.fSolvable));
results.push_back(entry);
@@ -2424,12 +2373,13 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
" \"changePosition\" (numeric, optional, default random) The index of the change output\n"
" \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n"
" \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n"
+ " \"feeRate\" (numeric, optional, default not set: makes wallet determine the fee) Set a specific feerate (" + CURRENCY_UNIT + " per KB)\n"
" }\n"
" for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n"
"\nResult:\n"
"{\n"
" \"hex\": \"value\", (string) The resulting raw transaction (hex-encoded string)\n"
- " \"fee\": n, (numeric) Fee the resulting transaction pays\n"
+ " \"fee\": n, (numeric) Fee in " + CURRENCY_UNIT + " the resulting transaction pays\n"
" \"changepos\": n (numeric) The position of the added change output, or -1\n"
"}\n"
"\"hex\" \n"
@@ -2450,6 +2400,8 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
int changePosition = -1;
bool includeWatching = false;
bool lockUnspents = false;
+ CFeeRate feeRate = CFeeRate(0);
+ bool overrideEstimatedFeerate = false;
if (params.size() > 1) {
if (params[1].type() == UniValue::VBOOL) {
@@ -2461,7 +2413,15 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
UniValue options = params[1];
- RPCTypeCheckObj(options, boost::assign::map_list_of("changeAddress", UniValue::VSTR)("changePosition", UniValue::VNUM)("includeWatching", UniValue::VBOOL)("lockUnspents", UniValue::VBOOL), true, true);
+ RPCTypeCheckObj(options,
+ {
+ {"changeAddress", UniValueType(UniValue::VSTR)},
+ {"changePosition", UniValueType(UniValue::VNUM)},
+ {"includeWatching", UniValueType(UniValue::VBOOL)},
+ {"lockUnspents", UniValueType(UniValue::VBOOL)},
+ {"feeRate", UniValueType()}, // will be checked below
+ },
+ true, true);
if (options.exists("changeAddress")) {
CBitcoinAddress address(options["changeAddress"].get_str());
@@ -2480,6 +2440,12 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
if (options.exists("lockUnspents"))
lockUnspents = options["lockUnspents"].get_bool();
+
+ if (options.exists("feeRate"))
+ {
+ feeRate = CFeeRate(AmountFromValue(options["feeRate"]));
+ overrideEstimatedFeerate = true;
+ }
}
}
@@ -2491,20 +2457,20 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
if (origTx.vout.size() == 0)
throw JSONRPCError(RPC_INVALID_PARAMETER, "TX must have at least one output");
- if (changePosition != -1 && (changePosition < 0 || changePosition > origTx.vout.size()))
+ if (changePosition != -1 && (changePosition < 0 || (unsigned int)changePosition > origTx.vout.size()))
throw JSONRPCError(RPC_INVALID_PARAMETER, "changePosition out of bounds");
CMutableTransaction tx(origTx);
- CAmount nFee;
+ CAmount nFeeOut;
string strFailReason;
- if(!pwalletMain->FundTransaction(tx, nFee, changePosition, strFailReason, includeWatching, lockUnspents, changeAddress))
+ if(!pwalletMain->FundTransaction(tx, nFeeOut, overrideEstimatedFeerate, feeRate, changePosition, strFailReason, includeWatching, lockUnspents, changeAddress))
throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason);
UniValue result(UniValue::VOBJ);
result.push_back(Pair("hex", EncodeHexTx(tx)));
result.push_back(Pair("changepos", changePosition));
- result.push_back(Pair("fee", ValueFromAmount(nFee)));
+ result.push_back(Pair("fee", ValueFromAmount(nFeeOut)));
return result;
}
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index da0d6f272b..9faf21591f 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -606,6 +606,78 @@ int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
return nRet;
}
+bool CWallet::AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment)
+{
+ CWalletDB walletdb(strWalletFile);
+ if (!walletdb.TxnBegin())
+ return false;
+
+ int64_t nNow = GetAdjustedTime();
+
+ // Debit
+ CAccountingEntry debit;
+ debit.nOrderPos = IncOrderPosNext(&walletdb);
+ debit.strAccount = strFrom;
+ debit.nCreditDebit = -nAmount;
+ debit.nTime = nNow;
+ debit.strOtherAccount = strTo;
+ debit.strComment = strComment;
+ AddAccountingEntry(debit, walletdb);
+
+ // Credit
+ CAccountingEntry credit;
+ credit.nOrderPos = IncOrderPosNext(&walletdb);
+ credit.strAccount = strTo;
+ credit.nCreditDebit = nAmount;
+ credit.nTime = nNow;
+ credit.strOtherAccount = strFrom;
+ credit.strComment = strComment;
+ AddAccountingEntry(credit, walletdb);
+
+ if (!walletdb.TxnCommit())
+ return false;
+
+ return true;
+}
+
+bool CWallet::GetAccountPubkey(CPubKey &pubKey, std::string strAccount, bool bForceNew)
+{
+ CWalletDB walletdb(strWalletFile);
+
+ CAccount account;
+ walletdb.ReadAccount(strAccount, account);
+
+ if (!bForceNew) {
+ if (!account.vchPubKey.IsValid())
+ bForceNew = true;
+ else {
+ // Check if the current key has been used
+ CScript scriptPubKey = GetScriptForDestination(account.vchPubKey.GetID());
+ for (map<uint256, CWalletTx>::iterator it = mapWallet.begin();
+ it != mapWallet.end() && account.vchPubKey.IsValid();
+ ++it)
+ BOOST_FOREACH(const CTxOut& txout, (*it).second.vout)
+ if (txout.scriptPubKey == scriptPubKey) {
+ bForceNew = true;
+ break;
+ }
+ }
+ }
+
+ // Generate a new key
+ if (bForceNew) {
+ if (!GetKeyFromPool(account.vchPubKey))
+ return false;
+
+ SetAddressBook(account.vchPubKey.GetID(), strAccount, "receive");
+ walletdb.WriteAccount(strAccount, account);
+ }
+
+ pubKey = account.vchPubKey;
+
+ return true;
+}
+
void CWallet::MarkDirty()
{
{
@@ -1909,7 +1981,7 @@ bool CWallet::SelectCoins(const vector<COutput>& vAvailableCoins, const CAmount&
return res;
}
-bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange)
+bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, bool overrideEstimatedFeeRate, const CFeeRate& specificFeeRate, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange)
{
vector<CRecipient> vecSend;
@@ -1924,6 +1996,9 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC
coinControl.destChange = destChange;
coinControl.fAllowOtherInputs = true;
coinControl.fAllowWatchOnly = includeWatching;
+ coinControl.fOverrideFeeRate = overrideEstimatedFeeRate;
+ coinControl.nFeeRate = specificFeeRate;
+
BOOST_FOREACH(const CTxIn& txin, tx.vin)
coinControl.Select(txin.prevout);
@@ -2157,7 +2232,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
// Insert change txn at random position:
nChangePosInOut = GetRandInt(txNew.vout.size()+1);
}
- else if (nChangePosInOut > txNew.vout.size())
+ else if ((unsigned int)nChangePosInOut > txNew.vout.size())
{
strFailReason = _("Change index out of range");
return false;
@@ -2233,6 +2308,8 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
if (coinControl && nFeeNeeded > 0 && coinControl->nMinimumTotalFee > nFeeNeeded) {
nFeeNeeded = coinControl->nMinimumTotalFee;
}
+ if (coinControl && coinControl->fOverrideFeeRate)
+ nFeeNeeded = coinControl->nFeeRate.GetFee(nBytes);
// If we made it here and we aren't even able to meet the relay fee on the next pass, give up
// because we must be at the maximum allowed fee.
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index b2180a5a26..683c901444 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -718,6 +718,8 @@ public:
* @return next transaction order id
*/
int64_t IncOrderPosNext(CWalletDB *pwalletdb = NULL);
+ bool AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment = "");
+ bool GetAccountPubkey(CPubKey &pubKey, std::string strAccount, bool bForceNew = false);
void MarkDirty();
bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb);
@@ -738,7 +740,7 @@ public:
* Insert additional inputs into the transaction by
* calling CreateTransaction();
*/
- bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange = CNoDestination());
+ bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, bool overrideEstimatedFeeRate, const CFeeRate& specificFeeRate, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange = CNoDestination());
/**
* Create a new transaction paying the recipients with a set of coins