From fdf8888b6f0c63e8a4cb1459752625e642d6a4dd Mon Sep 17 00:00:00 2001 From: John Newbery Date: Tue, 2 Apr 2019 13:41:12 -0400 Subject: [build] Move CheckTransaction from lib_server to lib_consensus CheckTransaction is a context-free function that does not require access to the blockchain or mempool. Move it from src/consensus/tx_verify in lib_server to a new unit src/consensus/tx_check in lib_consensus so that it can be called by non-server libraries. --- .../libbitcoinconsensus.vcxproj | 1 + src/Makefile.am | 2 + src/consensus/tx_check.cpp | 57 ++++++++++++++++++++++ src/consensus/tx_check.h | 20 ++++++++ src/consensus/tx_verify.cpp | 49 ------------------- src/consensus/tx_verify.h | 3 -- src/test/sighash_tests.cpp | 2 +- src/test/transaction_tests.cpp | 2 +- src/validation.cpp | 1 + src/wallet/walletdb.cpp | 2 +- 10 files changed, 84 insertions(+), 55 deletions(-) create mode 100644 src/consensus/tx_check.cpp create mode 100644 src/consensus/tx_check.h diff --git a/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj b/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj index a32aafbd74..227b1ebcd2 100644 --- a/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj +++ b/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj @@ -22,6 +22,7 @@ + diff --git a/src/Makefile.am b/src/Makefile.am index 0385c825ea..cb0745835a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -124,6 +124,7 @@ BITCOIN_CORE_H = \ compat/sanity.h \ compressor.h \ consensus/consensus.h \ + consensus/tx_check.h \ consensus/tx_verify.h \ core_io.h \ core_memusage.h \ @@ -391,6 +392,7 @@ libbitcoin_consensus_a_SOURCES = \ consensus/merkle.cpp \ consensus/merkle.h \ consensus/params.h \ + consensus/tx_check.cpp \ consensus/validation.h \ hash.cpp \ hash.h \ diff --git a/src/consensus/tx_check.cpp b/src/consensus/tx_check.cpp new file mode 100644 index 0000000000..61a607ef7f --- /dev/null +++ b/src/consensus/tx_check.cpp @@ -0,0 +1,57 @@ +// Copyright (c) 2017-2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include +#include + +bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fCheckDuplicateInputs) +{ + // Basic checks that don't depend on any context + if (tx.vin.empty()) + return state.DoS(10, false, REJECT_INVALID, "bad-txns-vin-empty"); + if (tx.vout.empty()) + return state.DoS(10, false, REJECT_INVALID, "bad-txns-vout-empty"); + // Size limits (this doesn't take the witness into account, as that hasn't been checked for malleability) + if (::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT) + return state.DoS(100, false, REJECT_INVALID, "bad-txns-oversize"); + + // Check for negative or overflow output values + CAmount nValueOut = 0; + for (const auto& txout : tx.vout) + { + if (txout.nValue < 0) + return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-negative"); + if (txout.nValue > MAX_MONEY) + return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-toolarge"); + nValueOut += txout.nValue; + if (!MoneyRange(nValueOut)) + return state.DoS(100, false, REJECT_INVALID, "bad-txns-txouttotal-toolarge"); + } + + // Check for duplicate inputs - note that this check is slow so we skip it in CheckBlock + if (fCheckDuplicateInputs) { + std::set vInOutPoints; + for (const auto& txin : tx.vin) + { + if (!vInOutPoints.insert(txin.prevout).second) + return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-duplicate"); + } + } + + if (tx.IsCoinBase()) + { + if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100) + return state.DoS(100, false, REJECT_INVALID, "bad-cb-length"); + } + else + { + for (const auto& txin : tx.vin) + if (txin.prevout.IsNull()) + return state.DoS(10, false, REJECT_INVALID, "bad-txns-prevout-null"); + } + + return true; +} diff --git a/src/consensus/tx_check.h b/src/consensus/tx_check.h new file mode 100644 index 0000000000..bcfdf36bf9 --- /dev/null +++ b/src/consensus/tx_check.h @@ -0,0 +1,20 @@ +// Copyright (c) 2017-2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_CONSENSUS_TX_CHECK_H +#define BITCOIN_CONSENSUS_TX_CHECK_H + +/** + * Context-independent transaction checking code that can be called outside the + * bitcoin server and doesn't depend on chain or mempool state. Transaction + * verification code that does call server functions or depend on server state + * belongs in tx_verify.h/cpp instead. + */ + +class CTransaction; +class CValidationState; + +bool CheckTransaction(const CTransaction& tx, CValidationState& state, bool fCheckDuplicateInputs=true); + +#endif // BITCOIN_CONSENSUS_TX_CHECK_H diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp index 0a7eacfb91..fbbbcfd040 100644 --- a/src/consensus/tx_verify.cpp +++ b/src/consensus/tx_verify.cpp @@ -156,55 +156,6 @@ int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& i return nSigOps; } -bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fCheckDuplicateInputs) -{ - // Basic checks that don't depend on any context - if (tx.vin.empty()) - return state.DoS(10, false, REJECT_INVALID, "bad-txns-vin-empty"); - if (tx.vout.empty()) - return state.DoS(10, false, REJECT_INVALID, "bad-txns-vout-empty"); - // Size limits (this doesn't take the witness into account, as that hasn't been checked for malleability) - if (::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT) - return state.DoS(100, false, REJECT_INVALID, "bad-txns-oversize"); - - // Check for negative or overflow output values - CAmount nValueOut = 0; - for (const auto& txout : tx.vout) - { - if (txout.nValue < 0) - return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-negative"); - if (txout.nValue > MAX_MONEY) - return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-toolarge"); - nValueOut += txout.nValue; - if (!MoneyRange(nValueOut)) - return state.DoS(100, false, REJECT_INVALID, "bad-txns-txouttotal-toolarge"); - } - - // Check for duplicate inputs - note that this check is slow so we skip it in CheckBlock - if (fCheckDuplicateInputs) { - std::set vInOutPoints; - for (const auto& txin : tx.vin) - { - if (!vInOutPoints.insert(txin.prevout).second) - return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-duplicate"); - } - } - - if (tx.IsCoinBase()) - { - if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100) - return state.DoS(100, false, REJECT_INVALID, "bad-cb-length"); - } - else - { - for (const auto& txin : tx.vin) - if (txin.prevout.IsNull()) - return state.DoS(10, false, REJECT_INVALID, "bad-txns-prevout-null"); - } - - return true; -} - bool Consensus::CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee) { // are the actual inputs available? diff --git a/src/consensus/tx_verify.h b/src/consensus/tx_verify.h index 0519cef8c0..3519fc555d 100644 --- a/src/consensus/tx_verify.h +++ b/src/consensus/tx_verify.h @@ -17,9 +17,6 @@ class CValidationState; /** Transaction validation functions */ -/** Context-independent validity checks */ -bool CheckTransaction(const CTransaction& tx, CValidationState& state, bool fCheckDuplicateInputs=true); - namespace Consensus { /** * Check whether all inputs of this transaction are valid (no double spends and amounts) diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 04d5462acb..07f4337221 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -2,7 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include +#include #include #include #include diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 39cff3f463..24a599f8d7 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/validation.cpp b/src/validation.cpp index ae3985485e..88a7ba9fd4 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 5149bb0263..3122cd6fa4 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -5,7 +5,7 @@ #include -#include +#include #include #include #include -- cgit v1.2.3 From 4a75c9d6512a5580e60104103ea11d2cd9586354 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Tue, 2 Apr 2019 14:14:58 -0400 Subject: [build] Move policy settings to new src/policy/settings unit This moves the following policy settings functions and globals to a new src/policy/settings unit in lib_server: - `incrementalRelayFee` - `dustRelayFee` - `nBytesPerSigOp` - `fIsBareMultisigStd` These settings are only required by the node and should not be accessed by other libraries. --- src/Makefile.am | 4 +++- src/init.cpp | 1 + src/interfaces/chain.cpp | 1 + src/interfaces/node.cpp | 1 + src/policy/policy.cpp | 5 +---- src/policy/policy.h | 6 ++---- src/policy/settings.cpp | 14 ++++++++++++++ src/policy/settings.h | 17 +++++++++++++++++ src/rpc/net.cpp | 1 + src/test/script_p2sh_tests.cpp | 1 + src/test/transaction_tests.cpp | 1 + src/txmempool.cpp | 1 + src/validation.cpp | 2 +- src/validation.h | 3 --- test/lint/lint-circular-dependencies.sh | 3 ++- 15 files changed, 47 insertions(+), 14 deletions(-) create mode 100644 src/policy/settings.cpp create mode 100644 src/policy/settings.h diff --git a/src/Makefile.am b/src/Makefile.am index cb0745835a..c07e268863 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -164,6 +164,7 @@ BITCOIN_CORE_H = \ policy/fees.h \ policy/policy.h \ policy/rbf.h \ + policy/settings.h \ pow.h \ protocol.h \ psbt.h \ @@ -269,8 +270,8 @@ libbitcoin_server_a_SOURCES = \ noui.cpp \ outputtype.cpp \ policy/fees.cpp \ - policy/policy.cpp \ policy/rbf.cpp \ + policy/settings.cpp \ pow.cpp \ rest.cpp \ rpc/blockchain.cpp \ @@ -436,6 +437,7 @@ libbitcoin_common_a_SOURCES = \ netaddress.cpp \ netbase.cpp \ policy/feerate.cpp \ + policy/policy.cpp \ protocol.cpp \ psbt.cpp \ scheduler.cpp \ diff --git a/src/init.cpp b/src/init.cpp index 6564ce5b9a..652b99474c 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/src/interfaces/chain.cpp b/src/interfaces/chain.cpp index f278e5de95..13e7848cc6 100644 --- a/src/interfaces/chain.cpp +++ b/src/interfaces/chain.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp index 6f7dce0c24..73a5074133 100644 --- a/src/interfaces/node.cpp +++ b/src/interfaces/node.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index d4cc538492..f1e6aadb5a 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -239,10 +240,6 @@ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) return true; } -CFeeRate incrementalRelayFee = CFeeRate(DEFAULT_INCREMENTAL_RELAY_FEE); -CFeeRate dustRelayFee = CFeeRate(DUST_RELAY_TX_FEE); -unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP; - int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost) { return (std::max(nWeight, nSigOpCost * nBytesPerSigOp) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR; diff --git a/src/policy/policy.h b/src/policy/policy.h index 3d47ac1267..8660af26de 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -34,6 +34,8 @@ static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE = 300; static const unsigned int DEFAULT_INCREMENTAL_RELAY_FEE = 1000; /** Default for -bytespersigop */ static const unsigned int DEFAULT_BYTES_PER_SIGOP = 20; +/** Default for -permitbaremultisig */ +static const bool DEFAULT_PERMIT_BAREMULTISIG = true; /** The maximum number of witness stack items in a standard P2WSH script */ static const unsigned int MAX_STANDARD_P2WSH_STACK_ITEMS = 100; /** The maximum size of each witness stack item in a standard P2WSH script */ @@ -98,10 +100,6 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) */ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs); -extern CFeeRate incrementalRelayFee; -extern CFeeRate dustRelayFee; -extern unsigned int nBytesPerSigOp; - /** Compute the virtual transaction size (weight reinterpreted as bytes). */ int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost); int64_t GetVirtualTransactionSize(const CTransaction& tx, int64_t nSigOpCost = 0); diff --git a/src/policy/settings.cpp b/src/policy/settings.cpp new file mode 100644 index 0000000000..e8e1559407 --- /dev/null +++ b/src/policy/settings.cpp @@ -0,0 +1,14 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include +#include + +bool fIsBareMultisigStd = DEFAULT_PERMIT_BAREMULTISIG; +CFeeRate incrementalRelayFee = CFeeRate(DEFAULT_INCREMENTAL_RELAY_FEE); +CFeeRate dustRelayFee = CFeeRate(DUST_RELAY_TX_FEE); +unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP; diff --git a/src/policy/settings.h b/src/policy/settings.h new file mode 100644 index 0000000000..1d2a1fb880 --- /dev/null +++ b/src/policy/settings.h @@ -0,0 +1,17 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_POLICY_SETTINGS_H +#define BITCOIN_POLICY_SETTINGS_H + +class CFeeRate; + +// Policy settings which are configurable at runtime. +extern CFeeRate incrementalRelayFee; +extern CFeeRate dustRelayFee; +extern unsigned int nBytesPerSigOp; +extern bool fIsBareMultisigStd; + +#endif // BITCOIN_POLICY_SETTINGS_H diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index c7b3478f44..e8cdce623c 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/src/test/script_p2sh_tests.cpp b/src/test/script_p2sh_tests.cpp index 3a2a11ef98..400c89726f 100644 --- a/src/test/script_p2sh_tests.cpp +++ b/src/test/script_p2sh_tests.cpp @@ -10,6 +10,7 @@ #include #include