LCOV - code coverage report
Current view: top level - src/policy - policy.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 67 79 84.8 %
Date: 2025-02-23 09:33:43 Functions: 7 7 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2014 The Bitcoin developers
       3             : // Distributed under the MIT software license, see the accompanying
       4             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       5             : 
       6             : // NOTE: This file is intended to be customised by the end user, and includes only local node policy logic
       7             : 
       8             : #include "policy/policy.h"
       9             : 
      10             : #include "consensus/tx_verify.h" // for IsFinal()
      11             : #include "tinyformat.h"
      12             : #include "util/system.h"
      13             : #include "utilstrencodings.h"
      14             : #include "validation.h"
      15             : 
      16             : 
      17             : bool fIsBareMultisigStd = DEFAULT_PERMIT_BAREMULTISIG;
      18             : 
      19             : CFeeRate dustRelayFee = CFeeRate(DUST_RELAY_TX_FEE);
      20             : 
      21      494857 : CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFeeIn)
      22             : {
      23             :     // "Dust" is defined in terms of dustRelayFee,
      24             :     // which has units satoshis-per-kilobyte.
      25             :     // If you'd pay more in fees than the value of the output
      26             :     // to spend something, then we consider it dust.
      27             :     // A typical spendable txout is 34 bytes big, and will
      28             :     // need a CTxIn of at least 148 bytes to spend:
      29             :     // so dust is a spendable txout less than
      30             :     // 546*dustRelayFee/1000 (in satoshis).
      31      494857 :     if (txout.scriptPubKey.IsUnspendable())
      32             :         return 0;
      33             : 
      34      494657 :     size_t nSize = GetSerializeSize(txout, 0);
      35      494657 :     nSize += (32 + 4 + 1 + 107 + 4); // the 148 mentioned above
      36      494657 :     return dustRelayFeeIn.GetFee(nSize);
      37             : }
      38             : 
      39        2086 : CAmount GetDustThreshold(const CFeeRate& dustRelayFeeIn)
      40             : {
      41             :     // return the dust threshold for a typical 34 bytes output
      42        2086 :     return dustRelayFeeIn.GetFee(182);
      43             : }
      44             : 
      45      494857 : bool IsDust(const CTxOut& txout, const CFeeRate& dustRelayFeeIn)
      46             : {
      47      494857 :     return (txout.nValue < GetDustThreshold(txout, dustRelayFeeIn));
      48             : }
      49             : 
      50        2206 : CAmount GetShieldedDustThreshold(const CFeeRate& dustRelayFeeIn)
      51             : {
      52        2206 :     unsigned int K = DEFAULT_SHIELDEDTXFEE_K;   // Fixed (100) for now
      53        2206 :     return K * dustRelayFeeIn.GetFee(SPENDDESCRIPTION_SIZE +
      54             :                                      CTXOUT_REGULAR_SIZE +
      55        2206 :                                      BINDINGSIG_SIZE);
      56             : }
      57             : 
      58             : /**
      59             :  * Check transaction inputs to mitigate two
      60             :  * potential denial-of-service attacks:
      61             :  *
      62             :  * 1. scriptSigs with extra data stuffed into them,
      63             :  *    not consumed by scriptPubKey (or P2SH script)
      64             :  * 2. P2SH scripts with a crazy number of expensive
      65             :  *    CHECKSIG/CHECKMULTISIG operations
      66             :  *
      67             :  * Check transaction inputs, and make sure any
      68             :  * pay-to-script-hash transactions are evaluating IsStandard scripts
      69             :  *
      70             :  * Why bother? To avoid denial-of-service attacks; an attacker
      71             :  * can submit a standard HASH... OP_EQUAL transaction,
      72             :  * which will get accepted into blocks. The redemption
      73             :  * script can be anything; an attacker could use a very
      74             :  * expensive-to-check-upon-redemption script like:
      75             :  *   DUP CHECKSIG DROP ... repeated 100 times... OP_1
      76             :  */
      77             : 
      78      492773 : bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType)
      79             : {
      80      985546 :     std::vector<valtype> vSolutions;
      81      492773 :     if (!Solver(scriptPubKey, whichType, vSolutions))
      82             :         return false;
      83             : 
      84      492764 :     if (whichType == TX_MULTISIG)
      85             :     {
      86           7 :         unsigned char m = vSolutions.front()[0];
      87           7 :         unsigned char n = vSolutions.back()[0];
      88             :         // Support up to x-of-3 multisig txns as standard
      89           7 :         if (n < 1 || n > 3)
      90             :             return false;
      91           6 :         if (m < 1 || m > n)
      92             :             return false;
      93      985554 :     } else if (whichType == TX_NULL_DATA &&
      94      492871 :                (!gArgs.GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER) || scriptPubKey.size() > nMaxDatacarrierBytes))
      95             :         return false;
      96             : 
      97      492762 :     return whichType != TX_NONSTANDARD;
      98             : }
      99             : 
     100      171254 : bool IsStandardTx(const CTransactionRef& tx, int nBlockHeight, std::string& reason)
     101             : {
     102      171254 :     AssertLockHeld(cs_main);
     103      171254 :     if (!Params().GetConsensus().NetworkUpgradeActive(nBlockHeight, Consensus::UPGRADE_V5_0)) {
     104             :         // Before v5, all txes with version other than STANDARD_VERSION (1) are considered non-standard
     105      168455 :         if (tx->nVersion != CTransaction::TxVersion::LEGACY) {
     106           0 :             reason = "version";
     107           0 :             return false;
     108             :         }
     109             :     }
     110             :     // After v5, all txes with a version number accepted by consensus are considered standard.
     111             : 
     112             :     // Treat non-final transactions as non-standard to prevent a specific type
     113             :     // of double-spend attack, as well as DoS attacks. (if the transaction
     114             :     // can't be mined, the attacker isn't expending resources broadcasting it)
     115             :     // Basically we don't want to propagate transactions that can't be included in
     116             :     // the next block.
     117             :     //
     118             :     // However, IsFinalTx() is confusing... Without arguments, it uses
     119             :     // chainActive.Height() to evaluate nLockTime; when a block is accepted, chainActive.Height()
     120             :     // is set to the value of nHeight in the block. However, when IsFinalTx()
     121             :     // is called within CBlock::AcceptBlock(), the height of the block *being*
     122             :     // evaluated is what is used. Thus if we want to know if a transaction can
     123             :     // be part of the *next* block, we need to call IsFinalTx() with one more
     124             :     // than chainActive.Height().
     125             :     //
     126             :     // Timestamps on the other hand don't get any special treatment, because we
     127             :     // can't know what timestamp the next block will have, and there aren't
     128             :     // timestamp applications where it matters.
     129      171254 :     if (!IsFinalTx(tx, nBlockHeight)) {
     130           0 :         reason = "non-final";
     131           0 :         return false;
     132             :     }
     133             : 
     134             :     // Extremely large transactions with lots of inputs can cost the network
     135             :     // almost as much to process as they cost the sender in fees, because
     136             :     // computing signature hashes is O(ninputs*txsize). Limiting transactions
     137             :     // to MAX_STANDARD_TX_SIZE mitigates CPU exhaustion attacks.
     138      171254 :     unsigned int sz = tx->GetTotalSize();
     139      171254 :     unsigned int nMaxSize = tx->IsShieldedTx() ? MAX_TX_SIZE_AFTER_SAPLING : MAX_STANDARD_TX_SIZE;
     140      171254 :     if (sz >= nMaxSize) {
     141           0 :         reason = "tx-size";
     142           0 :         return false;
     143             :     }
     144             : 
     145      499576 :     for (const CTxIn& txin : tx->vin) {
     146             :         // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
     147             :         // keys. (remember the 520 byte limit on redeemScript size) That works
     148             :         // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627
     149             :         // bytes of scriptSig, which we round off to 1650 bytes for some minor
     150             :         // future-proofing. That's also enough to spend a 20-of-20
     151             :         // CHECKMULTISIG scriptPubKey, though such a scriptPubKey is not
     152             :         // considered standard)
     153      637968 :         if (txin.scriptSig.size() > 1650) {
     154           0 :             reason = "scriptsig-size";
     155           0 :             return false;
     156             :         }
     157      328322 :         if (!txin.scriptSig.IsPushOnly()) {
     158           0 :             reason = "scriptsig-not-pushonly";
     159           0 :             return false;
     160             :         }
     161             :     }
     162             : 
     163      171254 :     unsigned int nDataOut = 0;
     164      171254 :     txnouttype whichType;
     165      664011 :     for (const CTxOut& txout : tx->vout) {
     166      492763 :         if (!::IsStandard(txout.scriptPubKey, whichType)) {
     167           4 :             reason = "scriptpubkey";
     168           6 :             return false;
     169             :         }
     170             : 
     171      492759 :         if (whichType == TX_NULL_DATA)
     172          39 :             nDataOut++;
     173      492720 :         else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) {
     174           0 :             reason = "bare-multisig";
     175           0 :             return false;
     176      492720 :         } else if (IsDust(txout, dustRelayFee)) {
     177           2 :             reason = "dust";
     178           2 :             return false;
     179             :         }
     180             :     }
     181             : 
     182             :     // only one OP_RETURN txout is permitted
     183      171248 :     if (nDataOut > 1) {
     184           3 :         reason = "multi-op-return";
     185           3 :         return false;
     186             :     }
     187             : 
     188             :     return true;
     189             : }
     190             : 
     191      171150 : bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
     192             : {
     193      171150 :     if (tx.IsCoinBase()) {
     194             :         return true; // coinbases don't use vin normally
     195             :     }
     196             : 
     197      499373 :     for (unsigned int i = 0; i < tx.vin.size(); i++) {
     198      328225 :         const CTxOut& prev = mapInputs.AccessCoin(tx.vin[i].prevout).out;
     199             : 
     200      656448 :         std::vector<std::vector<unsigned char> > vSolutions;
     201      328225 :         txnouttype whichType;
     202             :         // get the scriptPubKey corresponding to this input:
     203      328225 :         const CScript& prevScript = prev.scriptPubKey;
     204      328225 :         if (!Solver(prevScript, whichType, vSolutions))
     205           2 :             return false;
     206             : 
     207      328225 :         if (whichType == TX_SCRIPTHASH)
     208             :         {
     209       18689 :             std::vector<std::vector<unsigned char> > stack;
     210             :             // convert the scriptSig into a stack, so we can inspect the redeemScript
     211       37378 :             if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), tx.GetRequiredSigVersion()))
     212           2 :                 return false;
     213       18689 :             if (stack.empty())
     214             :                 return false;
     215       37376 :             CScript subscript(stack.back().begin(), stack.back().end());
     216       18689 :             if (subscript.GetSigOpCount(true) > MAX_P2SH_SIGOPS) {
     217           4 :                 return false;
     218             :             }
     219             :         }
     220             :     }
     221             : 
     222             :     return true;
     223             : }

Generated by: LCOV version 1.14