Bitcoin ABC  0.28.12
P2P Digital Currency
tx_verify.cpp
Go to the documentation of this file.
1 // Copyright (c) 2018-2020 The Bitcoin developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <consensus/tx_verify.h>
6 
7 #include <chain.h>
8 #include <coins.h>
9 #include <consensus/activation.h>
10 #include <consensus/amount.h>
11 #include <consensus/consensus.h>
12 #include <consensus/params.h>
13 #include <consensus/validation.h>
14 #include <primitives/transaction.h>
15 #include <script/script_flags.h>
16 #include <util/check.h>
17 #include <util/moneystr.h> // For FormatMoney
18 #include <version.h> // For PROTOCOL_VERSION
19 
20 static bool IsFinalTx(const CTransaction &tx, int nBlockHeight,
21  int64_t nBlockTime) {
22  if (tx.nLockTime == 0) {
23  return true;
24  }
25 
26  int64_t lockTime = tx.nLockTime;
27  int64_t lockTimeLimit =
28  (lockTime < LOCKTIME_THRESHOLD) ? nBlockHeight : nBlockTime;
29  if (lockTime < lockTimeLimit) {
30  return true;
31  }
32 
33  for (const auto &txin : tx.vin) {
34  if (txin.nSequence != CTxIn::SEQUENCE_FINAL) {
35  return false;
36  }
37  }
38  return true;
39 }
40 
42  const CTransaction &tx,
43  TxValidationState &state, int nHeight,
44  int64_t nMedianTimePast) {
45  if (!IsFinalTx(tx, nHeight, nMedianTimePast)) {
46  // While this is only one transaction, we use txns in the error to
47  // ensure continuity with other clients.
49  "bad-txns-nonfinal", "non-final transaction");
50  }
51 
52  if (IsMagneticAnomalyEnabled(params, nHeight)) {
53  // Size limit
56  "bad-txns-undersize");
57  }
58  }
59 
60  if (IsWellingtonEnabled(params, nHeight)) {
61  // Restrict version to 1 and 2
65  "bad-txns-version");
66  }
67  }
68 
69  return true;
70 }
71 
78 std::pair<int, int64_t> CalculateSequenceLocks(const CTransaction &tx,
79  int flags,
80  std::vector<int> &prevHeights,
81  const CBlockIndex &block) {
82  assert(prevHeights.size() == tx.vin.size());
83 
84  // Will be set to the equivalent height- and time-based nLockTime
85  // values that would be necessary to satisfy all relative lock-
86  // time constraints given our view of block chain history.
87  // The semantics of nLockTime are the last invalid height/time, so
88  // use -1 to have the effect of any height or time being valid.
89  int nMinHeight = -1;
90  int64_t nMinTime = -1;
91 
92  // tx.nVersion is signed integer so requires cast to unsigned otherwise
93  // we would be doing a signed comparison and half the range of nVersion
94  // wouldn't support BIP 68.
95  bool fEnforceBIP68 = static_cast<uint32_t>(tx.nVersion) >= 2 &&
97 
98  // Do not enforce sequence numbers as a relative lock time
99  // unless we have been instructed to
100  if (!fEnforceBIP68) {
101  return std::make_pair(nMinHeight, nMinTime);
102  }
103 
104  for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
105  const CTxIn &txin = tx.vin[txinIndex];
106 
107  // Sequence numbers with the most significant bit set are not
108  // treated as relative lock-times, nor are they given any
109  // consensus-enforced meaning at this point.
111  // The height of this input is not relevant for sequence locks
112  prevHeights[txinIndex] = 0;
113  continue;
114  }
115 
116  int nCoinHeight = prevHeights[txinIndex];
117 
119  const int64_t nCoinTime{
120  Assert(block.GetAncestor(std::max(nCoinHeight - 1, 0)))
121  ->GetMedianTimePast()};
122  // NOTE: Subtract 1 to maintain nLockTime semantics.
123  // BIP 68 relative lock times have the semantics of calculating the
124  // first block or time at which the transaction would be valid. When
125  // calculating the effective block time or height for the entire
126  // transaction, we switch to using the semantics of nLockTime which
127  // is the last invalid block time or height. Thus we subtract 1 from
128  // the calculated time or height.
129 
130  // Time-based relative lock-times are measured from the smallest
131  // allowed timestamp of the block containing the txout being spent,
132  // which is the median time past of the block prior.
133  nMinTime = std::max(
134  nMinTime,
135  nCoinTime +
138  1);
139  } else {
140  nMinHeight = std::max(
141  nMinHeight,
142  nCoinHeight +
143  int(txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) - 1);
144  }
145  }
146 
147  return std::make_pair(nMinHeight, nMinTime);
148 }
149 
151  std::pair<int, int64_t> lockPair) {
152  assert(block.pprev);
153  int64_t nBlockTime = block.pprev->GetMedianTimePast();
154  if (lockPair.first >= block.nHeight || lockPair.second >= nBlockTime) {
155  return false;
156  }
157 
158  return true;
159 }
160 
161 bool SequenceLocks(const CTransaction &tx, int flags,
162  std::vector<int> &prevHeights, const CBlockIndex &block) {
163  return EvaluateSequenceLocks(
164  block, CalculateSequenceLocks(tx, flags, prevHeights, block));
165 }
166 
167 namespace Consensus {
169  const CCoinsViewCache &inputs, int nSpendHeight,
170  Amount &txfee) {
171  // are the actual inputs available?
172  if (!inputs.HaveInputs(tx)) {
174  "bad-txns-inputs-missingorspent",
175  strprintf("%s: inputs missing/spent", __func__));
176  }
177 
178  Amount nValueIn = Amount::zero();
179  for (const auto &in : tx.vin) {
180  const COutPoint &prevout = in.prevout;
181  const Coin &coin = inputs.AccessCoin(prevout);
182  assert(!coin.IsSpent());
183 
184  // If prev is coinbase, check that it's matured
185  if (coin.IsCoinBase() &&
186  nSpendHeight - coin.GetHeight() < COINBASE_MATURITY) {
187  return state.Invalid(
189  "bad-txns-premature-spend-of-coinbase",
190  strprintf("tried to spend coinbase at depth %d",
191  nSpendHeight - coin.GetHeight()));
192  }
193 
194  // Check for negative or overflow input values
195  nValueIn += coin.GetTxOut().nValue;
196  if (!MoneyRange(coin.GetTxOut().nValue) || !MoneyRange(nValueIn)) {
198  "bad-txns-inputvalues-outofrange");
199  }
200  }
201 
202  const Amount value_out = tx.GetValueOut();
203  if (nValueIn < value_out) {
204  return state.Invalid(
205  TxValidationResult::TX_CONSENSUS, "bad-txns-in-belowout",
206  strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn),
207  FormatMoney(value_out)));
208  }
209 
210  // Tally transaction fees
211  const Amount txfee_aux = nValueIn - value_out;
212  if (!MoneyRange(txfee_aux)) {
214  "bad-txns-fee-outofrange");
215  }
216 
217  txfee = txfee_aux;
218  return true;
219 }
220 } // namespace Consensus
bool IsWellingtonEnabled(const Consensus::Params &params, int32_t nHeight)
Check if May 15th, 2023 protocol upgrade has activated.
Definition: activation.cpp:91
bool IsMagneticAnomalyEnabled(const Consensus::Params &params, int32_t nHeight)
Check if Nov 15, 2018 HF has activated using block height.
Definition: activation.cpp:37
bool MoneyRange(const Amount nValue)
Definition: amount.h:166
int flags
Definition: bitcoin-tx.cpp:533
#define Assert(val)
Identity function.
Definition: check.h:84
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: blockindex.h:26
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: blockindex.h:33
int64_t GetMedianTimePast() const
Definition: blockindex.h:190
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: blockindex.cpp:71
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: blockindex.h:39
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:203
bool HaveInputs(const CTransaction &tx) const
Check whether all prevouts of the transaction are present in the UTXO set represented by this view.
Definition: coins.cpp:306
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
Definition: coins.cpp:192
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:20
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:192
static constexpr int32_t MAX_VERSION
Definition: transaction.h:199
const uint32_t nLockTime
Definition: transaction.h:209
Amount GetValueOut() const
Definition: transaction.cpp:78
const int32_t nVersion
Definition: transaction.h:208
const std::vector< CTxIn > vin
Definition: transaction.h:206
static constexpr int32_t MIN_VERSION
Definition: transaction.h:199
An input of a transaction.
Definition: transaction.h:59
static const uint32_t SEQUENCE_LOCKTIME_DISABLE_FLAG
If this flag set, CTxIn::nSequence is NOT interpreted as a relative lock-time.
Definition: transaction.h:76
uint32_t nSequence
Definition: transaction.h:63
static const uint32_t SEQUENCE_LOCKTIME_MASK
If CTxIn::nSequence encodes a relative lock-time, this mask is applied to extract that lock-time from...
Definition: transaction.h:89
static const uint32_t SEQUENCE_FINAL
Setting nSequence to this value for every input in a transaction disables nLockTime.
Definition: transaction.h:69
static const uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG
If CTxIn::nSequence encodes a relative lock-time and this flag is set, the relative lock-time has uni...
Definition: transaction.h:83
static const int SEQUENCE_LOCKTIME_GRANULARITY
In order to use the same number of bits to encode roughly the same wall-clock duration,...
Definition: transaction.h:99
Amount nValue
Definition: transaction.h:130
A UTXO entry.
Definition: coins.h:27
uint32_t GetHeight() const
Definition: coins.h:44
bool IsCoinBase() const
Definition: coins.h:45
bool IsSpent() const
Definition: coins.h:46
CTxOut & GetTxOut()
Definition: coins.h:48
bool Invalid(Result result, const std::string &reject_reason="", const std::string &debug_message="")
Definition: validation.h:94
@ TX_MISSING_INPUTS
transaction was missing some of its inputs
@ TX_PREMATURE_SPEND
transaction spends a coinbase too early, or violates locktime/sequence locks
@ TX_CONSENSUS
invalid by consensus rules
static constexpr unsigned int LOCKTIME_VERIFY_SEQUENCE
Flags for nSequence and nLockTime locks.
Definition: consensus.h:38
static const uint64_t MIN_TX_SIZE
The minimum allowed size for a transaction, in bytes.
Definition: consensus.h:16
static const int COINBASE_MATURITY
Coinbase transaction outputs can only be spent after this number of new blocks (network rule).
Definition: consensus.h:32
unsigned int nHeight
std::string FormatMoney(const Amount amt)
Do not use these functions to represent or parse monetary amounts to or from JSON but use AmountFromV...
Definition: moneystr.cpp:13
bool CheckTxInputs(const CTransaction &tx, TxValidationState &state, const CCoinsViewCache &inputs, int nSpendHeight, Amount &txfee)
Check whether all inputs of this transaction are valid (no double spends and amounts).
Definition: tx_verify.cpp:168
static const unsigned int LOCKTIME_THRESHOLD
Definition: script.h:40
size_t GetSerializeSize(const T &t, int nVersion=0)
Definition: serialize.h:1276
Definition: amount.h:19
static constexpr Amount zero() noexcept
Definition: amount.h:32
Parameters that influence chain consensus.
Definition: params.h:34
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1202
std::pair< int, int64_t > CalculateSequenceLocks(const CTransaction &tx, int flags, std::vector< int > &prevHeights, const CBlockIndex &block)
Calculates the block height and previous block's median time past at which the transaction will be co...
Definition: tx_verify.cpp:78
static bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
Definition: tx_verify.cpp:20
bool EvaluateSequenceLocks(const CBlockIndex &block, std::pair< int, int64_t > lockPair)
Definition: tx_verify.cpp:150
bool SequenceLocks(const CTransaction &tx, int flags, std::vector< int > &prevHeights, const CBlockIndex &block)
Check if transaction is final per BIP 68 sequence numbers and can be included in a block.
Definition: tx_verify.cpp:161
bool ContextualCheckTransaction(const Consensus::Params &params, const CTransaction &tx, TxValidationState &state, int nHeight, int64_t nMedianTimePast)
Context dependent validity checks for non coinbase transactions.
Definition: tx_verify.cpp:41
assert(!tx.IsCoinBase())
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:11