MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / CheckTxInputs

Method CheckTxInputs

src/consensus/tx_verify.cpp:164–214  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

162}
163
164bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee)
165{
166 // are the actual inputs available?
167 if (!inputs.HaveInputs(tx)) {
168 return state.Invalid(TxValidationResult::TX_MISSING_INPUTS, "bad-txns-inputs-missingorspent",
169 strprintf("%s: inputs missing/spent", __func__));
170 }
171
172 CAmount nValueIn = 0;
173 for (unsigned int i = 0; i < tx.vin.size(); ++i) {
174 const COutPoint &prevout = tx.vin[i].prevout;
175 const Coin& coin = inputs.AccessCoin(prevout);
176 assert(!coin.IsSpent());
177
178 // If prev is coinbase, check that it's matured
179 if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) {
180 return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "bad-txns-premature-spend-of-coinbase",
181 strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight));
182 }
183
184 // Check for negative or overflow input values
185 nValueIn += coin.out.nValue;
186 if (!MoneyRange(coin.out.nValue) || !MoneyRange(nValueIn)) {
187 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputvalues-outofrange");
188 }
189 }
190
191 // `tx.GetValueOut()` won't throw in validation paths because output-range checks run first
192 // (`bad-txns-vout-negative`, `bad-txns-vout-toolarge`, `bad-txns-txouttotal-toolarge`):
193 // * `MemPoolAccept::PreChecks`: `CheckTransaction()` is called before this method;
194 // * `Chainstate::ConnectBlock`: `CheckTransaction()` is called via `CheckBlock()` before this method.
195 const CAmount value_out = tx.GetValueOut();
196 if (nValueIn < value_out) {
197 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-in-belowout",
198 strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(value_out)));
199 }
200
201 // Tally transaction fees
202 const CAmount txfee_aux = nValueIn - value_out;
203 if (!MoneyRange(txfee_aux)) {
204 // Unreachable, given the following preconditions:
205 // * `value_out` comes from `tx.GetValueOut()`, which throws unless `MoneyRange(value_out)` and asserts `MoneyRange(nValueOut)` on return.
206 // * `MoneyRange(nValueIn)` was enforced in the input loop.
207 // * `nValueIn < value_out` was handled above, so `nValueIn >= value_out` here (and `txfee_aux >= 0`).
208 // Therefore `0 <= txfee_aux = nValueIn - value_out <= nValueIn <= MAX_MONEY`.
209 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-fee-outofrange");
210 }
211
212 txfee = txfee_aux;
213 return true;
214}

Callers

nothing calls this directly

Calls 8

MoneyRangeFunction · 0.85
FormatMoneyFunction · 0.85
HaveInputsMethod · 0.80
InvalidMethod · 0.80
GetValueOutMethod · 0.80
sizeMethod · 0.45
IsSpentMethod · 0.45
IsCoinBaseMethod · 0.45

Tested by

no test coverage detected