aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml1
-rw-r--r--contrib/devtools/README.md6
-rwxr-xr-xcontrib/devtools/check-doc.py45
-rwxr-xr-xqa/rpc-tests/blockchain.py36
-rwxr-xr-xqa/rpc-tests/listtransactions.py5
-rwxr-xr-xqa/rpc-tests/receivedby.py5
-rw-r--r--qa/rpc-tests/test_framework/util.py47
-rwxr-xr-xqa/rpc-tests/wallet.py2
-rw-r--r--src/chainparams.cpp3
-rw-r--r--src/chainparams.h2
-rw-r--r--src/init.cpp15
-rw-r--r--src/main.cpp16
-rw-r--r--src/main.h2
-rw-r--r--src/rpcblockchain.cpp4
-rw-r--r--src/wallet/db.cpp2
15 files changed, 171 insertions, 20 deletions
diff --git a/.travis.yml b/.travis.yml
index e2d43d6330..71cee99254 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -64,6 +64,7 @@ script:
- test -n "$USE_SHELL" && eval '"$USE_SHELL" -c "./autogen.sh"' || ./autogen.sh
- ./configure --cache-file=config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false)
- make distdir PACKAGE=bitcoin VERSION=$HOST
+ - if [ "$RUN_TESTS" = "true" ]; then contrib/devtools/check-doc.py; fi
- cd bitcoin-$HOST
- ./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false)
- make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL V=1 ; false )
diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md
index 978f26b084..fcb2275fc9 100644
--- a/contrib/devtools/README.md
+++ b/contrib/devtools/README.md
@@ -2,6 +2,12 @@ Contents
========
This directory contains tools for developers working on this repository.
+check-doc.py
+============
+
+Check if all command line args are documented. The return value indicates the
+number of undocumented args.
+
clang-format.py
===============
diff --git a/contrib/devtools/check-doc.py b/contrib/devtools/check-doc.py
new file mode 100755
index 0000000000..9c589e6e6d
--- /dev/null
+++ b/contrib/devtools/check-doc.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+# Copyright (c) 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.
+
+'''
+This checks if all command line args are documented.
+Return value is 0 to indicate no error.
+
+Author: @MarcoFalke
+'''
+
+from subprocess import check_output
+import re
+
+FOLDER_GREP = 'src'
+FOLDER_TEST = 'src/test/'
+CMD_ROOT_DIR = '`git rev-parse --show-toplevel`/%s' % FOLDER_GREP
+CMD_GREP_ARGS = r"egrep -r -I '(map(Multi)?Args(\.count\(|\[)|Get(Bool)?Arg\()\"\-[^\"]+?\"' %s | grep -v '%s'" % (CMD_ROOT_DIR, FOLDER_TEST)
+CMD_GREP_DOCS = r"egrep -r -I 'HelpMessageOpt\(\"\-[^\"=]+?(=|\")' %s" % (CMD_ROOT_DIR)
+REGEX_ARG = re.compile(r'(?:map(?:Multi)?Args(?:\.count\(|\[)|Get(?:Bool)?Arg\()\"(\-[^\"]+?)\"')
+REGEX_DOC = re.compile(r'HelpMessageOpt\(\"(\-[^\"=]+?)(?:=|\")')
+# list unsupported, deprecated and duplicate args as they need no documentation
+SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet'])
+
+def main():
+ used = check_output(CMD_GREP_ARGS, shell=True)
+ docd = check_output(CMD_GREP_DOCS, shell=True)
+
+ args_used = set(re.findall(REGEX_ARG,used))
+ args_docd = set(re.findall(REGEX_DOC,docd)).union(SET_DOC_OPTIONAL)
+ args_need_doc = args_used.difference(args_docd)
+ args_unknown = args_docd.difference(args_used)
+
+ print "Args used : %s" % len(args_used)
+ print "Args documented : %s" % len(args_docd)
+ print "Args undocumented: %s" % len(args_need_doc)
+ print args_need_doc
+ print "Args unknown : %s" % len(args_unknown)
+ print args_unknown
+
+ exit(len(args_need_doc))
+
+if __name__ == "__main__":
+ main()
diff --git a/qa/rpc-tests/blockchain.py b/qa/rpc-tests/blockchain.py
index eccb506e57..b0fc7b0172 100755
--- a/qa/rpc-tests/blockchain.py
+++ b/qa/rpc-tests/blockchain.py
@@ -4,19 +4,25 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
-# Test RPC calls related to blockchain state.
+# Test RPC calls related to blockchain state. Tests correspond to code in
+# rpcblockchain.cpp.
#
from decimal import Decimal
from test_framework.test_framework import BitcoinTestFramework
+from test_framework.authproxy import JSONRPCException
from test_framework.util import (
initialize_chain,
assert_equal,
+ assert_raises,
+ assert_is_hex_string,
+ assert_is_hash_string,
start_nodes,
connect_nodes_bi,
)
+
class BlockchainTest(BitcoinTestFramework):
"""
Test blockchain-related RPC calls:
@@ -36,6 +42,10 @@ class BlockchainTest(BitcoinTestFramework):
self.sync_all()
def run_test(self):
+ self._test_gettxoutsetinfo()
+ self._test_getblockheader()
+
+ def _test_gettxoutsetinfo(self):
node = self.nodes[0]
res = node.gettxoutsetinfo()
@@ -47,6 +57,30 @@ class BlockchainTest(BitcoinTestFramework):
assert_equal(len(res[u'bestblock']), 64)
assert_equal(len(res[u'hash_serialized']), 64)
+ def _test_getblockheader(self):
+ node = self.nodes[0]
+
+ assert_raises(
+ JSONRPCException, lambda: node.getblockheader('nonsense'))
+
+ besthash = node.getbestblockhash()
+ secondbesthash = node.getblockhash(199)
+ header = node.getblockheader(besthash)
+
+ assert_equal(header['hash'], besthash)
+ assert_equal(header['height'], 200)
+ assert_equal(header['confirmations'], 1)
+ assert_equal(header['previousblockhash'], secondbesthash)
+ assert_is_hex_string(header['chainwork'])
+ assert_is_hash_string(header['hash'])
+ assert_is_hash_string(header['previousblockhash'])
+ assert_is_hash_string(header['merkleroot'])
+ assert_is_hash_string(header['bits'], length=None)
+ assert isinstance(header['time'], int)
+ assert isinstance(header['mediantime'], int)
+ assert isinstance(header['nonce'], int)
+ assert isinstance(header['version'], int)
+ assert isinstance(header['difficulty'], Decimal)
if __name__ == '__main__':
BlockchainTest().main()
diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py
index 8a1e3dc4bc..56c5a71fe1 100755
--- a/qa/rpc-tests/listtransactions.py
+++ b/qa/rpc-tests/listtransactions.py
@@ -32,6 +32,11 @@ def check_array_result(object_array, to_match, expected):
class ListTransactionsTest(BitcoinTestFramework):
+ def setup_nodes(self):
+ #This test requires mocktime
+ enable_mocktime()
+ return start_nodes(4, self.options.tmpdir)
+
def run_test(self):
# Simple send, 0 to 1:
txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)
diff --git a/qa/rpc-tests/receivedby.py b/qa/rpc-tests/receivedby.py
index 18af0e8102..606426b394 100755
--- a/qa/rpc-tests/receivedby.py
+++ b/qa/rpc-tests/receivedby.py
@@ -53,6 +53,11 @@ def check_array_result(object_array, to_match, expected, should_not_find = False
class ReceivedByTest(BitcoinTestFramework):
+ def setup_nodes(self):
+ #This test requires mocktime
+ enable_mocktime()
+ return start_nodes(4, self.options.tmpdir)
+
def run_test(self):
'''
listreceivedbyaddress Test
diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py
index 15fd50363e..bf89805f16 100644
--- a/qa/rpc-tests/test_framework/util.py
+++ b/qa/rpc-tests/test_framework/util.py
@@ -22,6 +22,26 @@ from .authproxy import AuthServiceProxy, JSONRPCException
COVERAGE_DIR = None
+#Set Mocktime default to OFF.
+#MOCKTIME is only needed for scripts that use the
+#cached version of the blockchain. If the cached
+#version of the blockchain is used without MOCKTIME
+#then the mempools will not sync due to IBD.
+MOCKTIME = 0
+
+def enable_mocktime():
+ #For backwared compatibility of the python scripts
+ #with previous versions of the cache, set MOCKTIME
+ #to Jan 1, 2014 + (201 * 10 * 60)
+ global MOCKTIME
+ MOCKTIME = 1388534400 + (201 * 10 * 60)
+
+def disable_mocktime():
+ global MOCKTIME
+ MOCKTIME = 0
+
+def get_mocktime():
+ return MOCKTIME
def enable_coverage(dirname):
"""Maintain a log of which RPC calls are made during testing."""
@@ -155,9 +175,10 @@ def initialize_chain(test_dir):
# Create a 200-block-long chain; each of the 4 nodes
# gets 25 mature blocks and 25 immature.
- # blocks are created with timestamps 10 minutes apart, starting
- # at 1 Jan 2014
- block_time = 1388534400
+ # blocks are created with timestamps 10 minutes apart
+ # starting from 2010 minutes in the past
+ enable_mocktime()
+ block_time = get_mocktime() - (201 * 10 * 60)
for i in range(2):
for peer in range(4):
for j in range(25):
@@ -170,6 +191,7 @@ def initialize_chain(test_dir):
# Shut them down, and clean up cache directories:
stop_nodes(rpcs)
wait_bitcoinds()
+ disable_mocktime()
for i in range(4):
os.remove(log_filename("cache", i, "debug.log"))
os.remove(log_filename("cache", i, "db.log"))
@@ -219,7 +241,7 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary=
if binary is None:
binary = os.getenv("BITCOIND", "bitcoind")
# RPC tests still depend on free transactions
- args = [ binary, "-datadir="+datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-blockprioritysize=50000" ]
+ args = [ binary, "-datadir="+datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-blockprioritysize=50000", "-mocktime="+str(get_mocktime()) ]
if extra_args is not None: args.extend(extra_args)
bitcoind_processes[i] = subprocess.Popen(args)
devnull = open(os.devnull, "w")
@@ -407,6 +429,23 @@ def assert_raises(exc, fun, *args, **kwds):
else:
raise AssertionError("No exception raised")
+def assert_is_hex_string(string):
+ try:
+ int(string, 16)
+ except Exception as e:
+ raise AssertionError(
+ "Couldn't interpret %r as hexadecimal; raised: %s" % (string, e))
+
+def assert_is_hash_string(string, length=64):
+ if not isinstance(string, basestring):
+ raise AssertionError("Expected a string, got type %r" % type(string))
+ elif length and len(string) != length:
+ raise AssertionError(
+ "String of length %d expected; got %d" % (length, len(string)))
+ elif not re.match('[abcdef0-9]+$', string):
+ raise AssertionError(
+ "String %r contains invalid characters for a hash." % string)
+
def satoshi_round(amount):
return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN)
diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py
index 2c0a009cae..43ba1d977a 100755
--- a/qa/rpc-tests/wallet.py
+++ b/qa/rpc-tests/wallet.py
@@ -3,7 +3,6 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
@@ -265,6 +264,7 @@ class WalletTest (BitcoinTestFramework):
'-salvagewallet',
]
for m in maintenance:
+ print "check " + m
stop_nodes(self.nodes)
wait_bitcoinds()
self.nodes = start_nodes(3, self.options.tmpdir, [[m]] * 3)
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index 9cf99492c9..b962f6ac0a 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -92,7 +92,6 @@ public:
pchMessageStart[3] = 0xd9;
vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284");
nDefaultPort = 8333;
- nMaxTipAge = 24 * 60 * 60;
nPruneAfterHeight = 100000;
genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1d00ffff, 1, 50 * COIN);
@@ -169,7 +168,6 @@ public:
pchMessageStart[3] = 0x07;
vAlertPubKey = ParseHex("04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a");
nDefaultPort = 18333;
- nMaxTipAge = 0x7fffffff;
nPruneAfterHeight = 1000;
genesis = CreateGenesisBlock(1296688602, 414098458, 0x1d00ffff, 1, 50 * COIN);
@@ -232,7 +230,6 @@ public:
pchMessageStart[1] = 0xbf;
pchMessageStart[2] = 0xb5;
pchMessageStart[3] = 0xda;
- nMaxTipAge = 24 * 60 * 60;
nDefaultPort = 18444;
nPruneAfterHeight = 1000;
diff --git a/src/chainparams.h b/src/chainparams.h
index fdf5c17a0e..88bc666765 100644
--- a/src/chainparams.h
+++ b/src/chainparams.h
@@ -64,7 +64,6 @@ public:
bool DefaultConsistencyChecks() const { return fDefaultConsistencyChecks; }
/** Policy: Filter transactions that do not match well-defined patterns */
bool RequireStandard() const { return fRequireStandard; }
- int64_t MaxTipAge() const { return nMaxTipAge; }
uint64_t PruneAfterHeight() const { return nPruneAfterHeight; }
/** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */
bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; }
@@ -84,7 +83,6 @@ protected:
//! Raw pub key bytes for the broadcast alert signing key.
std::vector<unsigned char> vAlertPubKey;
int nDefaultPort;
- long nMaxTipAge;
uint64_t nPruneAfterHeight;
std::vector<CDNSSeedData> vSeeds;
std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES];
diff --git a/src/init.cpp b/src/init.cpp
index 374e756abd..0a0e587763 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -312,7 +312,8 @@ std::string HelpMessage(HelpMessageMode mode)
// When adding new options to the categories, please keep and ensure alphabetical ordering.
// Do not translate _(...) -help-debug options, Many technical terms, and only a very small audience, so is unnecessary stress to translators.
string strUsage = HelpMessageGroup(_("Options:"));
- strUsage += HelpMessageOpt("-?", _("This help message"));
+ strUsage += HelpMessageOpt("-?", _("Print this help message and exit"));
+ strUsage += HelpMessageOpt("-version", _("Print version and exit"));
strUsage += HelpMessageOpt("-alerts", strprintf(_("Receive and display P2P network alerts (default: %u)"), DEFAULT_ALERTS));
strUsage += HelpMessageOpt("-alertnotify=<cmd>", _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)"));
strUsage += HelpMessageOpt("-blocknotify=<cmd>", _("Execute command when the best block changes (%s in cmd is replaced by block hash)"));
@@ -423,8 +424,11 @@ std::string HelpMessage(HelpMessageMode mode)
#endif
strUsage += HelpMessageGroup(_("Debugging/Testing options:"));
+ strUsage += HelpMessageOpt("-uacomment=<cmt>", _("Append comment to the user agent string"));
if (showDebug)
{
+ strUsage += HelpMessageOpt("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. Also sets -checkmempool (default: %u)", Params(CBaseChainParams::MAIN).DefaultConsistencyChecks()));
+ strUsage += HelpMessageOpt("-checkmempool=<n>", strprintf("Run checks every <n> transactions (default: %u)", Params(CBaseChainParams::MAIN).DefaultConsistencyChecks()));
strUsage += HelpMessageOpt("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", DEFAULT_CHECKPOINTS_ENABLED));
#ifdef ENABLE_WALLET
strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf("Flush wallet database activity from memory to disk log every <n> megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE));
@@ -447,6 +451,8 @@ std::string HelpMessage(HelpMessageMode mode)
debugCategories += ", qt";
strUsage += HelpMessageOpt("-debug=<category>", strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + ". " +
_("If <category> is not supplied or if <category> = 1, output all debugging information.") + _("<category> can be:") + " " + debugCategories + ".");
+ if (showDebug)
+ strUsage += HelpMessageOpt("-nodebug", "Turn off debugging messages, same as -debug=0");
strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), DEFAULT_GENERATE));
strUsage += HelpMessageOpt("-genproclimit=<n>", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), DEFAULT_GENERATE_THREADS));
strUsage += HelpMessageOpt("-help-debug", _("Show all debugging options (usage: --help -help-debug)"));
@@ -455,9 +461,11 @@ std::string HelpMessage(HelpMessageMode mode)
if (showDebug)
{
strUsage += HelpMessageOpt("-logtimemicros", strprintf("Add microsecond precision to debug timestamps (default: %u)", DEFAULT_LOGTIMEMICROS));
+ strUsage += HelpMessageOpt("-mocktime=<n>", "Replace actual time with <n> seconds since epoch (default: 0)");
strUsage += HelpMessageOpt("-limitfreerelay=<n>", strprintf("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)", DEFAULT_LIMITFREERELAY));
strUsage += HelpMessageOpt("-relaypriority", strprintf("Require high priority for relaying free or low-fee transactions (default: %u)", DEFAULT_RELAYPRIORITY));
strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf("Limit size of signature cache to <n> MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_SIZE));
+ strUsage += HelpMessageOpt("-maxtipage=<n>", strprintf("Maximum tip age in seconds to consider node in initial block download (default: %u)", DEFAULT_MAX_TIP_AGE));
}
strUsage += HelpMessageOpt("-minrelaytxfee=<amt>", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)"),
CURRENCY_UNIT, FormatMoney(DEFAULT_MIN_RELAY_TX_FEE)));
@@ -491,6 +499,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-server", _("Accept command line and JSON-RPC commands"));
strUsage += HelpMessageOpt("-rest", strprintf(_("Accept public REST requests (default: %u)"), DEFAULT_REST_ENABLE));
strUsage += HelpMessageOpt("-rpcbind=<addr>", _("Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)"));
+ strUsage += HelpMessageOpt("-rpccookiefile=<loc>", _("Location of the auth cookie (default: data dir)"));
strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
strUsage += HelpMessageOpt("-rpcauth=<userpw>", _("Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times"));
@@ -988,7 +997,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
{
CAmount nMaxFee = 0;
if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee))
- return InitError(AmountErrMsg("maxtxfee", mapArgs["-maptxfee"]));
+ return InitError(AmountErrMsg("maxtxfee", mapArgs["-maxtxfee"]));
if (nMaxFee > nHighTransactionMaxFeeWarning)
InitWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction."));
maxTxFee = nMaxFee;
@@ -1017,6 +1026,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
if (GetBoolArg("-peerbloomfilters", true))
nLocalServices |= NODE_BLOOM;
+ nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE);
+
// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
// Initialize elliptic curve code
diff --git a/src/main.cpp b/src/main.cpp
index 06374cc1b6..9870beecc7 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -75,6 +75,9 @@ bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED;
size_t nCoinCacheUsage = 5000 * 300;
uint64_t nPruneTarget = 0;
bool fAlerts = DEFAULT_ALERTS;
+/* If the tip is older than this (in seconds), the node is considered to be in initial block download.
+ */
+int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
/** Fees smaller than this (in satoshi) are considered zero fee (for relaying, mining and transaction creation) */
CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
@@ -1377,7 +1380,7 @@ bool IsInitialBlockDownload()
if (lockIBDState)
return false;
bool state = (chainActive.Height() < pindexBestHeader->nHeight - 24 * 6 ||
- pindexBestHeader->GetBlockTime() < GetTime() - chainParams.MaxTipAge());
+ pindexBestHeader->GetBlockTime() < GetTime() - nMaxTipAge);
if (!state)
lockIBDState = true;
return state;
@@ -1633,9 +1636,12 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
// Only if ALL inputs pass do we perform expensive ECDSA signature checks.
// Helps prevent CPU exhaustion attacks.
- // Skip ECDSA signature verification when connecting blocks
- // before the last block chain checkpoint. This is safe because block merkle hashes are
- // still computed and checked, and any change will be caught at the next checkpoint.
+ // Skip ECDSA signature verification when connecting blocks before the
+ // last block chain checkpoint. Assuming the checkpoints are valid this
+ // is safe because block merkle hashes are still computed and checked,
+ // and any change will be caught at the next checkpoint. Of course, if
+ // the checkpoint is for a chain that's invalid due to false scriptSigs
+ // this optimisation would allow an invalid chain to be accepted.
if (fScriptChecks) {
for (unsigned int i = 0; i < tx.vin.size(); i++) {
const COutPoint &prevout = tx.vin[i].prevout;
@@ -4538,7 +4544,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
{
if (fBlocksOnly)
LogPrint("net", "transaction (%s) inv sent in violation of protocol peer=%d\n", inv.hash.ToString(), pfrom->id);
- else if (!fAlreadyHave && !fImporting && !fReindex)
+ else if (!fAlreadyHave && !fImporting && !fReindex && !IsInitialBlockDownload())
pfrom->AskFor(inv);
}
diff --git a/src/main.h b/src/main.h
index cefaedabf5..228877641d 100644
--- a/src/main.h
+++ b/src/main.h
@@ -97,6 +97,7 @@ static const unsigned int AVG_INVENTORY_BROADCAST_INTERVAL = 5;
static const unsigned int DEFAULT_LIMITFREERELAY = 15;
static const bool DEFAULT_RELAYPRIORITY = true;
+static const int64_t DEFAULT_MAX_TIP_AGE = 24 * 60 * 60;
/** Default for -permitbaremultisig */
static const bool DEFAULT_PERMIT_BAREMULTISIG = true;
@@ -137,6 +138,7 @@ extern bool fCheckpointsEnabled;
extern size_t nCoinCacheUsage;
extern CFeeRate minRelayTxFee;
extern bool fAlerts;
+extern int64_t nMaxTipAge;
/** Best header we've seen so far (used for getheaders queries' starting points). */
extern CBlockIndex *pindexBestHeader;
diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp
index b76b0ca403..954441d15c 100644
--- a/src/rpcblockchain.cpp
+++ b/src/rpcblockchain.cpp
@@ -323,7 +323,8 @@ UniValue getblockheader(const UniValue& params, bool fHelp)
" \"bits\" : \"1d00ffff\", (string) The bits\n"
" \"difficulty\" : x.xxx, (numeric) The difficulty\n"
" \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
- " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
+ " \"nextblockhash\" : \"hash\", (string) The hash of the next block\n"
+ " \"chainwork\" : \"0000...1f3\" (string) Expected number of hashes required to produce the current chain (in hex)\n"
"}\n"
"\nResult (for verbose=false):\n"
"\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
@@ -384,6 +385,7 @@ UniValue getblock(const UniValue& params, bool fHelp)
" \"nonce\" : n, (numeric) The nonce\n"
" \"bits\" : \"1d00ffff\", (string) The bits\n"
" \"difficulty\" : x.xxx, (numeric) The difficulty\n"
+ " \"chainwork\" : \"xxxx\", (string) Expected number of hashes required to produce the chain up to this block (in hex)\n"
" \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
" \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
"}\n"
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
index d18250b76f..50b0f40a6a 100644
--- a/src/wallet/db.cpp
+++ b/src/wallet/db.cpp
@@ -205,7 +205,7 @@ bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector<C
std::string keyHex, valueHex;
while (!strDump.eof() && keyHex != "DATA=END") {
getline(strDump, keyHex);
- if (keyHex != "DATA_END") {
+ if (keyHex != "DATA=END") {
getline(strDump, valueHex);
vResult.push_back(make_pair(ParseHex(keyHex), ParseHex(valueHex)));
}