Changeset View
Changeset View
Standalone View
Standalone View
src/consensus/tx_check.cpp
// Copyright (c) 2017-2018 The Bitcoin Core developers | // Copyright (c) 2017-2018 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include <coins.h> | #include <coins.h> | ||||
#include <consensus/consensus.h> | #include <consensus/consensus.h> | ||||
#include <consensus/validation.h> | #include <consensus/validation.h> | ||||
#include <primitives/transaction.h> | #include <primitives/transaction.h> | ||||
#include <version.h> | #include <version.h> | ||||
#include <unordered_set> | #include <unordered_set> | ||||
static bool CheckTransactionCommon(const CTransaction &tx, | static bool CheckTransactionCommon(const CTransaction &tx, | ||||
CValidationState &state) { | CValidationState &state) { | ||||
// Basic checks that don't depend on any context | // Basic checks that don't depend on any context | ||||
if (tx.vin.empty()) { | if (tx.vin.empty()) { | ||||
return state.DoS(10, false, REJECT_INVALID, "bad-txns-vin-empty"); | return state.DoS(100, false, REJECT_INVALID, "bad-txns-vin-empty"); | ||||
} | } | ||||
if (tx.vout.empty()) { | if (tx.vout.empty()) { | ||||
return state.DoS(10, false, REJECT_INVALID, "bad-txns-vout-empty"); | return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-empty"); | ||||
} | } | ||||
// Size limit | // Size limit | ||||
if (::GetSerializeSize(tx, PROTOCOL_VERSION) > MAX_TX_SIZE) { | if (::GetSerializeSize(tx, PROTOCOL_VERSION) > MAX_TX_SIZE) { | ||||
return state.DoS(100, false, REJECT_INVALID, "bad-txns-oversize"); | return state.DoS(100, false, REJECT_INVALID, "bad-txns-oversize"); | ||||
} | } | ||||
// Check for negative or overflow output values | // Check for negative or overflow output values | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | bool CheckRegularTransaction(const CTransaction &tx, CValidationState &state) { | ||||
if (!CheckTransactionCommon(tx, state)) { | if (!CheckTransactionCommon(tx, state)) { | ||||
// CheckTransactionCommon fill in the state. | // CheckTransactionCommon fill in the state. | ||||
return false; | return false; | ||||
} | } | ||||
std::unordered_set<COutPoint, SaltedOutpointHasher> vInOutPoints; | std::unordered_set<COutPoint, SaltedOutpointHasher> vInOutPoints; | ||||
for (const auto &txin : tx.vin) { | for (const auto &txin : tx.vin) { | ||||
if (txin.prevout.IsNull()) { | if (txin.prevout.IsNull()) { | ||||
return state.DoS(10, false, REJECT_INVALID, | return state.DoS(100, false, REJECT_INVALID, | ||||
"bad-txns-prevout-null"); | "bad-txns-prevout-null"); | ||||
} | } | ||||
if (!vInOutPoints.insert(txin.prevout).second) { | if (!vInOutPoints.insert(txin.prevout).second) { | ||||
return state.DoS(100, false, REJECT_INVALID, | return state.DoS(100, false, REJECT_INVALID, | ||||
"bad-txns-inputs-duplicate"); | "bad-txns-inputs-duplicate"); | ||||
} | } | ||||
} | } | ||||
return true; | return true; | ||||
} | } |