diff options
Diffstat (limited to 'src/main.cpp')
-rw-r--r-- | src/main.cpp | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/src/main.cpp b/src/main.cpp index 9832259964..f19acdfbd1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -586,15 +586,13 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime) } // -// Check transaction inputs, and make sure any -// pay-to-script-hash transactions are evaluating IsStandard scripts +// Check transaction inputs to mitigate two +// potential denial-of-service attacks: // -// Why bother? To avoid denial-of-service attacks; an attacker -// can submit a standard HASH... OP_EQUAL transaction, -// which will get accepted into blocks. The redemption -// script can be anything; an attacker could use a very -// expensive-to-check-upon-redemption script like: -// DUP CHECKSIG DROP ... repeated 100 times... OP_1 +// 1. scriptSigs with extra data stuffed into them, +// not consumed by scriptPubKey (or P2SH script) +// 2. P2SH scripts with a crazy number of expensive +// CHECKSIG/CHECKMULTISIG operations // bool AreInputsStandard(const CTransaction& tx, CCoinsViewCache& mapInputs) { @@ -618,8 +616,9 @@ bool AreInputsStandard(const CTransaction& tx, CCoinsViewCache& mapInputs) // Transactions with extra stuff in their scriptSigs are // non-standard. Note that this EvalScript() call will // be quick, because if there are any operations - // beside "push data" in the scriptSig the - // IsStandard() call returns false + // beside "push data" in the scriptSig + // IsStandard() will have already returned false + // and this method isn't called. vector<vector<unsigned char> > stack; if (!EvalScript(stack, tx.vin[i].scriptSig, tx, i, false, 0)) return false; @@ -631,16 +630,20 @@ bool AreInputsStandard(const CTransaction& tx, CCoinsViewCache& mapInputs) CScript subscript(stack.back().begin(), stack.back().end()); vector<vector<unsigned char> > vSolutions2; txnouttype whichType2; - if (!Solver(subscript, whichType2, vSolutions2)) - return false; - if (whichType2 == TX_SCRIPTHASH) - return false; - - int tmpExpected; - tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2); - if (tmpExpected < 0) - return false; - nArgsExpected += tmpExpected; + if (Solver(subscript, whichType2, vSolutions2)) + { + int tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2); + if (tmpExpected < 0) + return false; + nArgsExpected += tmpExpected; + } + else + { + // Any other Script with less than 15 sigops OK: + unsigned int sigops = subscript.GetSigOpCount(true); + // ... extra data left on the stack after execution is OK, too: + return (sigops <= MAX_P2SH_SIGOPS); + } } if (stack.size() != (unsigned int)nArgsExpected) @@ -792,6 +795,16 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) int64_t GetMinFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree, enum GetMinFee_mode mode) { + { + LOCK(mempool.cs); + uint256 hash = tx.GetHash(); + double dPriorityDelta = 0; + int64_t nFeeDelta = 0; + mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta); + if (dPriorityDelta > 0 || nFeeDelta > 0) + return 0; + } + // Base fee is either minTxFee or minRelayTxFee CFeeRate baseFeeRate = (mode == GMF_RELAY) ? tx.minRelayTxFee : tx.minTxFee; @@ -3642,7 +3655,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) if (pindex) pindex = chainActive.Next(pindex); int nLimit = 500; - LogPrint("net", "getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString(), nLimit); + LogPrint("net", "getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop==uint256(0) ? "end" : hashStop.ToString(), nLimit); for (; pindex; pindex = chainActive.Next(pindex)) { if (pindex->GetBlockHash() == hashStop) |