git / moonbite-core / src/consensus/tx_check.cpp · raw

// Copyright (c) 2017-2019 The Bitcoin Core developers// Distributed under the MIT software license, see the accompanying// file COPYING or http://www.opensource.org/licenses/mit-license.php.#include <consensus/tx_check.h>#include <primitives/transaction.h>#include <consensus/validation.h>bool CheckTransaction(const CTransaction& tx, TxValidationState& state){    // Basic checks that don't depend on any context    if (!tx.IsMWEBOnly()) {        // MoonBite: the first HogEx after MWEB activation has no previous        // HogAddr to spend and, with no peg-ins in that block, no inputs at        // all. Upstream rejects it here, which stalls the chain at the        // activation height whenever the activation block carries no peg-in.        // HogEx inputs/outputs are fully validated by MWEB::Node instead.        if (tx.vin.empty() && !tx.IsHogEx())            return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vin-empty");        if (tx.vout.empty())            return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-empty");    }	    // Size limits (this doesn't take the witness into account, as that hasn't been checked for malleability)    if (::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS | SERIALIZE_NO_MWEB) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT)        return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-oversize");    // Check for negative or overflow output values (see CVE-2010-5139)    CAmount nValueOut = 0;    for (const auto& txout : tx.vout)    {        if (txout.nValue < 0)            return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-negative");        if (txout.nValue > MAX_MONEY)            return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-toolarge");        nValueOut += txout.nValue;        if (!MoneyRange(nValueOut))            return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-txouttotal-toolarge");    }    // Check for duplicate inputs (see CVE-2018-17144)    // While Consensus::CheckTxInputs does check if all inputs of a tx are available, and UpdateCoins marks all inputs    // of a tx as spent, it does not check if the tx has duplicate inputs.    // Failure to run this check will result in either a crash or an inflation bug, depending on the implementation of    // the underlying coins database.    std::set<COutPoint> vInOutPoints;    for (const auto& txin : tx.vin) {        if (!vInOutPoints.insert(txin.prevout).second)            return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputs-duplicate");    }    if (tx.IsCoinBase())    {        if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)            return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-cb-length");    }    else    {        for (const auto& txin : tx.vin)            if (txin.prevout.IsNull())                return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-prevout-null");    }    return true;}