Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nI
vector<bool> vfExec;
vector<valtype> stack;
vector<valtype> altstack;
unsigned int nOpCount = 0;
if (pvStackRet)
pvStackRet->clear();

Expand Down Expand Up @@ -85,6 +86,13 @@ bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nI
opcode == OP_MOD || opcode == OP_LSHIFT || opcode == OP_RSHIFT)
return false;

// Counted outside fExec for the same reason: the cost of a script must
// not depend on which branch a signature happens to take. Pushes are
// exempt because their cost is already bounded by the script's own
// length and by MAX_SCRIPT_ELEMENT_SIZE.
if (opcode > OP_16 && ++nOpCount > MAX_OPS_PER_SCRIPT)
return false;

if (fExec && opcode <= OP_PUSHDATA4)
stack.push_back(vchPushValue);
else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF))
Expand Down Expand Up @@ -824,6 +832,11 @@ bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nI
default:
return false;
}

// Both stacks together, because OP_TOALTSTACK would otherwise move the
// problem rather than solve it.
if (stack.size() + altstack.size() > MAX_STACK_SIZE)
return false;
}


Expand Down
9 changes: 9 additions & 0 deletions src/script.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ class CTransaction;
// script evaluation allocates whatever the transaction asks it to.
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520;

// Bounds on what one script may do while being evaluated. The element cap
// above limits how big a single item is; these limit how many there can be and
// how much work producing them costs. Without them, a script pays for itself
// once, in bytes, and then multiplies: 520 bytes per stack entry means a
// script of N bytes made almost entirely of OP_DUP occupies roughly 520N in
// memory, and every node that validates it pays.
static const unsigned int MAX_OPS_PER_SCRIPT = 201;
static const unsigned int MAX_STACK_SIZE = 1000;

enum
{
SIGHASH_ALL = 1,
Expand Down