Bitcoin Core  28.1.0
P2P Digital Currency
validation.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2022 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #ifndef BITCOIN_CONSENSUS_VALIDATION_H
7 #define BITCOIN_CONSENSUS_VALIDATION_H
8 
9 #include <string>
10 #include <consensus/consensus.h>
11 #include <primitives/transaction.h>
12 #include <primitives/block.h>
13 
15 static constexpr int NO_WITNESS_COMMITMENT{-1};
16 
18 static constexpr size_t MINIMUM_WITNESS_COMMITMENT{38};
19 
23 enum class TxValidationResult {
24  TX_RESULT_UNSET = 0,
25  TX_CONSENSUS,
26 
38 
57  TX_UNKNOWN,
58 };
59 
66  BLOCK_RESULT_UNSET = 0,
68 
84 };
85 
86 
87 
91 template <typename Result>
93 {
94 private:
95  enum class ModeState {
96  M_VALID,
97  M_INVALID,
98  M_ERROR,
99  } m_mode{ModeState::M_VALID};
101  std::string m_reject_reason;
102  std::string m_debug_message;
103 
104 public:
105  bool Invalid(Result result,
106  const std::string& reject_reason = "",
107  const std::string& debug_message = "")
108  {
109  m_result = result;
110  m_reject_reason = reject_reason;
111  m_debug_message = debug_message;
112  if (m_mode != ModeState::M_ERROR) m_mode = ModeState::M_INVALID;
113  return false;
114  }
115  bool Error(const std::string& reject_reason)
116  {
117  if (m_mode == ModeState::M_VALID)
118  m_reject_reason = reject_reason;
119  m_mode = ModeState::M_ERROR;
120  return false;
121  }
122  bool IsValid() const { return m_mode == ModeState::M_VALID; }
123  bool IsInvalid() const { return m_mode == ModeState::M_INVALID; }
124  bool IsError() const { return m_mode == ModeState::M_ERROR; }
125  Result GetResult() const { return m_result; }
126  std::string GetRejectReason() const { return m_reject_reason; }
127  std::string GetDebugMessage() const { return m_debug_message; }
128  std::string ToString() const
129  {
130  if (IsValid()) {
131  return "Valid";
132  }
133 
134  if (!m_debug_message.empty()) {
135  return m_reject_reason + ", " + m_debug_message;
136  }
137 
138  return m_reject_reason;
139  }
140 };
141 
142 class TxValidationState : public ValidationState<TxValidationResult> {};
143 class BlockValidationState : public ValidationState<BlockValidationResult> {};
144 
145 // These implement the weight = (stripped_size * 4) + witness_size formula,
146 // using only serialization with and without witness data. As witness_size
147 // is equal to total_size - stripped_size, this formula is identical to:
148 // weight = (stripped_size * 3) + total_size.
149 static inline int32_t GetTransactionWeight(const CTransaction& tx)
150 {
152 }
153 static inline int64_t GetBlockWeight(const CBlock& block)
154 {
156 }
157 static inline int64_t GetTransactionInputWeight(const CTxIn& txin)
158 {
159  // scriptWitness size is added here because witnesses and txins are split up in segwit serialization.
161 }
162 
164 inline int GetWitnessCommitmentIndex(const CBlock& block)
165 {
166  int commitpos = NO_WITNESS_COMMITMENT;
167  if (!block.vtx.empty()) {
168  for (size_t o = 0; o < block.vtx[0]->vout.size(); o++) {
169  const CTxOut& vout = block.vtx[0]->vout[o];
171  vout.scriptPubKey[0] == OP_RETURN &&
172  vout.scriptPubKey[1] == 0x24 &&
173  vout.scriptPubKey[2] == 0xaa &&
174  vout.scriptPubKey[3] == 0x21 &&
175  vout.scriptPubKey[4] == 0xa9 &&
176  vout.scriptPubKey[5] == 0xed) {
177  commitpos = o;
178  }
179  }
180  }
181  return commitpos;
182 }
183 
184 #endif // BITCOIN_CONSENSUS_VALIDATION_H
invalid by consensus rules
bool Error(const std::string &reject_reason)
Definition: validation.h:115
static const int WITNESS_SCALE_FACTOR
Definition: consensus.h:21
std::string GetDebugMessage() const
Definition: validation.h:127
CScript scriptPubKey
Definition: transaction.h:153
Template for capturing information about block/transaction validation.
Definition: validation.h:92
Definition: block.h:68
We don&#39;t have the previous block the checked one is built on.
transaction was not validated because package failed
invalid proof of work or time too old
CScriptWitness scriptWitness
Only serialized through CTransaction.
Definition: transaction.h:72
network rule violation (DoS value may be set)
size_t GetSerializeSize(const T &t)
Definition: serialize.h:1101
BlockValidationResult
A "reason" why a block was invalid, suitable for determining whether the provider of the block should...
Definition: validation.h:65
transaction was missing some of its inputs
static constexpr size_t MINIMUM_WITNESS_COMMITMENT
Minimum size of a witness commitment structure.
Definition: validation.h:18
std::vector< std::vector< unsigned char > > stack
Definition: script.h:577
violated mempool&#39;s fee/size/descendant/RBF/etc limits
the block header may be on a too-little-work chain
inputs (covered by txid) failed policy rules
transaction spends a coinbase too early, or violates locktime/sequence locks
static constexpr int NO_WITNESS_COMMITMENT
Index marker for when no witness commitment is present in a coinbase transaction. ...
Definition: validation.h:15
static int32_t GetTransactionWeight(const CTransaction &tx)
Definition: validation.h:149
initial value. Tx has not yet been rejected
bool IsValid() const
Definition: validation.h:122
initial value. Block has not yet been rejected
Invalid by a change to consensus rules more recent than SegWit.
bool Invalid(Result result, const std::string &reject_reason="", const std::string &debug_message="")
Definition: validation.h:105
Transaction might have a witness prior to SegWit activation, or witness may have been malleated (whic...
this block was cached as being invalid and we didn&#39;t store the reason why
An input of a transaction.
Definition: transaction.h:66
static int64_t GetTransactionInputWeight(const CTxIn &txin)
Definition: validation.h:157
std::string ToString() const
Definition: validation.h:128
the block failed to meet one of our checkpoints
Result GetResult() const
Definition: validation.h:125
An output of a transaction.
Definition: transaction.h:149
fails some policy, but might be acceptable if submitted in a (different) package
std::string m_debug_message
Definition: validation.h:102
Transaction is missing a witness.
invalid by consensus rules (excluding any below reasons)
std::vector< CTransactionRef > vtx
Definition: block.h:72
the block&#39;s data didn&#39;t match the data committed to by the PoW
A block this one builds on is invalid.
bool IsInvalid() const
Definition: validation.h:123
Invalid by a change to consensus rules more recent than SegWit.
this node does not have a mempool so can&#39;t validate the transaction
size_type size() const
Definition: prevector.h:296
block timestamp was > 2 hours in the future (or our clock is bad)
std::string m_reject_reason
Definition: validation.h:101
The basic transaction that is broadcasted on the network and contained in blocks. ...
Definition: transaction.h:295
std::string GetRejectReason() const
Definition: validation.h:126
int GetWitnessCommitmentIndex(const CBlock &block)
Compute at which vout of the block&#39;s coinbase transaction the witness commitment occurs, or -1 if not found.
Definition: validation.h:164
static int64_t GetBlockWeight(const CBlock &block)
Definition: validation.h:153
Tx already in mempool or conflicts with a tx in the chain (if it conflicts with another tx in mempool...
otherwise didn&#39;t meet our local policy rules
bool IsError() const
Definition: validation.h:124
static constexpr TransactionSerParams TX_WITH_WITNESS
Definition: transaction.h:195
static constexpr TransactionSerParams TX_NO_WITNESS
Definition: transaction.h:196
TxValidationResult
A "reason" why a transaction was invalid, suitable for determining whether the provider of the transa...
Definition: validation.h:23