Changeset View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 475 Lines • ▼ Show 20 Lines | |||||
static uint32_t GetStandardScriptFlags(const Consensus::Params ¶ms, | static uint32_t GetStandardScriptFlags(const Consensus::Params ¶ms, | ||||
const CBlockIndex *pindexTip) { | const CBlockIndex *pindexTip) { | ||||
uint32_t flags = STANDARD_SCRIPT_VERIFY_FLAGS; | uint32_t flags = STANDARD_SCRIPT_VERIFY_FLAGS; | ||||
// Disable input sigchecks limit for mempool admission, prior to its | // Disable input sigchecks limit for mempool admission, prior to its | ||||
// proper activation. | // proper activation. | ||||
flags &= ~SCRIPT_VERIFY_INPUT_SIGCHECKS; | flags &= ~SCRIPT_VERIFY_INPUT_SIGCHECKS; | ||||
if (IsPhononEnabled(params, pindexTip)) { | |||||
flags |= SCRIPT_REPORT_SIGCHECKS; | |||||
} | |||||
// We make sure this node will have replay protection during the next hard | // We make sure this node will have replay protection during the next hard | ||||
// fork. | // fork. | ||||
if (IsReplayProtectionEnabled(params, pindexTip)) { | if (IsReplayProtectionEnabled(params, pindexTip)) { | ||||
flags |= SCRIPT_ENABLE_REPLAY_PROTECTION; | flags |= SCRIPT_ENABLE_REPLAY_PROTECTION; | ||||
} | } | ||||
return flags; | return flags; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 228 Lines • ▼ Show 20 Lines | for (const CTxIn &txin : tx.vin) { | ||||
PrecomputedTransactionData txdata(tx); | PrecomputedTransactionData txdata(tx); | ||||
int nSigChecksStandard; | int nSigChecksStandard; | ||||
if (!CheckInputs(tx, state, view, true, scriptVerifyFlags, true, false, | if (!CheckInputs(tx, state, view, true, scriptVerifyFlags, true, false, | ||||
txdata, nSigChecksStandard)) { | txdata, nSigChecksStandard)) { | ||||
// State filled in by CheckInputs. | // State filled in by CheckInputs. | ||||
return false; | return false; | ||||
} | } | ||||
// After the sigchecks activation we repurpose the 'sigops' tracking in | |||||
// mempool/mining to actually track sigchecks instead. (Proper SigOps | |||||
// will not need to be counted any more since it's getting deactivated.) | |||||
auto nSigChecksOrOps = | |||||
(nextBlockScriptVerifyFlags & SCRIPT_REPORT_SIGCHECKS) | |||||
? nSigChecksStandard | |||||
: nSigOpsCount; | |||||
deadalnix: This is really trashy, but we'll have to live with this for a few month. Please keep in mind to… | |||||
markblundebergAuthorUnsubmitted Done Inline ActionsYep, trashy is the right word. :D markblundeberg: Yep, trashy is the right word. :D | |||||
CTxMemPoolEntry entry(ptx, nFees, nAcceptTime, chainActive.Height(), | CTxMemPoolEntry entry(ptx, nFees, nAcceptTime, chainActive.Height(), | ||||
fSpendsCoinbase, nSigOpsCount, lp); | fSpendsCoinbase, nSigChecksOrOps, lp); | ||||
unsigned int nVirtualSize = entry.GetTxVirtualSize(); | unsigned int nVirtualSize = entry.GetTxVirtualSize(); | ||||
Amount mempoolRejectFee = | Amount mempoolRejectFee = | ||||
pool.GetMinFee( | pool.GetMinFee( | ||||
gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * | gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * | ||||
1000000) | 1000000) | ||||
.GetFee(nVirtualSize); | .GetFee(nVirtualSize); | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | for (const CTxIn &txin : tx.vin) { | ||||
// This can occur under some circumstances, if the node receives an | // This can occur under some circumstances, if the node receives an | ||||
// unrequested tx which is invalid due to new consensus rules not | // unrequested tx which is invalid due to new consensus rules not | ||||
// being activated yet (during IBD). | // being activated yet (during IBD). | ||||
return error("%s: BUG! PLEASE REPORT THIS! CheckInputs failed " | return error("%s: BUG! PLEASE REPORT THIS! CheckInputs failed " | ||||
"against next-block but not STANDARD flags %s, %s", | "against next-block but not STANDARD flags %s, %s", | ||||
__func__, txid.ToString(), FormatStateMessage(state)); | __func__, txid.ToString(), FormatStateMessage(state)); | ||||
} | } | ||||
if (nSigChecksStandard != nSigChecksConsensus) { | |||||
// We can't accept this transaction as we've used the standard count | |||||
// for the mempool/mining, but the consensus count will be enforced | |||||
// in validation (we don't want to produce bad block templates). | |||||
return error( | |||||
"%s: BUG! PLEASE REPORT THIS! SigChecks count differed between " | |||||
"standard and consensus flags in %s", | |||||
__func__, txid.ToString()); | |||||
} | |||||
if (test_accept) { | if (test_accept) { | ||||
// Tx was accepted, but not added | // Tx was accepted, but not added | ||||
return true; | return true; | ||||
} | } | ||||
// Store transaction in memory. | // Store transaction in memory. | ||||
pool.addUnchecked(entry, setAncestors); | pool.addUnchecked(entry, setAncestors); | ||||
▲ Show 20 Lines • Show All 856 Lines • ▼ Show 20 Lines | static uint32_t GetNextBlockScriptFlags(const Consensus::Params ¶ms, | ||||
} | } | ||||
if (IsGravitonEnabled(params, pindex)) { | if (IsGravitonEnabled(params, pindex)) { | ||||
flags |= SCRIPT_ENABLE_SCHNORR_MULTISIG; | flags |= SCRIPT_ENABLE_SCHNORR_MULTISIG; | ||||
flags |= SCRIPT_VERIFY_MINIMALDATA; | flags |= SCRIPT_VERIFY_MINIMALDATA; | ||||
} | } | ||||
if (IsPhononEnabled(params, pindex)) { | if (IsPhononEnabled(params, pindex)) { | ||||
flags |= SCRIPT_REPORT_SIGCHECKS; | |||||
flags |= SCRIPT_ZERO_SIGOPS; | flags |= SCRIPT_ZERO_SIGOPS; | ||||
deadalnixUnsubmitted Done Inline ActionsIs that important that both flags are different? deadalnix: Is that important that both flags are different? | |||||
markblundebergAuthorUnsubmitted Done Inline ActionsI prefer it that way... they are both going to be removed anyway so those bits will be freed up soon enough. This diff definitely does need to turn on this flag though. markblundeberg: I prefer it that way... they are both going to be removed anyway so those bits will be freed up… | |||||
} | } | ||||
// We make sure this node will have replay protection during the next hard | // We make sure this node will have replay protection during the next hard | ||||
// fork. | // fork. | ||||
if (IsReplayProtectionEnabled(params, pindex)) { | if (IsReplayProtectionEnabled(params, pindex)) { | ||||
flags |= SCRIPT_ENABLE_REPLAY_PROTECTION; | flags |= SCRIPT_ENABLE_REPLAY_PROTECTION; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 190 Lines • ▼ Show 20 Lines | bool CChainState::ConnectBlock(const CBlock &block, CValidationState &state, | ||||
int nInputs = 0; | int nInputs = 0; | ||||
// Sigops counting. We need to do it again because of P2SH. | // Sigops counting. We need to do it again because of P2SH. | ||||
uint64_t nSigOpsCount = 0; | uint64_t nSigOpsCount = 0; | ||||
const uint64_t currentBlockSize = | const uint64_t currentBlockSize = | ||||
::GetSerializeSize(block, PROTOCOL_VERSION); | ::GetSerializeSize(block, PROTOCOL_VERSION); | ||||
const uint64_t nMaxSigOpsCount = GetMaxBlockSigOpsCount(currentBlockSize); | const uint64_t nMaxSigOpsCount = GetMaxBlockSigOpsCount(currentBlockSize); | ||||
CheckInputsLimiter nSigChecksBlockLimiter( | |||||
deadalnixUnsubmitted Done Inline ActionsI'm not sure how CheckInputsLimiter came to be named that way, but it obviously suck. It doesn't say what it is limiting (so the name don't give any meaningful info as to what this *IS*), but it does say what it is passed to, which is an abstraction failure. Imagine if you buy a car to go to work, and so you decide to call it a workgoer instead of a car. Well then it gets very confusing when everybody starts to use the workgoer to go to the gym, in holidays, or wherever. deadalnix: I'm not sure how `CheckInputsLimiter` came to be named that way, but it obviously suck. It… | |||||
markblundebergAuthorUnsubmitted Done Inline ActionsPerhaps. We can rename it later. markblundeberg: Perhaps. We can rename it later. | |||||
GetMaxBlockSigChecksCount(options.getExcessiveBlockSize())); | |||||
blockundo.vtxundo.reserve(block.vtx.size() - 1); | blockundo.vtxundo.reserve(block.vtx.size() - 1); | ||||
// Add all outputs | // Add all outputs | ||||
try { | try { | ||||
for (const auto &ptx : block.vtx) { | for (const auto &ptx : block.vtx) { | ||||
AddCoins(view, *ptx, pindex->nHeight); | AddCoins(view, *ptx, pindex->nHeight); | ||||
} | } | ||||
} catch (const std::logic_error &e) { | } catch (const std::logic_error &e) { | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | for (const auto &ptx : block.vtx) { | ||||
bool fCacheResults = fJustCheck; | bool fCacheResults = fJustCheck; | ||||
std::vector<CScriptCheck> vChecks; | std::vector<CScriptCheck> vChecks; | ||||
// nSigChecksRet may be accurate (found in cache) or 0 (checks were | // nSigChecksRet may be accurate (found in cache) or 0 (checks were | ||||
// deferred into vChecks). | // deferred into vChecks). | ||||
int nSigChecksRet; | int nSigChecksRet; | ||||
if (!CheckInputs(tx, state, view, fScriptChecks, flags, fCacheResults, | if (!CheckInputs(tx, state, view, fScriptChecks, flags, fCacheResults, | ||||
fCacheResults, PrecomputedTransactionData(tx), | fCacheResults, PrecomputedTransactionData(tx), | ||||
nSigChecksRet, &vChecks)) { | nSigChecksRet, &vChecks, &nSigChecksBlockLimiter)) { | ||||
// Parallel CheckInputs shouldn't fail except for this reason, which | |||||
// is banworthy. Use "blk-bad-inputs" to mimic the parallel script | |||||
// check error. | |||||
if (!nSigChecksBlockLimiter.check()) { | |||||
return state.DoS(100, false, REJECT_INVALID, "blk-bad-inputs", | |||||
false, "CheckInputs exceeded SigChecks limit"); | |||||
} | |||||
return error("ConnectBlock(): CheckInputs on %s failed with %s", | return error("ConnectBlock(): CheckInputs on %s failed with %s", | ||||
tx.GetId().ToString(), FormatStateMessage(state)); | tx.GetId().ToString(), FormatStateMessage(state)); | ||||
} | } | ||||
control.Add(vChecks); | control.Add(vChecks); | ||||
blockundo.vtxundo.push_back(CTxUndo()); | blockundo.vtxundo.push_back(CTxUndo()); | ||||
// Note: this must execute in the same iteration as CheckTxInputs (not | // Note: this must execute in the same iteration as CheckTxInputs (not | ||||
▲ Show 20 Lines • Show All 3,838 Lines • Show Last 20 Lines |
This is really trashy, but we'll have to live with this for a few month. Please keep in mind to clean this up.