aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am86
-rw-r--r--src/Makefile.bench.include1
-rw-r--r--src/Makefile.qt.include2
-rw-r--r--src/Makefile.qttest.include2
-rw-r--r--src/Makefile.test.include2
-rw-r--r--src/chain.cpp32
-rw-r--r--src/chain.h4
-rw-r--r--src/init.cpp42
-rw-r--r--src/main.cpp105
-rw-r--r--src/main.h22
-rw-r--r--src/net.cpp18
-rw-r--r--src/policy/policy.cpp37
-rw-r--r--src/pow.cpp32
-rw-r--r--src/pow.h5
-rw-r--r--src/script/standard.cpp21
-rw-r--r--src/script/standard.h1
-rw-r--r--src/test/script_P2SH_tests.cpp9
-rw-r--r--src/test/transaction_tests.cpp8
-rw-r--r--src/wallet/wallet.cpp1
-rw-r--r--src/wallet/wallet.h8
20 files changed, 189 insertions, 249 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index b1b8ae123e..12ef337494 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -28,6 +28,7 @@ BITCOIN_INCLUDES += -I$(srcdir)/univalue/include
LIBBITCOIN_SERVER=libbitcoin_server.a
LIBBITCOIN_WALLET=libbitcoin_wallet.a
LIBBITCOIN_COMMON=libbitcoin_common.a
+LIBBITCOIN_CONSENSUS=libbitcoin_consensus.a
LIBBITCOIN_CLI=libbitcoin_cli.a
LIBBITCOIN_UTIL=libbitcoin_util.a
LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a
@@ -47,6 +48,7 @@ EXTRA_LIBRARIES = \
crypto/libbitcoin_crypto.a \
libbitcoin_util.a \
libbitcoin_common.a \
+ libbitcoin_consensus.a \
libbitcoin_server.a \
libbitcoin_cli.a
if ENABLE_WALLET
@@ -59,9 +61,9 @@ endif
if BUILD_BITCOIN_LIBS
lib_LTLIBRARIES = libbitcoinconsensus.la
-LIBBITCOIN_CONSENSUS=libbitcoinconsensus.la
+LIBBITCOINCONSENSUS=libbitcoinconsensus.la
else
-LIBBITCOIN_CONSENSUS=
+LIBBITCOINCONSENSUS=
endif
bin_PROGRAMS =
@@ -81,8 +83,6 @@ endif
BITCOIN_CORE_H = \
addrman.h \
alert.h \
- amount.h \
- arith_uint256.h \
base58.h \
bloom.h \
chain.h \
@@ -100,12 +100,8 @@ BITCOIN_CORE_H = \
compat/sanity.h \
compressor.h \
consensus/consensus.h \
- consensus/merkle.h \
- consensus/params.h \
- consensus/validation.h \
core_io.h \
core_memusage.h \
- hash.h \
httprpc.h \
httpserver.h \
init.h \
@@ -124,24 +120,16 @@ BITCOIN_CORE_H = \
policy/policy.h \
policy/rbf.h \
pow.h \
- prevector.h \
- primitives/block.h \
- primitives/transaction.h \
protocol.h \
- pubkey.h \
random.h \
reverselock.h \
rpc/client.h \
rpc/protocol.h \
rpc/server.h \
scheduler.h \
- script/interpreter.h \
- script/script.h \
- script/script_error.h \
script/sigcache.h \
script/sign.h \
script/standard.h \
- serialize.h \
streams.h \
support/allocators/secure.h \
support/allocators/zeroafterfree.h \
@@ -150,19 +138,15 @@ BITCOIN_CORE_H = \
sync.h \
threadsafety.h \
timedata.h \
- tinyformat.h \
torcontrol.h \
txdb.h \
txmempool.h \
ui_interface.h \
- uint256.h \
undo.h \
util.h \
utilmoneystr.h \
- utilstrencodings.h \
utiltime.h \
validationinterface.h \
- version.h \
wallet/crypter.h \
wallet/db.h \
wallet/rpcwallet.h \
@@ -262,31 +246,57 @@ crypto_libbitcoin_crypto_a_SOURCES = \
crypto/sha512.cpp \
crypto/sha512.h
+# consensus: shared between all executables that validate any consensus rules.
+libbitcoin_consensus_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
+libbitcoin_consensus_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
+libbitcoin_consensus_a_SOURCES = \
+ amount.h \
+ arith_uint256.cpp \
+ arith_uint256.h \
+ consensus/merkle.cpp \
+ consensus/merkle.h \
+ consensus/params.h \
+ consensus/validation.h \
+ hash.cpp \
+ hash.h \
+ prevector.h \
+ primitives/block.cpp \
+ primitives/block.h \
+ primitives/transaction.cpp \
+ primitives/transaction.h \
+ pubkey.cpp \
+ pubkey.h \
+ script/bitcoinconsensus.cpp \
+ script/interpreter.cpp \
+ script/interpreter.h \
+ script/script.cpp \
+ script/script.h \
+ script/script_error.cpp \
+ script/script_error.h \
+ serialize.h \
+ tinyformat.h \
+ uint256.cpp \
+ uint256.h \
+ utilstrencodings.cpp \
+ utilstrencodings.h \
+ version.h
+
# common: shared between bitcoind, and bitcoin-qt and non-server tools
libbitcoin_common_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
libbitcoin_common_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
libbitcoin_common_a_SOURCES = \
amount.cpp \
- arith_uint256.cpp \
base58.cpp \
chainparams.cpp \
coins.cpp \
compressor.cpp \
- consensus/merkle.cpp \
core_read.cpp \
core_write.cpp \
- hash.cpp \
key.cpp \
keystore.cpp \
netbase.cpp \
- primitives/block.cpp \
- primitives/transaction.cpp \
protocol.cpp \
- pubkey.cpp \
scheduler.cpp \
- script/interpreter.cpp \
- script/script.cpp \
- script/script_error.cpp \
script/sign.cpp \
script/standard.cpp \
$(BITCOIN_CORE_H)
@@ -307,7 +317,6 @@ libbitcoin_util_a_SOURCES = \
rpc/protocol.cpp \
support/cleanse.cpp \
sync.cpp \
- uint256.cpp \
util.cpp \
utilmoneystr.cpp \
utilstrencodings.cpp \
@@ -343,6 +352,7 @@ bitcoind_LDADD = \
$(LIBBITCOIN_COMMON) \
$(LIBUNIVALUE) \
$(LIBBITCOIN_UTIL) \
+ $(LIBBITCOIN_CONSENSUS) \
$(LIBBITCOIN_CRYPTO) \
$(LIBLEVELDB) \
$(LIBMEMENV) \
@@ -390,6 +400,7 @@ bitcoin_tx_LDADD = \
$(LIBUNIVALUE) \
$(LIBBITCOIN_COMMON) \
$(LIBBITCOIN_UTIL) \
+ $(LIBBITCOIN_CONSENSUS) \
$(LIBBITCOIN_CRYPTO) \
$(LIBSECP256K1)
@@ -399,20 +410,7 @@ bitcoin_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS)
# bitcoinconsensus library #
if BUILD_BITCOIN_LIBS
include_HEADERS = script/bitcoinconsensus.h
-libbitcoinconsensus_la_SOURCES = \
- crypto/hmac_sha512.cpp \
- crypto/ripemd160.cpp \
- crypto/sha1.cpp \
- crypto/sha256.cpp \
- crypto/sha512.cpp \
- hash.cpp \
- primitives/transaction.cpp \
- pubkey.cpp \
- script/bitcoinconsensus.cpp \
- script/interpreter.cpp \
- script/script.cpp \
- uint256.cpp \
- utilstrencodings.cpp
+libbitcoinconsensus_la_SOURCES = $(crypto_libbitcoin_crypto_a_SOURCES) $(libbitcoin_consensus_a_SOURCES)
if GLIBC_BACK_COMPAT
libbitcoinconsensus_la_SOURCES += compat/glibc_compat.cpp
diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include
index d660a3a747..d3cecb6b43 100644
--- a/src/Makefile.bench.include
+++ b/src/Makefile.bench.include
@@ -16,6 +16,7 @@ bench_bench_bitcoin_LDADD = \
$(LIBBITCOIN_COMMON) \
$(LIBBITCOIN_UNIVALUE) \
$(LIBBITCOIN_UTIL) \
+ $(LIBBITCOIN_CONSENSUS) \
$(LIBBITCOIN_CRYPTO) \
$(LIBLEVELDB) \
$(LIBMEMENV) \
diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include
index 96b7adcbf9..d75b2c2810 100644
--- a/src/Makefile.qt.include
+++ b/src/Makefile.qt.include
@@ -378,7 +378,7 @@ endif
if ENABLE_ZMQ
qt_bitcoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
endif
-qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
+qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
$(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
$(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
qt_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include
index ede3fac4c3..813a343ffa 100644
--- a/src/Makefile.qttest.include
+++ b/src/Makefile.qttest.include
@@ -33,7 +33,7 @@ endif
if ENABLE_ZMQ
qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
endif
-qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) \
+qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) \
$(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
$(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
$(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index d89132f806..b22b8b8b96 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -95,7 +95,7 @@ endif
test_test_bitcoin_SOURCES = $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES)
test_test_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS)
-test_test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
+test_test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
$(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1)
test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
if ENABLE_WALLET
diff --git a/src/chain.cpp b/src/chain.cpp
index 3450ed6c3f..32f6480f84 100644
--- a/src/chain.cpp
+++ b/src/chain.cpp
@@ -110,3 +110,35 @@ void CBlockIndex::BuildSkip()
if (pprev)
pskip = pprev->GetAncestor(GetSkipHeight(nHeight));
}
+
+arith_uint256 GetBlockProof(const CBlockIndex& block)
+{
+ arith_uint256 bnTarget;
+ bool fNegative;
+ bool fOverflow;
+ bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
+ if (fNegative || fOverflow || bnTarget == 0)
+ return 0;
+ // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
+ // as it's too large for a arith_uint256. However, as 2**256 is at least as large
+ // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
+ // or ~bnTarget / (nTarget+1) + 1.
+ return (~bnTarget / (bnTarget + 1)) + 1;
+}
+
+int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params)
+{
+ arith_uint256 r;
+ int sign = 1;
+ if (to.nChainWork > from.nChainWork) {
+ r = to.nChainWork - from.nChainWork;
+ } else {
+ r = from.nChainWork - to.nChainWork;
+ sign = -1;
+ }
+ r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip);
+ if (r.bits() > 63) {
+ return sign * std::numeric_limits<int64_t>::max();
+ }
+ return sign * r.GetLow64();
+}
diff --git a/src/chain.h b/src/chain.h
index b9b1b9306f..9199983565 100644
--- a/src/chain.h
+++ b/src/chain.h
@@ -282,6 +282,10 @@ public:
const CBlockIndex* GetAncestor(int height) const;
};
+arith_uint256 GetBlockProof(const CBlockIndex& block);
+/** Return the time it would take to redo the work difference between from and to, assuming the current hashrate corresponds to the difficulty at tip, in seconds. */
+int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params&);
+
/** Used to marshal pointers into hashes for db storage. */
class CDiskBlockIndex : public CBlockIndex
{
diff --git a/src/init.cpp b/src/init.cpp
index 3d9b4041c3..6b51521997 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -47,8 +47,10 @@
#include <signal.h>
#endif
+#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/replace.hpp>
+#include <boost/algorithm/string/split.hpp>
#include <boost/bind.hpp>
#include <boost/filesystem.hpp>
#include <boost/function.hpp>
@@ -367,7 +369,6 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-onion=<ip:port>", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy"));
strUsage += HelpMessageOpt("-onlynet=<net>", _("Only connect to nodes in network <net> (ipv4, ipv6 or onion)"));
strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), DEFAULT_PERMIT_BAREMULTISIG));
- strUsage += HelpMessageOpt("-permitrbf", strprintf(_("Permit transaction replacements in the memory pool (default: %u)"), DEFAULT_PERMIT_REPLACEMENT));
strUsage += HelpMessageOpt("-peerbloomfilters", strprintf(_("Support filtering of blocks and transaction with bloom filters (default: %u)"), 1));
if (showDebug)
strUsage += HelpMessageOpt("-enforcenodebloom", strprintf("Enforce minimum protocol version to limit use of bloom filters (default: %u)", 0));
@@ -388,7 +389,8 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-whitebind=<addr>", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6"));
strUsage += HelpMessageOpt("-whitelist=<netmask>", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") +
" " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway"));
- strUsage += HelpMessageOpt("-whitelistalwaysrelay", strprintf(_("Always relay transactions received from whitelisted peers (default: %d)"), DEFAULT_WHITELISTALWAYSRELAY));
+ strUsage += HelpMessageOpt("-whitelistrelay", strprintf(_("Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d)"), DEFAULT_WHITELISTRELAY));
+ strUsage += HelpMessageOpt("-whitelistforcerelay", strprintf(_("Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d)"), DEFAULT_WHITELISTFORCERELAY));
strUsage += HelpMessageOpt("-maxuploadtarget=<n>", strprintf(_("Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)"), DEFAULT_MAX_UPLOAD_TARGET));
#ifdef ENABLE_WALLET
@@ -406,8 +408,6 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), DEFAULT_SEND_FREE_TRANSACTIONS));
strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE));
strUsage += HelpMessageOpt("-txconfirmtarget=<n>", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET));
- strUsage += HelpMessageOpt("-maxtxfee=<amt>", strprintf(_("Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)"),
- CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MAXFEE)));
strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup"));
strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat"));
strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST));
@@ -470,6 +470,8 @@ std::string HelpMessage(HelpMessageMode mode)
}
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)));
+ strUsage += HelpMessageOpt("-maxtxfee=<amt>", strprintf(_("Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s)"),
+ CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MAXFEE)));
strUsage += HelpMessageOpt("-printtoconsole", _("Send trace/debug info to console instead of debug.log file"));
if (showDebug)
{
@@ -488,6 +490,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-bytespersigop", strprintf(_("Minimum bytes per sigop in transactions we relay and mine (default: %u)"), DEFAULT_BYTES_PER_SIGOP));
strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), DEFAULT_ACCEPT_DATACARRIER));
strUsage += HelpMessageOpt("-datacarriersize", strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY));
+ strUsage += HelpMessageOpt("-mempoolreplacement", strprintf(_("Enable transaction replacement in the memory pool (default: %u)"), DEFAULT_ENABLE_REPLACEMENT));
strUsage += HelpMessageGroup(_("Block creation options:"));
strUsage += HelpMessageOpt("-blockminsize=<n>", strprintf(_("Set minimum block size in bytes (default: %u)"), DEFAULT_BLOCK_MIN_SIZE));
@@ -750,15 +753,21 @@ void InitParameterInteraction()
LogPrintf("%s: parameter interaction: -zapwallettxes=<mode> -> setting -rescan=1\n", __func__);
}
- // disable walletbroadcast and whitelistalwaysrelay in blocksonly mode
+ // disable walletbroadcast and whitelistrelay in blocksonly mode
if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) {
- if (SoftSetBoolArg("-whitelistalwaysrelay", false))
- LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -whitelistalwaysrelay=0\n", __func__);
+ if (SoftSetBoolArg("-whitelistrelay", false))
+ LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -whitelistrelay=0\n", __func__);
#ifdef ENABLE_WALLET
if (SoftSetBoolArg("-walletbroadcast", false))
LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0\n", __func__);
#endif
}
+
+ // Forcing relay from whitelisted hosts implies we will accept relays from them in the first place.
+ if (GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) {
+ if (SoftSetBoolArg("-whitelistrelay", true))
+ LogPrintf("%s: parameter interaction: -whitelistforcerelay=1 -> setting -whitelistrelay=1\n", __func__);
+ }
}
static std::string ResolveErrMsg(const char * const optname, const std::string& strBind)
@@ -895,6 +904,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
if (GetBoolArg("-benchmark", false))
InitWarning(_("Unsupported argument -benchmark ignored, use -debug=bench."));
+ if (GetBoolArg("-whitelistalwaysrelay", false))
+ InitWarning(_("Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay."));
+
// Checkmempool and checkblockindex default to true in regtest mode
int ratio = std::min<int>(std::max<int>(GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000);
if (ratio != 0) {
@@ -978,7 +990,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
CAmount nFeePerK = 0;
if (!ParseMoney(mapArgs["-fallbackfee"], nFeePerK))
return InitError(strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"), mapArgs["-fallbackfee"]));
- if (nFeePerK > nHighTransactionFeeWarning)
+ if (nFeePerK > HIGH_TX_FEE_PER_KB)
InitWarning(_("-fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available."));
CWallet::fallbackFee = CFeeRate(nFeePerK);
}
@@ -987,7 +999,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
CAmount nFeePerK = 0;
if (!ParseMoney(mapArgs["-paytxfee"], nFeePerK))
return InitError(AmountErrMsg("paytxfee", mapArgs["-paytxfee"]));
- if (nFeePerK > nHighTransactionFeeWarning)
+ if (nFeePerK > HIGH_TX_FEE_PER_KB)
InitWarning(_("-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction."));
payTxFee = CFeeRate(nFeePerK, 1000);
if (payTxFee < ::minRelayTxFee)
@@ -1001,7 +1013,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
CAmount nMaxFee = 0;
if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee))
return InitError(AmountErrMsg("maxtxfee", mapArgs["-maxtxfee"]));
- if (nMaxFee > nHighTransactionMaxFeeWarning)
+ if (nMaxFee > HIGH_MAX_TX_FEE)
InitWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction."));
maxTxFee = nMaxFee;
if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee)
@@ -1030,7 +1042,15 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
nLocalServices |= NODE_BLOOM;
nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE);
- fPermitReplacement = GetBoolArg("-permitrbf", DEFAULT_PERMIT_REPLACEMENT);
+
+ fEnableReplacement = GetBoolArg("-mempoolreplacement", DEFAULT_ENABLE_REPLACEMENT);
+ if ((!fEnableReplacement) && mapArgs.count("-mempoolreplacement")) {
+ // Minimal effort at forwards compatibility
+ std::string strReplacementModeList = GetArg("-mempoolreplacement", ""); // default is impossible
+ std::vector<std::string> vstrReplacementModes;
+ boost::split(vstrReplacementModes, strReplacementModeList, boost::is_any_of(","));
+ fEnableReplacement = (std::find(vstrReplacementModes.begin(), vstrReplacementModes.end(), "fee") != vstrReplacementModes.end());
+ }
// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
diff --git a/src/main.cpp b/src/main.cpp
index 8beff9769a..b165366ddc 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -75,13 +75,11 @@ 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;
-bool fPermitReplacement = DEFAULT_PERMIT_REPLACEMENT;
+bool fEnableReplacement = DEFAULT_ENABLE_REPLACEMENT;
-/** Fees smaller than this (in satoshi) are considered zero fee (for relaying, mining and transaction creation) */
CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
+CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE;
CTxMemPool mempool(::minRelayTxFee);
@@ -818,12 +816,13 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
bool* pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectAbsurdFee,
std::vector<uint256>& vHashTxnToUncache)
{
+ const uint256 hash = tx.GetHash();
AssertLockHeld(cs_main);
if (pfMissingInputs)
*pfMissingInputs = false;
if (!CheckTransaction(tx, state))
- return false;
+ return error("%s: CheckTransaction: %s, %s", __func__, hash.ToString(), FormatStateMessage(state));
// Coinbase is only valid in a block, not as a loose transaction
if (tx.IsCoinBase())
@@ -841,7 +840,6 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
return state.DoS(0, false, REJECT_NONSTANDARD, "non-final");
// is it already in the memory pool?
- uint256 hash = tx.GetHash();
if (pool.exists(hash))
return state.Invalid(false, REJECT_ALREADY_KNOWN, "txn-already-in-mempool");
@@ -869,7 +867,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
// unconfirmed ancestors anyway; doing otherwise is hopelessly
// insecure.
bool fReplacementOptOut = true;
- if (fPermitReplacement)
+ if (fEnableReplacement)
{
BOOST_FOREACH(const CTxIn &txin, ptxConflicting->vin)
{
@@ -1004,10 +1002,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
dFreeCount += nSize;
}
- if (fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000)
+ if (fRejectAbsurdFee && nFees > maxTxFee)
return state.Invalid(false,
REJECT_HIGHFEE, "absurdly-high-fee",
- strprintf("%d > %d", nFees, ::minRelayTxFee.GetFee(nSize) * 10000));
+ strprintf("%d > %d", nFees, maxTxFee));
// Calculate in-mempool ancestors, up to a limit.
CTxMemPool::setEntries setAncestors;
@@ -1177,7 +1175,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
// Check against previous transactions
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true))
- return false;
+ return error("%s: CheckInputs: %s, %s", __func__, hash.ToString(), FormatStateMessage(state));
// Check again against just the consensus-critical mandatory script
// verification flags, in case of bugs in the standard flags that cause
@@ -1966,7 +1964,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
// Check it again in case a previous version let a bad block in
if (!CheckBlock(block, state, !fJustCheck, !fJustCheck))
- return false;
+ return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state));
// verify that the view's current state corresponds to the previous block
uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
@@ -2911,13 +2909,11 @@ bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool f
{
// Check proof of work matches claimed amount
if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus()))
- return state.DoS(50, error("CheckBlockHeader(): proof of work failed"),
- REJECT_INVALID, "high-hash");
+ return state.DoS(50, false, REJECT_INVALID, "high-hash", false, "proof of work failed");
// Check timestamp
if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
- return state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),
- REJECT_INVALID, "time-too-new");
+ return state.Invalid(false, REJECT_INVALID, "time-too-new", "block timestamp too far in the future");
return true;
}
@@ -2939,15 +2935,13 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
bool mutated;
uint256 hashMerkleRoot2 = BlockMerkleRoot(block, &mutated);
if (block.hashMerkleRoot != hashMerkleRoot2)
- return state.DoS(100, error("CheckBlock(): hashMerkleRoot mismatch"),
- REJECT_INVALID, "bad-txnmrklroot", true);
+ return state.DoS(100, false, REJECT_INVALID, "bad-txnmrklroot", true, "hashMerkleRoot mismatch");
// Check for merkle tree malleability (CVE-2012-2459): repeating sequences
// of transactions in a block without affecting the merkle root of a block,
// while still invalidating it.
if (mutated)
- return state.DoS(100, error("CheckBlock(): duplicate transaction"),
- REJECT_INVALID, "bad-txns-duplicate", true);
+ return state.DoS(100, false, REJECT_INVALID, "bad-txns-duplicate", true, "duplicate transaction");
}
// All potential-corruption validation must be done before we do any
@@ -2956,24 +2950,20 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
// Size limits
if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
- return state.DoS(100, error("CheckBlock(): size limits failed"),
- REJECT_INVALID, "bad-blk-length");
+ return state.DoS(100, false, REJECT_INVALID, "bad-blk-length", false, "size limits failed");
// First transaction must be coinbase, the rest must not be
if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
- return state.DoS(100, error("CheckBlock(): first tx is not coinbase"),
- REJECT_INVALID, "bad-cb-missing");
+ return state.DoS(100, false, REJECT_INVALID, "bad-cb-missing", false, "first tx is not coinbase");
for (unsigned int i = 1; i < block.vtx.size(); i++)
if (block.vtx[i].IsCoinBase())
- return state.DoS(100, error("CheckBlock(): more than one coinbase"),
- REJECT_INVALID, "bad-cb-multiple");
+ return state.DoS(100, false, REJECT_INVALID, "bad-cb-multiple", false, "more than one coinbase");
// Check transactions
BOOST_FOREACH(const CTransaction& tx, block.vtx)
if (!CheckTransaction(tx, state))
- return error("CheckBlock(): CheckTransaction of %s failed with %s",
- tx.GetHash().ToString(),
- FormatStateMessage(state));
+ return state.Invalid(false, state.GetRejectCode(), state.GetRejectReason(),
+ strprintf("Transaction check failed (tx hash %s) %s", tx.GetHash().ToString(), state.GetDebugMessage()));
unsigned int nSigOps = 0;
BOOST_FOREACH(const CTransaction& tx, block.vtx)
@@ -2981,8 +2971,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
nSigOps += GetLegacySigOpCount(tx);
}
if (nSigOps > MAX_BLOCK_SIGOPS)
- return state.DoS(100, error("CheckBlock(): out-of-bounds SigOpCount"),
- REJECT_INVALID, "bad-blk-sigops");
+ return state.DoS(100, false, REJECT_INVALID, "bad-blk-sigops", false, "out-of-bounds SigOpCount");
if (fCheckPOW && fCheckMerkleRoot)
block.fChecked = true;
@@ -3009,28 +2998,17 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
const Consensus::Params& consensusParams = Params().GetConsensus();
// Check proof of work
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
- return state.DoS(100, error("%s: incorrect proof of work", __func__),
- REJECT_INVALID, "bad-diffbits");
+ return state.DoS(100, false, REJECT_INVALID, "bad-diffbits", false, "incorrect proof of work");
// Check timestamp against prev
if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
- return state.Invalid(error("%s: block's timestamp is too early", __func__),
- REJECT_INVALID, "time-too-old");
-
- // Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
- if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams))
- return state.Invalid(error("%s: rejected nVersion=1 block", __func__),
- REJECT_OBSOLETE, "bad-version");
+ return state.Invalid(false, REJECT_INVALID, "time-too-old", "block's timestamp is too early");
- // Reject block.nVersion=2 blocks when 95% (75% on testnet) of the network has upgraded:
- if (block.nVersion < 3 && IsSuperMajority(3, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams))
- return state.Invalid(error("%s: rejected nVersion=2 block", __func__),
- REJECT_OBSOLETE, "bad-version");
-
- // Reject block.nVersion=3 blocks when 95% (75% on testnet) of the network has upgraded:
- if (block.nVersion < 4 && IsSuperMajority(4, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams))
- return state.Invalid(error("%s : rejected nVersion=3 block", __func__),
- REJECT_OBSOLETE, "bad-version");
+ // Reject outdated version blocks when 95% (75% on testnet) of the network has upgraded:
+ for (int32_t version = 2; version < 5; ++version) // check for version 2, 3 and 4 upgrades
+ if (block.nVersion < version && IsSuperMajority(version, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams))
+ return state.Invalid(false, REJECT_OBSOLETE, strprintf("bad-version(v%d)", version - 1),
+ strprintf("rejected nVersion=%d block", version - 1));
return true;
}
@@ -3047,7 +3025,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn
? pindexPrev->GetMedianTimePast()
: block.GetBlockTime();
if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) {
- return state.DoS(10, error("%s: contains a non-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal");
+ return state.DoS(10, false, REJECT_INVALID, "bad-txns-nonfinal", false, "non-final transaction");
}
}
@@ -3058,7 +3036,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn
CScript expect = CScript() << nHeight;
if (block.vtx[0].vin[0].scriptSig.size() < expect.size() ||
!std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) {
- return state.DoS(100, error("%s: block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height");
+ return state.DoS(100, false, REJECT_INVALID, "bad-cb-height", false, "block height mismatch in coinbase");
}
}
@@ -3085,7 +3063,7 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state
}
if (!CheckBlockHeader(block, state))
- return false;
+ return error("%s: Consensus::CheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state));
// Get prev block index
CBlockIndex* pindexPrev = NULL;
@@ -3101,7 +3079,7 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state
return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, state.GetRejectReason().c_str());
if (!ContextualCheckBlockHeader(block, state, pindexPrev))
- return false;
+ return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state));
}
if (pindex == NULL)
pindex = AddToBlockIndex(block);
@@ -3148,7 +3126,7 @@ static bool AcceptBlock(const CBlock& block, CValidationState& state, const CCha
pindex->nStatus |= BLOCK_FAILED_VALID;
setDirtyBlockIndex.insert(pindex);
}
- return false;
+ return error("%s: %s", __func__, FormatStateMessage(state));
}
int nHeight = pindex->nHeight;
@@ -3199,7 +3177,7 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, c
bool fRequested = MarkBlockAsReceived(pblock->GetHash());
fRequested |= fForceProcessing;
if (!checked) {
- return error("%s: CheckBlock FAILED", __func__);
+ return error("%s: CheckBlock FAILED %s", __func__, FormatStateMessage(state));
}
// Store to disk
@@ -3233,11 +3211,11 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams,
// NOTE: CheckBlockHeader is called by CheckBlock
if (!ContextualCheckBlockHeader(block, state, pindexPrev))
- return false;
+ return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, FormatStateMessage(state));
if (!CheckBlock(block, state, fCheckPOW, fCheckMerkleRoot))
- return false;
+ return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state));
if (!ContextualCheckBlock(block, state, pindexPrev))
- return false;
+ return error("%s: Consensus::ContextualCheckBlock: %s", __func__, FormatStateMessage(state));
if (!ConnectBlock(block, state, &indexDummy, viewNew, true))
return false;
assert(state.IsValid());
@@ -3567,7 +3545,8 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview,
return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
// check level 1: verify block validity
if (nCheckLevel >= 1 && !CheckBlock(block, state))
- return error("VerifyDB(): *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
+ return error("%s: *** found bad block at %d, hash=%s (%s)\n", __func__,
+ pindex->nHeight, pindex->GetBlockHash().ToString(), FormatStateMessage(state));
// check level 2: verify undo validity
if (nCheckLevel >= 2 && pindex) {
CBlockUndo undo;
@@ -4495,8 +4474,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
bool fBlocksOnly = GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY);
- // Allow whitelisted peers to send data other than blocks in blocks only mode if whitelistalwaysrelay is true
- if (pfrom->fWhitelisted && GetBoolArg("-whitelistalwaysrelay", DEFAULT_WHITELISTALWAYSRELAY))
+ // Allow whitelisted peers to send data other than blocks in blocks only mode if whitelistrelay is true
+ if (pfrom->fWhitelisted && GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY))
fBlocksOnly = false;
LOCK(cs_main);
@@ -4675,8 +4654,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
else if (strCommand == NetMsgType::TX)
{
// Stop processing the transaction early if
- // We are in blocks only mode and peer is either not whitelisted or whitelistalwaysrelay is off
- if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && (!pfrom->fWhitelisted || !GetBoolArg("-whitelistalwaysrelay", DEFAULT_WHITELISTALWAYSRELAY)))
+ // We are in blocks only mode and peer is either not whitelisted or whitelistrelay is off
+ if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && (!pfrom->fWhitelisted || !GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY)))
{
LogPrint("net", "transaction sent in violation of protocol peer=%d\n", pfrom->id);
return true;
@@ -4776,7 +4755,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
assert(recentRejects);
recentRejects->insert(tx.GetHash());
- if (pfrom->fWhitelisted && GetBoolArg("-whitelistalwaysrelay", DEFAULT_WHITELISTALWAYSRELAY)) {
+ if (pfrom->fWhitelisted && GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) {
// Always relay transactions received from whitelisted peers, even
// if they were already in the mempool or rejected from it due
// to policy, allowing the node to function as a gateway for
diff --git a/src/main.h b/src/main.h
index 4a51317762..f9145a1a79 100644
--- a/src/main.h
+++ b/src/main.h
@@ -42,10 +42,18 @@ struct CNodeStateStats;
/** Default for accepting alerts from the P2P network. */
static const bool DEFAULT_ALERTS = true;
-/** Default for DEFAULT_WHITELISTALWAYSRELAY. */
-static const bool DEFAULT_WHITELISTALWAYSRELAY = true;
+/** Default for DEFAULT_WHITELISTRELAY. */
+static const bool DEFAULT_WHITELISTRELAY = true;
+/** Default for DEFAULT_WHITELISTFORCERELAY. */
+static const bool DEFAULT_WHITELISTFORCERELAY = true;
/** Default for -minrelaytxfee, minimum relay fee for transactions */
static const unsigned int DEFAULT_MIN_RELAY_TX_FEE = 1000;
+//! -maxtxfee default
+static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN;
+//! Discourage users to set fees higher than this amount (in satoshis) per kB
+static const CAmount HIGH_TX_FEE_PER_KB = 0.01 * COIN;
+//! -maxtxfee will warn if called with a higher fee than this amount (in satoshis)
+static const CAmount HIGH_MAX_TX_FEE = 100 * HIGH_TX_FEE_PER_KB;
/** Default for -maxorphantx, maximum number of orphan transactions kept in memory */
static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100;
/** Default for -limitancestorcount, max number of in-mempool ancestors */
@@ -107,8 +115,8 @@ static const bool DEFAULT_TXINDEX = false;
static const unsigned int DEFAULT_BANSCORE_THRESHOLD = 100;
static const bool DEFAULT_TESTSAFEMODE = false;
-/** Default for -permitrbf */
-static const bool DEFAULT_PERMIT_REPLACEMENT = true;
+/** Default for -mempoolreplacement */
+static const bool DEFAULT_ENABLE_REPLACEMENT = true;
/** Maximum number of headers to announce when relaying blocks with headers message.*/
static const unsigned int MAX_BLOCKS_TO_ANNOUNCE = 8;
@@ -138,10 +146,14 @@ extern unsigned int nBytesPerSigOp;
extern bool fCheckBlockIndex;
extern bool fCheckpointsEnabled;
extern size_t nCoinCacheUsage;
+/** A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation) */
extern CFeeRate minRelayTxFee;
+/** Absolute maximum transaction fee (in satoshis) used by wallet and mempool (rejects high fee in sendrawtransaction) */
+extern CAmount maxTxFee;
extern bool fAlerts;
+/** If the tip is older than this (in seconds), the node is considered to be in initial block download. */
extern int64_t nMaxTipAge;
-extern bool fPermitReplacement;
+extern bool fEnableReplacement;
/** Best header we've seen so far (used for getheaders queries' starting points). */
extern CBlockIndex *pindexBestHeader;
diff --git a/src/net.cpp b/src/net.cpp
index 48e9e10157..14e22f6cb3 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -899,8 +899,6 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) {
continue;
if (node->fDisconnect)
continue;
- if (node->addr.IsLocal())
- continue;
vEvictionCandidates.push_back(CNodeRef(node));
}
}
@@ -931,15 +929,20 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) {
if (vEvictionCandidates.empty()) return false;
- // Identify the network group with the most connections
+ // Identify the network group with the most connections and youngest member.
+ // (vEvictionCandidates is already sorted by reverse connect time)
std::vector<unsigned char> naMostConnections;
unsigned int nMostConnections = 0;
+ int64_t nMostConnectionsTime = 0;
std::map<std::vector<unsigned char>, std::vector<CNodeRef> > mapAddrCounts;
BOOST_FOREACH(const CNodeRef &node, vEvictionCandidates) {
mapAddrCounts[node->addr.GetGroup()].push_back(node);
+ int64_t grouptime = mapAddrCounts[node->addr.GetGroup()][0]->nTimeConnected;
+ size_t groupsize = mapAddrCounts[node->addr.GetGroup()].size();
- if (mapAddrCounts[node->addr.GetGroup()].size() > nMostConnections) {
- nMostConnections = mapAddrCounts[node->addr.GetGroup()].size();
+ if (groupsize > nMostConnections || (groupsize == nMostConnections && grouptime > nMostConnectionsTime)) {
+ nMostConnections = groupsize;
+ nMostConnectionsTime = grouptime;
naMostConnections = node->addr.GetGroup();
}
}
@@ -947,14 +950,13 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) {
// Reduce to the network group with the most connections
vEvictionCandidates = mapAddrCounts[naMostConnections];
- // Do not disconnect peers if there is only 1 connection from their network group
+ // Do not disconnect peers if there is only one unprotected connection from their network group.
if (vEvictionCandidates.size() <= 1)
// unless we prefer the new connection (for whitelisted peers)
if (!fPreferNewConnection)
return false;
- // Disconnect the most recent connection from the network group with the most connections
- std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected);
+ // Disconnect from the network group with the most connections
vEvictionCandidates[0]->fDisconnect = true;
return true;
diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp
index 019df72279..332abc430e 100644
--- a/src/policy/policy.cpp
+++ b/src/policy/policy.cpp
@@ -132,45 +132,20 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
const CScript& prevScript = prev.scriptPubKey;
if (!Solver(prevScript, whichType, vSolutions))
return false;
- int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions);
- if (nArgsExpected < 0)
- return false;
-
- // Transactions with extra stuff in their scriptSigs are
- // non-standard. Note that this EvalScript() call will
- // be quick, because if there are any operations
- // beside "push data" in the scriptSig
- // IsStandardTx() will have already returned false
- // and this method isn't called.
- std::vector<std::vector<unsigned char> > stack;
- if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker()))
- return false;
if (whichType == TX_SCRIPTHASH)
{
+ std::vector<std::vector<unsigned char> > stack;
+ // convert the scriptSig into a stack, so we can inspect the redeemScript
+ if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), 0))
+ return false;
if (stack.empty())
return false;
CScript subscript(stack.back().begin(), stack.back().end());
- std::vector<std::vector<unsigned char> > vSolutions2;
- txnouttype whichType2;
- if (Solver(subscript, whichType2, vSolutions2))
- {
- int tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2);
- if (tmpExpected < 0)
- return false;
- nArgsExpected += tmpExpected;
- }
- else
- {
- // Any other Script with less than 15 sigops OK:
- unsigned int sigops = subscript.GetSigOpCount(true);
- // ... extra data left on the stack after execution is OK, too:
- return (sigops <= MAX_P2SH_SIGOPS);
+ if (subscript.GetSigOpCount(true) > MAX_P2SH_SIGOPS) {
+ return false;
}
}
-
- if (stack.size() != (unsigned int)nArgsExpected)
- return false;
}
return true;
diff --git a/src/pow.cpp b/src/pow.cpp
index 7392defe64..40c72f9d79 100644
--- a/src/pow.cpp
+++ b/src/pow.cpp
@@ -102,35 +102,3 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&
return true;
}
-
-arith_uint256 GetBlockProof(const CBlockIndex& block)
-{
- arith_uint256 bnTarget;
- bool fNegative;
- bool fOverflow;
- bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
- if (fNegative || fOverflow || bnTarget == 0)
- return 0;
- // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
- // as it's too large for a arith_uint256. However, as 2**256 is at least as large
- // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
- // or ~bnTarget / (nTarget+1) + 1.
- return (~bnTarget / (bnTarget + 1)) + 1;
-}
-
-int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params)
-{
- arith_uint256 r;
- int sign = 1;
- if (to.nChainWork > from.nChainWork) {
- r = to.nChainWork - from.nChainWork;
- } else {
- r = from.nChainWork - to.nChainWork;
- sign = -1;
- }
- r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip);
- if (r.bits() > 63) {
- return sign * std::numeric_limits<int64_t>::max();
- }
- return sign * r.GetLow64();
-}
diff --git a/src/pow.h b/src/pow.h
index 4399440929..23e9c1c351 100644
--- a/src/pow.h
+++ b/src/pow.h
@@ -13,16 +13,11 @@
class CBlockHeader;
class CBlockIndex;
class uint256;
-class arith_uint256;
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&);
unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params&);
/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&);
-arith_uint256 GetBlockProof(const CBlockIndex& block);
-
-/** Return the time it would take to redo the work difference between from and to, assuming the current hashrate corresponds to the difficulty at tip, in seconds. */
-int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params&);
#endif // BITCOIN_POW_H
diff --git a/src/script/standard.cpp b/src/script/standard.cpp
index 30935768ac..67b6af327a 100644
--- a/src/script/standard.cpp
+++ b/src/script/standard.cpp
@@ -161,27 +161,6 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsi
return false;
}
-int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned char> >& vSolutions)
-{
- switch (t)
- {
- case TX_NONSTANDARD:
- case TX_NULL_DATA:
- return -1;
- case TX_PUBKEY:
- return 1;
- case TX_PUBKEYHASH:
- return 2;
- case TX_MULTISIG:
- if (vSolutions.size() < 1 || vSolutions[0].size() < 1)
- return -1;
- return vSolutions[0][0] + 1;
- case TX_SCRIPTHASH:
- return 1; // doesn't include args needed by the script
- }
- return -1;
-}
-
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
{
vector<valtype> vSolutions;
diff --git a/src/script/standard.h b/src/script/standard.h
index 6bac6e4097..64bf010ec1 100644
--- a/src/script/standard.h
+++ b/src/script/standard.h
@@ -71,7 +71,6 @@ typedef boost::variant<CNoDestination, CKeyID, CScriptID> CTxDestination;
const char* GetTxnOutputType(txnouttype t);
bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet);
-int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned char> >& vSolutions);
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet);
bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet);
diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp
index 7bd4b8441b..28b85e8d29 100644
--- a/src/test/script_P2SH_tests.cpp
+++ b/src/test/script_P2SH_tests.cpp
@@ -346,15 +346,6 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
// 22 P2SH sigops for all inputs (1 for vin[0], 6 for vin[3], 15 for vin[4]
BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txTo, coins), 22U);
- // Make sure adding crap to the scriptSigs makes them non-standard:
- for (int i = 0; i < 3; i++)
- {
- CScript t = txTo.vin[i].scriptSig;
- txTo.vin[i].scriptSig = (CScript() << 11) + t;
- BOOST_CHECK(!::AreInputsStandard(txTo, coins));
- txTo.vin[i].scriptSig = t;
- }
-
CMutableTransaction txToNonStd1;
txToNonStd1.vout.resize(1);
txToNonStd1.vout[0].scriptPubKey = GetScriptForDestination(key[1].GetPubKey().GetID());
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index 3dca7ea0f7..c27f194b55 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -310,14 +310,6 @@ BOOST_AUTO_TEST_CASE(test_Get)
BOOST_CHECK(AreInputsStandard(t1, coins));
BOOST_CHECK_EQUAL(coins.GetValueIn(t1), (50+21+22)*CENT);
-
- // Adding extra junk to the scriptSig should make it non-standard:
- t1.vin[0].scriptSig << OP_11;
- BOOST_CHECK(!AreInputsStandard(t1, coins));
-
- // ... as should not having enough:
- t1.vin[0].scriptSig = CScript();
- BOOST_CHECK(!AreInputsStandard(t1, coins));
}
BOOST_AUTO_TEST_CASE(test_IsStandard)
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 5b8bd55498..dd9d549f66 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -37,7 +37,6 @@ using namespace std;
* Settings
*/
CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
-CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE;
unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET;
bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE;
bool fSendFreeTransactions = DEFAULT_SEND_FREE_TRANSACTIONS;
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index ffc7dcbd2c..28d2f8a04f 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -32,7 +32,6 @@
* Settings
*/
extern CFeeRate payTxFee;
-extern CAmount maxTxFee;
extern unsigned int nTxConfirmTarget;
extern bool bSpendZeroConfChange;
extern bool fSendFreeTransactions;
@@ -40,14 +39,10 @@ extern bool fSendFreeTransactions;
static const unsigned int DEFAULT_KEYPOOL_SIZE = 100;
//! -paytxfee default
static const CAmount DEFAULT_TRANSACTION_FEE = 0;
-//! -paytxfee will warn if called with a higher fee than this amount (in satoshis) per KB
-static const CAmount nHighTransactionFeeWarning = 0.01 * COIN;
//! -fallbackfee default
static const CAmount DEFAULT_FALLBACK_FEE = 20000;
//! -mintxfee default
static const CAmount DEFAULT_TRANSACTION_MINFEE = 1000;
-//! -maxtxfee default
-static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN;
//! minimum change amount
static const CAmount MIN_CHANGE = CENT;
//! Default for -spendzeroconfchange
@@ -56,8 +51,6 @@ static const bool DEFAULT_SPEND_ZEROCONF_CHANGE = true;
static const bool DEFAULT_SEND_FREE_TRANSACTIONS = false;
//! -txconfirmtarget default
static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 2;
-//! -maxtxfee will warn if called with a higher fee than this amount (in satoshis)
-static const CAmount nHighTransactionMaxFeeWarning = 100 * nHighTransactionFeeWarning;
//! Largest (in bytes) free transaction we're willing to create
static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000;
static const bool DEFAULT_WALLETBROADCAST = true;
@@ -211,6 +204,7 @@ public:
int GetDepthInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); }
bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet) > 0; }
int GetBlocksToMaturity() const;
+ /** Pass this transaction to the mempool. Fails if absolute fee exceeds maxTxFee. */
bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectAbsurdFee=true);
bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); }
bool isAbandoned() const { return (hashBlock == ABANDON_HASH); }