Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 375 Lines • ▼ Show 20 Lines | if (useExistingLockPoints) { | ||||
} | } | ||||
} | } | ||||
lp->maxInputBlock = tip->GetAncestor(maxInputHeight); | lp->maxInputBlock = tip->GetAncestor(maxInputHeight); | ||||
} | } | ||||
} | } | ||||
return EvaluateSequenceLocks(index, lockPair); | return EvaluateSequenceLocks(index, lockPair); | ||||
} | } | ||||
uint64_t GetSigOpCountWithoutP2SH(const CTransaction &tx) { | uint64_t GetSigOpCountWithoutP2SH(const CTransaction &tx, uint32_t flags) { | ||||
uint64_t nSigOps = 0; | uint64_t nSigOps = 0; | ||||
for (const auto &txin : tx.vin) { | for (const auto &txin : tx.vin) { | ||||
nSigOps += txin.scriptSig.GetSigOpCount(false); | nSigOps += txin.scriptSig.GetSigOpCount(false); | ||||
} | } | ||||
for (const auto &txout : tx.vout) { | for (const auto &txout : tx.vout) { | ||||
nSigOps += txout.scriptPubKey.GetSigOpCount(false); | nSigOps += txout.scriptPubKey.GetSigOpCount(false); | ||||
} | } | ||||
return nSigOps; | return nSigOps; | ||||
} | } | ||||
uint64_t GetP2SHSigOpCount(const CTransaction &tx, | uint64_t GetP2SHSigOpCount(const CTransaction &tx, const CCoinsViewCache &view, | ||||
const CCoinsViewCache &view) { | uint32_t flags) { | ||||
if (tx.IsCoinBase()) { | if ((flags & SCRIPT_VERIFY_P2SH) == 0 || tx.IsCoinBase()) { | ||||
return 0; | return 0; | ||||
} | } | ||||
uint64_t nSigOps = 0; | uint64_t nSigOps = 0; | ||||
for (auto &i : tx.vin) { | for (auto &i : tx.vin) { | ||||
const CTxOut &prevout = view.GetOutputFor(i); | const CTxOut &prevout = view.GetOutputFor(i); | ||||
if (prevout.scriptPubKey.IsPayToScriptHash()) { | if (prevout.scriptPubKey.IsPayToScriptHash()) { | ||||
nSigOps += prevout.scriptPubKey.GetSigOpCount(i.scriptSig); | nSigOps += prevout.scriptPubKey.GetSigOpCount(i.scriptSig); | ||||
} | } | ||||
} | } | ||||
return nSigOps; | |||||
} | |||||
uint64_t GetTransactionSigOpCount(const CTransaction &tx, | |||||
const CCoinsViewCache &view, int flags) { | |||||
uint64_t nSigOps = GetSigOpCountWithoutP2SH(tx); | |||||
if (tx.IsCoinBase()) { | |||||
return nSigOps; | return nSigOps; | ||||
} | } | ||||
if (flags & SCRIPT_VERIFY_P2SH) { | uint64_t GetTransactionSigOpCount(const CTransaction &tx, | ||||
nSigOps += GetP2SHSigOpCount(tx, view); | const CCoinsViewCache &view, uint32_t flags) { | ||||
} | return GetSigOpCountWithoutP2SH(tx, flags) + | ||||
GetP2SHSigOpCount(tx, view, flags); | |||||
return nSigOps; | |||||
} | } | ||||
static bool CheckTransactionCommon(const CTransaction &tx, | static bool CheckTransactionCommon(const CTransaction &tx, | ||||
CValidationState &state, | CValidationState &state, | ||||
bool fCheckDuplicateInputs) { | bool fCheckDuplicateInputs) { | ||||
// 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(10, false, REJECT_INVALID, "bad-txns-vin-empty"); | ||||
Show All 23 Lines | for (const auto &txout : tx.vout) { | ||||
nValueOut += txout.nValue; | nValueOut += txout.nValue; | ||||
if (!MoneyRange(nValueOut)) { | if (!MoneyRange(nValueOut)) { | ||||
return state.DoS(100, false, REJECT_INVALID, | return state.DoS(100, false, REJECT_INVALID, | ||||
"bad-txns-txouttotal-toolarge"); | "bad-txns-txouttotal-toolarge"); | ||||
} | } | ||||
} | } | ||||
if (GetSigOpCountWithoutP2SH(tx) > MAX_TX_SIGOPS_COUNT) { | if (GetSigOpCountWithoutP2SH(tx, STANDARD_CHECKDATASIG_VERIFY_FLAGS) > | ||||
MAX_TX_SIGOPS_COUNT) { | |||||
return state.DoS(100, false, REJECT_INVALID, "bad-txn-sigops"); | return state.DoS(100, false, REJECT_INVALID, "bad-txn-sigops"); | ||||
} | } | ||||
// Check for duplicate inputs - note that this check is slow so we skip it | // Check for duplicate inputs - note that this check is slow so we skip it | ||||
// in CheckBlock | // in CheckBlock | ||||
if (fCheckDuplicateInputs) { | if (fCheckDuplicateInputs) { | ||||
std::set<COutPoint> vInOutPoints; | std::set<COutPoint> vInOutPoints; | ||||
for (const auto &txin : tx.vin) { | for (const auto &txin : tx.vin) { | ||||
▲ Show 20 Lines • Show All 1,642 Lines • ▼ Show 20 Lines | for (const auto &ptx : block.vtx) { | ||||
nInputs += tx.vin.size(); | nInputs += tx.vin.size(); | ||||
vPos.push_back(std::make_pair(tx.GetId(), pos)); | vPos.push_back(std::make_pair(tx.GetId(), pos)); | ||||
pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); | pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); | ||||
if (tx.IsCoinBase()) { | if (tx.IsCoinBase()) { | ||||
// We've already checked for sigops count before P2SH in CheckBlock. | // We've already checked for sigops count before P2SH in CheckBlock. | ||||
nSigOpsCount += GetSigOpCountWithoutP2SH(tx); | nSigOpsCount += GetSigOpCountWithoutP2SH(tx, flags); | ||||
} | } | ||||
if (fIsMagneticAnomalyEnabled || tx.IsCoinBase()) { | if (fIsMagneticAnomalyEnabled || tx.IsCoinBase()) { | ||||
AddCoins(view, tx, pindex->nHeight); | AddCoins(view, tx, pindex->nHeight); | ||||
} | } | ||||
} | } | ||||
for (const auto &ptx : block.vtx) { | for (const auto &ptx : block.vtx) { | ||||
▲ Show 20 Lines • Show All 1,372 Lines • ▼ Show 20 Lines | bool CheckBlock(const Config &config, const CBlock &block, | ||||
// Check transactions | // Check transactions | ||||
auto txCount = block.vtx.size(); | auto txCount = block.vtx.size(); | ||||
auto *tx = block.vtx[0].get(); | auto *tx = block.vtx[0].get(); | ||||
size_t i = 0; | size_t i = 0; | ||||
while (true) { | while (true) { | ||||
// Count the sigops for the current transaction. If the total sigops | // Count the sigops for the current transaction. If the total sigops | ||||
// count is too high, the the block is invalid. | // count is too high, the the block is invalid. | ||||
nSigOps += GetSigOpCountWithoutP2SH(*tx); | nSigOps += GetSigOpCountWithoutP2SH(*tx, STANDARD_SCRIPT_VERIFY_FLAGS); | ||||
if (nSigOps > nMaxSigOpsCount) { | if (nSigOps > nMaxSigOpsCount) { | ||||
return state.DoS(100, false, REJECT_INVALID, "bad-blk-sigops", | return state.DoS(100, false, REJECT_INVALID, "bad-blk-sigops", | ||||
false, "out-of-bounds SigOpCount"); | false, "out-of-bounds SigOpCount"); | ||||
} | } | ||||
// Go to the next transaction. | // Go to the next transaction. | ||||
i++; | i++; | ||||
▲ Show 20 Lines • Show All 2,031 Lines • Show Last 20 Lines |