Bitcoin ABC  0.24.11
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 <amount.h>
8 #include <chain.h>
9 #include <coins.h>
10 #include <consensus/activation.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/moneystr.h> // For FormatMoney
17 #include <version.h> // For PROTOCOL_VERSION
18 
19 static bool IsFinalTx(const CTransaction &tx, int nBlockHeight,
20  int64_t nBlockTime) {
21  if (tx.nLockTime == 0) {
22  return true;
23  }
24 
25  int64_t lockTime = tx.nLockTime;
26  int64_t lockTimeLimit =
27  (lockTime < LOCKTIME_THRESHOLD) ? nBlockHeight : nBlockTime;
28  if (lockTime < lockTimeLimit) {
29  return true;
30  }
31 
32  for (const auto &txin : tx.vin) {
33  if (txin.nSequence != CTxIn::SEQUENCE_FINAL) {
34  return false;
35  }
36  }
37  return true;
38 }
39 
41  const CTransaction &tx,
42  TxValidationState &state, int nHeight,
43  int64_t nLockTimeCutoff,
44  int64_t nMedianTimePast) {
45  if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) {
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  return true;
61 }
62 
69 std::pair<int, int64_t> CalculateSequenceLocks(const CTransaction &tx,
70  int flags,
71  std::vector<int> &prevHeights,
72  const CBlockIndex &block) {
73  assert(prevHeights.size() == tx.vin.size());
74 
75  // Will be set to the equivalent height- and time-based nLockTime
76  // values that would be necessary to satisfy all relative lock-
77  // time constraints given our view of block chain history.
78  // The semantics of nLockTime are the last invalid height/time, so
79  // use -1 to have the effect of any height or time being valid.
80  int nMinHeight = -1;
81  int64_t nMinTime = -1;
82 
83  // tx.nVersion is signed integer so requires cast to unsigned otherwise
84  // we would be doing a signed comparison and half the range of nVersion
85  // wouldn't support BIP 68.
86  bool fEnforceBIP68 = static_cast<uint32_t>(tx.nVersion) >= 2 &&
88 
89  // Do not enforce sequence numbers as a relative lock time
90  // unless we have been instructed to
91  if (!fEnforceBIP68) {
92  return std::make_pair(nMinHeight, nMinTime);
93  }
94 
95  for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
96  const CTxIn &txin = tx.vin[txinIndex];
97 
98  // Sequence numbers with the most significant bit set are not
99  // treated as relative lock-times, nor are they given any
100  // consensus-enforced meaning at this point.
102  // The height of this input is not relevant for sequence locks
103  prevHeights[txinIndex] = 0;
104  continue;
105  }
106 
107  int nCoinHeight = prevHeights[txinIndex];
108 
110  int64_t nCoinTime = block.GetAncestor(std::max(nCoinHeight - 1, 0))
111  ->GetMedianTimePast();
112  // NOTE: Subtract 1 to maintain nLockTime semantics.
113  // BIP 68 relative lock times have the semantics of calculating the
114  // first block or time at which the transaction would be valid. When
115  // calculating the effective block time or height for the entire
116  // transaction, we switch to using the semantics of nLockTime which
117  // is the last invalid block time or height. Thus we subtract 1 from
118  // the calculated time or height.
119 
120  // Time-based relative lock-times are measured from the smallest
121  // allowed timestamp of the block containing the txout being spent,
122  // which is the median time past of the block prior.
123  nMinTime = std::max(
124  nMinTime,
125  nCoinTime +
128  1);
129  } else {
130  nMinHeight = std::max(
131  nMinHeight,
132  nCoinHeight +
133  int(txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) - 1);
134  }
135  }
136 
137  return std::make_pair(nMinHeight, nMinTime);
138 }
139 
141  std::pair<int, int64_t> lockPair) {
142  assert(block.pprev);
143  int64_t nBlockTime = block.pprev->GetMedianTimePast();
144  if (lockPair.first >= block.nHeight || lockPair.second >= nBlockTime) {
145  return false;
146  }
147 
148  return true;
149 }
150 
151 bool SequenceLocks(const CTransaction &tx, int flags,
152  std::vector<int> &prevHeights, const CBlockIndex &block) {
153  return EvaluateSequenceLocks(
154  block, CalculateSequenceLocks(tx, flags, prevHeights, block));
155 }
156 
157 namespace Consensus {
159  const CCoinsViewCache &inputs, int nSpendHeight,
160  Amount &txfee) {
161  // are the actual inputs available?
162  if (!inputs.HaveInputs(tx)) {
164  "bad-txns-inputs-missingorspent",
165  strprintf("%s: inputs missing/spent", __func__));
166  }
167 
168  Amount nValueIn = Amount::zero();
169  for (const auto &in : tx.vin) {
170  const COutPoint &prevout = in.prevout;
171  const Coin &coin = inputs.AccessCoin(prevout);
172  assert(!coin.IsSpent());
173 
174  // If prev is coinbase, check that it's matured
175  if (coin.IsCoinBase() &&
176  nSpendHeight - coin.GetHeight() < COINBASE_MATURITY) {
177  return state.Invalid(
179  "bad-txns-premature-spend-of-coinbase",
180  strprintf("tried to spend coinbase at depth %d",
181  nSpendHeight - coin.GetHeight()));
182  }
183 
184  // Check for negative or overflow input values
185  nValueIn += coin.GetTxOut().nValue;
186  if (!MoneyRange(coin.GetTxOut().nValue) || !MoneyRange(nValueIn)) {
188  "bad-txns-inputvalues-outofrange");
189  }
190  }
191 
192  const Amount value_out = tx.GetValueOut();
193  if (nValueIn < value_out) {
194  return state.Invalid(
195  TxValidationResult::TX_CONSENSUS, "bad-txns-in-belowout",
196  strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn),
197  FormatMoney(value_out)));
198  }
199 
200  // Tally transaction fees
201  const Amount txfee_aux = nValueIn - value_out;
202  if (!MoneyRange(txfee_aux)) {
204  "bad-txns-fee-outofrange");
205  }
206 
207  txfee = txfee_aux;
208  return true;
209 }
210 } // namespace Consensus
GetSerializeSize
size_t GetSerializeSize(const T &t, int nVersion=0)
Definition: serialize.h:1182
CTxIn
An input of a transaction.
Definition: transaction.h:61
CTransaction::vin
const std::vector< CTxIn > vin
Definition: transaction.h:210
MoneyRange
bool MoneyRange(const Amount nValue)
Definition: amount.h:176
CTxOut::nValue
Amount nValue
Definition: transaction.h:132
CBlockIndex::GetAncestor
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: blockindex.cpp:71
LOCKTIME_THRESHOLD
static const unsigned int LOCKTIME_THRESHOLD
Definition: script.h:39
COINBASE_MATURITY
static const int COINBASE_MATURITY
Coinbase transaction outputs can only be spent after this number of new blocks (network rule).
Definition: consensus.h:32
EvaluateSequenceLocks
bool EvaluateSequenceLocks(const CBlockIndex &block, std::pair< int, int64_t > lockPair)
Definition: tx_verify.cpp:140
nHeight
unsigned int nHeight
Definition: mempool_eviction.cpp:13
flags
int flags
Definition: bitcoin-tx.cpp:532
moneystr.h
transaction.h
CalculateSequenceLocks
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:69
CBlockIndex::pprev
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: blockindex.h:30
CBlockIndex::nHeight
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: blockindex.h:36
script_flags.h
CTransaction::nLockTime
const uint32_t nLockTime
Definition: transaction.h:213
validation.h
ContextualCheckTransaction
bool ContextualCheckTransaction(const Consensus::Params &params, const CTransaction &tx, TxValidationState &state, int nHeight, int64_t nLockTimeCutoff, int64_t nMedianTimePast)
Context dependent validity checks for non coinbase transactions.
Definition: tx_verify.cpp:40
CCoinsViewCache::AccessCoin
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
Definition: coins.cpp:180
version.h
Consensus::CheckTxInputs
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:158
CTxIn::SEQUENCE_LOCKTIME_MASK
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:91
CTransaction
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:194
IsMagneticAnomalyEnabled
bool IsMagneticAnomalyEnabled(const Consensus::Params &params, int32_t nHeight)
Check if Nov 15, 2018 HF has activated using block height.
Definition: activation.cpp:37
CTxIn::SEQUENCE_FINAL
static const uint32_t SEQUENCE_FINAL
Setting nSequence to this value for every input in a transaction disables nLockTime.
Definition: transaction.h:71
Amount::zero
static constexpr Amount zero()
Definition: amount.h:42
CTxIn::nSequence
uint32_t nSequence
Definition: transaction.h:65
TxValidationState
Definition: validation.h:137
LOCKTIME_VERIFY_SEQUENCE
static constexpr unsigned int LOCKTIME_VERIFY_SEQUENCE
Flags for nSequence and nLockTime locks.
Definition: consensus.h:38
Consensus::Params
Parameters that influence chain consensus.
Definition: params.h:59
activation.h
Consensus
Definition: blockdb.h:10
tx_verify.h
Coin
A UTXO entry.
Definition: coins.h:27
CBlockIndex::GetMedianTimePast
int64_t GetMedianTimePast() const
Definition: blockindex.h:172
MIN_TX_SIZE
static const uint64_t MIN_TX_SIZE
The minimum allowed size for a transaction, in bytes.
Definition: consensus.h:16
consensus.h
CTxIn::SEQUENCE_LOCKTIME_GRANULARITY
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:101
Amount
Definition: amount.h:19
ValidationState::Invalid
bool Invalid(Result result, const std::string &reject_reason="", const std::string &debug_message="")
Definition: validation.h:100
coins.h
TxValidationResult::TX_PREMATURE_SPEND
@ TX_PREMATURE_SPEND
transaction spends a coinbase too early, or violates locktime/sequence locks
IsFinalTx
static bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
Definition: tx_verify.cpp:19
CTransaction::GetValueOut
Amount GetValueOut() const
Definition: transaction.cpp:76
strprintf
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1201
TxValidationResult::TX_CONSENSUS
@ TX_CONSENSUS
invalid by consensus rules
CCoinsViewCache
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:231
TxValidationResult::TX_MISSING_INPUTS
@ TX_MISSING_INPUTS
transaction was missing some of its inputs
SequenceLocks
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:151
CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG
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:85
FormatMoney
std::string FormatMoney(const Amount amt)
Money parsing/formatting utilities.
Definition: moneystr.cpp:12
params.h
CCoinsViewCache::HaveInputs
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:290
Coin::GetHeight
uint32_t GetHeight() const
Definition: coins.h:44
COutPoint
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:22
CTransaction::nVersion
const int32_t nVersion
Definition: transaction.h:212
Coin::IsSpent
bool IsSpent() const
Definition: coins.h:46
CBlockIndex
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: blockindex.h:23
Coin::GetTxOut
CTxOut & GetTxOut()
Definition: coins.h:48
amount.h
PROTOCOL_VERSION
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:11
CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG
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:78
Coin::IsCoinBase
bool IsCoinBase() const
Definition: coins.h:45