diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.am | 86 | ||||
| -rw-r--r-- | src/Makefile.bench.include | 1 | ||||
| -rw-r--r-- | src/Makefile.qt.include | 2 | ||||
| -rw-r--r-- | src/Makefile.qttest.include | 2 | ||||
| -rw-r--r-- | src/Makefile.test.include | 2 | ||||
| -rw-r--r-- | src/chain.cpp | 32 | ||||
| -rw-r--r-- | src/chain.h | 4 | ||||
| -rw-r--r-- | src/init.cpp | 24 | ||||
| -rw-r--r-- | src/main.cpp | 12 | ||||
| -rw-r--r-- | src/main.h | 40 | ||||
| -rw-r--r-- | src/net.cpp | 18 | ||||
| -rw-r--r-- | src/policy/policy.cpp | 37 | ||||
| -rw-r--r-- | src/pow.cpp | 32 | ||||
| -rw-r--r-- | src/pow.h | 5 | ||||
| -rw-r--r-- | src/script/standard.cpp | 21 | ||||
| -rw-r--r-- | src/script/standard.h | 1 | ||||
| -rw-r--r-- | src/test/script_P2SH_tests.cpp | 9 | ||||
| -rw-r--r-- | src/test/transaction_tests.cpp | 8 | ||||
| -rw-r--r-- | src/wallet/wallet.cpp | 1 | ||||
| -rw-r--r-- | src/wallet/wallet.h | 8 |
20 files changed, 148 insertions, 197 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index b1b8ae123..12ef33749 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 d660a3a74..d3cecb6b4 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 96b7adcbf..d75b2c281 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 ede3fac4c..813a343ff 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 d89132f80..b22b8b8b9 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 3450ed6c3..32f6480f8 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 b9b1b9306..919998356 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 173570069..6b5152199 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)); @@ -407,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)); @@ -471,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) { @@ -489,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)); @@ -988,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); } @@ -997,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) @@ -1011,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) @@ -1040,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 01d1024b0..984523408 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); @@ -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; diff --git a/src/main.h b/src/main.h index c4074cda8..f9145a1a7 100644 --- a/src/main.h +++ b/src/main.h @@ -48,6 +48,12 @@ static const bool DEFAULT_WHITELISTRELAY = true; 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 */ @@ -109,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; @@ -140,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; @@ -397,23 +407,27 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus /** Functions for validating blocks and updating the block tree */ -/** Undo the effects of this block (with given index) on the UTXO set represented by coins. - * In case pfClean is provided, operation will try to be tolerant about errors, and *pfClean - * will be true if no problems were found. Otherwise, the return value will be false in case - * of problems. Note that in any case, coins may be modified. */ -bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockIndex* pindex, CCoinsViewCache& coins, bool* pfClean = NULL); - -/** Apply the effects of this block (with given index) on the UTXO set represented by coins */ -bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false); - /** Context-independent validity checks */ bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW = true); bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW = true, bool fCheckMerkleRoot = true); -/** Context-dependent validity checks */ +/** Context-dependent validity checks. + * By "context", we mean only the previous block headers, but not the UTXO + * set; UTXO-related validity checks are done in ConnectBlock(). */ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex *pindexPrev); bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex *pindexPrev); +/** Apply the effects of this block (with given index) on the UTXO set represented by coins. + * Validity checks that depend on the UTXO set are also done; ConnectBlock() + * can fail if those validity checks fail (among other reasons). */ +bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false); + +/** Undo the effects of this block (with given index) on the UTXO set represented by coins. + * In case pfClean is provided, operation will try to be tolerant about errors, and *pfClean + * will be true if no problems were found. Otherwise, the return value will be false in case + * of problems. Note that in any case, coins may be modified. */ +bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockIndex* pindex, CCoinsViewCache& coins, bool* pfClean = NULL); + /** Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held) */ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, const CBlock& block, CBlockIndex* pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true); diff --git a/src/net.cpp b/src/net.cpp index 48e9e1015..14e22f6cb 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 019df7227..332abc430 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 7392defe6..40c72f9d7 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(); -} @@ -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 30935768a..67b6af327 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 6bac6e409..64bf010ec 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 7bd4b8441..28b85e8d2 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 3dca7ea0f..c27f194b5 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 5b8bd5549..dd9d549f6 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 ffc7dcbd2..28d2f8a04 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); } |