Auto merge of #2099 - str4d:2074-misc, r=arcalinea
Bitcoin 0.12 misc PRs 1 Cherry-picked from the following upstream PRs: - bitcoin/bitcoin#6198 - bitcoin/bitcoin#6206 - bitcoin/bitcoin#5927 - bitcoin/bitcoin#6213 - bitcoin/bitcoin#6061 - bitcoin/bitcoin#6283 (partial, remainder was pulled in #929) - bitcoin/bitcoin#6272 - bitcoin/bitcoin#6316 - bitcoin/bitcoin#6133 - bitcoin/bitcoin#6387 - bitcoin/bitcoin#6401 - bitcoin/bitcoin#6434 - bitcoin/bitcoin#6372 - bitcoin/bitcoin#6447 - bitcoin/bitcoin#6149 - bitcoin/bitcoin#6468 Part of #2074.
This commit is contained in:
commit
99c4c6de0c
|
@ -178,12 +178,13 @@ AC_ARG_ENABLE([debug],
|
|||
[enable_debug=no])
|
||||
|
||||
if test "x$enable_debug" = xyes; then
|
||||
CPPFLAGS="$CPPFLAGS -DDEBUG -DDEBUG_LOCKORDER"
|
||||
if test "x$GCC" = xyes; then
|
||||
CFLAGS="-g3 -O0 -DDEBUG"
|
||||
CFLAGS="$CFLAGS -g3 -O0"
|
||||
fi
|
||||
|
||||
if test "x$GXX" = xyes; then
|
||||
CXXFLAGS="-g3 -O0 -DDEBUG"
|
||||
CXXFLAGS="$CXXFLAGS -g3 -O0"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -193,7 +194,7 @@ fi
|
|||
if test "x$CXXFLAGS_overridden" = "xno"; then
|
||||
CXXFLAGS="$CXXFLAGS -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter -Wno-self-assign"
|
||||
fi
|
||||
CPPFLAGS="$CPPFLAGS -DBOOST_SPIRIT_THREADSAFE -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS"
|
||||
CPPFLAGS="$CPPFLAGS -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS"
|
||||
|
||||
AC_ARG_WITH([utils],
|
||||
[AS_HELP_STRING([--with-utils],
|
||||
|
|
|
@ -32,7 +32,11 @@ required_files="${BITCOIND_CONFIGFILE}"
|
|||
start_stop_daemon_args="-u ${BITCOIND_USER} \
|
||||
-N ${BITCOIND_NICE} -w 2000"
|
||||
pidfile="${BITCOIND_PIDFILE}"
|
||||
retry=60
|
||||
|
||||
# The retry schedule to use when stopping the daemon. Could be either
|
||||
# a timeout in seconds or multiple signal/timeout pairs (like
|
||||
# "SIGKILL/180 SIGTERM/300")
|
||||
retry="${BITCOIND_SIGTERM_TIMEOUT}"
|
||||
|
||||
depend() {
|
||||
need localmount net
|
||||
|
|
|
@ -25,3 +25,9 @@
|
|||
# Additional options (avoid -conf and -datadir, use flags above)
|
||||
BITCOIND_OPTS="-disablewallet"
|
||||
|
||||
# The timeout in seconds OpenRC will wait for bitcoind to terminate
|
||||
# after a SIGTERM has been raised.
|
||||
# Note that this will be mapped as argument to start-stop-daemon's
|
||||
# '--retry' option, which means you can specify a retry schedule
|
||||
# here. For more information see man 8 start-stop-daemon.
|
||||
BITCOIND_SIGTERM_TIMEOUT=60
|
||||
|
|
|
@ -26,7 +26,7 @@ output.
|
|||
|
||||
Optional config file setting for linearize-data:
|
||||
* "netmagic": network magic number
|
||||
* "max_out_sz": maximum output file size (default 1000*1000*1000)
|
||||
* "max_out_sz": maximum output file size (default `1000*1000*1000`)
|
||||
* "split_timestamp": Split files when a new month is first seen, in addition to
|
||||
reaching a maximum file size.
|
||||
* "file_timestamp": Set each file's last-modified time to that of the
|
||||
|
|
|
@ -12,6 +12,7 @@ import json
|
|||
import struct
|
||||
import re
|
||||
import os
|
||||
import os.path
|
||||
import base64
|
||||
import httplib
|
||||
import sys
|
||||
|
@ -121,13 +122,14 @@ class BlockDataCopier:
|
|||
self.outOfOrderSize = 0 # running total size for items in outOfOrderData
|
||||
|
||||
def writeBlock(self, inhdr, blk_hdr, rawblock):
|
||||
if not self.fileOutput and ((self.outsz + self.inLen) > self.maxOutSz):
|
||||
blockSizeOnDisk = len(inhdr) + len(blk_hdr) + len(rawblock)
|
||||
if not self.fileOutput and ((self.outsz + blockSizeOnDisk) > self.maxOutSz):
|
||||
self.outF.close()
|
||||
if self.setFileTime:
|
||||
os.utime(outFname, (int(time.time()), highTS))
|
||||
self.outF = None
|
||||
self.outFname = None
|
||||
self.outFn = outFn + 1
|
||||
self.outFn = self.outFn + 1
|
||||
self.outsz = 0
|
||||
|
||||
(blkDate, blkTS) = get_blk_dt(blk_hdr)
|
||||
|
@ -147,7 +149,7 @@ class BlockDataCopier:
|
|||
if self.fileOutput:
|
||||
outFname = self.settings['output_file']
|
||||
else:
|
||||
outFname = "%s/blk%05d.dat" % (self.settings['output'], outFn)
|
||||
outFname = os.path.join(self.settings['output'], "blk%05d.dat" % self.outFn)
|
||||
print("Output file " + outFname)
|
||||
self.outF = open(outFname, "wb")
|
||||
|
||||
|
@ -165,7 +167,7 @@ class BlockDataCopier:
|
|||
(self.blkCountIn, self.blkCountOut, len(self.blkindex), 100.0 * self.blkCountOut / len(self.blkindex)))
|
||||
|
||||
def inFileName(self, fn):
|
||||
return "%s/blk%05d.dat" % (self.settings['input'], fn)
|
||||
return os.path.join(self.settings['input'], "blk%05d.dat" % fn)
|
||||
|
||||
def fetchBlock(self, extent):
|
||||
'''Fetch block contents from disk given extents'''
|
||||
|
|
|
@ -68,10 +68,10 @@ class ProxyTest(BitcoinTestFramework):
|
|||
['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf1.addr),'-proxyrandomize=1'],
|
||||
['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf1.addr),'-onion=%s:%i' % (self.conf2.addr),'-proxyrandomize=0'],
|
||||
['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf2.addr),'-proxyrandomize=1'],
|
||||
['-listen', '-debug=net', '-debug=proxy', '-proxy=[%s]:%i' % (self.conf3.addr),'-proxyrandomize=0']
|
||||
['-listen', '-debug=net', '-debug=proxy', '-proxy=[%s]:%i' % (self.conf3.addr),'-proxyrandomize=0', '-noonion']
|
||||
])
|
||||
|
||||
def node_test(self, node, proxies, auth):
|
||||
def node_test(self, node, proxies, auth, test_onion=True):
|
||||
rv = []
|
||||
# Test: outgoing IPv4 connection through node
|
||||
node.addnode("15.61.23.23:1234", "onetry")
|
||||
|
@ -99,6 +99,7 @@ class ProxyTest(BitcoinTestFramework):
|
|||
assert_equal(cmd.password, None)
|
||||
rv.append(cmd)
|
||||
|
||||
if test_onion:
|
||||
# Test: outgoing onion connection through node
|
||||
node.addnode("bitcoinostk4e4re.onion:8333", "onetry")
|
||||
cmd = proxies[2].queue.get()
|
||||
|
@ -139,7 +140,40 @@ class ProxyTest(BitcoinTestFramework):
|
|||
assert_equal(len(credentials), 4)
|
||||
|
||||
# proxy on IPv6 localhost
|
||||
self.node_test(self.nodes[3], [self.serv3, self.serv3, self.serv3, self.serv3], False)
|
||||
self.node_test(self.nodes[3], [self.serv3, self.serv3, self.serv3, self.serv3], False, False)
|
||||
|
||||
def networks_dict(d):
|
||||
r = {}
|
||||
for x in d['networks']:
|
||||
r[x['name']] = x
|
||||
return r
|
||||
|
||||
# test RPC getnetworkinfo
|
||||
n0 = networks_dict(self.nodes[0].getnetworkinfo())
|
||||
for net in ['ipv4','ipv6','onion']:
|
||||
assert_equal(n0[net]['proxy'], '%s:%i' % (self.conf1.addr))
|
||||
assert_equal(n0[net]['proxy_randomize_credentials'], True)
|
||||
assert_equal(n0['onion']['reachable'], True)
|
||||
|
||||
n1 = networks_dict(self.nodes[1].getnetworkinfo())
|
||||
for net in ['ipv4','ipv6']:
|
||||
assert_equal(n1[net]['proxy'], '%s:%i' % (self.conf1.addr))
|
||||
assert_equal(n1[net]['proxy_randomize_credentials'], False)
|
||||
assert_equal(n1['onion']['proxy'], '%s:%i' % (self.conf2.addr))
|
||||
assert_equal(n1['onion']['proxy_randomize_credentials'], False)
|
||||
assert_equal(n1['onion']['reachable'], True)
|
||||
|
||||
n2 = networks_dict(self.nodes[2].getnetworkinfo())
|
||||
for net in ['ipv4','ipv6','onion']:
|
||||
assert_equal(n2[net]['proxy'], '%s:%i' % (self.conf2.addr))
|
||||
assert_equal(n2[net]['proxy_randomize_credentials'], True)
|
||||
assert_equal(n2['onion']['reachable'], True)
|
||||
|
||||
n3 = networks_dict(self.nodes[3].getnetworkinfo())
|
||||
for net in ['ipv4','ipv6']:
|
||||
assert_equal(n3[net]['proxy'], '[%s]:%i' % (self.conf3.addr))
|
||||
assert_equal(n3[net]['proxy_randomize_credentials'], False)
|
||||
assert_equal(n3['onion']['reachable'], False)
|
||||
|
||||
if __name__ == '__main__':
|
||||
ProxyTest().main()
|
||||
|
|
|
@ -470,7 +470,7 @@ public:
|
|||
}
|
||||
|
||||
//! Return the number of (unique) addresses in all tables.
|
||||
int size()
|
||||
size_t size() const
|
||||
{
|
||||
return vRandom.size();
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ std::string CUnsignedAlert::ToString() const
|
|||
BOOST_FOREACH(int n, setCancel)
|
||||
strSetCancel += strprintf("%d ", n);
|
||||
std::string strSetSubVer;
|
||||
BOOST_FOREACH(std::string str, setSubVer)
|
||||
BOOST_FOREACH(const std::string& str, setSubVer)
|
||||
strSetSubVer += "\"" + str + "\" ";
|
||||
return strprintf(
|
||||
"CAlert(\n"
|
||||
|
@ -112,7 +112,7 @@ bool CAlert::Cancels(const CAlert& alert) const
|
|||
return (alert.nID <= nCancel || setCancel.count(alert.nID));
|
||||
}
|
||||
|
||||
bool CAlert::AppliesTo(int nVersion, std::string strSubVerIn) const
|
||||
bool CAlert::AppliesTo(int nVersion, const std::string& strSubVerIn) const
|
||||
{
|
||||
// TODO: rework for client-version-embedded-in-strSubVer ?
|
||||
return (IsInEffect() &&
|
||||
|
|
|
@ -97,7 +97,7 @@ public:
|
|||
uint256 GetHash() const;
|
||||
bool IsInEffect() const;
|
||||
bool Cancels(const CAlert& alert) const;
|
||||
bool AppliesTo(int nVersion, std::string strSubVerIn) const;
|
||||
bool AppliesTo(int nVersion, const std::string& strSubVerIn) const;
|
||||
bool AppliesToMe() const;
|
||||
bool RelayTo(CNode* pnode) const;
|
||||
bool CheckSignature(const std::vector<unsigned char>& alertKey) const;
|
||||
|
|
10
src/amount.h
10
src/amount.h
|
@ -16,7 +16,15 @@ typedef int64_t CAmount;
|
|||
static const CAmount COIN = 100000000;
|
||||
static const CAmount CENT = 1000000;
|
||||
|
||||
/** No amount larger than this (in satoshi) is valid */
|
||||
/** No amount larger than this (in satoshi) is valid.
|
||||
*
|
||||
* Note that this constant is *not* the total money supply, which in Bitcoin
|
||||
* currently happens to be less than 21,000,000 BTC for various reasons, but
|
||||
* rather a sanity check. As this sanity check is used by consensus-critical
|
||||
* validation code, the exact value of the MAX_MONEY constant is consensus
|
||||
* critical; in unusual circumstances like a(nother) overflow bug that allowed
|
||||
* for the creation of coins out of thin air modification could lead to a fork.
|
||||
* */
|
||||
static const CAmount MAX_MONEY = 21000000 * COIN;
|
||||
inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
|
||||
|
||||
|
|
|
@ -171,7 +171,10 @@ public:
|
|||
|
||||
K GetKey() {
|
||||
K ret;
|
||||
ret.Decode(&vchData[0], &vchData[Size]);
|
||||
if (vchData.size() == Size) {
|
||||
//if base58 encouded data not holds a ext key, return a !IsValid() key
|
||||
ret.Decode(&vchData[0]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -179,6 +182,10 @@ public:
|
|||
SetKey(key);
|
||||
}
|
||||
|
||||
CBitcoinExtKeyBase(const std::string& strBase58c) {
|
||||
SetString(strBase58c.c_str(), Params().Base58Prefix(Type).size());
|
||||
}
|
||||
|
||||
CBitcoinExtKeyBase() {}
|
||||
};
|
||||
|
||||
|
|
|
@ -200,6 +200,15 @@ int CommandLineRPC(int argc, char *argv[])
|
|||
throw CConnectionFailed("server in warmup");
|
||||
strPrint = "error: " + error.write();
|
||||
nRet = abs(code);
|
||||
if (error.isObject())
|
||||
{
|
||||
UniValue errCode = find_value(error, "code");
|
||||
UniValue errMsg = find_value(error, "message");
|
||||
strPrint = errCode.isNull() ? "" : "error code: "+errCode.getValStr()+"\n";
|
||||
|
||||
if (errMsg.isStr())
|
||||
strPrint += "error message:\n"+errMsg.get_str();
|
||||
}
|
||||
} else {
|
||||
// Result
|
||||
if (result.isNull())
|
||||
|
|
|
@ -82,9 +82,10 @@ CBlockIndex* CBlockIndex::GetAncestor(int height)
|
|||
while (heightWalk > height) {
|
||||
int heightSkip = GetSkipHeight(heightWalk);
|
||||
int heightSkipPrev = GetSkipHeight(heightWalk - 1);
|
||||
if (heightSkip == height ||
|
||||
if (pindexWalk->pskip != NULL &&
|
||||
(heightSkip == height ||
|
||||
(heightSkip > height && !(heightSkipPrev < heightSkip - 2 &&
|
||||
heightSkipPrev >= height))) {
|
||||
heightSkipPrev >= height)))) {
|
||||
// Only follow pskip if pprev->pskip isn't better than pskip->pprev.
|
||||
pindexWalk = pindexWalk->pskip;
|
||||
heightWalk = heightSkip;
|
||||
|
|
|
@ -24,15 +24,6 @@ namespace Checkpoints {
|
|||
*/
|
||||
static const double SIGCHECK_VERIFICATION_FACTOR = 5.0;
|
||||
|
||||
bool CheckBlock(const CCheckpointData& data, int nHeight, const uint256& hash)
|
||||
{
|
||||
const MapCheckpoints& checkpoints = data.mapCheckpoints;
|
||||
|
||||
MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
|
||||
if (i == checkpoints.end()) return true;
|
||||
return hash == i->second;
|
||||
}
|
||||
|
||||
//! Guess how far we are in the verification process at the given block index
|
||||
double GuessVerificationProgress(const CCheckpointData& data, CBlockIndex *pindex, bool fSigchecks) {
|
||||
if (pindex==NULL)
|
||||
|
|
|
@ -26,9 +26,6 @@ struct CCheckpointData {
|
|||
double fTransactionsPerDay;
|
||||
};
|
||||
|
||||
//! Returns true if block passes checkpoint checks
|
||||
bool CheckBlock(const CCheckpointData& data, int nHeight, const uint256& hash);
|
||||
|
||||
//! Return conservative estimate of total number of blocks, 0 if unknown
|
||||
int GetTotalBlocksEstimate(const CCheckpointData& data);
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
unsigned char _chRejectCode=0, std::string _strRejectReason="") {
|
||||
return DoS(0, ret, _chRejectCode, _strRejectReason);
|
||||
}
|
||||
virtual bool Error(std::string strRejectReasonIn="") {
|
||||
virtual bool Error(const std::string& strRejectReasonIn) {
|
||||
if (mode == MODE_VALID)
|
||||
strRejectReason = strRejectReasonIn;
|
||||
mode = MODE_ERROR;
|
||||
|
|
|
@ -15,7 +15,7 @@ class uint256;
|
|||
class UniValue;
|
||||
|
||||
// core_read.cpp
|
||||
extern CScript ParseScript(std::string s);
|
||||
extern CScript ParseScript(const std::string& s);
|
||||
extern bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx);
|
||||
extern bool DecodeHexBlk(CBlock&, const std::string& strHexBlk);
|
||||
extern uint256 ParseHashUV(const UniValue& v, const std::string& strName);
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
CScript ParseScript(std::string s)
|
||||
CScript ParseScript(const std::string& s)
|
||||
{
|
||||
CScript result;
|
||||
|
||||
|
|
65
src/init.cpp
65
src/init.cpp
|
@ -357,7 +357,7 @@ std::string HelpMessage(HelpMessageMode mode)
|
|||
strUsage += HelpMessageOpt("-timeout=<n>", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT));
|
||||
#ifdef USE_UPNP
|
||||
#if USE_UPNP
|
||||
strUsage += HelpMessageOpt("-upnp", _("Use UPnP to map the listening port (default: 1 when listening)"));
|
||||
strUsage += HelpMessageOpt("-upnp", _("Use UPnP to map the listening port (default: 1 when listening and no -proxy)"));
|
||||
#else
|
||||
strUsage += HelpMessageOpt("-upnp", strprintf(_("Use UPnP to map the listening port (default: %u)"), 0));
|
||||
#endif
|
||||
|
@ -387,7 +387,6 @@ std::string HelpMessage(HelpMessageMode mode)
|
|||
strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)"));
|
||||
strUsage += HelpMessageOpt("-zapwallettxes=<mode>", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") +
|
||||
" " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)"));
|
||||
|
||||
#endif
|
||||
|
||||
#if ENABLE_ZMQ
|
||||
|
@ -401,7 +400,7 @@ std::string HelpMessage(HelpMessageMode mode)
|
|||
strUsage += HelpMessageGroup(_("Debugging/Testing options:"));
|
||||
if (showDebug)
|
||||
{
|
||||
strUsage += HelpMessageOpt("-checkpoints", strprintf("Only accept block chain matching built-in checkpoints (default: %u)", 1));
|
||||
strUsage += HelpMessageOpt("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", 1));
|
||||
strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf("Flush database activity from memory pool to disk log every <n> megabytes (default: %u)", 100));
|
||||
strUsage += HelpMessageOpt("-disablesafemode", strprintf("Disable safemode, override a real safe mode event (default: %u)", 0));
|
||||
strUsage += HelpMessageOpt("-testsafemode", strprintf("Force safe mode (default: %u)", 0));
|
||||
|
@ -446,6 +445,8 @@ std::string HelpMessage(HelpMessageMode mode)
|
|||
strUsage += HelpMessageOpt("-blockminsize=<n>", strprintf(_("Set minimum block size in bytes (default: %u)"), 0));
|
||||
strUsage += HelpMessageOpt("-blockmaxsize=<n>", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE));
|
||||
strUsage += HelpMessageOpt("-blockprioritysize=<n>", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE));
|
||||
if (GetBoolArg("-help-debug", false))
|
||||
strUsage += HelpMessageOpt("-blockversion=<n>", strprintf("Override block version to test forking scenarios (default: %d)", (int)CBlock::CURRENT_VERSION));
|
||||
|
||||
#ifdef ENABLE_MINING
|
||||
strUsage += HelpMessageGroup(_("Mining options:"));
|
||||
|
@ -612,7 +613,7 @@ void ThreadImport(std::vector<boost::filesystem::path> vImportFiles)
|
|||
}
|
||||
|
||||
// -loadblock=
|
||||
BOOST_FOREACH(boost::filesystem::path &path, vImportFiles) {
|
||||
BOOST_FOREACH(const boost::filesystem::path& path, vImportFiles) {
|
||||
FILE *file = fopen(path.string().c_str(), "rb");
|
||||
if (file) {
|
||||
CImportingNow imp;
|
||||
|
@ -766,6 +767,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
fLogTimestamps = GetBoolArg("-logtimestamps", true);
|
||||
fLogIPs = GetBoolArg("-logips", false);
|
||||
|
||||
LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
|
||||
LogPrintf("Zcash version %s (%s)\n", FormatFullVersion(), CLIENT_DATE);
|
||||
|
||||
// when specifying an explicit binding address, you want to listen on it
|
||||
// even when -connect or -proxy is specified
|
||||
if (mapArgs.count("-bind")) {
|
||||
|
@ -1030,8 +1034,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
#endif
|
||||
if (GetBoolArg("-shrinkdebugfile", !fDebug))
|
||||
ShrinkDebugFile();
|
||||
LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
|
||||
LogPrintf("Zcash version %s (%s)\n", FormatFullVersion(), CLIENT_DATE);
|
||||
|
||||
if (fPrintToDebugLog)
|
||||
OpenDebugLog();
|
||||
|
||||
LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION));
|
||||
#ifdef ENABLE_WALLET
|
||||
LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0));
|
||||
|
@ -1113,7 +1119,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
|
||||
if (mapArgs.count("-onlynet")) {
|
||||
std::set<enum Network> nets;
|
||||
BOOST_FOREACH(std::string snet, mapMultiArgs["-onlynet"]) {
|
||||
BOOST_FOREACH(const std::string& snet, mapMultiArgs["-onlynet"]) {
|
||||
enum Network net = ParseNetwork(snet);
|
||||
if (net == NET_UNROUTABLE)
|
||||
return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet));
|
||||
|
@ -1135,32 +1141,37 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
}
|
||||
}
|
||||
|
||||
proxyType addrProxy;
|
||||
bool fProxy = false;
|
||||
if (mapArgs.count("-proxy")) {
|
||||
addrProxy = proxyType(CService(mapArgs["-proxy"], 9050), GetBoolArg("-proxyrandomize", true));
|
||||
bool proxyRandomize = GetBoolArg("-proxyrandomize", true);
|
||||
// -proxy sets a proxy for all outgoing network traffic
|
||||
// -noproxy (or -proxy=0) as well as the empty string can be used to not set a proxy, this is the default
|
||||
std::string proxyArg = GetArg("-proxy", "");
|
||||
if (proxyArg != "" && proxyArg != "0") {
|
||||
proxyType addrProxy = proxyType(CService(proxyArg, 9050), proxyRandomize);
|
||||
if (!addrProxy.IsValid())
|
||||
return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"]));
|
||||
return InitError(strprintf(_("Invalid -proxy address: '%s'"), proxyArg));
|
||||
|
||||
SetProxy(NET_IPV4, addrProxy);
|
||||
SetProxy(NET_IPV6, addrProxy);
|
||||
SetProxy(NET_TOR, addrProxy);
|
||||
SetNameProxy(addrProxy);
|
||||
fProxy = true;
|
||||
SetReachable(NET_TOR); // by default, -proxy sets onion as reachable, unless -noonion later
|
||||
}
|
||||
|
||||
// -onion can override normal proxy, -noonion disables connecting to .onion entirely
|
||||
if (!(mapArgs.count("-onion") && mapArgs["-onion"] == "0") &&
|
||||
(fProxy || mapArgs.count("-onion"))) {
|
||||
proxyType addrOnion;
|
||||
if (!mapArgs.count("-onion"))
|
||||
addrOnion = addrProxy;
|
||||
else
|
||||
addrOnion = proxyType(CService(mapArgs["-onion"], 9050), GetBoolArg("-proxyrandomize", true));
|
||||
// -onion can be used to set only a proxy for .onion, or override normal proxy for .onion addresses
|
||||
// -noonion (or -onion=0) disables connecting to .onion entirely
|
||||
// An empty string is used to not override the onion proxy (in which case it defaults to -proxy set above, or none)
|
||||
std::string onionArg = GetArg("-onion", "");
|
||||
if (onionArg != "") {
|
||||
if (onionArg == "0") { // Handle -noonion/-onion=0
|
||||
SetReachable(NET_TOR, false); // set onions as unreachable
|
||||
} else {
|
||||
proxyType addrOnion = proxyType(CService(onionArg, 9050), proxyRandomize);
|
||||
if (!addrOnion.IsValid())
|
||||
return InitError(strprintf(_("Invalid -onion address: '%s'"), mapArgs["-onion"]));
|
||||
return InitError(strprintf(_("Invalid -onion address: '%s'"), onionArg));
|
||||
SetProxy(NET_TOR, addrOnion);
|
||||
SetReachable(NET_TOR);
|
||||
}
|
||||
}
|
||||
|
||||
// see Step 2: parameter interactions for more information about these
|
||||
fListen = GetBoolArg("-listen", DEFAULT_LISTEN);
|
||||
|
@ -1170,13 +1181,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
bool fBound = false;
|
||||
if (fListen) {
|
||||
if (mapArgs.count("-bind") || mapArgs.count("-whitebind")) {
|
||||
BOOST_FOREACH(std::string strBind, mapMultiArgs["-bind"]) {
|
||||
BOOST_FOREACH(const std::string& strBind, mapMultiArgs["-bind"]) {
|
||||
CService addrBind;
|
||||
if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false))
|
||||
return InitError(strprintf(_("Cannot resolve -bind address: '%s'"), strBind));
|
||||
fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR));
|
||||
}
|
||||
BOOST_FOREACH(std::string strBind, mapMultiArgs["-whitebind"]) {
|
||||
BOOST_FOREACH(const std::string& strBind, mapMultiArgs["-whitebind"]) {
|
||||
CService addrBind;
|
||||
if (!Lookup(strBind.c_str(), addrBind, 0, false))
|
||||
return InitError(strprintf(_("Cannot resolve -whitebind address: '%s'"), strBind));
|
||||
|
@ -1196,7 +1207,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
}
|
||||
|
||||
if (mapArgs.count("-externalip")) {
|
||||
BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) {
|
||||
BOOST_FOREACH(const std::string& strAddr, mapMultiArgs["-externalip"]) {
|
||||
CService addrLocal(strAddr, GetListenPort(), fNameLookup);
|
||||
if (!addrLocal.IsValid())
|
||||
return InitError(strprintf(_("Cannot resolve -externalip address: '%s'"), strAddr));
|
||||
|
@ -1204,7 +1215,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"])
|
||||
BOOST_FOREACH(const std::string& strDest, mapMultiArgs["-seednode"])
|
||||
AddOneShot(strDest);
|
||||
|
||||
#if ENABLE_ZMQ
|
||||
|
@ -1572,7 +1583,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
std::vector<boost::filesystem::path> vImportFiles;
|
||||
if (mapArgs.count("-loadblock"))
|
||||
{
|
||||
BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"])
|
||||
BOOST_FOREACH(const std::string& strFile, mapMultiArgs["-loadblock"])
|
||||
vImportFiles.push_back(strFile);
|
||||
}
|
||||
threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles));
|
||||
|
|
87
src/main.cpp
87
src/main.cpp
|
@ -1607,13 +1607,16 @@ bool CScriptCheck::operator()() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool NonContextualCheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, const Consensus::Params& consensusParams, std::vector<CScriptCheck> *pvChecks)
|
||||
int GetSpendHeight(const CCoinsViewCache& inputs)
|
||||
{
|
||||
if (!tx.IsCoinBase())
|
||||
{
|
||||
if (pvChecks)
|
||||
pvChecks->reserve(tx.vin.size());
|
||||
LOCK(cs_main);
|
||||
CBlockIndex* pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
|
||||
return pindexPrev->nHeight + 1;
|
||||
}
|
||||
|
||||
namespace Consensus {
|
||||
bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, const Consensus::Params& consensusParams)
|
||||
{
|
||||
// This doesn't trigger the DoS code on purpose; if it did, it would make it easier
|
||||
// for an attacker to attempt to split the network.
|
||||
if (!inputs.HaveInputs(tx))
|
||||
|
@ -1632,6 +1635,13 @@ bool NonContextualCheckInputs(const CTransaction& tx, CValidationState &state, c
|
|||
assert(coins);
|
||||
|
||||
if (coins->IsCoinBase()) {
|
||||
// Ensure that coinbases are matured
|
||||
if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) {
|
||||
return state.Invalid(
|
||||
error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
|
||||
REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
|
||||
}
|
||||
|
||||
// Ensure that coinbases cannot be spent to transparent outputs
|
||||
// Disabled on regtest
|
||||
if (fCoinbaseEnforcedProtectionEnabled &&
|
||||
|
@ -1670,6 +1680,19 @@ bool NonContextualCheckInputs(const CTransaction& tx, CValidationState &state, c
|
|||
if (!MoneyRange(nFees))
|
||||
return state.DoS(100, error("CheckInputs(): nFees out of range"),
|
||||
REJECT_INVALID, "bad-txns-fee-outofrange");
|
||||
return true;
|
||||
}
|
||||
}// namespace Consensus
|
||||
|
||||
bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, const Consensus::Params& consensusParams, std::vector<CScriptCheck> *pvChecks)
|
||||
{
|
||||
if (!Consensus::CheckTxInputs(tx, state, inputs, GetSpendHeight(inputs), consensusParams))
|
||||
return false;
|
||||
|
||||
if (!tx.IsCoinBase())
|
||||
{
|
||||
if (pvChecks)
|
||||
pvChecks->reserve(tx.vin.size());
|
||||
|
||||
// The first loop above does all the inexpensive checks.
|
||||
// Only if ALL inputs pass do we perform expensive ECDSA signature checks.
|
||||
|
@ -1718,40 +1741,6 @@ bool NonContextualCheckInputs(const CTransaction& tx, CValidationState &state, c
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, const Consensus::Params& consensusParams, std::vector<CScriptCheck> *pvChecks)
|
||||
{
|
||||
if (!NonContextualCheckInputs(tx, state, inputs, fScriptChecks, flags, cacheStore, consensusParams, pvChecks)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!tx.IsCoinBase())
|
||||
{
|
||||
// While checking, GetBestBlock() refers to the parent block.
|
||||
// This is also true for mempool checks.
|
||||
CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
|
||||
int nSpendHeight = pindexPrev->nHeight + 1;
|
||||
for (unsigned int i = 0; i < tx.vin.size(); i++)
|
||||
{
|
||||
const COutPoint &prevout = tx.vin[i].prevout;
|
||||
const CCoins *coins = inputs.AccessCoins(prevout.hash);
|
||||
// Assertion is okay because NonContextualCheckInputs ensures the inputs
|
||||
// are available.
|
||||
assert(coins);
|
||||
|
||||
// If prev is coinbase, check that it's matured
|
||||
if (coins->IsCoinBase()) {
|
||||
if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) {
|
||||
return state.Invalid(
|
||||
error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
|
||||
REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart)
|
||||
|
@ -2044,7 +2033,15 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||
const CChainParams& chainparams = Params();
|
||||
AssertLockHeld(cs_main);
|
||||
|
||||
bool fExpensiveChecks = (!fCheckpointsEnabled || pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()));
|
||||
bool fExpensiveChecks = true;
|
||||
if (fCheckpointsEnabled) {
|
||||
CBlockIndex *pindexLastCheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints());
|
||||
if (pindexLastCheckpoint && pindexLastCheckpoint->GetAncestor(pindex->nHeight) == pindex) {
|
||||
// This block is an ancestor of a checkpoint: disable script checks
|
||||
fExpensiveChecks = false;
|
||||
}
|
||||
}
|
||||
|
||||
auto verifier = libzcash::ProofVerifier::Strict();
|
||||
auto disabledVerifier = libzcash::ProofVerifier::Disabled();
|
||||
|
||||
|
@ -2481,7 +2478,6 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
|
|||
LogPrint("bench", " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001);
|
||||
{
|
||||
CCoinsViewCache view(pcoinsTip);
|
||||
CInv inv(MSG_BLOCK, pindexNew->GetBlockHash());
|
||||
bool rv = ConnectBlock(*pblock, state, pindexNew, view);
|
||||
GetMainSignals().BlockChecked(*pblock, state);
|
||||
if (!rv) {
|
||||
|
@ -2489,7 +2485,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
|
|||
InvalidBlockFound(pindexNew, state);
|
||||
return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
|
||||
}
|
||||
mapBlockSource.erase(inv.hash);
|
||||
mapBlockSource.erase(pindexNew->GetBlockHash());
|
||||
nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
|
||||
LogPrint("bench", " - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
|
||||
assert(view.Flush());
|
||||
|
@ -3068,11 +3064,6 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
|
|||
|
||||
if (fCheckpointsEnabled)
|
||||
{
|
||||
// Check that the block chain matches the known block chain up to a checkpoint
|
||||
if (!Checkpoints::CheckBlock(chainParams.Checkpoints(), nHeight, hash))
|
||||
return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),
|
||||
REJECT_CHECKPOINT, "checkpoint mismatch");
|
||||
|
||||
// Don't accept any forks from the main chain prior to last checkpoint
|
||||
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(chainParams.Checkpoints());
|
||||
if (pcheckpoint && nHeight < pcheckpoint->nHeight)
|
||||
|
@ -4072,7 +4063,7 @@ void static CheckBlockIndex()
|
|||
// CAlert
|
||||
//
|
||||
|
||||
string GetWarnings(string strFor)
|
||||
std::string GetWarnings(const std::string& strFor)
|
||||
{
|
||||
int nPriority = 0;
|
||||
string strStatusBar;
|
||||
|
|
21
src/main.h
21
src/main.h
|
@ -145,7 +145,7 @@ extern bool fPruneMode;
|
|||
/** Number of MiB of block files that we're trying to stay below. */
|
||||
extern uint64_t nPruneTarget;
|
||||
/** Block files containing a block-height within MIN_BLOCKS_TO_KEEP of chainActive.Tip() will not be pruned. */
|
||||
static const signed int MIN_BLOCKS_TO_KEEP = 288;
|
||||
static const unsigned int MIN_BLOCKS_TO_KEEP = 288;
|
||||
|
||||
// Require that user allocate at least 550MB for block & undo files (blk???.dat and rev???.dat)
|
||||
// At 1MB per block, 288 blocks = 288MB.
|
||||
|
@ -155,7 +155,7 @@ static const signed int MIN_BLOCKS_TO_KEEP = 288;
|
|||
// full block file chunks, we need the high water mark which triggers the prune to be
|
||||
// one 128MB block file + added 15% undo data = 147MB greater for a total of 545MB
|
||||
// Setting the target to > than 550MB will make it likely we can respect the target.
|
||||
static const signed int MIN_DISK_SPACE_FOR_BLOCK_FILES = 550 * 1024 * 1024;
|
||||
static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES = 550 * 1024 * 1024;
|
||||
|
||||
/** Register with a network node to receive its signals */
|
||||
void RegisterNodeSignals(CNodeSignals& nodeSignals);
|
||||
|
@ -207,7 +207,7 @@ void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const
|
|||
/** Check whether we are doing an initial block download (synchronizing from disk or network) */
|
||||
bool IsInitialBlockDownload();
|
||||
/** Format a string that describes several potential problems detected by the core */
|
||||
std::string GetWarnings(std::string strFor);
|
||||
std::string GetWarnings(const std::string& strFor);
|
||||
/** Retrieve a transaction (from memory pool, or from disk, if possible) */
|
||||
bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, bool fAllowSlow = false);
|
||||
/** Find the best known block, and make it the tip of the block chain */
|
||||
|
@ -332,10 +332,6 @@ bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, cons
|
|||
unsigned int flags, bool cacheStore, const Consensus::Params& consensusParams,
|
||||
std::vector<CScriptCheck> *pvChecks = NULL);
|
||||
|
||||
bool NonContextualCheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &view, bool fScriptChecks,
|
||||
unsigned int flags, bool cacheStore, const Consensus::Params& consensusParams,
|
||||
std::vector<CScriptCheck> *pvChecks = NULL);
|
||||
|
||||
/** Apply the effects of this transaction on the UTXO set represented by view */
|
||||
void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight);
|
||||
|
||||
|
@ -520,4 +516,15 @@ extern CCoinsViewCache *pcoinsTip;
|
|||
/** Global variable that points to the active block tree (protected by cs_main) */
|
||||
extern CBlockTreeDB *pblocktree;
|
||||
|
||||
/**
|
||||
* Return the spend height, which is one more than the inputs.GetBestBlock().
|
||||
* While checking, GetBestBlock() refers to the parent block. (protected by cs_main)
|
||||
* This is also true for mempool checks.
|
||||
*/
|
||||
int GetSpendHeight(const CCoinsViewCache& inputs);
|
||||
|
||||
namespace Consensus {
|
||||
bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, const Consensus::Params& consensusParams);
|
||||
}
|
||||
|
||||
#endif // BITCOIN_MAIN_H
|
||||
|
|
21
src/net.cpp
21
src/net.cpp
|
@ -107,7 +107,7 @@ boost::condition_variable messageHandlerCondition;
|
|||
static CNodeSignals g_signals;
|
||||
CNodeSignals& GetNodeSignals() { return g_signals; }
|
||||
|
||||
void AddOneShot(string strDest)
|
||||
void AddOneShot(const std::string& strDest)
|
||||
{
|
||||
LOCK(cs_vOneShots);
|
||||
vOneShots.push_back(strDest);
|
||||
|
@ -1316,7 +1316,7 @@ void ThreadDNSAddressSeed()
|
|||
vector<CAddress> vAdd;
|
||||
if (LookupHost(seed.host.c_str(), vIPs))
|
||||
{
|
||||
BOOST_FOREACH(CNetAddr& ip, vIPs)
|
||||
BOOST_FOREACH(const CNetAddr& ip, vIPs)
|
||||
{
|
||||
int nOneDay = 24*3600;
|
||||
CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()));
|
||||
|
@ -1380,7 +1380,7 @@ void ThreadOpenConnections()
|
|||
for (int64_t nLoop = 0;; nLoop++)
|
||||
{
|
||||
ProcessOneShot();
|
||||
BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
|
||||
BOOST_FOREACH(const std::string& strAddr, mapMultiArgs["-connect"])
|
||||
{
|
||||
CAddress addr;
|
||||
OpenNetworkConnection(addr, NULL, strAddr.c_str());
|
||||
|
@ -1483,10 +1483,10 @@ void ThreadOpenAddedConnections()
|
|||
list<string> lAddresses(0);
|
||||
{
|
||||
LOCK(cs_vAddedNodes);
|
||||
BOOST_FOREACH(string& strAddNode, vAddedNodes)
|
||||
BOOST_FOREACH(const std::string& strAddNode, vAddedNodes)
|
||||
lAddresses.push_back(strAddNode);
|
||||
}
|
||||
BOOST_FOREACH(string& strAddNode, lAddresses) {
|
||||
BOOST_FOREACH(const std::string& strAddNode, lAddresses) {
|
||||
CAddress addr;
|
||||
CSemaphoreGrant grant(*semOutbound);
|
||||
OpenNetworkConnection(addr, &grant, strAddNode.c_str());
|
||||
|
@ -1501,20 +1501,19 @@ void ThreadOpenAddedConnections()
|
|||
list<string> lAddresses(0);
|
||||
{
|
||||
LOCK(cs_vAddedNodes);
|
||||
BOOST_FOREACH(string& strAddNode, vAddedNodes)
|
||||
BOOST_FOREACH(const std::string& strAddNode, vAddedNodes)
|
||||
lAddresses.push_back(strAddNode);
|
||||
}
|
||||
|
||||
list<vector<CService> > lservAddressesToAdd(0);
|
||||
BOOST_FOREACH(string& strAddNode, lAddresses)
|
||||
{
|
||||
BOOST_FOREACH(const std::string& strAddNode, lAddresses) {
|
||||
vector<CService> vservNode(0);
|
||||
if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0))
|
||||
{
|
||||
lservAddressesToAdd.push_back(vservNode);
|
||||
{
|
||||
LOCK(cs_setservAddNodeAddresses);
|
||||
BOOST_FOREACH(CService& serv, vservNode)
|
||||
BOOST_FOREACH(const CService& serv, vservNode)
|
||||
setservAddNodeAddresses.insert(serv);
|
||||
}
|
||||
}
|
||||
|
@ -1525,7 +1524,7 @@ void ThreadOpenAddedConnections()
|
|||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
for (list<vector<CService> >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
|
||||
BOOST_FOREACH(CService& addrNode, *(it))
|
||||
BOOST_FOREACH(const CService& addrNode, *(it))
|
||||
if (pnode->addr == addrNode)
|
||||
{
|
||||
it = lservAddressesToAdd.erase(it);
|
||||
|
@ -2110,7 +2109,7 @@ bool CAddrDB::Read(CAddrMan& addr)
|
|||
unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); }
|
||||
unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); }
|
||||
|
||||
CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fInboundIn) :
|
||||
CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) :
|
||||
ssSend(SER_NETWORK, INIT_PROTO_VERSION),
|
||||
addrKnown(5000, 0.001),
|
||||
setInventoryKnown(SendBufferSize() / 1000)
|
||||
|
|
|
@ -65,7 +65,7 @@ static const size_t SETASKFOR_MAX_SZ = 2 * MAX_INV_SZ;
|
|||
unsigned int ReceiveFloodSize();
|
||||
unsigned int SendBufferSize();
|
||||
|
||||
void AddOneShot(std::string strDest);
|
||||
void AddOneShot(const std::string& strDest);
|
||||
void AddressCurrentlyConnected(const CService& addr);
|
||||
CNode* FindNode(const CNetAddr& ip);
|
||||
CNode* FindNode(const std::string& addrName);
|
||||
|
@ -328,7 +328,7 @@ public:
|
|||
// Whether a ping is requested.
|
||||
bool fPingQueued;
|
||||
|
||||
CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false);
|
||||
CNode(SOCKET hSocketIn, const CAddress &addrIn, const std::string &addrNameIn = "", bool fInboundIn = false);
|
||||
~CNode();
|
||||
|
||||
private:
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
static const int MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once
|
||||
static const size_t MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once
|
||||
|
||||
enum RetFormat {
|
||||
RF_UNDEF,
|
||||
|
|
|
@ -651,8 +651,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
|
|||
UniValue transactions(UniValue::VARR);
|
||||
map<uint256, int64_t> setTxIndex;
|
||||
int i = 0;
|
||||
BOOST_FOREACH (CTransaction& tx, pblock->vtx)
|
||||
{
|
||||
BOOST_FOREACH (const CTransaction& tx, pblock->vtx) {
|
||||
uint256 txHash = tx.GetHash();
|
||||
setTxIndex[txHash] = i++;
|
||||
|
||||
|
|
|
@ -253,19 +253,20 @@ UniValue getaddednodeinfo(const UniValue& params, bool fHelp)
|
|||
if (params.size() == 1)
|
||||
{
|
||||
LOCK(cs_vAddedNodes);
|
||||
BOOST_FOREACH(string& strAddNode, vAddedNodes)
|
||||
BOOST_FOREACH(const std::string& strAddNode, vAddedNodes)
|
||||
laddedNodes.push_back(strAddNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
string strNode = params[1].get_str();
|
||||
LOCK(cs_vAddedNodes);
|
||||
BOOST_FOREACH(string& strAddNode, vAddedNodes)
|
||||
BOOST_FOREACH(const std::string& strAddNode, vAddedNodes) {
|
||||
if (strAddNode == strNode)
|
||||
{
|
||||
laddedNodes.push_back(strAddNode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (laddedNodes.size() == 0)
|
||||
throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
|
||||
}
|
||||
|
@ -273,8 +274,7 @@ UniValue getaddednodeinfo(const UniValue& params, bool fHelp)
|
|||
UniValue ret(UniValue::VARR);
|
||||
if (!fDns)
|
||||
{
|
||||
BOOST_FOREACH(string& strAddNode, laddedNodes)
|
||||
{
|
||||
BOOST_FOREACH (const std::string& strAddNode, laddedNodes) {
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("addednode", strAddNode));
|
||||
ret.push_back(obj);
|
||||
|
@ -283,8 +283,7 @@ UniValue getaddednodeinfo(const UniValue& params, bool fHelp)
|
|||
}
|
||||
|
||||
list<pair<string, vector<CService> > > laddedAddreses(0);
|
||||
BOOST_FOREACH(string& strAddNode, laddedNodes)
|
||||
{
|
||||
BOOST_FOREACH(const std::string& strAddNode, laddedNodes) {
|
||||
vector<CService> vservNode(0);
|
||||
if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0))
|
||||
laddedAddreses.push_back(make_pair(strAddNode, vservNode));
|
||||
|
@ -306,12 +305,11 @@ UniValue getaddednodeinfo(const UniValue& params, bool fHelp)
|
|||
|
||||
UniValue addresses(UniValue::VARR);
|
||||
bool fConnected = false;
|
||||
BOOST_FOREACH(CService& addrNode, it->second)
|
||||
{
|
||||
BOOST_FOREACH(const CService& addrNode, it->second) {
|
||||
bool fFound = false;
|
||||
UniValue node(UniValue::VOBJ);
|
||||
node.push_back(Pair("address", addrNode.ToString()));
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
BOOST_FOREACH(CNode* pnode, vNodes) {
|
||||
if (pnode->addr == addrNode)
|
||||
{
|
||||
fFound = true;
|
||||
|
@ -319,6 +317,7 @@ UniValue getaddednodeinfo(const UniValue& params, bool fHelp)
|
|||
node.push_back(Pair("connected", pnode->fInbound ? "inbound" : "outbound"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!fFound)
|
||||
node.push_back(Pair("connected", "false"));
|
||||
addresses.push_back(node);
|
||||
|
|
|
@ -253,7 +253,6 @@ int ReadHTTPMessage(std::basic_istream<char>& stream, map<string,
|
|||
*
|
||||
* 1.0 spec: http://json-rpc.org/wiki/specification
|
||||
* 1.2 spec: http://jsonrpc.org/historical/json-rpc-over-http.html
|
||||
* http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx
|
||||
*/
|
||||
|
||||
string JSONRPCRequest(const string& strMethod, const UniValue& params, const UniValue& id)
|
||||
|
|
|
@ -177,7 +177,7 @@ vector<unsigned char> ParseHexO(const UniValue& o, string strKey)
|
|||
* Note: This interface may still be subject to change.
|
||||
*/
|
||||
|
||||
string CRPCTable::help(string strCommand) const
|
||||
std::string CRPCTable::help(const std::string& strCommand) const
|
||||
{
|
||||
string strRet;
|
||||
string category;
|
||||
|
@ -419,7 +419,7 @@ CRPCTable::CRPCTable()
|
|||
}
|
||||
}
|
||||
|
||||
const CRPCCommand *CRPCTable::operator[](string name) const
|
||||
const CRPCCommand *CRPCTable::operator[](const std::string& name) const
|
||||
{
|
||||
map<string, const CRPCCommand*>::const_iterator it = mapCommands.find(name);
|
||||
if (it == mapCommands.end())
|
||||
|
@ -1071,11 +1071,13 @@ UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms
|
|||
g_rpcSignals.PostCommand(*pcmd);
|
||||
}
|
||||
|
||||
std::string HelpExampleCli(string methodname, string args){
|
||||
std::string HelpExampleCli(const std::string& methodname, const std::string& args)
|
||||
{
|
||||
return "> zcash-cli " + methodname + " " + args + "\n";
|
||||
}
|
||||
|
||||
std::string HelpExampleRpc(string methodname, string args){
|
||||
std::string HelpExampleRpc(const std::string& methodname, const std::string& args)
|
||||
{
|
||||
return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\":\"curltest\", "
|
||||
"\"method\": \"" + methodname + "\", \"params\": [" + args + "] }' -H 'content-type: text/plain;' http://127.0.0.1:8232/\n";
|
||||
}
|
||||
|
|
|
@ -116,8 +116,8 @@ private:
|
|||
std::map<std::string, const CRPCCommand*> mapCommands;
|
||||
public:
|
||||
CRPCTable();
|
||||
const CRPCCommand* operator[](std::string name) const;
|
||||
std::string help(std::string name) const;
|
||||
const CRPCCommand* operator[](const std::string& name) const;
|
||||
std::string help(const std::string& name) const;
|
||||
|
||||
/**
|
||||
* Execute a method.
|
||||
|
@ -149,8 +149,8 @@ extern UniValue ValueFromAmount(const CAmount& amount);
|
|||
extern double GetDifficulty(const CBlockIndex* blockindex = NULL);
|
||||
extern double GetNetworkDifficulty(const CBlockIndex* blockindex = NULL);
|
||||
extern std::string HelpRequiringPassphrase();
|
||||
extern std::string HelpExampleCli(std::string methodname, std::string args);
|
||||
extern std::string HelpExampleRpc(std::string methodname, std::string args);
|
||||
extern std::string HelpExampleCli(const std::string& methodname, const std::string& args);
|
||||
extern std::string HelpExampleRpc(const std::string& methodname, const std::string& args);
|
||||
|
||||
extern void EnsureWalletIsUnlocked();
|
||||
|
||||
|
|
|
@ -23,20 +23,6 @@ BOOST_FIXTURE_TEST_SUITE(Checkpoints_tests, BasicTestingSetup)
|
|||
BOOST_AUTO_TEST_CASE(sanity)
|
||||
{
|
||||
const Checkpoints::CCheckpointData& checkpoints = Params(CBaseChainParams::MAIN).Checkpoints();
|
||||
uint256 p11111 = uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d");
|
||||
uint256 p134444 = uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe");
|
||||
BOOST_CHECK(Checkpoints::CheckBlock(checkpoints, 11111, p11111));
|
||||
BOOST_CHECK(Checkpoints::CheckBlock(checkpoints, 134444, p134444));
|
||||
|
||||
|
||||
// Wrong hashes at checkpoints should fail:
|
||||
BOOST_CHECK(!Checkpoints::CheckBlock(checkpoints, 11111, p134444));
|
||||
BOOST_CHECK(!Checkpoints::CheckBlock(checkpoints, 134444, p11111));
|
||||
|
||||
// ... but any hash not at a checkpoint should succeed:
|
||||
BOOST_CHECK(Checkpoints::CheckBlock(checkpoints, 11111+1, p134444));
|
||||
BOOST_CHECK(Checkpoints::CheckBlock(checkpoints, 134444+1, p11111));
|
||||
|
||||
BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate(checkpoints) >= 134444);
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -88,12 +88,23 @@ void RunTest(const TestVector &test) {
|
|||
unsigned char data[74];
|
||||
key.Encode(data);
|
||||
pubkey.Encode(data);
|
||||
|
||||
// Test private key
|
||||
CBitcoinExtKey b58key; b58key.SetKey(key);
|
||||
BOOST_CHECK(b58key.ToString() == derive.prv);
|
||||
|
||||
CBitcoinExtKey b58keyDecodeCheck(derive.prv);
|
||||
CExtKey checkKey = b58keyDecodeCheck.GetKey();
|
||||
assert(checkKey == key); //ensure a base58 decoded key also matches
|
||||
|
||||
// Test public key
|
||||
CBitcoinExtPubKey b58pubkey; b58pubkey.SetKey(pubkey);
|
||||
BOOST_CHECK(b58pubkey.ToString() == derive.pub);
|
||||
|
||||
CBitcoinExtPubKey b58PubkeyDecodeCheck(derive.pub);
|
||||
CExtPubKey checkPubKey = b58PubkeyDecodeCheck.GetKey();
|
||||
assert(checkPubKey == pubkey); //ensure a base58 decoded pubkey also matches
|
||||
|
||||
// Derive new keys
|
||||
CExtKey keyNew;
|
||||
BOOST_CHECK(key.Derive(keyNew, derive.nChild));
|
||||
|
|
|
@ -756,7 +756,7 @@ BOOST_AUTO_TEST_CASE(coins_coinbase_spends)
|
|||
|
||||
{
|
||||
CTransaction tx2(mtx2);
|
||||
BOOST_CHECK(NonContextualCheckInputs(tx2, state, cache, false, SCRIPT_VERIFY_NONE, false, Params().GetConsensus()));
|
||||
BOOST_CHECK(Consensus::CheckTxInputs(tx2, state, cache, 100+COINBASE_MATURITY, Params().GetConsensus()));
|
||||
}
|
||||
|
||||
mtx2.vout.resize(1);
|
||||
|
@ -765,7 +765,7 @@ BOOST_AUTO_TEST_CASE(coins_coinbase_spends)
|
|||
|
||||
{
|
||||
CTransaction tx2(mtx2);
|
||||
BOOST_CHECK(!NonContextualCheckInputs(tx2, state, cache, false, SCRIPT_VERIFY_NONE, false, Params().GetConsensus()));
|
||||
BOOST_CHECK(!Consensus::CheckTxInputs(tx2, state, cache, 100+COINBASE_MATURITY, Params().GetConsensus()));
|
||||
BOOST_CHECK(state.GetRejectReason() == "bad-txns-coinbase-spend-has-transparent-outputs");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -176,7 +176,7 @@ void CTxMemPool::removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned in
|
|||
continue;
|
||||
const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash);
|
||||
if (fSanityCheck) assert(coins);
|
||||
if (!coins || (coins->IsCoinBase() && nMemPoolHeight - coins->nHeight < COINBASE_MATURITY)) {
|
||||
if (!coins || (coins->IsCoinBase() && ((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY)) {
|
||||
transactionsToRemove.push_back(tx);
|
||||
break;
|
||||
}
|
||||
|
|
93
src/util.cpp
93
src/util.cpp
|
@ -165,23 +165,51 @@ instance_of_cinit;
|
|||
*/
|
||||
|
||||
static boost::once_flag debugPrintInitFlag = BOOST_ONCE_INIT;
|
||||
|
||||
/**
|
||||
* We use boost::call_once() to make sure these are initialized
|
||||
* in a thread-safe manner the first time called:
|
||||
* We use boost::call_once() to make sure mutexDebugLog and
|
||||
* vMsgsBeforeOpenLog are initialized in a thread-safe manner.
|
||||
*
|
||||
* NOTE: fileout, mutexDebugLog and sometimes vMsgsBeforeOpenLog
|
||||
* are leaked on exit. This is ugly, but will be cleaned up by
|
||||
* the OS/libc. When the shutdown sequence is fully audited and
|
||||
* tested, explicit destruction of these objects can be implemented.
|
||||
*/
|
||||
static FILE* fileout = NULL;
|
||||
static boost::mutex* mutexDebugLog = NULL;
|
||||
static list<string> *vMsgsBeforeOpenLog;
|
||||
|
||||
static int FileWriteStr(const std::string &str, FILE *fp)
|
||||
{
|
||||
return fwrite(str.data(), 1, str.size(), fp);
|
||||
}
|
||||
|
||||
static void DebugPrintInit()
|
||||
{
|
||||
assert(fileout == NULL);
|
||||
assert(mutexDebugLog == NULL);
|
||||
mutexDebugLog = new boost::mutex();
|
||||
vMsgsBeforeOpenLog = new list<string>;
|
||||
}
|
||||
|
||||
void OpenDebugLog()
|
||||
{
|
||||
boost::call_once(&DebugPrintInit, debugPrintInitFlag);
|
||||
boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
|
||||
|
||||
assert(fileout == NULL);
|
||||
assert(vMsgsBeforeOpenLog);
|
||||
boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
|
||||
fileout = fopen(pathDebug.string().c_str(), "a");
|
||||
if (fileout) setbuf(fileout, NULL); // unbuffered
|
||||
|
||||
mutexDebugLog = new boost::mutex();
|
||||
// dump buffered messages from before we opened the log
|
||||
while (!vMsgsBeforeOpenLog->empty()) {
|
||||
FileWriteStr(vMsgsBeforeOpenLog->front(), fileout);
|
||||
vMsgsBeforeOpenLog->pop_front();
|
||||
}
|
||||
|
||||
delete vMsgsBeforeOpenLog;
|
||||
vMsgsBeforeOpenLog = NULL;
|
||||
}
|
||||
|
||||
bool LogAcceptCategory(const char* category)
|
||||
|
@ -213,25 +241,56 @@ bool LogAcceptCategory(const char* category)
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* fStartedNewLine is a state variable held by the calling context that will
|
||||
* suppress printing of the timestamp when multiple calls are made that don't
|
||||
* end in a newline. Initialize it to true, and hold it, in the calling context.
|
||||
*/
|
||||
static std::string LogTimestampStr(const std::string &str, bool *fStartedNewLine)
|
||||
{
|
||||
string strStamped;
|
||||
|
||||
if (!fLogTimestamps)
|
||||
return str;
|
||||
|
||||
if (*fStartedNewLine)
|
||||
strStamped = DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()) + ' ' + str;
|
||||
else
|
||||
strStamped = str;
|
||||
|
||||
if (!str.empty() && str[str.size()-1] == '\n')
|
||||
*fStartedNewLine = true;
|
||||
else
|
||||
*fStartedNewLine = false;
|
||||
|
||||
return strStamped;
|
||||
}
|
||||
|
||||
int LogPrintStr(const std::string &str)
|
||||
{
|
||||
int ret = 0; // Returns total number of characters written
|
||||
static bool fStartedNewLine = true;
|
||||
if (fPrintToConsole)
|
||||
{
|
||||
// print to console
|
||||
ret = fwrite(str.data(), 1, str.size(), stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
else if (fPrintToDebugLog && AreBaseParamsConfigured())
|
||||
else if (fPrintToDebugLog)
|
||||
{
|
||||
static bool fStartedNewLine = true;
|
||||
boost::call_once(&DebugPrintInit, debugPrintInitFlag);
|
||||
|
||||
if (fileout == NULL)
|
||||
return ret;
|
||||
|
||||
boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
|
||||
|
||||
string strTimestamped = LogTimestampStr(str, &fStartedNewLine);
|
||||
|
||||
// buffer if we haven't opened the log yet
|
||||
if (fileout == NULL) {
|
||||
assert(vMsgsBeforeOpenLog);
|
||||
ret = strTimestamped.length();
|
||||
vMsgsBeforeOpenLog->push_back(strTimestamped);
|
||||
}
|
||||
else
|
||||
{
|
||||
// reopen the log file, if requested
|
||||
if (fReopenDebugLog) {
|
||||
fReopenDebugLog = false;
|
||||
|
@ -240,17 +299,9 @@ int LogPrintStr(const std::string &str)
|
|||
setbuf(fileout, NULL); // unbuffered
|
||||
}
|
||||
|
||||
// Debug print useful for profiling
|
||||
if (fLogTimestamps && fStartedNewLine)
|
||||
ret += fprintf(fileout, "%s ", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()).c_str());
|
||||
if (!str.empty() && str[str.size()-1] == '\n')
|
||||
fStartedNewLine = true;
|
||||
else
|
||||
fStartedNewLine = false;
|
||||
|
||||
ret = fwrite(str.data(), 1, str.size(), fileout);
|
||||
ret = FileWriteStr(strTimestamped, fileout);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -770,7 +821,7 @@ boost::filesystem::path GetTempPath() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void runCommand(std::string strCommand)
|
||||
void runCommand(const std::string& strCommand)
|
||||
{
|
||||
int nErr = ::system(strCommand.c_str());
|
||||
if (nErr)
|
||||
|
|
|
@ -136,8 +136,9 @@ void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map
|
|||
boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
|
||||
#endif
|
||||
boost::filesystem::path GetTempPath();
|
||||
void OpenDebugLog();
|
||||
void ShrinkDebugFile();
|
||||
void runCommand(std::string strCommand);
|
||||
void runCommand(const std::string& strCommand);
|
||||
const boost::filesystem::path GetExportDir();
|
||||
|
||||
/** Returns licensing information (for -version) */
|
||||
|
|
|
@ -488,7 +488,7 @@ bool ParseDouble(const std::string& str, double *out)
|
|||
return text.eof() && !text.fail();
|
||||
}
|
||||
|
||||
std::string FormatParagraph(const std::string in, size_t width, size_t indent)
|
||||
std::string FormatParagraph(const std::string& in, size_t width, size_t indent)
|
||||
{
|
||||
std::stringstream out;
|
||||
size_t col = 0;
|
||||
|
|
|
@ -93,7 +93,7 @@ inline std::string HexStr(const T& vch, bool fSpaces=false)
|
|||
* Format a paragraph of text to a fixed width, adding spaces for
|
||||
* indentation to any added line.
|
||||
*/
|
||||
std::string FormatParagraph(const std::string in, size_t width=79, size_t indent=0);
|
||||
std::string FormatParagraph(const std::string& in, size_t width = 79, size_t indent = 0);
|
||||
|
||||
/**
|
||||
* Timing-attack-resistant comparison.
|
||||
|
|
|
@ -3148,7 +3148,7 @@ set< set<CTxDestination> > CWallet::GetAddressGroupings()
|
|||
return ret;
|
||||
}
|
||||
|
||||
set<CTxDestination> CWallet::GetAccountAddresses(string strAccount) const
|
||||
std::set<CTxDestination> CWallet::GetAccountAddresses(const std::string& strAccount) const
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
set<CTxDestination> result;
|
||||
|
|
|
@ -708,7 +708,7 @@ public:
|
|||
SetNull();
|
||||
}
|
||||
|
||||
CWallet(std::string strWalletFileIn)
|
||||
CWallet(const std::string& strWalletFileIn)
|
||||
{
|
||||
SetNull();
|
||||
|
||||
|
@ -931,7 +931,7 @@ public:
|
|||
std::set< std::set<CTxDestination> > GetAddressGroupings();
|
||||
std::map<CTxDestination, CAmount> GetAddressBalances();
|
||||
|
||||
std::set<CTxDestination> GetAccountAddresses(std::string strAccount) const;
|
||||
std::set<CTxDestination> GetAccountAddresses(const std::string& strAccount) const;
|
||||
|
||||
boost::optional<uint256> GetNoteNullifier(
|
||||
const JSDescription& jsdesc,
|
||||
|
|
Loading…
Reference in New Issue