Implement a hard fork for extended/infinite claim expiration times #112
74
configure.ac
|
@ -171,6 +171,24 @@ if test "x$CXXFLAGS_overridden" = "xno"; then
|
|||
fi
|
||||
CPPFLAGS="$CPPFLAGS -DBOOST_SPIRIT_THREADSAFE -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS"
|
||||
|
||||
AC_ARG_WITH([utils],
|
||||
[AS_HELP_STRING([--with-utils],
|
||||
[build bitcoin-cli bitcoin-tx (default=yes)])],
|
||||
[build_bitcoin_utils=$withval],
|
||||
[build_bitcoin_utils=yes])
|
||||
|
||||
AC_ARG_WITH([libs],
|
||||
[AS_HELP_STRING([--with-libs],
|
||||
[build libraries (default=yes)])],
|
||||
[build_bitcoin_libs=$withval],
|
||||
[build_bitcoin_libs=yes])
|
||||
|
||||
AC_ARG_WITH([daemon],
|
||||
[AS_HELP_STRING([--with-daemon],
|
||||
[build bitcoind daemon (default=yes)])],
|
||||
[build_bitcoind=$withval],
|
||||
[build_bitcoind=yes])
|
||||
|
||||
AC_LANG_PUSH([C++])
|
||||
|
||||
use_pkgconfig=yes
|
||||
|
@ -500,6 +518,19 @@ if test x$use_upnp != xno; then
|
|||
)
|
||||
fi
|
||||
|
||||
BITCOIN_QT_INIT
|
||||
|
||||
dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus
|
||||
BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt4])
|
||||
|
||||
if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests = xnononono; then
|
||||
use_boost=no
|
||||
else
|
||||
use_boost=yes
|
||||
fi
|
||||
|
||||
if test x$use_boost = xyes; then
|
||||
|
||||
dnl Check for boost libs
|
||||
AX_BOOST_BASE
|
||||
AX_BOOST_SYSTEM
|
||||
|
@ -537,6 +568,10 @@ if test x$use_reduce_exports != xno; then
|
|||
CPPFLAGS="$TEMP_CPPFLAGS"
|
||||
fi
|
||||
|
||||
elif test x$use_reduce_exports = xauto; then
|
||||
use_reduce_exports=yes
|
||||
fi
|
||||
|
||||
if test x$use_reduce_exports != xno; then
|
||||
CXXFLAGS="$CXXFLAGS $RE_CXXFLAGS"
|
||||
AX_CHECK_LINK_FLAG([[-Wl,--exclude-libs,ALL]], [RELDFLAGS="-Wl,--exclude-libs,ALL"])
|
||||
|
@ -549,6 +584,8 @@ if test x$use_tests = xyes; then
|
|||
fi
|
||||
|
||||
|
||||
if test x$use_boost = xyes; then
|
||||
|
||||
AX_BOOST_UNIT_TEST_FRAMEWORK
|
||||
|
||||
dnl Determine if -DBOOST_TEST_DYN_LINK is needed
|
||||
|
@ -568,8 +605,12 @@ if test x$use_tests = xyes; then
|
|||
[AC_MSG_RESULT(no)])
|
||||
LIBS="$TEMP_LIBS"
|
||||
CPPFLAGS="$TEMP_CPPFLAGS"
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
if test x$use_boost = xyes; then
|
||||
|
||||
BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB"
|
||||
|
||||
dnl Boost >= 1.50 uses sleep_for rather than the now-deprecated sleep, however
|
||||
|
@ -626,25 +667,7 @@ if test x$boost_sleep != xyes; then
|
|||
AC_MSG_ERROR(No working boost sleep implementation found.)
|
||||
fi
|
||||
|
||||
AC_ARG_WITH([utils],
|
||||
[AS_HELP_STRING([--with-utils],
|
||||
[build bitcoin-cli bitcoin-tx (default=yes)])],
|
||||
[build_bitcoin_utils=$withval],
|
||||
[build_bitcoin_utils=yes])
|
||||
|
||||
AC_ARG_WITH([libs],
|
||||
[AS_HELP_STRING([--with-libs],
|
||||
[build libraries (default=yes)])],
|
||||
[build_bitcoin_libs=$withval],
|
||||
[build_bitcoin_libs=yes])
|
||||
|
||||
AC_ARG_WITH([daemon],
|
||||
[AS_HELP_STRING([--with-daemon],
|
||||
[build bitcoind daemon (default=yes)])],
|
||||
[build_bitcoind=$withval],
|
||||
[build_bitcoind=yes])
|
||||
|
||||
BITCOIN_QT_INIT
|
||||
fi
|
||||
|
||||
if test x$use_pkgconfig = xyes; then
|
||||
|
||||
|
@ -678,6 +701,14 @@ else
|
|||
fi
|
||||
fi
|
||||
|
||||
CFLAGS_TEMP="$CFLAGS"
|
||||
LIBS_TEMP="$LIBS"
|
||||
CFLAGS="$CFLAGS $SSL_CFLAGS $CRYPTO_CFLAGS"
|
||||
LIBS="$LIBS $SSL_LIBS $CRYPTO_LIBS"
|
||||
AC_CHECK_HEADER([openssl/ec.h],, AC_MSG_ERROR(OpenSSL ec header missing),)
|
||||
CFLAGS="$CFLAGS_TEMP"
|
||||
LIBS="$LIBS_TEMP"
|
||||
|
||||
BITCOIN_QT_PATH_PROGS([PROTOC], [protoc],$protoc_bin_path)
|
||||
|
||||
AC_MSG_CHECKING([whether to build bitcoind])
|
||||
|
@ -696,9 +727,6 @@ if test x$build_bitcoin_libs = xyes; then
|
|||
fi
|
||||
AC_MSG_RESULT($build_bitcoin_libs)
|
||||
|
||||
dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus
|
||||
BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt4])
|
||||
|
||||
AC_LANG_POP
|
||||
|
||||
if test "x$use_ccache" != "xno"; then
|
||||
|
@ -812,7 +840,7 @@ else
|
|||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
if test x$build_bitcoin_utils$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_tests = xnononono; then
|
||||
if test x$build_bitcoin_utils$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_tests = xnonononono; then
|
||||
AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-gui or --enable-tests])
|
||||
fi
|
||||
|
||||
|
|
73
contrib/devtools/optimize-pngs.py
Executable file
|
@ -0,0 +1,73 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import hashlib
|
||||
from PIL import Image
|
||||
|
||||
def file_hash(filename):
|
||||
'''Return hash of raw file contents'''
|
||||
with open(filename, 'rb') as f:
|
||||
return hashlib.sha256(f.read()).hexdigest()
|
||||
|
||||
def content_hash(filename):
|
||||
'''Return hash of RGBA contents of image'''
|
||||
i = Image.open(filename)
|
||||
i = i.convert('RGBA')
|
||||
data = i.tostring()
|
||||
return hashlib.sha256(data).hexdigest()
|
||||
|
||||
#optimize png, remove various color profiles, remove ancillary chunks (alla) and text chunks (text)
|
||||
#pngcrush -brute -ow -rem gAMA -rem cHRM -rem iCCP -rem sRGB -rem alla -rem text
|
||||
|
||||
pngcrush = 'pngcrush'
|
||||
git = 'git'
|
||||
folders = ["src/qt/res/movies", "src/qt/res/icons", "src/qt/res/images"]
|
||||
basePath = subprocess.check_output([git, 'rev-parse', '--show-toplevel']).rstrip('\n')
|
||||
totalSaveBytes = 0
|
||||
|
||||
outputArray = []
|
||||
for folder in folders:
|
||||
absFolder=os.path.join(basePath, folder)
|
||||
for file in os.listdir(absFolder):
|
||||
extension = os.path.splitext(file)[1]
|
||||
if extension.lower() == '.png':
|
||||
print("optimizing "+file+"..."),
|
||||
file_path = os.path.join(absFolder, file)
|
||||
fileMetaMap = {'file' : file, 'osize': os.path.getsize(file_path), 'sha256Old' : file_hash(file_path)};
|
||||
fileMetaMap['contentHashPre'] = content_hash(file_path)
|
||||
|
||||
pngCrushOutput = ""
|
||||
try:
|
||||
pngCrushOutput = subprocess.check_output(
|
||||
[pngcrush, "-brute", "-ow", "-rem", "gAMA", "-rem", "cHRM", "-rem", "iCCP", "-rem", "sRGB", "-rem", "alla", "-rem", "text", file_path],
|
||||
stderr=subprocess.STDOUT).rstrip('\n')
|
||||
except:
|
||||
print "pngcrush is not installed, aborting..."
|
||||
sys.exit(0)
|
||||
|
||||
#verify
|
||||
if "Not a PNG file" in subprocess.check_output([pngcrush, "-n", "-v", file_path], stderr=subprocess.STDOUT):
|
||||
print "PNG file "+file+" is corrupted after crushing, check out pngcursh version"
|
||||
sys.exit(1)
|
||||
|
||||
fileMetaMap['sha256New'] = file_hash(file_path)
|
||||
fileMetaMap['contentHashPost'] = content_hash(file_path)
|
||||
|
||||
if fileMetaMap['contentHashPre'] != fileMetaMap['contentHashPost']:
|
||||
print "Image contents of PNG file "+file+" before and after crushing don't match"
|
||||
sys.exit(1)
|
||||
|
||||
fileMetaMap['psize'] = os.path.getsize(file_path)
|
||||
outputArray.append(fileMetaMap)
|
||||
print("done\n"),
|
||||
|
||||
print "summary:\n+++++++++++++++++"
|
||||
for fileDict in outputArray:
|
||||
oldHash = fileDict['sha256Old']
|
||||
newHash = fileDict['sha256New']
|
||||
totalSaveBytes += fileDict['osize'] - fileDict['psize']
|
||||
print fileDict['file']+"\n size diff from: "+str(fileDict['osize'])+" to: "+str(fileDict['psize'])+"\n old sha256: "+oldHash+"\n new sha256: "+newHash+"\n"
|
||||
|
||||
print "completed. Total reduction: "+str(totalSaveBytes)+" bytes"
|
BIN
contrib/gitian-downloader/jonasschnelli.pgp
Normal file
|
@ -1,11 +1,8 @@
|
|||
### Seeds ###
|
||||
|
||||
Utility to generate the pnSeed[] array that is compiled into the client
|
||||
(see [src/net.cpp](/src/net.cpp)).
|
||||
Utility to generate the seeds.txt list that is compiled into the client
|
||||
(see [src/chainparamsseeds.h](/src/chainparamsseeds.h) and [share/seeds](/share/seeds)).
|
||||
|
||||
The 600 seeds compiled into the 0.8 release were created from sipa's DNS seed data, like this:
|
||||
The 512 seeds compiled into the 0.10 release were created from sipa's DNS seed data, like this:
|
||||
|
||||
curl -s http://bitcoin.sipa.be/seeds.txt | head -1000 | makeseeds.py
|
||||
|
||||
The input to makeseeds.py is assumed to be approximately sorted from most-reliable to least-reliable,
|
||||
with IP:port first on each line (lines that don't match IPv4:port are ignored).
|
||||
curl -s http://bitcoin.sipa.be/seeds.txt | makeseeds.py
|
||||
|
|
|
@ -1,32 +1,118 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Generate pnSeed[] from Pieter's DNS seeder
|
||||
# Generate seeds.txt from Pieter's DNS seeder
|
||||
#
|
||||
|
||||
NSEEDS=600
|
||||
NSEEDS=512
|
||||
|
||||
MAX_SEEDS_PER_ASN=2
|
||||
|
||||
MIN_BLOCKS = 337600
|
||||
|
||||
# These are hosts that have been observed to be behaving strangely (e.g.
|
||||
# aggressively connecting to every node).
|
||||
SUSPICIOUS_HOSTS = set([
|
||||
"130.211.129.106", "178.63.107.226",
|
||||
"83.81.130.26", "88.198.17.7", "148.251.238.178", "176.9.46.6",
|
||||
"54.173.72.127", "54.174.10.182", "54.183.64.54", "54.194.231.211",
|
||||
"54.66.214.167", "54.66.220.137", "54.67.33.14", "54.77.251.214",
|
||||
"54.94.195.96", "54.94.200.247"
|
||||
])
|
||||
|
||||
import re
|
||||
import sys
|
||||
from subprocess import check_output
|
||||
import dns.resolver
|
||||
|
||||
PATTERN_IPV4 = re.compile(r"^((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})):8333$")
|
||||
PATTERN_AGENT = re.compile(r"^(\/Satoshi:0.8.6\/|\/Satoshi:0.9.(2|3)\/|\/Satoshi:0.10.\d{1,2}\/)$")
|
||||
|
||||
def parseline(line):
|
||||
sline = line.split()
|
||||
if len(sline) < 11:
|
||||
return None
|
||||
# Match only IPv4
|
||||
m = PATTERN_IPV4.match(sline[0])
|
||||
if m is None:
|
||||
return None
|
||||
# Do IPv4 sanity check
|
||||
ip = 0
|
||||
for i in range(0,4):
|
||||
if int(m.group(i+2)) < 0 or int(m.group(i+2)) > 255:
|
||||
return None
|
||||
ip = ip + (int(m.group(i+2)) << (8*(3-i)))
|
||||
if ip == 0:
|
||||
return None
|
||||
# Skip bad results.
|
||||
if sline[1] == 0:
|
||||
return None
|
||||
# Extract uptime %.
|
||||
uptime30 = float(sline[7][:-1])
|
||||
# Extract Unix timestamp of last success.
|
||||
lastsuccess = int(sline[2])
|
||||
# Extract protocol version.
|
||||
version = int(sline[10])
|
||||
# Extract user agent.
|
||||
agent = sline[11][1:-1]
|
||||
# Extract service flags.
|
||||
service = int(sline[9], 16)
|
||||
# Extract blocks.
|
||||
blocks = int(sline[8])
|
||||
# Construct result.
|
||||
return {
|
||||
'ip': m.group(1),
|
||||
'ipnum': ip,
|
||||
'uptime': uptime30,
|
||||
'lastsuccess': lastsuccess,
|
||||
'version': version,
|
||||
'agent': agent,
|
||||
'service': service,
|
||||
'blocks': blocks,
|
||||
}
|
||||
|
||||
# Based on Greg Maxwell's seed_filter.py
|
||||
def filterbyasn(ips, max_per_asn, max_total):
|
||||
result = []
|
||||
asn_count = {}
|
||||
for ip in ips:
|
||||
if len(result) == max_total:
|
||||
break
|
||||
try:
|
||||
asn = int([x.to_text() for x in dns.resolver.query('.'.join(reversed(ip['ip'].split('.'))) + '.origin.asn.cymru.com', 'TXT').response.answer][0].split('\"')[1].split(' ')[0])
|
||||
if asn not in asn_count:
|
||||
asn_count[asn] = 0
|
||||
if asn_count[asn] == max_per_asn:
|
||||
continue
|
||||
asn_count[asn] += 1
|
||||
result.append(ip)
|
||||
except:
|
||||
sys.stderr.write('ERR: Could not resolve ASN for "' + ip['ip'] + '"\n')
|
||||
return result
|
||||
|
||||
def main():
|
||||
lines = sys.stdin.readlines()
|
||||
ips = [parseline(line) for line in lines]
|
||||
|
||||
ips = []
|
||||
pattern = re.compile(r"^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}):8333")
|
||||
for line in lines:
|
||||
m = pattern.match(line)
|
||||
if m is None:
|
||||
continue
|
||||
ip = 0
|
||||
for i in range(0,4):
|
||||
ip = ip + (int(m.group(i+1)) << (8*(i)))
|
||||
if ip == 0:
|
||||
continue
|
||||
ips.append(ip)
|
||||
# Skip entries with valid IPv4 address.
|
||||
ips = [ip for ip in ips if ip is not None]
|
||||
# Skip entries from suspicious hosts.
|
||||
ips = [ip for ip in ips if ip['ip'] not in SUSPICIOUS_HOSTS]
|
||||
# Enforce minimal number of blocks.
|
||||
ips = [ip for ip in ips if ip['blocks'] >= MIN_BLOCKS]
|
||||
# Require service bit 1.
|
||||
ips = [ip for ip in ips if (ip['service'] & 1) == 1]
|
||||
# Require at least 50% 30-day uptime.
|
||||
ips = [ip for ip in ips if ip['uptime'] > 50]
|
||||
# Require a known and recent user agent.
|
||||
ips = [ip for ip in ips if PATTERN_AGENT.match(ip['agent'])]
|
||||
# Sort by availability (and use last success as tie breaker)
|
||||
ips.sort(key=lambda x: (x['uptime'], x['lastsuccess'], x['ip']), reverse=True)
|
||||
# Look up ASNs and limit results, both per ASN and globally.
|
||||
ips = filterbyasn(ips, MAX_SEEDS_PER_ASN, NSEEDS)
|
||||
# Sort the results by IP address (for deterministic output).
|
||||
ips.sort(key=lambda x: (x['ipnum']))
|
||||
|
||||
for row in range(0, min(NSEEDS,len(ips)), 8):
|
||||
print " " + ", ".join([ "0x%08x"%i for i in ips[row:row+8] ]) + ","
|
||||
for ip in ips:
|
||||
print ip['ip']
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package=openssl
|
||||
$(package)_version=1.0.1j
|
||||
$(package)_version=1.0.1k
|
||||
$(package)_download_path=https://www.openssl.org/source
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=1b60ca8789ba6f03e8ef20da2293b8dc131c39d83814e775069f02d26354edf3
|
||||
$(package)_sha256_hash=8f9faeaebad088e772f4ef5e38252d472be4d878c6b3a2718c10a4fcebe7a41c
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)"
|
||||
|
@ -23,7 +23,7 @@ $(package)_config_opts_i686_mingw32=mingw
|
|||
endef
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
sed -i.old "/define DATE/d" crypto/Makefile && \
|
||||
sed -i.old "/define DATE/d" util/mkbuildinf.pl && \
|
||||
sed -i.old "s|engines apps test|engines|" Makefile.org
|
||||
endef
|
||||
|
||||
|
|
|
@ -21,12 +21,6 @@ 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.
|
||||
|
||||
There's also an assumption that you already have `git` installed. If
|
||||
not, it's the path of least resistance to install [Github for Mac](https://mac.github.com/)
|
||||
(OS X 10.7+) or
|
||||
[Git for OS X](https://code.google.com/p/git-osx-installer/). It is also
|
||||
available via Homebrew.
|
||||
|
||||
You will also need to install [Homebrew](http://brew.sh) in order to install library
|
||||
dependencies.
|
||||
|
||||
|
@ -38,7 +32,9 @@ Instructions: Homebrew
|
|||
|
||||
#### Install dependencies using Homebrew
|
||||
|
||||
brew install autoconf automake libtool boost miniupnpc openssl pkg-config protobuf qt
|
||||
brew install autoconf automake libtool boost miniupnpc openssl pkg-config protobuf qt5
|
||||
|
||||
NOTE: Building with Qt4 is still supported, however, could result in a broken UI. As such, building with Qt5 is recommended.
|
||||
|
||||
#### Installing berkeley-db4 using Homebrew
|
||||
|
||||
|
@ -46,7 +42,7 @@ The homebrew package for berkeley-db4 has been broken for some time. It will in
|
|||
|
||||
Running this command takes you into brew's interactive mode, which allows you to configure, make, and install by hand:
|
||||
```
|
||||
$ brew install https://raw.github.com/mxcl/homebrew/master/Library/Formula/berkeley-db4.rb -–without-java
|
||||
$ brew install https://raw.github.com/homebrew/homebrew/master/Library/Formula/berkeley-db4.rb -–without-java
|
||||
```
|
||||
|
||||
The rest of these commands are run inside brew interactive mode:
|
||||
|
@ -73,7 +69,7 @@ After exiting, you'll get a warning that the install is keg-only, which means it
|
|||
2. Build bitcoind:
|
||||
|
||||
./autogen.sh
|
||||
./configure
|
||||
./configure --with-gui=qt5
|
||||
make
|
||||
|
||||
3. It is also a good idea to build and run the unit tests:
|
||||
|
@ -115,7 +111,7 @@ All dependencies should be compiled with these flags:
|
|||
-arch x86_64
|
||||
-isysroot $(xcode-select --print-path)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk
|
||||
|
||||
Once dependencies are compiled, see release-process.md for how the Bitcoin-Qt.app
|
||||
Once dependencies are compiled, see [doc/release-process.md](release-process.md) for how the Bitcoin-Qt.app
|
||||
bundle is packaged and signed to create the .dmg disk image that is distributed.
|
||||
|
||||
Running
|
||||
|
|
|
@ -26,6 +26,7 @@ testScripts=(
|
|||
'mempool_spendcoinbase.py'
|
||||
'mempool_coinbase_spends.py'
|
||||
'httpbasics.py'
|
||||
'zapwallettxes.py'
|
||||
# 'forknotify.py'
|
||||
);
|
||||
if [ "x${ENABLE_BITCOIND}${ENABLE_UTILS}${ENABLE_WALLET}" = "x111" ]; then
|
||||
|
@ -33,7 +34,7 @@ if [ "x${ENABLE_BITCOIND}${ENABLE_UTILS}${ENABLE_WALLET}" = "x111" ]; then
|
|||
do
|
||||
if [ -z "$1" ] || [ "$1" == "${testScripts[$i]}" ] || [ "$1.py" == "${testScripts[$i]}" ]
|
||||
then
|
||||
echo -e "running testscript \033[1m${testScripts[$i]}...\033[0m"
|
||||
echo -e "Running testscript \033[1m${testScripts[$i]}...\033[0m"
|
||||
${BUILDDIR}/qa/rpc-tests/${testScripts[$i]} --srcdir "${BUILDDIR}/src"
|
||||
fi
|
||||
done
|
||||
|
|
|
@ -10,7 +10,7 @@ touch "$DATADIR/regtest/debug.log"
|
|||
tail -q -n 1 -F "$DATADIR/regtest/debug.log" | grep -m 1 -q "Done loading" &
|
||||
WAITER=$!
|
||||
PORT=`expr 10000 + $$ % 55536`
|
||||
"@abs_top_builddir@/src/bitcoind@EXEEXT@" -connect=0.0.0.0 -datadir="$DATADIR" -rpcuser=user -rpcpassword=pass -listen -keypool=3 -debug -debug=net -logtimestamps -checkmempool=0 -port=$PORT -whitelist=127.0.0.1 -regtest -rpcport=`expr $PORT + 1` &
|
||||
"@abs_top_builddir@/src/bitcoind@EXEEXT@" -connect=0.0.0.0 -datadir="$DATADIR" -rpcuser=user -rpcpassword=pass -listen -keypool=3 -debug -debug=net -logtimestamps -checkmempool=0 -relaypriority=0 -port=$PORT -whitelist=127.0.0.1 -regtest -rpcport=`expr $PORT + 1` &
|
||||
BITCOIND=$!
|
||||
|
||||
#Install a watchdog.
|
||||
|
|
|
@ -21,6 +21,9 @@ except ImportError:
|
|||
import urlparse
|
||||
|
||||
class HTTPBasicsTest (BitcoinTestFramework):
|
||||
def setup_nodes(self):
|
||||
return start_nodes(4, self.options.tmpdir, extra_args=[['-rpckeepalive=1'], ['-rpckeepalive=0'], [], []])
|
||||
|
||||
def run_test(self):
|
||||
|
||||
#################################################
|
||||
|
@ -71,6 +74,29 @@ class HTTPBasicsTest (BitcoinTestFramework):
|
|||
assert_equal('"error":null' in out1, True)
|
||||
assert_equal(conn.sock!=None, False) #now the connection must be closed after the response
|
||||
|
||||
#node1 (2nd node) is running with disabled keep-alive option
|
||||
urlNode1 = urlparse.urlparse(self.nodes[1].url)
|
||||
authpair = urlNode1.username + ':' + urlNode1.password
|
||||
headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
|
||||
|
||||
conn = httplib.HTTPConnection(urlNode1.hostname, urlNode1.port)
|
||||
conn.connect()
|
||||
conn.request('GET', '/', '{"method": "getbestblockhash"}', headers)
|
||||
out1 = conn.getresponse().read();
|
||||
assert_equal('"error":null' in out1, True)
|
||||
assert_equal(conn.sock!=None, False) #connection must be closed because keep-alive was set to false
|
||||
|
||||
#node2 (third node) is running with standard keep-alive parameters which means keep-alive is off
|
||||
urlNode2 = urlparse.urlparse(self.nodes[2].url)
|
||||
authpair = urlNode2.username + ':' + urlNode2.password
|
||||
headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
|
||||
|
||||
conn = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port)
|
||||
conn.connect()
|
||||
conn.request('GET', '/', '{"method": "getbestblockhash"}', headers)
|
||||
out1 = conn.getresponse().read();
|
||||
assert_equal('"error":null' in out1, True)
|
||||
assert_equal(conn.sock!=None, False) #connection must be closed because bitcoind should use keep-alive by default
|
||||
|
||||
if __name__ == '__main__':
|
||||
HTTPBasicsTest ().main ()
|
||||
|
|
|
@ -16,20 +16,20 @@ class EstimateFeeTest(BitcoinTestFramework):
|
|||
def setup_network(self):
|
||||
self.nodes = []
|
||||
self.nodes.append(start_node(0, self.options.tmpdir,
|
||||
["-debug=mempool", "-debug=estimatefee"]))
|
||||
["-debug=mempool", "-debug=estimatefee", "-relaypriority=0"]))
|
||||
# Node1 mines small-but-not-tiny blocks, and allows free transactions.
|
||||
# NOTE: the CreateNewBlock code starts counting block size at 1,000 bytes,
|
||||
# so blockmaxsize of 2,000 is really just 1,000 bytes (room enough for
|
||||
# 6 or 7 transactions)
|
||||
self.nodes.append(start_node(1, self.options.tmpdir,
|
||||
["-blockprioritysize=1500", "-blockmaxsize=2000",
|
||||
"-debug=mempool", "-debug=estimatefee"]))
|
||||
"-debug=mempool", "-debug=estimatefee", "-relaypriority=0"]))
|
||||
connect_nodes(self.nodes[1], 0)
|
||||
|
||||
# Node2 is a stingy miner, that
|
||||
# produces very small blocks (room for only 3 or so transactions)
|
||||
node2args = [ "-blockprioritysize=0", "-blockmaxsize=1500",
|
||||
"-debug=mempool", "-debug=estimatefee"]
|
||||
"-debug=mempool", "-debug=estimatefee", "-relaypriority=0"]
|
||||
self.nodes.append(start_node(2, self.options.tmpdir, node2args))
|
||||
connect_nodes(self.nodes[2], 0)
|
||||
|
||||
|
|
|
@ -33,8 +33,11 @@ class BitcoinTestFramework(object):
|
|||
print("Initializing test directory "+self.options.tmpdir)
|
||||
initialize_chain(self.options.tmpdir)
|
||||
|
||||
def setup_nodes(self):
|
||||
return start_nodes(4, self.options.tmpdir)
|
||||
|
||||
def setup_network(self, split = False):
|
||||
self.nodes = start_nodes(4, self.options.tmpdir)
|
||||
self.nodes = self.setup_nodes()
|
||||
|
||||
# Connect the nodes as a "chain". This allows us
|
||||
# to split the network between nodes 1 and 2 to get
|
||||
|
|
82
qa/rpc-tests/zapwallettxes.py
Executable file
|
@ -0,0 +1,82 @@
|
|||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2014 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 import BitcoinTestFramework
|
||||
from util import *
|
||||
|
||||
|
||||
class ZapWalletTXesTest (BitcoinTestFramework):
|
||||
|
||||
def setup_chain(self):
|
||||
print("Initializing test directory "+self.options.tmpdir)
|
||||
initialize_chain_clean(self.options.tmpdir, 3)
|
||||
|
||||
def setup_network(self, split=False):
|
||||
self.nodes = start_nodes(3, self.options.tmpdir)
|
||||
connect_nodes_bi(self.nodes,0,1)
|
||||
connect_nodes_bi(self.nodes,1,2)
|
||||
connect_nodes_bi(self.nodes,0,2)
|
||||
self.is_network_split=False
|
||||
self.sync_all()
|
||||
|
||||
def run_test (self):
|
||||
print "Mining blocks..."
|
||||
self.nodes[0].setgenerate(True, 1)
|
||||
self.sync_all()
|
||||
self.nodes[1].setgenerate(True, 101)
|
||||
self.sync_all()
|
||||
|
||||
assert_equal(self.nodes[0].getbalance(), 50)
|
||||
|
||||
txid0 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)
|
||||
txid1 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10)
|
||||
self.sync_all()
|
||||
self.nodes[0].setgenerate(True, 1)
|
||||
self.sync_all()
|
||||
|
||||
txid2 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)
|
||||
txid3 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10)
|
||||
|
||||
tx0 = self.nodes[0].gettransaction(txid0)
|
||||
assert_equal(tx0['txid'], txid0) #tx0 must be available (confirmed)
|
||||
|
||||
tx1 = self.nodes[0].gettransaction(txid1)
|
||||
assert_equal(tx1['txid'], txid1) #tx1 must be available (confirmed)
|
||||
|
||||
tx2 = self.nodes[0].gettransaction(txid2)
|
||||
assert_equal(tx2['txid'], txid2) #tx2 must be available (unconfirmed)
|
||||
|
||||
tx3 = self.nodes[0].gettransaction(txid3)
|
||||
assert_equal(tx3['txid'], txid3) #tx3 must be available (unconfirmed)
|
||||
|
||||
#restart bitcoind
|
||||
self.nodes[0].stop()
|
||||
bitcoind_processes[0].wait()
|
||||
self.nodes[0] = start_node(0,self.options.tmpdir)
|
||||
|
||||
tx3 = self.nodes[0].gettransaction(txid3)
|
||||
assert_equal(tx3['txid'], txid3) #tx must be available (unconfirmed)
|
||||
|
||||
self.nodes[0].stop()
|
||||
bitcoind_processes[0].wait()
|
||||
|
||||
#restart bitcoind with zapwallettxes
|
||||
self.nodes[0] = start_node(0,self.options.tmpdir, ["-zapwallettxes=1"])
|
||||
|
||||
aException = False
|
||||
try:
|
||||
tx3 = self.nodes[0].gettransaction(txid3)
|
||||
except JSONRPCException,e:
|
||||
print e
|
||||
aException = True
|
||||
|
||||
assert_equal(aException, True) #there must be a expection because the unconfirmed wallettx0 must be gone by now
|
||||
|
||||
tx0 = self.nodes[0].gettransaction(txid0)
|
||||
assert_equal(tx0['txid'], txid0) #tx0 (confirmed) must still be available because it was confirmed
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ZapWalletTXesTest ().main ()
|
|
@ -1,165 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
# Test -zapwallettxes=<mode>
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "Usage: $0 path_to_binaries"
|
||||
echo "e.g. $0 ../../src"
|
||||
echo "Env vars BITCOIND and BITCOINCLI may be used to specify the exact binaries used"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -f
|
||||
|
||||
BITCOIND=${BITCOIND:-${1}/bitcoind}
|
||||
CLI=${BITCOINCLI:-${1}/bitcoin-cli}
|
||||
|
||||
DIR="${BASH_SOURCE%/*}"
|
||||
SENDANDWAIT="${DIR}/send.sh"
|
||||
if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
|
||||
. "$DIR/util.sh"
|
||||
|
||||
D=$(mktemp -d test.XXXXX)
|
||||
|
||||
D1=${D}/node1
|
||||
CreateDataDir "$D1" port=11000 rpcport=11001
|
||||
B1ARGS="-datadir=$D1"
|
||||
$BITCOIND $B1ARGS &
|
||||
B1PID=$!
|
||||
|
||||
D2=${D}/node2
|
||||
CreateDataDir "$D2" port=11010 rpcport=11011
|
||||
B2ARGS="-datadir=$D2"
|
||||
$BITCOIND $B2ARGS &
|
||||
B2PID=$!
|
||||
|
||||
function CleanUp {
|
||||
$CLI $B2ARGS stop > /dev/null 2>&1
|
||||
wait $B2PID
|
||||
$CLI $B1ARGS stop > /dev/null 2>&1
|
||||
wait $B1PID
|
||||
|
||||
rm -rf $D
|
||||
}
|
||||
|
||||
# 110 blocks, 10 mature == 500 XBT
|
||||
$CLI $B1ARGS setgenerate true 110
|
||||
$CLI $B2ARGS setgenerate true 110
|
||||
|
||||
CheckBalance "$B1ARGS" 500
|
||||
CheckBalance "$B2ARGS" 500
|
||||
|
||||
# Send 10 XBT
|
||||
TXID1_DEFAULT=$($CLI $B1ARGS sendtoaddress "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 10)
|
||||
TXID2_DEFAULT=$($CLI $B2ARGS sendtoaddress "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 10)
|
||||
|
||||
CheckBalance $B1ARGS 490
|
||||
CheckBalance $B2ARGS 490
|
||||
|
||||
# Move 10 XBT to testaccount
|
||||
TMP=$($CLI $B1ARGS move "" "testaccount" 10)
|
||||
TMP=$($CLI $B2ARGS move "" "testaccount" 10)
|
||||
|
||||
CheckBalance $B1ARGS 10 "testaccount"
|
||||
CheckBalance $B2ARGS 10 "testaccount"
|
||||
|
||||
# Send 1 XBT from testaccount
|
||||
TXID1_TESTACCOUNT=$($CLI $B1ARGS sendfrom "testaccount" "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 1)
|
||||
TXID2_TESTACCOUNT=$($CLI $B2ARGS sendfrom "testaccount" "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 1)
|
||||
|
||||
CheckBalance $B1ARGS 9 "testaccount"
|
||||
CheckBalance $B2ARGS 9 "testaccount"
|
||||
|
||||
CheckBalance $B1ARGS 489
|
||||
CheckBalance $B2ARGS 489
|
||||
|
||||
# Confirm transactions
|
||||
$CLI $B1ARGS setgenerate true 1
|
||||
$CLI $B2ARGS setgenerate true 1
|
||||
|
||||
# Create unconfirmed transaction
|
||||
TXID1_UNCONFIRMED=$($CLI $B1ARGS sendtoaddress "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 1)
|
||||
TXID2_UNCONFIRMED=$($CLI $B2ARGS sendtoaddress "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 1)
|
||||
|
||||
# check balance (we created another 50 and spent 1 in the meantime)
|
||||
CheckBalance $B1ARGS 538
|
||||
CheckBalance $B2ARGS 538
|
||||
|
||||
# Safety check, if unconfirmed transactions are there
|
||||
$CLI $B1ARGS gettransaction $TXID1_UNCONFIRMED > /dev/null 2>&1
|
||||
if [[ $? -ne 0 ]] ; then
|
||||
echoerr "gettransaction1_1: $TXID1_UNCONFIRMED failed"
|
||||
CleanUp
|
||||
exit 1
|
||||
fi
|
||||
$CLI $B2ARGS gettransaction $TXID2_UNCONFIRMED > /dev/null 2>&1
|
||||
if [[ $? -ne 0 ]] ; then
|
||||
echoerr "gettransaction2_1: $TXID2_UNCONFIRMED failed"
|
||||
CleanUp
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# stop nodes
|
||||
$CLI $B2ARGS stop > /dev/null 2>&1
|
||||
wait $B2PID
|
||||
$CLI $B1ARGS stop > /dev/null 2>&1
|
||||
wait $B1PID
|
||||
|
||||
# restart nodes with -zapwallettxes
|
||||
$BITCOIND -zapwallettxes=1 $B1ARGS &
|
||||
B1PID=$!
|
||||
$BITCOIND -zapwallettxes=2 $B2ARGS &
|
||||
B2PID=$!
|
||||
|
||||
# check if confirmed transactions are there
|
||||
$CLI $B1ARGS gettransaction $TXID1_DEFAULT > /dev/null 2>&1
|
||||
if [[ $? -ne 0 ]] ; then
|
||||
echoerr "check confirmed transaction 1: $TXID1_DEFAULT failed"
|
||||
CleanUp
|
||||
exit 1
|
||||
fi
|
||||
$CLI $B2ARGS gettransaction $TXID2_DEFAULT > /dev/null 2>&1
|
||||
if [[ $? -ne 0 ]] ; then
|
||||
echoerr "check confirmed transaction 2: $TXID2_DEFAULT failed"
|
||||
CleanUp
|
||||
exit 1
|
||||
fi
|
||||
$CLI $B1ARGS gettransaction $TXID1_TESTACCOUNT > /dev/null 2>&1
|
||||
if [[ $? -ne 0 ]] ; then
|
||||
echoerr "check confirmed transaction 3: $TXID1_TESTACCOUNT failed"
|
||||
CleanUp
|
||||
exit 1
|
||||
fi
|
||||
$CLI $B2ARGS gettransaction $TXID2_TESTACCOUNT > /dev/null 2>&1
|
||||
if [[ $? -ne 0 ]] ; then
|
||||
echoerr "check confirmed transaction 4: $TXID2_TESTACCOUNT failed"
|
||||
CleanUp
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check if unconfirmed transaction is gone
|
||||
$CLI $B1ARGS gettransaction $TXID1_UNCONFIRMED > /dev/null 2>&1
|
||||
if [[ $? -eq 0 ]] ; then
|
||||
echoerr "check unconfirmed transaction 1: $TXID1_UNCONFIRMED failed"
|
||||
CleanUp
|
||||
exit 1
|
||||
fi
|
||||
$CLI $B2ARGS gettransaction $TXID2_UNCONFIRMED > /dev/null 2>&1
|
||||
if [[ $? -eq 0 ]] ; then
|
||||
echoerr "check unconfirmed transaction 2: $TXID2_UNCONFIRMED failed"
|
||||
CleanUp
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check zapwallet mode 1, testaccount balance must be 9 (keeping transaction metadata)
|
||||
CheckBalance $B1ARGS 9 "testaccount"
|
||||
|
||||
# check zapwallet mode 2, testaccount balance must be 10 (dropping transaction metadata)
|
||||
CheckBalance $B2ARGS 10 "testaccount"
|
||||
|
||||
echo "Tests successful, cleaning up"
|
||||
CleanUp
|
||||
exit 0
|
|
@ -37,7 +37,7 @@ $(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*)
|
|||
|
||||
# Make is not made aware of per-object dependencies to avoid limiting building parallelization
|
||||
# But to build the less dependent modules first, we manually select their order here:
|
||||
noinst_LIBRARIES = \
|
||||
EXTRA_LIBRARIES = \
|
||||
crypto/libbitcoin_crypto.a \
|
||||
libbitcoin_util.a \
|
||||
libbitcoin_common.a \
|
||||
|
@ -46,7 +46,7 @@ noinst_LIBRARIES = \
|
|||
libbitcoin_cli.a
|
||||
if ENABLE_WALLET
|
||||
BITCOIN_INCLUDES += $(BDB_CPPFLAGS)
|
||||
noinst_LIBRARIES += libbitcoin_wallet.a
|
||||
EXTRA_LIBRARIES += libbitcoin_wallet.a
|
||||
endif
|
||||
|
||||
if BUILD_BITCOIN_LIBS
|
||||
|
@ -234,6 +234,7 @@ univalue_libbitcoin_univalue_a_SOURCES = \
|
|||
libbitcoin_common_a_CPPFLAGS = $(BITCOIN_INCLUDES)
|
||||
libbitcoin_common_a_SOURCES = \
|
||||
allocators.cpp \
|
||||
arith_uint256.cpp \
|
||||
amount.cpp \
|
||||
base58.cpp \
|
||||
chainparams.cpp \
|
||||
|
@ -264,7 +265,6 @@ libbitcoin_common_a_SOURCES = \
|
|||
# backward-compatibility objects and their sanity checks are linked.
|
||||
libbitcoin_util_a_CPPFLAGS = $(BITCOIN_INCLUDES)
|
||||
libbitcoin_util_a_SOURCES = \
|
||||
arith_uint256.cpp \
|
||||
chainparamsbase.cpp \
|
||||
clientversion.cpp \
|
||||
compat/glibc_sanity.cpp \
|
||||
|
@ -356,7 +356,6 @@ bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
|||
if BUILD_BITCOIN_LIBS
|
||||
include_HEADERS = script/bitcoinconsensus.h
|
||||
libbitcoinconsensus_la_SOURCES = \
|
||||
arith_uint256.cpp \
|
||||
crypto/hmac_sha512.cpp \
|
||||
crypto/ripemd160.cpp \
|
||||
crypto/sha1.cpp \
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
bin_PROGRAMS += qt/bitcoin-qt
|
||||
noinst_LIBRARIES += qt/libbitcoinqt.a
|
||||
EXTRA_LIBRARIES += qt/libbitcoinqt.a
|
||||
|
||||
# bitcoin qt core #
|
||||
QT_TS = \
|
||||
|
|
|
@ -58,6 +58,7 @@ BITCOIN_TESTS =\
|
|||
test/netbase_tests.cpp \
|
||||
test/pmt_tests.cpp \
|
||||
test/rpc_tests.cpp \
|
||||
test/sanity_tests.cpp \
|
||||
test/script_P2SH_tests.cpp \
|
||||
test/script_tests.cpp \
|
||||
test/scriptnum_tests.cpp \
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
#define _(x) std::string(x) /* Keep the _() around in case gettext or such will be used later to translate non-UI */
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
using namespace boost::asio;
|
||||
using namespace json_spirit;
|
||||
|
||||
std::string HelpMessageCli()
|
||||
|
@ -108,12 +106,12 @@ Object CallRPC(const string& strMethod, const Array& params)
|
|||
|
||||
// Connect to localhost
|
||||
bool fUseSSL = GetBoolArg("-rpcssl", false);
|
||||
asio::io_service io_service;
|
||||
ssl::context context(io_service, ssl::context::sslv23);
|
||||
context.set_options(ssl::context::no_sslv2 | ssl::context::no_sslv3);
|
||||
asio::ssl::stream<asio::ip::tcp::socket> sslStream(io_service, context);
|
||||
SSLIOStreamDevice<asio::ip::tcp> d(sslStream, fUseSSL);
|
||||
iostreams::stream< SSLIOStreamDevice<asio::ip::tcp> > stream(d);
|
||||
boost::asio::io_service io_service;
|
||||
boost::asio::ssl::context context(io_service, boost::asio::ssl::context::sslv23);
|
||||
context.set_options(boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::no_sslv3);
|
||||
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> sslStream(io_service, context);
|
||||
SSLIOStreamDevice<boost::asio::ip::tcp> d(sslStream, fUseSSL);
|
||||
boost::iostreams::stream< SSLIOStreamDevice<boost::asio::ip::tcp> > stream(d);
|
||||
|
||||
const bool fConnected = d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(BaseParams().RPCPort())));
|
||||
if (!fConnected)
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/assign/list_of.hpp>
|
||||
|
||||
using namespace boost::assign;
|
||||
using namespace std;
|
||||
|
||||
static bool fCreateBlank;
|
||||
|
@ -375,7 +374,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
|
|||
if (!prevOut.isObject())
|
||||
throw runtime_error("expected prevtxs internal object");
|
||||
|
||||
map<string,UniValue::VType> types = map_list_of("txid", UniValue::VSTR)("vout",UniValue::VNUM)("scriptPubKey",UniValue::VSTR);
|
||||
map<string,UniValue::VType> types = boost::assign::map_list_of("txid", UniValue::VSTR)("vout",UniValue::VNUM)("scriptPubKey",UniValue::VSTR);
|
||||
if (!prevOut.checkObject(types))
|
||||
throw runtime_error("prevtxs internal object typecheck fail");
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <stdio.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost::assign;
|
||||
|
||||
struct SeedSpec6 {
|
||||
uint8_t addr[16];
|
||||
|
@ -106,7 +105,6 @@ static const Checkpoints::CCheckpointData dataRegtest = {
|
|||
class CMainParams : public CChainParams {
|
||||
public:
|
||||
CMainParams() {
|
||||
networkID = CBaseChainParams::MAIN;
|
||||
strNetworkID = "newcc";
|
||||
/**
|
||||
* The message start string is designed to be unlikely to occur in normal data.
|
||||
|
@ -187,11 +185,11 @@ public:
|
|||
vSeeds.clear();
|
||||
//vFixedSeeds.clear();
|
||||
|
||||
base58Prefixes[PUBKEY_ADDRESS] = list_of(0);
|
||||
base58Prefixes[SCRIPT_ADDRESS] = list_of(5);
|
||||
base58Prefixes[SECRET_KEY] = list_of(128);
|
||||
base58Prefixes[EXT_PUBLIC_KEY] = list_of(0x04)(0x88)(0xB2)(0x1E);
|
||||
base58Prefixes[EXT_SECRET_KEY] = list_of(0x04)(0x88)(0xAD)(0xE4);
|
||||
base58Prefixes[PUBKEY_ADDRESS] = boost::assign::list_of(0);
|
||||
base58Prefixes[SCRIPT_ADDRESS] = boost::assign::list_of(5);
|
||||
base58Prefixes[SECRET_KEY] = boost::assign::list_of(128);
|
||||
base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x88)(0xB2)(0x1E);
|
||||
base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x88)(0xAD)(0xE4);
|
||||
|
||||
convertSeed6(vFixedSeeds, pnSeed6_main, ARRAYLEN(pnSeed6_main));
|
||||
|
||||
|
@ -218,7 +216,6 @@ static CMainParams mainParams;
|
|||
class CTestNetParams : public CMainParams {
|
||||
public:
|
||||
CTestNetParams() {
|
||||
networkID = CBaseChainParams::TESTNET;
|
||||
strNetworkID = "test";
|
||||
pchMessageStart[0] = 0x0b;
|
||||
pchMessageStart[1] = 0x11;
|
||||
|
@ -246,11 +243,11 @@ public:
|
|||
//vSeeds.push_back(CDNSSeedData("bluematt.me", "testnet-seed.bluematt.me"));
|
||||
//vSeeds.push_back(CDNSSeedData("bitcoin.schildbach.de", "testnet-seed.bitcoin.schildbach.de"));
|
||||
|
||||
base58Prefixes[PUBKEY_ADDRESS] = list_of(111);
|
||||
base58Prefixes[SCRIPT_ADDRESS] = list_of(196);
|
||||
base58Prefixes[SECRET_KEY] = list_of(239);
|
||||
base58Prefixes[EXT_PUBLIC_KEY] = list_of(0x04)(0x35)(0x87)(0xCF);
|
||||
base58Prefixes[EXT_SECRET_KEY] = list_of(0x04)(0x35)(0x83)(0x94);
|
||||
base58Prefixes[PUBKEY_ADDRESS] = boost::assign::list_of(111);
|
||||
base58Prefixes[SCRIPT_ADDRESS] = boost::assign::list_of(196);
|
||||
base58Prefixes[SECRET_KEY] = boost::assign::list_of(239);
|
||||
base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF);
|
||||
base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94);
|
||||
|
||||
convertSeed6(vFixedSeeds, pnSeed6_test, ARRAYLEN(pnSeed6_test));
|
||||
|
||||
|
@ -275,7 +272,6 @@ static CTestNetParams testNetParams;
|
|||
class CRegTestParams : public CTestNetParams {
|
||||
public:
|
||||
CRegTestParams() {
|
||||
networkID = CBaseChainParams::REGTEST;
|
||||
strNetworkID = "regtest";
|
||||
pchMessageStart[0] = 0xfa;
|
||||
pchMessageStart[1] = 0xbf;
|
||||
|
@ -320,7 +316,6 @@ static CRegTestParams regTestParams;
|
|||
class CUnitTestParams : public CMainParams, public CModifiableParams {
|
||||
public:
|
||||
CUnitTestParams() {
|
||||
networkID = CBaseChainParams::UNITTEST;
|
||||
strNetworkID = "unittest";
|
||||
nDefaultPort = 18445;
|
||||
vFixedSeeds.clear(); //! Unit test mode doesn't have any fixed seeds.
|
||||
|
|
|
@ -97,7 +97,6 @@ protected:
|
|||
int nMinerThreads;
|
||||
std::vector<CDNSSeedData> vSeeds;
|
||||
std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES];
|
||||
CBaseChainParams::Network networkID;
|
||||
std::string strNetworkID;
|
||||
CBlock genesis;
|
||||
std::vector<CAddress> vFixedSeeds;
|
||||
|
|
|
@ -9,10 +9,6 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
#include <boost/assign/list_of.hpp>
|
||||
|
||||
using namespace boost::assign;
|
||||
|
||||
/**
|
||||
* Main network
|
||||
*/
|
||||
|
@ -21,7 +17,6 @@ class CBaseMainParams : public CBaseChainParams
|
|||
public:
|
||||
CBaseMainParams()
|
||||
{
|
||||
networkID = CBaseChainParams::MAIN;
|
||||
nRPCPort = 8332;
|
||||
}
|
||||
};
|
||||
|
@ -35,7 +30,6 @@ class CBaseTestNetParams : public CBaseMainParams
|
|||
public:
|
||||
CBaseTestNetParams()
|
||||
{
|
||||
networkID = CBaseChainParams::TESTNET;
|
||||
nRPCPort = 18332;
|
||||
strDataDir = "testnet3";
|
||||
}
|
||||
|
@ -50,7 +44,6 @@ class CBaseRegTestParams : public CBaseTestNetParams
|
|||
public:
|
||||
CBaseRegTestParams()
|
||||
{
|
||||
networkID = CBaseChainParams::REGTEST;
|
||||
strDataDir = "regtest";
|
||||
}
|
||||
};
|
||||
|
@ -64,7 +57,6 @@ class CBaseUnitTestParams : public CBaseMainParams
|
|||
public:
|
||||
CBaseUnitTestParams()
|
||||
{
|
||||
networkID = CBaseChainParams::UNITTEST;
|
||||
strDataDir = "unittest";
|
||||
}
|
||||
};
|
||||
|
|
|
@ -32,7 +32,6 @@ protected:
|
|||
|
||||
int nRPCPort;
|
||||
std::string strDataDir;
|
||||
Network networkID;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -92,7 +92,6 @@ bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const {
|
|||
|
||||
CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) {
|
||||
assert(!hasModifier);
|
||||
hasModifier = true;
|
||||
std::pair<CCoinsMap::iterator, bool> ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry()));
|
||||
if (ret.second) {
|
||||
if (!base->GetCoins(txid, ret.first->second.coins)) {
|
||||
|
@ -233,7 +232,10 @@ double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const
|
|||
return tx.ComputePriority(dResult);
|
||||
}
|
||||
|
||||
CCoinsModifier::CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_) : cache(cache_), it(it_) {}
|
||||
CCoinsModifier::CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_) : cache(cache_), it(it_) {
|
||||
assert(!cache.hasModifier);
|
||||
cache.hasModifier = true;
|
||||
}
|
||||
|
||||
CCoinsModifier::~CCoinsModifier()
|
||||
{
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/assign/list_of.hpp>
|
||||
|
||||
using namespace boost;
|
||||
using namespace boost::algorithm;
|
||||
using namespace std;
|
||||
|
||||
CScript ParseScript(std::string s)
|
||||
|
@ -44,13 +42,13 @@ CScript ParseScript(std::string s)
|
|||
string strName(name);
|
||||
mapOpNames[strName] = (opcodetype)op;
|
||||
// Convenience: OP_ADD and just ADD are both recognized:
|
||||
replace_first(strName, "OP_", "");
|
||||
boost::algorithm::replace_first(strName, "OP_", "");
|
||||
mapOpNames[strName] = (opcodetype)op;
|
||||
}
|
||||
}
|
||||
|
||||
vector<string> words;
|
||||
split(words, s, is_any_of(" \t\n"), token_compress_on);
|
||||
boost::algorithm::split(words, s, boost::algorithm::is_any_of(" \t\n"), boost::algorithm::token_compress_on);
|
||||
|
||||
for (std::vector<std::string>::const_iterator w = words.begin(); w != words.end(); ++w)
|
||||
{
|
||||
|
@ -58,20 +56,20 @@ CScript ParseScript(std::string s)
|
|||
{
|
||||
// Empty string, ignore. (boost::split given '' will return one word)
|
||||
}
|
||||
else if (all(*w, is_digit()) ||
|
||||
(starts_with(*w, "-") && all(string(w->begin()+1, w->end()), is_digit())))
|
||||
else if (all(*w, boost::algorithm::is_digit()) ||
|
||||
(boost::algorithm::starts_with(*w, "-") && all(string(w->begin()+1, w->end()), boost::algorithm::is_digit())))
|
||||
{
|
||||
// Number
|
||||
int64_t n = atoi64(*w);
|
||||
result << n;
|
||||
}
|
||||
else if (starts_with(*w, "0x") && (w->begin()+2 != w->end()) && IsHex(string(w->begin()+2, w->end())))
|
||||
else if (boost::algorithm::starts_with(*w, "0x") && (w->begin()+2 != w->end()) && IsHex(string(w->begin()+2, w->end())))
|
||||
{
|
||||
// Raw hex data, inserted NOT pushed onto stack:
|
||||
std::vector<unsigned char> raw = ParseHex(string(w->begin()+2, w->end()));
|
||||
result.insert(result.end(), raw.begin(), raw.end());
|
||||
}
|
||||
else if (w->size() >= 2 && starts_with(*w, "'") && ends_with(*w, "'"))
|
||||
else if (w->size() >= 2 && boost::algorithm::starts_with(*w, "'") && boost::algorithm::ends_with(*w, "'"))
|
||||
{
|
||||
// Single-quoted string, pushed as data. NOTE: this is poor-man's
|
||||
// parsing, spaces/tabs/newlines in single-quoted strings won't work.
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include <openssl/rand.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
|
||||
unsigned int nWalletDBUpdated;
|
||||
|
@ -73,9 +72,9 @@ bool CDBEnv::Open(const boost::filesystem::path& pathIn)
|
|||
boost::this_thread::interruption_point();
|
||||
|
||||
path = pathIn;
|
||||
filesystem::path pathLogDir = path / "database";
|
||||
boost::filesystem::path pathLogDir = path / "database";
|
||||
TryCreateDirectory(pathLogDir);
|
||||
filesystem::path pathErrorFile = path / "db.log";
|
||||
boost::filesystem::path pathErrorFile = path / "db.log";
|
||||
LogPrintf("CDBEnv::Open : LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string());
|
||||
|
||||
unsigned int nEnvFlags = 0;
|
||||
|
|
2
src/db.h
|
@ -23,8 +23,6 @@
|
|||
class CDiskBlockIndex;
|
||||
class COutPoint;
|
||||
|
||||
struct CBlockLocator;
|
||||
|
||||
extern unsigned int nWalletDBUpdated;
|
||||
|
||||
void ThreadFlushWalletDB(const std::string& strWalletFile);
|
||||
|
|
|
@ -117,10 +117,34 @@ bool CECKey::SetPubKey(const unsigned char* pubkey, size_t size) {
|
|||
}
|
||||
|
||||
bool CECKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) {
|
||||
// -1 = error, 0 = bad sig, 1 = good
|
||||
if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
|
||||
if (vchSig.empty())
|
||||
return false;
|
||||
return true;
|
||||
|
||||
// New versions of OpenSSL will reject non-canonical DER signatures. de/re-serialize first.
|
||||
unsigned char *norm_der = NULL;
|
||||
ECDSA_SIG *norm_sig = ECDSA_SIG_new();
|
||||
const unsigned char* sigptr = &vchSig[0];
|
||||
assert(norm_sig);
|
||||
if (d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size()) == NULL)
|
||||
{
|
||||
/* As of OpenSSL 1.0.0p d2i_ECDSA_SIG frees and nulls the pointer on
|
||||
* error. But OpenSSL's own use of this function redundantly frees the
|
||||
* result. As ECDSA_SIG_free(NULL) is a no-op, and in the absence of a
|
||||
* clear contract for the function behaving the same way is more
|
||||
* conservative.
|
||||
*/
|
||||
ECDSA_SIG_free(norm_sig);
|
||||
return false;
|
||||
}
|
||||
int derlen = i2d_ECDSA_SIG(norm_sig, &norm_der);
|
||||
ECDSA_SIG_free(norm_sig);
|
||||
if (derlen <= 0)
|
||||
return false;
|
||||
|
||||
// -1 = error, 0 = bad sig, 1 = good
|
||||
bool ret = ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), norm_der, derlen, pkey) == 1;
|
||||
OPENSSL_free(norm_der);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CECKey::Recover(const uint256 &hash, const unsigned char *p64, int rec)
|
||||
|
|
54
src/init.cpp
|
@ -43,7 +43,6 @@
|
|||
#include <boost/thread.hpp>
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
using namespace boost;
|
||||
using namespace std;
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
|
@ -112,7 +111,28 @@ bool ShutdownRequested()
|
|||
return fRequestShutdown;
|
||||
}
|
||||
|
||||
class CCoinsViewErrorCatcher : public CCoinsViewBacked
|
||||
{
|
||||
public:
|
||||
CCoinsViewErrorCatcher(CCoinsView* view) : CCoinsViewBacked(view) {}
|
||||
bool GetCoins(const uint256 &txid, CCoins &coins) const {
|
||||
try {
|
||||
return CCoinsViewBacked::GetCoins(txid, coins);
|
||||
} catch(const std::runtime_error& e) {
|
||||
uiInterface.ThreadSafeMessageBox(_("Error reading from database, shutting down."), "", CClientUIInterface::MSG_ERROR);
|
||||
LogPrintf("Error reading from database: %s\n", e.what());
|
||||
// Starting the shutdown sequence and returning false to the caller would be
|
||||
// interpreted as 'entry not found' (as opposed to unable to read data), and
|
||||
// could lead to invalid interpration. Just exit immediately, as we can't
|
||||
// continue anyway, and all writes should be atomic.
|
||||
abort();
|
||||
}
|
||||
}
|
||||
// Writes do not need similar protection, as failure to write is handled by the caller.
|
||||
};
|
||||
|
||||
static CCoinsViewDB *pcoinsdbview = NULL;
|
||||
static CCoinsViewErrorCatcher *pcoinscatcher = NULL;
|
||||
|
||||
void Shutdown()
|
||||
{
|
||||
|
@ -155,6 +175,8 @@ void Shutdown()
|
|||
}
|
||||
delete pcoinsTip;
|
||||
pcoinsTip = NULL;
|
||||
delete pcoinscatcher;
|
||||
pcoinscatcher = NULL;
|
||||
delete pcoinsdbview;
|
||||
pcoinsdbview = NULL;
|
||||
delete pblocktree;
|
||||
|
@ -324,6 +346,7 @@ std::string HelpMessage(HelpMessageMode mode)
|
|||
if (GetBoolArg("-help-debug", false))
|
||||
{
|
||||
strUsage += " -limitfreerelay=<n> " + strprintf(_("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)"), 15) + "\n";
|
||||
strUsage += " -relaypriority " + strprintf(_("Require high priority for relaying free or low-fee transactions (default:%u)"), 1) + "\n";
|
||||
strUsage += " -maxsigcachesize=<n> " + strprintf(_("Limit size of signature cache to <n> entries (default: %u)"), 50000) + "\n";
|
||||
}
|
||||
strUsage += " -minrelaytxfee=<amt> " + strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK())) + "\n";
|
||||
|
@ -357,6 +380,7 @@ std::string HelpMessage(HelpMessageMode mode)
|
|||
strUsage += " -rpcport=<port> " + strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), 8332, 18332) + "\n";
|
||||
strUsage += " -rpcallowip=<ip> " + _("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") + "\n";
|
||||
strUsage += " -rpcthreads=<n> " + strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4) + "\n";
|
||||
strUsage += " -rpckeepalive " + strprintf(_("RPC support for HTTP persistent connections (default: %d)"), 0) + "\n";
|
||||
|
||||
strUsage += "\n" + _("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n";
|
||||
strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n";
|
||||
|
@ -427,12 +451,12 @@ void ThreadImport(std::vector<boost::filesystem::path> vImportFiles)
|
|||
}
|
||||
|
||||
// hardcoded $DATADIR/bootstrap.dat
|
||||
filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat";
|
||||
if (filesystem::exists(pathBootstrap)) {
|
||||
boost::filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat";
|
||||
if (boost::filesystem::exists(pathBootstrap)) {
|
||||
FILE *file = fopen(pathBootstrap.string().c_str(), "rb");
|
||||
if (file) {
|
||||
CImportingNow imp;
|
||||
filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old";
|
||||
boost::filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old";
|
||||
LogPrintf("Importing bootstrap.dat...\n");
|
||||
LoadExternalBlockFile(file);
|
||||
RenameOver(pathBootstrap, pathBootstrapOld);
|
||||
|
@ -816,7 +840,7 @@ bool AppInit2(boost::thread_group& threadGroup)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (filesystem::exists(GetDataDir() / strWalletFile))
|
||||
if (boost::filesystem::exists(GetDataDir() / strWalletFile))
|
||||
{
|
||||
CDBEnv::VerifyResult r = bitdb.Verify(strWalletFile, CWalletDB::Recover);
|
||||
if (r == CDBEnv::RECOVER_OK)
|
||||
|
@ -937,20 +961,20 @@ bool AppInit2(boost::thread_group& threadGroup)
|
|||
fReindex = GetBoolArg("-reindex", false);
|
||||
|
||||
// Upgrading to 0.8; hard-link the old blknnnn.dat files into /blocks/
|
||||
filesystem::path blocksDir = GetDataDir() / "blocks";
|
||||
if (!filesystem::exists(blocksDir))
|
||||
boost::filesystem::path blocksDir = GetDataDir() / "blocks";
|
||||
if (!boost::filesystem::exists(blocksDir))
|
||||
{
|
||||
filesystem::create_directories(blocksDir);
|
||||
boost::filesystem::create_directories(blocksDir);
|
||||
bool linked = false;
|
||||
for (unsigned int i = 1; i < 10000; i++) {
|
||||
filesystem::path source = GetDataDir() / strprintf("blk%04u.dat", i);
|
||||
if (!filesystem::exists(source)) break;
|
||||
filesystem::path dest = blocksDir / strprintf("blk%05u.dat", i-1);
|
||||
boost::filesystem::path source = GetDataDir() / strprintf("blk%04u.dat", i);
|
||||
if (!boost::filesystem::exists(source)) break;
|
||||
boost::filesystem::path dest = blocksDir / strprintf("blk%05u.dat", i-1);
|
||||
try {
|
||||
filesystem::create_hard_link(source, dest);
|
||||
boost::filesystem::create_hard_link(source, dest);
|
||||
LogPrintf("Hardlinked %s -> %s\n", source.string(), dest.string());
|
||||
linked = true;
|
||||
} catch (const filesystem::filesystem_error& e) {
|
||||
} catch (const boost::filesystem::filesystem_error& e) {
|
||||
// Note: hardlink creation failing is not a disaster, it just means
|
||||
// blocks will get re-downloaded from peers.
|
||||
LogPrintf("Error hardlinking blk%04u.dat : %s\n", i, e.what());
|
||||
|
@ -990,11 +1014,13 @@ bool AppInit2(boost::thread_group& threadGroup)
|
|||
UnloadBlockIndex();
|
||||
delete pcoinsTip;
|
||||
delete pcoinsdbview;
|
||||
delete pcoinscatcher;
|
||||
delete pblocktree;
|
||||
|
||||
pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex);
|
||||
pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex);
|
||||
pcoinsTip = new CCoinsViewCache(pcoinsdbview);
|
||||
pcoinscatcher = new CCoinsViewErrorCatcher(pcoinsdbview);
|
||||
pcoinsTip = new CCoinsViewCache(pcoinscatcher);
|
||||
|
||||
if (fReindex)
|
||||
pblocktree->WriteReindexing(true);
|
||||
|
|
83
src/main.cpp
|
@ -30,7 +30,6 @@
|
|||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
using namespace boost;
|
||||
using namespace std;
|
||||
|
||||
#if defined(NDEBUG)
|
||||
|
@ -141,9 +140,14 @@ namespace {
|
|||
uint256 hash;
|
||||
CBlockIndex *pindex; //! Optional.
|
||||
int64_t nTime; //! Time of "getdata" request in microseconds.
|
||||
int nValidatedQueuedBefore; //! Number of blocks queued with validated headers (globally) at the time this one is requested.
|
||||
bool fValidatedHeaders; //! Whether this block has validated headers at the time of request.
|
||||
};
|
||||
map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;
|
||||
|
||||
/** Number of blocks in flight with validated headers. */
|
||||
int nQueuedValidatedHeaders = 0;
|
||||
|
||||
/** Number of preferable block download peers. */
|
||||
int nPreferredDownload = 0;
|
||||
|
||||
|
@ -325,6 +329,7 @@ void MarkBlockAsReceived(const uint256& hash) {
|
|||
map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
|
||||
if (itInFlight != mapBlocksInFlight.end()) {
|
||||
CNodeState *state = State(itInFlight->second.first);
|
||||
nQueuedValidatedHeaders -= itInFlight->second.second->fValidatedHeaders;
|
||||
state->vBlocksInFlight.erase(itInFlight->second.second);
|
||||
state->nBlocksInFlight--;
|
||||
state->nStallingSince = 0;
|
||||
|
@ -340,7 +345,8 @@ void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, CBlockIndex *pindex
|
|||
// Make sure it's not listed somewhere already.
|
||||
MarkBlockAsReceived(hash);
|
||||
|
||||
QueuedBlock newentry = {hash, pindex, GetTimeMicros()};
|
||||
QueuedBlock newentry = {hash, pindex, GetTimeMicros(), nQueuedValidatedHeaders, pindex != NULL};
|
||||
nQueuedValidatedHeaders += newentry.fValidatedHeaders;
|
||||
list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry);
|
||||
state->nBlocksInFlight++;
|
||||
mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
|
||||
|
@ -622,35 +628,12 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
|
|||
|
||||
bool IsStandardTx(const CTransaction& tx, string& reason)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
// TODO: We may have a different version here
|
||||
if (tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) {
|
||||
reason = "version";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Treat non-final transactions as non-standard to prevent a specific type
|
||||
// of double-spend attack, as well as DoS attacks. (if the transaction
|
||||
// can't be mined, the attacker isn't expending resources broadcasting it)
|
||||
// Basically we don't want to propagate transactions that can't be included in
|
||||
// the next block.
|
||||
//
|
||||
// However, IsFinalTx() is confusing... Without arguments, it uses
|
||||
// chainActive.Height() to evaluate nLockTime; when a block is accepted, chainActive.Height()
|
||||
// is set to the value of nHeight in the block. However, when IsFinalTx()
|
||||
// is called within CBlock::AcceptBlock(), the height of the block *being*
|
||||
// evaluated is what is used. Thus if we want to know if a transaction can
|
||||
// be part of the *next* block, we need to call IsFinalTx() with one more
|
||||
// than chainActive.Height().
|
||||
//
|
||||
// Timestamps on the other hand don't get any special treatment, because we
|
||||
// can't know what timestamp the next block will have, and there aren't
|
||||
// timestamp applications where it matters.
|
||||
if (!IsFinalTx(tx, chainActive.Height() + 1)) {
|
||||
reason = "non-final";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extremely large transactions with lots of inputs can cost the network
|
||||
// almost as much to process as they cost the sender in fees, because
|
||||
// computing signature hashes is O(ninputs*txsize). Limiting transactions
|
||||
|
@ -765,7 +748,7 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
|
|||
// IsStandard() will have already returned false
|
||||
// and this method isn't called.
|
||||
vector<vector<unsigned char> > stack;
|
||||
if (!EvalScript(stack, tx.vin[i].scriptSig, false, BaseSignatureChecker()))
|
||||
if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker()))
|
||||
return false;
|
||||
|
||||
if (whichType == TX_SCRIPTHASH)
|
||||
|
@ -944,6 +927,26 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
|||
error("AcceptToMemoryPool : nonstandard transaction: %s", reason),
|
||||
REJECT_NONSTANDARD, reason);
|
||||
|
||||
// Only accept nLockTime-using transactions that can be mined in the next
|
||||
// block; we don't want our mempool filled up with transactions that can't
|
||||
// be mined yet.
|
||||
//
|
||||
// However, IsFinalTx() is confusing... Without arguments, it uses
|
||||
// chainActive.Height() to evaluate nLockTime; when a block is accepted,
|
||||
// chainActive.Height() is set to the value of nHeight in the block.
|
||||
// However, when IsFinalTx() is called within CBlock::AcceptBlock(), the
|
||||
// height of the block *being* evaluated is what is used. Thus if we want
|
||||
// to know if a transaction can be part of the *next* block, we need to
|
||||
// call IsFinalTx() with one more than chainActive.Height().
|
||||
//
|
||||
// Timestamps on the other hand don't get any special treatment, because we
|
||||
// can't know what timestamp the next block will have, and there aren't
|
||||
// timestamp applications where it matters.
|
||||
if (!IsFinalTx(tx, chainActive.Height() + 1))
|
||||
return state.DoS(0,
|
||||
error("AcceptToMemoryPool : non-final"),
|
||||
REJECT_NONSTANDARD, "non-final");
|
||||
|
||||
// is it already in the memory pool?
|
||||
uint256 hash = tx.GetHash();
|
||||
if (pool.exists(hash))
|
||||
|
@ -1008,15 +1011,15 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
|||
|
||||
// Check that the transaction doesn't have an excessive number of
|
||||
// sigops, making it impossible to mine. Since the coinbase transaction
|
||||
// itself can contain sigops MAX_TX_SIGOPS is less than
|
||||
// itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than
|
||||
// MAX_BLOCK_SIGOPS; we still consider this an invalid rather than
|
||||
// merely non-standard transaction.
|
||||
unsigned int nSigOps = GetLegacySigOpCount(tx);
|
||||
nSigOps += GetP2SHSigOpCount(tx, view);
|
||||
if (nSigOps > MAX_TX_SIGOPS)
|
||||
if (nSigOps > MAX_STANDARD_TX_SIGOPS)
|
||||
return state.DoS(0,
|
||||
error("AcceptToMemoryPool : too many sigops %s, %d > %d",
|
||||
hash.ToString(), nSigOps, MAX_TX_SIGOPS),
|
||||
hash.ToString(), nSigOps, MAX_STANDARD_TX_SIGOPS),
|
||||
REJECT_NONSTANDARD, "bad-txns-too-many-sigops");
|
||||
|
||||
CAmount nValueOut = tx.GetValueOut();
|
||||
|
@ -1033,6 +1036,11 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
|||
hash.ToString(), nFees, txMinFee),
|
||||
REJECT_INSUFFICIENTFEE, "insufficient fee");
|
||||
|
||||
// Require that free transactions have sufficient priority to be mined in the next block.
|
||||
if (GetBoolArg("-relaypriority", true) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) {
|
||||
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
|
||||
}
|
||||
|
||||
// Continuously rate-limit free (really, very-low-fee) transactions
|
||||
// This mitigates 'penny-flooding' -- sending thousands of free transactions just to
|
||||
// be annoying or make others' transactions take longer to confirm.
|
||||
|
@ -1052,7 +1060,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
|||
// At default rate it would take over a month to fill 1GB
|
||||
if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000)
|
||||
return state.DoS(0, error("AcceptToMemoryPool : free transaction rejected by rate limiter"),
|
||||
REJECT_INSUFFICIENTFEE, "insufficient priority");
|
||||
REJECT_INSUFFICIENTFEE, "rate limited free transaction");
|
||||
LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
|
||||
dFreeCount += nSize;
|
||||
}
|
||||
|
@ -1888,6 +1896,7 @@ enum FlushStateMode {
|
|||
bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
|
||||
LOCK(cs_main);
|
||||
static int64_t nLastWrite = 0;
|
||||
try {
|
||||
if ((mode == FLUSH_STATE_ALWAYS) ||
|
||||
((mode == FLUSH_STATE_PERIODIC || mode == FLUSH_STATE_IF_NEEDED) && pcoinsTip->GetCacheSize() > nCoinCacheSize) ||
|
||||
(mode == FLUSH_STATE_PERIODIC && GetTimeMicros() > nLastWrite + DATABASE_WRITE_INTERVAL * 1000000)) {
|
||||
|
@ -1927,6 +1936,9 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
|
|||
}
|
||||
nLastWrite = GetTimeMicros();
|
||||
}
|
||||
} catch (const std::runtime_error& e) {
|
||||
return state.Abort(std::string("System error while flushing: ") + e.what());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2797,7 +2809,7 @@ bool AbortNode(const std::string &strMessage, const std::string &userMessage) {
|
|||
|
||||
bool CheckDiskSpace(uint64_t nAdditionalBytes)
|
||||
{
|
||||
uint64_t nFreeBytesAvailable = filesystem::space(GetDataDir()).available;
|
||||
uint64_t nFreeBytesAvailable = boost::filesystem::space(GetDataDir()).available;
|
||||
|
||||
// Check for nMinDiskSpace bytes (currently 50MB)
|
||||
if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
|
||||
|
@ -4530,6 +4542,15 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
|||
LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id);
|
||||
pto->fDisconnect = true;
|
||||
}
|
||||
// In case there is a block that has been in flight from this peer for (1 + 0.5 * N) times the block interval
|
||||
// (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to
|
||||
// timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link
|
||||
// being saturated. We only count validated in-flight blocks so peers can't advertize nonexisting block hashes
|
||||
// to unreasonably increase our timeout.
|
||||
if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0 && state.vBlocksInFlight.front().nTime < nNow - 500000 * Params().TargetSpacing() * (2 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) {
|
||||
LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", state.vBlocksInFlight.front().hash.ToString(), pto->id);
|
||||
pto->fDisconnect = true;
|
||||
}
|
||||
|
||||
//
|
||||
// Message: getdata (blocks)
|
||||
|
|
|
@ -60,7 +60,7 @@ static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
|
|||
/** Maximum number of signature check operations in an IsStandard() P2SH script */
|
||||
static const unsigned int MAX_P2SH_SIGOPS = 15;
|
||||
/** The maximum number of sigops we're willing to relay/mine in a single tx */
|
||||
static const unsigned int MAX_TX_SIGOPS = MAX_BLOCK_SIGOPS/5;
|
||||
static const unsigned int MAX_STANDARD_TX_SIGOPS = MAX_BLOCK_SIGOPS/5;
|
||||
/** Default for -maxorphantx, maximum number of orphan transactions kept in memory */
|
||||
static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100;
|
||||
/** The maximum size of a blk?????.dat file (since 0.8) */
|
||||
|
|
|
@ -49,7 +49,6 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
using namespace boost;
|
||||
using namespace std;
|
||||
|
||||
namespace {
|
||||
|
|
|
@ -162,7 +162,7 @@ struct CBlockLocator
|
|||
vHave.clear();
|
||||
}
|
||||
|
||||
bool IsNull()
|
||||
bool IsNull() const
|
||||
{
|
||||
return vHave.empty();
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
class AmountSpinBox: public QAbstractSpinBox
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AmountSpinBox(QWidget *parent):
|
||||
QAbstractSpinBox(parent),
|
||||
|
@ -72,23 +73,6 @@ public:
|
|||
setValue(val);
|
||||
}
|
||||
|
||||
StepEnabled stepEnabled() const
|
||||
{
|
||||
StepEnabled rv = 0;
|
||||
if(text().isEmpty()) // Allow step-up with empty field
|
||||
return StepUpEnabled;
|
||||
bool valid = false;
|
||||
CAmount val = value(&valid);
|
||||
if(valid)
|
||||
{
|
||||
if(val > 0)
|
||||
rv |= StepDownEnabled;
|
||||
if(val < BitcoinUnits::maxMoney())
|
||||
rv |= StepUpEnabled;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
void setDisplayUnit(int unit)
|
||||
{
|
||||
bool valid = false;
|
||||
|
@ -139,6 +123,7 @@ public:
|
|||
}
|
||||
return cachedMinimumSizeHint;
|
||||
}
|
||||
|
||||
private:
|
||||
int currentUnit;
|
||||
CAmount singleStep;
|
||||
|
@ -179,6 +164,26 @@ protected:
|
|||
return QAbstractSpinBox::event(event);
|
||||
}
|
||||
|
||||
StepEnabled stepEnabled() const
|
||||
{
|
||||
if (isReadOnly()) // Disable steps when AmountSpinBox is read-only
|
||||
return StepNone;
|
||||
if (text().isEmpty()) // Allow step-up with empty field
|
||||
return StepUpEnabled;
|
||||
|
||||
StepEnabled rv = 0;
|
||||
bool valid = false;
|
||||
CAmount val = value(&valid);
|
||||
if(valid)
|
||||
{
|
||||
if(val > 0)
|
||||
rv |= StepDownEnabled;
|
||||
if(val < BitcoinUnits::maxMoney())
|
||||
rv |= StepUpEnabled;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
signals:
|
||||
void valueChanged();
|
||||
};
|
||||
|
|
|
@ -76,12 +76,14 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) :
|
|||
historyAction(0),
|
||||
quitAction(0),
|
||||
sendCoinsAction(0),
|
||||
sendCoinsMenuAction(0),
|
||||
usedSendingAddressesAction(0),
|
||||
usedReceivingAddressesAction(0),
|
||||
signMessageAction(0),
|
||||
verifyMessageAction(0),
|
||||
aboutAction(0),
|
||||
receiveCoinsAction(0),
|
||||
receiveCoinsMenuAction(0),
|
||||
optionsAction(0),
|
||||
toggleHideAction(0),
|
||||
encryptWalletAction(0),
|
||||
|
@ -256,6 +258,10 @@ void BitcoinGUI::createActions(const NetworkStyle *networkStyle)
|
|||
sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2));
|
||||
tabGroup->addAction(sendCoinsAction);
|
||||
|
||||
sendCoinsMenuAction = new QAction(TextColorIcon(":/icons/send"), sendCoinsAction->text(), this);
|
||||
sendCoinsMenuAction->setStatusTip(sendCoinsAction->statusTip());
|
||||
sendCoinsMenuAction->setToolTip(sendCoinsMenuAction->statusTip());
|
||||
|
||||
receiveCoinsAction = new QAction(SingleColorIcon(":/icons/receiving_addresses"), tr("&Receive"), this);
|
||||
receiveCoinsAction->setStatusTip(tr("Request payments (generates QR codes and bitcoin: URIs)"));
|
||||
receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip());
|
||||
|
@ -263,6 +269,10 @@ void BitcoinGUI::createActions(const NetworkStyle *networkStyle)
|
|||
receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3));
|
||||
tabGroup->addAction(receiveCoinsAction);
|
||||
|
||||
receiveCoinsMenuAction = new QAction(TextColorIcon(":/icons/receiving_addresses"), receiveCoinsAction->text(), this);
|
||||
receiveCoinsMenuAction->setStatusTip(receiveCoinsAction->statusTip());
|
||||
receiveCoinsMenuAction->setToolTip(receiveCoinsMenuAction->statusTip());
|
||||
|
||||
historyAction = new QAction(SingleColorIcon(":/icons/history"), tr("&Transactions"), this);
|
||||
historyAction->setStatusTip(tr("Browse transaction history"));
|
||||
historyAction->setToolTip(historyAction->statusTip());
|
||||
|
@ -277,8 +287,12 @@ void BitcoinGUI::createActions(const NetworkStyle *networkStyle)
|
|||
connect(overviewAction, SIGNAL(triggered()), this, SLOT(gotoOverviewPage()));
|
||||
connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
|
||||
connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage()));
|
||||
connect(sendCoinsMenuAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
|
||||
connect(sendCoinsMenuAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage()));
|
||||
connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
|
||||
connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage()));
|
||||
connect(receiveCoinsMenuAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
|
||||
connect(receiveCoinsMenuAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage()));
|
||||
connect(historyAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
|
||||
connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage()));
|
||||
#endif // ENABLE_WALLET
|
||||
|
@ -475,7 +489,9 @@ void BitcoinGUI::setWalletActionsEnabled(bool enabled)
|
|||
{
|
||||
overviewAction->setEnabled(enabled);
|
||||
sendCoinsAction->setEnabled(enabled);
|
||||
sendCoinsMenuAction->setEnabled(enabled);
|
||||
receiveCoinsAction->setEnabled(enabled);
|
||||
receiveCoinsMenuAction->setEnabled(enabled);
|
||||
historyAction->setEnabled(enabled);
|
||||
encryptWalletAction->setEnabled(enabled);
|
||||
backupWalletAction->setEnabled(enabled);
|
||||
|
@ -522,8 +538,8 @@ void BitcoinGUI::createTrayIconMenu()
|
|||
// Configuration of the tray icon (or dock icon) icon menu
|
||||
trayIconMenu->addAction(toggleHideAction);
|
||||
trayIconMenu->addSeparator();
|
||||
trayIconMenu->addAction(sendCoinsAction);
|
||||
trayIconMenu->addAction(receiveCoinsAction);
|
||||
trayIconMenu->addAction(sendCoinsMenuAction);
|
||||
trayIconMenu->addAction(receiveCoinsMenuAction);
|
||||
trayIconMenu->addSeparator();
|
||||
trayIconMenu->addAction(signMessageAction);
|
||||
trayIconMenu->addAction(verifyMessageAction);
|
||||
|
|
|
@ -90,12 +90,14 @@ private:
|
|||
QAction *historyAction;
|
||||
QAction *quitAction;
|
||||
QAction *sendCoinsAction;
|
||||
QAction *sendCoinsMenuAction;
|
||||
QAction *usedSendingAddressesAction;
|
||||
QAction *usedReceivingAddressesAction;
|
||||
QAction *signMessageAction;
|
||||
QAction *verifyMessageAction;
|
||||
QAction *aboutAction;
|
||||
QAction *receiveCoinsAction;
|
||||
QAction *receiveCoinsMenuAction;
|
||||
QAction *optionsAction;
|
||||
QAction *toggleHideAction;
|
||||
QAction *encryptWalletAction;
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>400</height>
|
||||
<width>585</width>
|
||||
<height>225</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
|
@ -34,6 +34,13 @@
|
|||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTextEdit" name="helpMessage">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="verticalScrollBarPolicy">
|
||||
|
@ -47,19 +54,22 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>659</width>
|
||||
<height>348</height>
|
||||
<width>447</width>
|
||||
<height>68</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="helpMessageLabel">
|
||||
<widget class="QLabel" name="aboutMessage">
|
||||
<property name="cursor">
|
||||
<cursorShape>IBeamCursor</cursorShape>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<item>
|
||||
<widget class="QLabel" name="infoLabel_SM">
|
||||
<property name="text">
|
||||
<string>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</string>
|
||||
<string>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
|
@ -237,7 +237,7 @@
|
|||
<item>
|
||||
<widget class="QLabel" name="infoLabel_VM">
|
||||
<property name="text">
|
||||
<string>Enter the signing address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack.</string>
|
||||
<string>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#include <QUrlQuery>
|
||||
#endif
|
||||
|
||||
using namespace boost;
|
||||
using namespace std;
|
||||
|
||||
const int BITCOIN_IPC_CONNECT_TIMEOUT = 1000; // milliseconds
|
||||
|
@ -522,8 +521,7 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
|
|||
const payments::PaymentDetails& details = request.getDetails();
|
||||
|
||||
// Payment request network matches client network?
|
||||
if (details.network() != Params().NetworkIDString())
|
||||
{
|
||||
if (!verifyNetwork(request.getDetails())) {
|
||||
emit message(tr("Payment request rejected"), tr("Payment request network doesn't match client network."),
|
||||
CClientUIInterface::MSG_ERROR);
|
||||
|
||||
|
@ -746,3 +744,15 @@ void PaymentServer::handlePaymentACK(const QString& paymentACKMsg)
|
|||
// currently we don't futher process or store the paymentACK message
|
||||
emit message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL);
|
||||
}
|
||||
|
||||
bool PaymentServer::verifyNetwork(const payments::PaymentDetails& requestDetails)
|
||||
{
|
||||
bool fVerified = requestDetails.network() == Params().NetworkIDString();
|
||||
if (!fVerified) {
|
||||
qWarning() << QString("PaymentServer::%1: Payment request network \"%2\" doesn't match client network \"%3\".")
|
||||
.arg(__func__)
|
||||
.arg(QString::fromStdString(requestDetails.network()))
|
||||
.arg(QString::fromStdString(Params().NetworkIDString()));
|
||||
}
|
||||
return fVerified;
|
||||
}
|
||||
|
|
|
@ -91,6 +91,9 @@ public:
|
|||
// This is now public, because we use it in paymentservertests.cpp
|
||||
static bool readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request);
|
||||
|
||||
// Verify that the payment request network matches the client network
|
||||
static bool verifyNetwork(const payments::PaymentDetails& requestDetails);
|
||||
|
||||
signals:
|
||||
// Fired when a valid payment request is received
|
||||
void receivedPaymentRequest(SendCoinsRecipient);
|
||||
|
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 784 B After Width: | Height: | Size: 712 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 306 KiB After Width: | Height: | Size: 306 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 883 B After Width: | Height: | Size: 883 B |
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 762 B After Width: | Height: | Size: 762 B |
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |