MCPcopy Create free account
hub / github.com/ElementsProject/elements / CheckTxInputs

Method CheckTxInputs

src/consensus/tx_verify.cpp:195–277  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

193}
194
195bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmountMap& fee_map, std::set<std::pair<uint256, COutPoint>>& setPeginsSpent, std::vector<CCheck*> *pvChecks, const bool cacheStore, bool fScriptChecks, const std::vector<std::pair<CScript, CScript>>& fedpegscripts)
196{
197 // are the actual inputs available?
198 if (!inputs.HaveInputs(tx)) {
199 return state.Invalid(TxValidationResult::TX_MISSING_INPUTS, "bad-txns-inputs-missingorspent",
200 strprintf("%s: inputs missing/spent", __func__));
201 }
202
203 std::vector<CTxOut> spent_inputs;
204 CAmount nValueIn = 0;
205 for (unsigned int i = 0; i < tx.vin.size(); ++i) {
206 const COutPoint &prevout = tx.vin[i].prevout;
207 if (tx.vin[i].m_is_pegin) {
208 // Check existence and validity of pegin witness
209 std::string err;
210 if (tx.witness.vtxinwit.size() <= i || !IsValidPeginWitness(tx.witness.vtxinwit[i].m_pegin_witness, fedpegscripts, prevout, err, true)) {
211 return state.Invalid(TxValidationResult::TX_WITNESS_MUTATED, "bad-pegin-witness", err);
212 }
213 std::pair<uint256, COutPoint> pegin = std::make_pair(uint256(tx.witness.vtxinwit[i].m_pegin_witness.stack[2]), prevout);
214 if (inputs.IsPeginSpent(pegin)) {
215 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-double-pegin", strprintf("Double-pegin of %s:%d", prevout.hash.ToString(), prevout.n));
216 }
217 if (setPeginsSpent.count(pegin)) {
218 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-double-pegin-in-obj",
219 strprintf("Double-pegin of %s:%d in single tx/block", prevout.hash.ToString(), prevout.n));
220 }
221 setPeginsSpent.insert(pegin);
222
223 // Tally the input amount.
224 spent_inputs.push_back(GetPeginOutputFromWitness(tx.witness.vtxinwit[i].m_pegin_witness));
225 const CTxOut& out = spent_inputs.back();
226 nValueIn += out.nValue.GetAmount(); // Non-explicit already filtered by IsValidPeginWitness
227 if (!MoneyRange(out.nValue.GetAmount())) {
228 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputvalues-outofrange");
229 }
230 } else {
231 const Coin& coin = inputs.AccessCoin(prevout);
232 assert(!coin.IsSpent());
233
234 // If prev is coinbase, check that it's matured
235 if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) {
236 return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "bad-txns-premature-spend-of-coinbase",
237 strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight));
238 }
239 spent_inputs.push_back(coin.out);
240 if (coin.out.nValue.IsExplicit()) {
241 nValueIn += coin.out.nValue.GetAmount();
242 }
243 }
244 }
245
246 if (g_con_elementsmode) {
247 // Tally transaction fees
248 if (!HasValidFee(tx)) {
249 return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-fee-outofrange");
250 }
251
252 // Verify that amounts add up.

Callers

nothing calls this directly

Calls 15

IsValidPeginWitnessFunction · 0.85
HasValidFeeFunction · 0.85
VerifyAmountsFunction · 0.85
GetFeeMapFunction · 0.85
CAssetClass · 0.85
FormatMoneyFunction · 0.85
HaveInputsMethod · 0.80
InvalidMethod · 0.80
countMethod · 0.80
GetAmountMethod · 0.80
IsExplicitMethod · 0.80

Tested by

no test coverage detected