diff options
Diffstat (limited to 'src/consensus')
-rw-r--r-- | src/consensus/amount.h | 29 | ||||
-rw-r--r-- | src/consensus/params.h | 60 | ||||
-rw-r--r-- | src/consensus/tx_check.cpp | 3 | ||||
-rw-r--r-- | src/consensus/tx_verify.cpp | 22 | ||||
-rw-r--r-- | src/consensus/tx_verify.h | 10 | ||||
-rw-r--r-- | src/consensus/validation.h | 69 |
6 files changed, 159 insertions, 34 deletions
diff --git a/src/consensus/amount.h b/src/consensus/amount.h new file mode 100644 index 0000000000..f0eb4e0723 --- /dev/null +++ b/src/consensus/amount.h @@ -0,0 +1,29 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2021 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_AMOUNT_H +#define BITCOIN_CONSENSUS_AMOUNT_H + +#include <cstdint> + +/** Amount in satoshis (Can be negative) */ +typedef int64_t CAmount; + +/** The amount of satoshis in one BTC. */ +static constexpr CAmount COIN = 100000000; + +/** No amount larger than this (in satoshi) is valid. + * + * Note that this constant is *not* the total money supply, which in Bitcoin + * currently happens to be less than 21,000,000 BTC for various reasons, but + * rather a sanity check. As this sanity check is used by consensus-critical + * validation code, the exact value of the MAX_MONEY constant is consensus + * critical; in unusual circumstances like a(nother) overflow bug that allowed + * for the creation of coins out of thin air modification could lead to a fork. + * */ +static constexpr CAmount MAX_MONEY = 21000000 * COIN; +inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } + +#endif // BITCOIN_CONSENSUS_AMOUNT_H diff --git a/src/consensus/params.h b/src/consensus/params.h index 61b1fbc2e5..1ed5ca469f 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2019 The Bitcoin Core developers +// Copyright (c) 2009-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -11,12 +11,27 @@ namespace Consensus { -enum DeploymentPos -{ +/** + * A buried deployment is one where the height of the activation has been hardcoded into + * the client implementation long after the consensus change has activated. See BIP 90. + */ +enum BuriedDeployment : int16_t { + // buried deployments get negative values to avoid overlap with DeploymentPos + DEPLOYMENT_HEIGHTINCB = std::numeric_limits<int16_t>::min(), + DEPLOYMENT_CLTV, + DEPLOYMENT_DERSIG, + DEPLOYMENT_CSV, + DEPLOYMENT_SEGWIT, +}; +constexpr bool ValidDeployment(BuriedDeployment dep) { return dep <= DEPLOYMENT_SEGWIT; } + +enum DeploymentPos : uint16_t { DEPLOYMENT_TESTDUMMY, - // NOTE: Also add new deployments to VersionBitsDeploymentInfo in versionbits.cpp + DEPLOYMENT_TAPROOT, // Deployment of Schnorr/Taproot (BIPs 340-342) + // NOTE: Also add new deployments to VersionBitsDeploymentInfo in deploymentinfo.cpp MAX_VERSION_BITS_DEPLOYMENTS }; +constexpr bool ValidDeployment(DeploymentPos dep) { return dep < MAX_VERSION_BITS_DEPLOYMENTS; } /** * Struct for each individual consensus rule change using BIP9. @@ -28,6 +43,11 @@ struct BIP9Deployment { int64_t nStartTime; /** Timeout/expiry MedianTime for the deployment attempt. */ int64_t nTimeout; + /** If lock in occurs, delay activation until at least this block + * height. Note that activation will only occur on a retarget + * boundary. + */ + int min_activation_height{0}; /** Constant for nTimeout very far in the future. */ static constexpr int64_t NO_TIMEOUT = std::numeric_limits<int64_t>::max(); @@ -37,6 +57,11 @@ struct BIP9Deployment { * process (which takes at least 3 BIP9 intervals). Only tests that specifically test the * behaviour during activation cannot use this. */ static constexpr int64_t ALWAYS_ACTIVE = -1; + + /** Special value for nStartTime indicating that the deployment is never active. + * This is useful for integrating the code changes for a new feature + * prior to deploying it on some or all networks. */ + static constexpr int64_t NEVER_ACTIVE = -2; }; /** @@ -78,9 +103,36 @@ struct Params { int64_t nPowTargetSpacing; int64_t nPowTargetTimespan; int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; } + /** The best chain should have at least this much work */ uint256 nMinimumChainWork; + /** By default assume that the signatures in ancestors of this block are valid */ uint256 defaultAssumeValid; + + /** + * If true, witness commitments contain a payload equal to a Bitcoin Script solution + * to the signet challenge. See BIP325. + */ + bool signet_blocks{false}; + std::vector<uint8_t> signet_challenge; + + int DeploymentHeight(BuriedDeployment dep) const + { + switch (dep) { + case DEPLOYMENT_HEIGHTINCB: + return BIP34Height; + case DEPLOYMENT_CLTV: + return BIP65Height; + case DEPLOYMENT_DERSIG: + return BIP66Height; + case DEPLOYMENT_CSV: + return CSVHeight; + case DEPLOYMENT_SEGWIT: + return SegwitHeight; + } // no default case, so the compiler can warn about missing cases + return std::numeric_limits<int>::max(); + } }; + } // namespace Consensus #endif // BITCOIN_CONSENSUS_PARAMS_H diff --git a/src/consensus/tx_check.cpp b/src/consensus/tx_check.cpp index bb8cd10c63..f949655909 100644 --- a/src/consensus/tx_check.cpp +++ b/src/consensus/tx_check.cpp @@ -1,9 +1,10 @@ -// Copyright (c) 2017-2019 The Bitcoin Core developers +// Copyright (c) 2017-2021 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 <consensus/tx_check.h> +#include <consensus/amount.h> #include <primitives/transaction.h> #include <consensus/validation.h> diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp index 9e8e6530f1..5738c333ce 100644 --- a/src/consensus/tx_verify.cpp +++ b/src/consensus/tx_verify.cpp @@ -1,17 +1,16 @@ -// Copyright (c) 2017-2019 The Bitcoin Core developers +// Copyright (c) 2017-2021 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 <consensus/tx_verify.h> +#include <chain.h> +#include <coins.h> +#include <consensus/amount.h> #include <consensus/consensus.h> +#include <consensus/validation.h> #include <primitives/transaction.h> #include <script/interpreter.h> -#include <consensus/validation.h> - -// TODO remove the following dependencies -#include <chain.h> -#include <coins.h> #include <util/moneystr.h> bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime) @@ -20,6 +19,15 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime) return true; if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime)) return true; + + // Even if tx.nLockTime isn't satisfied by nBlockHeight/nBlockTime, a + // transaction is still considered final if all inputs' nSequence == + // SEQUENCE_FINAL (0xffffffff), in which case nLockTime is ignored. + // + // Because of this behavior OP_CHECKLOCKTIMEVERIFY/CheckLockTime() will + // also check that the spending input's nSequence != SEQUENCE_FINAL, + // ensuring that an unsatisfied nLockTime value will actually cause + // IsFinalTx() to return false here: for (const auto& txin : tx.vin) { if (!(txin.nSequence == CTxIn::SEQUENCE_FINAL)) return false; @@ -135,7 +143,7 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in return nSigOps; } -int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, int flags) +int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, uint32_t flags) { int64_t nSigOps = GetLegacySigOpCount(tx) * WITNESS_SCALE_FACTOR; diff --git a/src/consensus/tx_verify.h b/src/consensus/tx_verify.h index e2a9328df8..1209c0faa5 100644 --- a/src/consensus/tx_verify.h +++ b/src/consensus/tx_verify.h @@ -1,11 +1,11 @@ -// Copyright (c) 2017-2019 The Bitcoin Core developers +// Copyright (c) 2017-2021 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_VERIFY_H #define BITCOIN_CONSENSUS_TX_VERIFY_H -#include <amount.h> +#include <consensus/amount.h> #include <stdint.h> #include <vector> @@ -24,7 +24,7 @@ namespace Consensus { * @param[out] txfee Set to the transaction fee if successful. * Preconditions: tx.IsCoinBase() is false. */ -bool CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee); +[[nodiscard]] bool CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee); } // namespace Consensus /** Auxiliary functions for transaction validation (ideally should not be exposed) */ @@ -49,10 +49,10 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& ma * Compute total signature operation cost of a transaction. * @param[in] tx Transaction for which we are computing the cost * @param[in] inputs Map of previous transactions that have outputs we're spending - * @param[out] flags Script verification flags + * @param[in] flags Script verification flags * @return Total signature operation cost of tx */ -int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, int flags); +int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, uint32_t flags); /** * Check if transaction is final and can be included in a block with the diff --git a/src/consensus/validation.h b/src/consensus/validation.h index a79e7b9d12..6027bb9aeb 100644 --- a/src/consensus/validation.h +++ b/src/consensus/validation.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2019 The Bitcoin Core developers +// Copyright (c) 2009-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -12,6 +12,12 @@ #include <primitives/transaction.h> #include <primitives/block.h> +/** Index marker for when no witness commitment is present in a coinbase transaction. */ +static constexpr int NO_WITNESS_COMMITMENT{-1}; + +/** Minimum size of a witness commitment structure. Defined in BIP 141. **/ +static constexpr size_t MINIMUM_WITNESS_COMMITMENT{38}; + /** A "reason" why a transaction was invalid, suitable for determining whether the * provider of the transaction should be banned/ignored/disconnected/etc. */ @@ -26,22 +32,28 @@ enum class TxValidationResult { * is uninteresting. */ TX_RECENT_CONSENSUS_CHANGE, - TX_NOT_STANDARD, //!< didn't meet our local policy rules + TX_INPUTS_NOT_STANDARD, //!< inputs (covered by txid) failed policy rules + TX_NOT_STANDARD, //!< otherwise didn't meet our local policy rules TX_MISSING_INPUTS, //!< transaction was missing some of its inputs TX_PREMATURE_SPEND, //!< transaction spends a coinbase too early, or violates locktime/sequence locks /** - * Transaction might be missing a witness, have a witness prior to SegWit + * Transaction might have a witness prior to SegWit * activation, or witness may have been malleated (which includes * non-standard witnesses). */ TX_WITNESS_MUTATED, /** + * Transaction is missing a witness. + */ + TX_WITNESS_STRIPPED, + /** * Tx already in mempool or conflicts with a tx in the chain * (if it conflicts with another tx in mempool, we use MEMPOOL_POLICY as it failed to reach the RBF threshold) * Currently this is only used if the transaction already exists in the mempool or on chain. */ TX_CONFLICT, TX_MEMPOOL_POLICY, //!< violated mempool's fee/size/descendant/RBF/etc limits + TX_NO_MEMPOOL, //!< this node does not have a mempool so can't validate the transaction }; /** A "reason" why a block was invalid, suitable for determining whether the @@ -75,37 +87,39 @@ enum class BlockValidationResult { * by TxValidationState and BlockValidationState for validation information on transactions * and blocks respectively. */ template <typename Result> -class ValidationState { +class ValidationState +{ private: - enum mode_state { - MODE_VALID, //!< everything ok - MODE_INVALID, //!< network rule violation (DoS value may be set) - MODE_ERROR, //!< run-time error - } m_mode{MODE_VALID}; + enum class ModeState { + M_VALID, //!< everything ok + M_INVALID, //!< network rule violation (DoS value may be set) + M_ERROR, //!< run-time error + } m_mode{ModeState::M_VALID}; Result m_result{}; std::string m_reject_reason; std::string m_debug_message; + public: bool Invalid(Result result, - const std::string &reject_reason="", - const std::string &debug_message="") + const std::string& reject_reason = "", + const std::string& debug_message = "") { m_result = result; m_reject_reason = reject_reason; m_debug_message = debug_message; - if (m_mode != MODE_ERROR) m_mode = MODE_INVALID; + if (m_mode != ModeState::M_ERROR) m_mode = ModeState::M_INVALID; return false; } bool Error(const std::string& reject_reason) { - if (m_mode == MODE_VALID) + if (m_mode == ModeState::M_VALID) m_reject_reason = reject_reason; - m_mode = MODE_ERROR; + m_mode = ModeState::M_ERROR; return false; } - bool IsValid() const { return m_mode == MODE_VALID; } - bool IsInvalid() const { return m_mode == MODE_INVALID; } - bool IsError() const { return m_mode == MODE_ERROR; } + bool IsValid() const { return m_mode == ModeState::M_VALID; } + bool IsInvalid() const { return m_mode == ModeState::M_INVALID; } + bool IsError() const { return m_mode == ModeState::M_ERROR; } Result GetResult() const { return m_result; } std::string GetRejectReason() const { return m_reject_reason; } std::string GetDebugMessage() const { return m_debug_message; } @@ -144,4 +158,25 @@ static inline int64_t GetTransactionInputWeight(const CTxIn& txin) return ::GetSerializeSize(txin, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(txin, PROTOCOL_VERSION) + ::GetSerializeSize(txin.scriptWitness.stack, PROTOCOL_VERSION); } +/** Compute at which vout of the block's coinbase transaction the witness commitment occurs, or -1 if not found */ +inline int GetWitnessCommitmentIndex(const CBlock& block) +{ + int commitpos = NO_WITNESS_COMMITMENT; + if (!block.vtx.empty()) { + for (size_t o = 0; o < block.vtx[0]->vout.size(); o++) { + const CTxOut& vout = block.vtx[0]->vout[o]; + if (vout.scriptPubKey.size() >= MINIMUM_WITNESS_COMMITMENT && + vout.scriptPubKey[0] == OP_RETURN && + vout.scriptPubKey[1] == 0x24 && + vout.scriptPubKey[2] == 0xaa && + vout.scriptPubKey[3] == 0x21 && + vout.scriptPubKey[4] == 0xa9 && + vout.scriptPubKey[5] == 0xed) { + commitpos = o; + } + } + } + return commitpos; +} + #endif // BITCOIN_CONSENSUS_VALIDATION_H |