diff options
author | John Newbery <john@johnnewbery.com> | 2019-04-02 13:41:12 -0400 |
---|---|---|
committer | John Newbery <john@johnnewbery.com> | 2019-04-09 17:53:08 -0400 |
commit | fdf8888b6f0c63e8a4cb1459752625e642d6a4dd (patch) | |
tree | f68fbaf3d09a60b9dd63abb5be6bc079d0a0cdb5 /src/consensus/tx_check.cpp | |
parent | 93de9abe6d6847bce6db8da15f15b50b01972e70 (diff) | |
download | bitcoin-fdf8888b6f0c63e8a4cb1459752625e642d6a4dd.tar.xz |
[build] Move CheckTransaction from lib_server to lib_consensus
CheckTransaction is a context-free function that does not require access
to the blockchain or mempool. Move it from src/consensus/tx_verify in
lib_server to a new unit src/consensus/tx_check in lib_consensus so that
it can be called by non-server libraries.
Diffstat (limited to 'src/consensus/tx_check.cpp')
-rw-r--r-- | src/consensus/tx_check.cpp | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/src/consensus/tx_check.cpp b/src/consensus/tx_check.cpp new file mode 100644 index 0000000000..61a607ef7f --- /dev/null +++ b/src/consensus/tx_check.cpp @@ -0,0 +1,57 @@ +// Copyright (c) 2017-2018 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, CValidationState &state, bool fCheckDuplicateInputs) +{ + // Basic checks that don't depend on any context + if (tx.vin.empty()) + return state.DoS(10, false, REJECT_INVALID, "bad-txns-vin-empty"); + if (tx.vout.empty()) + return state.DoS(10, false, REJECT_INVALID, "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) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT) + return state.DoS(100, false, REJECT_INVALID, "bad-txns-oversize"); + + // Check for negative or overflow output values + CAmount nValueOut = 0; + for (const auto& txout : tx.vout) + { + if (txout.nValue < 0) + return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-negative"); + if (txout.nValue > MAX_MONEY) + return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-toolarge"); + nValueOut += txout.nValue; + if (!MoneyRange(nValueOut)) + return state.DoS(100, false, REJECT_INVALID, "bad-txns-txouttotal-toolarge"); + } + + // Check for duplicate inputs - note that this check is slow so we skip it in CheckBlock + if (fCheckDuplicateInputs) { + std::set<COutPoint> vInOutPoints; + for (const auto& txin : tx.vin) + { + if (!vInOutPoints.insert(txin.prevout).second) + return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-duplicate"); + } + } + + if (tx.IsCoinBase()) + { + if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100) + return state.DoS(100, false, REJECT_INVALID, "bad-cb-length"); + } + else + { + for (const auto& txin : tx.vin) + if (txin.prevout.IsNull()) + return state.DoS(10, false, REJECT_INVALID, "bad-txns-prevout-null"); + } + + return true; +} |