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

Function CheckInputScripts

src/validation.cpp:1739–1826  ·  view source on GitHub ↗

* Check whether all of this transaction's input scripts succeed. * * This involves ECDSA signature checks so can be computationally intensive. This function should * only be called after the cheap sanity checks in CheckTxInputs passed. * * If pvChecks is not nullptr, script checks are pushed onto it instead of being performed inline. Any * script checks which are not necessary (eg due to scr

Source from the content-addressed store, hash-verified

1737 * Non-static (and re-declared) in src/test/txvalidationcache_tests.cpp
1738 */
1739bool CheckInputScripts(const CTransaction& tx, TxValidationState& state,
1740 const CCoinsViewCache& inputs, unsigned int flags, bool cacheSigStore,
1741 bool cacheFullScriptStore, PrecomputedTransactionData& txdata,
1742 std::vector<CCheck*>* pvChecks)
1743{
1744 if (tx.IsCoinBase()) return true;
1745
1746 if (pvChecks) {
1747 pvChecks->reserve(tx.vin.size());
1748 }
1749
1750 // First check if script executions have been cached with the same
1751 // flags. Note that this assumes that the inputs provided are
1752 // correct (ie that the transaction hash which is in tx's prevouts
1753 // properly commits to the scriptPubKey in the inputs view of that
1754 // transaction).
1755 uint256 hashCacheEntry;
1756 CSHA256 hasher = g_scriptExecutionCacheHasher;
1757 hasher.Write(tx.GetWitnessHash().begin(), 32).Write((unsigned char*)&flags, sizeof(flags)).Finalize(hashCacheEntry.begin());
1758 AssertLockHeld(cs_main); //TODO: Remove this requirement by making CuckooCache not require external locks
1759 if (g_scriptExecutionCache.contains(hashCacheEntry, !cacheFullScriptStore)) {
1760 return true;
1761 }
1762
1763 if (!txdata.m_spent_outputs_ready) {
1764 std::vector<CTxOut> spent_outputs;
1765 spent_outputs.reserve(tx.vin.size());
1766
1767 for (unsigned int i = 0; i < tx.vin.size(); i++) {
1768 const COutPoint& prevout = tx.vin[i].prevout;
1769 // ELEMENTS:
1770 // If input is peg-in, create "coin" to evaluate against
1771 Coin pegin_coin;
1772 if (tx.vin[i].m_is_pegin) {
1773 // Height of "output" in script evaluation will be 0
1774 pegin_coin = Coin(GetPeginOutputFromWitness(tx.witness.vtxinwit[i].m_pegin_witness), 0, false);
1775 }
1776 const Coin& coin = tx.vin[i].m_is_pegin ? pegin_coin : inputs.AccessCoin(prevout);
1777 // end ELEMENTS
1778 assert(!coin.IsSpent());
1779 spent_outputs.emplace_back(coin.out);
1780 }
1781 txdata.Init(tx, std::move(spent_outputs));
1782 }
1783 assert(txdata.m_spent_outputs.size() == tx.vin.size());
1784
1785 for (unsigned int i = 0; i < tx.vin.size(); i++) {
1786 // We very carefully only pass in things to CScriptCheck which
1787 // are clearly committed to by tx' witness hash. This provides
1788 // a sanity check that our caching is not introducing consensus
1789 // failures through additional data in, eg, the coins being
1790 // spent being checked as a part of CScriptCheck.
1791
1792 // Verify signature
1793 CCheck* check = new CScriptCheck(txdata.m_spent_outputs[i], tx, i, flags, cacheSigStore, &txdata);
1794 ScriptError serror = QueueCheck(pvChecks, check);
1795 if (serror != SCRIPT_ERR_OK) {
1796 // Tx failures never trigger disconnections/bans.

Callers 5

validation.cppFile · 0.85
PolicyScriptChecksMethod · 0.85
ConnectBlockMethod · 0.85
EXCLUSIVE_LOCKS_REQUIREDFunction · 0.85
BOOST_FIXTURE_TEST_CASEFunction · 0.85

Calls 15

QueueCheckFunction · 0.85
ScriptErrorStringFunction · 0.85
emplace_backMethod · 0.80
InvalidMethod · 0.80
CoinClass · 0.70
IsCoinBaseMethod · 0.45
reserveMethod · 0.45
sizeMethod · 0.45
FinalizeMethod · 0.45
WriteMethod · 0.45
beginMethod · 0.45

Tested by 2

EXCLUSIVE_LOCKS_REQUIREDFunction · 0.68
BOOST_FIXTURE_TEST_CASEFunction · 0.68