diff options
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 70 |
1 files changed, 37 insertions, 33 deletions
diff --git a/src/main.cpp b/src/main.cpp index a43eef07b..c8ea62758 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -69,11 +69,16 @@ bool fHavePruned = false; bool fPruneMode = false; bool fIsBareMultisigStd = DEFAULT_PERMIT_BAREMULTISIG; bool fRequireStandard = true; +unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP; bool fCheckBlockIndex = false; bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED; size_t nCoinCacheUsage = 5000 * 300; uint64_t nPruneTarget = 0; bool fAlerts = DEFAULT_ALERTS; +/* If the tip is older than this (in seconds), the node is considered to be in initial block download. + */ +int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; +bool fPermitReplacement = DEFAULT_PERMIT_REPLACEMENT; /** Fees smaller than this (in satoshi) are considered zero fee (for relaying, mining and transaction creation) */ CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE); @@ -84,8 +89,8 @@ struct COrphanTx { CTransaction tx; NodeId fromPeer; }; -map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(cs_main);; -map<uint256, set<uint256> > mapOrphanTransactionsByPrev GUARDED_BY(cs_main);; +map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(cs_main); +map<uint256, set<uint256> > mapOrphanTransactionsByPrev GUARDED_BY(cs_main); void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main); /** @@ -864,12 +869,15 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C // unconfirmed ancestors anyway; doing otherwise is hopelessly // insecure. bool fReplacementOptOut = true; - BOOST_FOREACH(const CTxIn &txin, ptxConflicting->vin) + if (fPermitReplacement) { - if (txin.nSequence < std::numeric_limits<unsigned int>::max()-1) + BOOST_FOREACH(const CTxIn &txin, ptxConflicting->vin) { - fReplacementOptOut = false; - break; + if (txin.nSequence < std::numeric_limits<unsigned int>::max()-1) + { + fReplacementOptOut = false; + break; + } } } if (fReplacementOptOut) @@ -929,16 +937,8 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C if (fRequireStandard && !AreInputsStandard(tx, view)) return state.Invalid(false, REJECT_NONSTANDARD, "bad-txns-nonstandard-inputs"); - // Check that the transaction doesn't have an excessive number of - // sigops, making it impossible to mine. Since the coinbase transaction - // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than - // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than - // merely non-standard transaction. unsigned int nSigOps = GetLegacySigOpCount(tx); nSigOps += GetP2SHSigOpCount(tx, view); - if (nSigOps > MAX_STANDARD_TX_SIGOPS) - return state.DoS(0, false, REJECT_NONSTANDARD, "bad-txns-too-many-sigops", false, - strprintf("%d > %d", nSigOps, MAX_STANDARD_TX_SIGOPS)); CAmount nValueOut = tx.GetValueOut(); CAmount nFees = nValueIn-nValueOut; @@ -964,6 +964,15 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx), inChainInputValue, fSpendsCoinbase, nSigOps); unsigned int nSize = entry.GetTxSize(); + // Check that the transaction doesn't have an excessive number of + // sigops, making it impossible to mine. Since the coinbase transaction + // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than + // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than + // merely non-standard transaction. + if ((nSigOps > MAX_STANDARD_TX_SIGOPS) || (nBytesPerSigOp && nSigOps > nSize / nBytesPerSigOp)) + return state.DoS(0, false, REJECT_NONSTANDARD, "bad-txns-too-many-sigops", false, + strprintf("%d", nSigOps)); + CAmount mempoolRejectFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nSize); if (mempoolRejectFee > 0 && nModifiedFees < mempoolRejectFee) { return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool min fee not met", false, strprintf("%d < %d", nFees, mempoolRejectFee)); @@ -1375,7 +1384,7 @@ bool IsInitialBlockDownload() if (lockIBDState) return false; bool state = (chainActive.Height() < pindexBestHeader->nHeight - 24 * 6 || - pindexBestHeader->GetBlockTime() < GetTime() - chainParams.MaxTipAge()); + pindexBestHeader->GetBlockTime() < GetTime() - nMaxTipAge); if (!state) lockIBDState = true; return state; @@ -1537,17 +1546,9 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach undo.nVersion = coins->nVersion; } } - // add outputs - inputs.ModifyNewCoins(tx.GetHash())->FromTx(tx, nHeight); - } - else { - // add outputs for coinbase tx - // In this case call the full ModifyCoins which will do a database - // lookup to be sure the coins do not already exist otherwise we do not - // know whether to mark them fresh or not. We want the duplicate coinbases - // before BIP30 to still be properly overwritten. - inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight); } + // add outputs + inputs.ModifyNewCoins(tx.GetHash(), tx.IsCoinBase())->FromTx(tx, nHeight); } void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight) @@ -1631,9 +1632,12 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // Only if ALL inputs pass do we perform expensive ECDSA signature checks. // Helps prevent CPU exhaustion attacks. - // Skip ECDSA signature verification when connecting blocks - // before the last block chain checkpoint. This is safe because block merkle hashes are - // still computed and checked, and any change will be caught at the next checkpoint. + // Skip ECDSA signature verification when connecting blocks before the + // last block chain checkpoint. Assuming the checkpoints are valid this + // is safe because block merkle hashes are still computed and checked, + // and any change will be caught at the next checkpoint. Of course, if + // the checkpoint is for a chain that's invalid due to false scriptSigs + // this optimisation would allow an invalid chain to be accepted. if (fScriptChecks) { for (unsigned int i = 0; i < tx.vin.size(); i++) { const COutPoint &prevout = tx.vin[i].prevout; @@ -1653,9 +1657,9 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // arguments; if so, don't trigger DoS protection to // avoid splitting the network between upgraded and // non-upgraded nodes. - CScriptCheck check(*coins, tx, i, + CScriptCheck check2(*coins, tx, i, flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore); - if (check()) + if (check2()) return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError()))); } // Failures of other flags indicate a transaction that is @@ -2978,7 +2982,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo } if (nSigOps > MAX_BLOCK_SIGOPS) return state.DoS(100, error("CheckBlock(): out-of-bounds SigOpCount"), - REJECT_INVALID, "bad-blk-sigops", true); + REJECT_INVALID, "bad-blk-sigops"); if (fCheckPOW && fCheckMerkleRoot) block.fChecked = true; @@ -4536,7 +4540,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, { if (fBlocksOnly) LogPrint("net", "transaction (%s) inv sent in violation of protocol peer=%d\n", inv.hash.ToString(), pfrom->id); - else if (!fAlreadyHave && !fImporting && !fReindex) + else if (!fAlreadyHave && !fImporting && !fReindex && !IsInitialBlockDownload()) pfrom->AskFor(inv); } |