Accurate sigop/sighash accounting and limits

Adds a ValidationCostTracker class that is passed to
CheckInputs() / CScriptCheck() to keep track of the exact number
of signature operations required to validate a block, and the
exact number of bytes hashed to compute signature hashes.

Also extends CHashWriter to keep track of number of bytes hashed.

Signature operations per block are limited to MAX_BLOCK_SIGOPS
(unchanged at 20,000)

Bytes hashed to compute signatures is limited to MAX_BLOCK_SIGHASH
(1.3 GB in this commit).

Conflicts:
	src/main.cpp
	src/miner.cpp
	src/script/interpreter.h
This commit is contained in:
Gavin Andresen
2016-01-22 11:03:50 -05:00
committed by Tom Zander
parent 76e123a3b3
commit 3aadc515e0
8 changed files with 138 additions and 27 deletions

View File

@@ -79,6 +79,7 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& s
if(!pblocktemplate.get())
return NULL;
CBlock *pblock = &pblocktemplate->block; // pointer for convenience
ValidationCostTracker resourceTracker(std::numeric_limits<size_t>::max(), std::numeric_limits<size_t>::max());
// Create coinbase tx
CMutableTransaction txNew;
@@ -169,6 +170,7 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& s
CTxMemPool::indexed_transaction_set::nth_index<3>::type::iterator mi = mempool.mapTx.get<3>().begin();
CTxMemPool::txiter iter;
uint32_t nMaxLegacySigops = MaxLegacySigops(pblock->nTime);
while (mi != mempool.mapTx.get<3>().end() || !clearedTxs.empty())
{
@@ -236,8 +238,8 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& s
continue;
unsigned int nTxSigOps = iter->GetSigOpCount();
if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) {
if (nBlockSigOps > MAX_BLOCK_SIGOPS - 2) {
if (nBlockSigOps + nTxSigOps >= nMaxLegacySigops) {
if (nBlockSigOps > nMaxLegacySigops - 2) {
break;
}
continue;