| 1788 | } |
| 1789 | |
| 1790 | bool CheckInputScripts(const CTransaction &tx, TxValidationState &state, |
| 1791 | const CCoinsViewCache &inputs, const uint32_t flags, |
| 1792 | bool sigCacheStore, bool scriptCacheStore, |
| 1793 | const PrecomputedTransactionData &txdata, |
| 1794 | ValidationCache &validation_cache, int &nSigChecksOut, |
| 1795 | TxSigCheckLimiter &txLimitSigChecks, |
| 1796 | CheckInputsLimiter *pBlockLimitSigChecks, |
| 1797 | std::vector<CScriptCheck> *pvChecks) { |
| 1798 | AssertLockHeld(cs_main); |
| 1799 | assert(!tx.IsCoinBase()); |
| 1800 | |
| 1801 | if (pvChecks) { |
| 1802 | pvChecks->reserve(tx.vin.size()); |
| 1803 | } |
| 1804 | |
| 1805 | // First check if script executions have been cached with the same flags. |
| 1806 | // Note that this assumes that the inputs provided are correct (ie that the |
| 1807 | // transaction hash which is in tx's prevouts properly commits to the |
| 1808 | // scriptPubKey in the inputs view of that transaction). |
| 1809 | ScriptCacheKey hashCacheEntry( |
| 1810 | tx, flags, validation_cache.ScriptExecutionCacheHasher()); |
| 1811 | ScriptCacheElement elem(hashCacheEntry, 0); |
| 1812 | bool found_in_cache = validation_cache.m_script_execution_cache.get( |
| 1813 | elem, /*erase=*/!scriptCacheStore); |
| 1814 | nSigChecksOut = elem.nSigChecks; |
| 1815 | if (found_in_cache) { |
| 1816 | if (!txLimitSigChecks.consume_and_check(nSigChecksOut) || |
| 1817 | (pBlockLimitSigChecks && |
| 1818 | !pBlockLimitSigChecks->consume_and_check(nSigChecksOut))) { |
| 1819 | return state.Invalid(TxValidationResult::TX_CONSENSUS, |
| 1820 | "too-many-sigchecks"); |
| 1821 | } |
| 1822 | return true; |
| 1823 | } |
| 1824 | |
| 1825 | int nSigChecksTotal = 0; |
| 1826 | |
| 1827 | for (size_t i = 0; i < tx.vin.size(); i++) { |
| 1828 | const COutPoint &prevout = tx.vin[i].prevout; |
| 1829 | const Coin &coin = inputs.AccessCoin(prevout); |
| 1830 | assert(!coin.IsSpent()); |
| 1831 | |
| 1832 | // We very carefully only pass in things to CScriptCheck which are |
| 1833 | // clearly committed to by tx's hash. This provides a sanity |
| 1834 | // check that our caching is not introducing consensus failures through |
| 1835 | // additional data in, eg, the coins being spent being checked as a part |
| 1836 | // of CScriptCheck. |
| 1837 | |
| 1838 | // Verify signature |
| 1839 | CScriptCheck check( |
| 1840 | coin.GetTxOut(), tx, validation_cache.m_signature_cache, i, flags, |
| 1841 | sigCacheStore, txdata, &txLimitSigChecks, pBlockLimitSigChecks); |
| 1842 | |
| 1843 | // If pvChecks is not null, defer the check execution to the caller. |
| 1844 | if (pvChecks) { |
| 1845 | pvChecks->push_back(std::move(check)); |
| 1846 | continue; |
| 1847 | } |