bitcoin/bitcoin — Issue #729: OP_EVAL doesn't stop recursion
Author: roconnor
Created: 2011-12-27 02:42:23+00:00
State: open

Currently in the OP_EVAL processing code you have:

if (!EvalScriptInner(stack, subscript, txTo, nIn, nHashType, pbegincodehash, pendcodehash, nOpCount, nSigOpCount, fStrictOpEval, nRecurseDepth++))

The postfix ++ operator returns the unincremented value of the variables.

So my understanding is that (1) this doesn't limit the depth of recursive calls and (2) this does limit the number of non-recursive calls you OP_EVAL you have in one script.

In particular (1) implies that that Gavin's example (why wasn't this tested) of "OP_PUSHDATA {OP_DUP OP_EVAL} OP_DUP OP_EVAL" should run in an infinite loop (though I haven't tested this).

More generally, this OP_EVAL is a very large change that clearly hasn't been vetted nearly enough. It took me all of 70 minutes of looking to find this bug. You guys are not ready to implement this. OP_EVAL turns a fundamentally Turing-incomplete langauge with clear termination conditions into what I believe an "in-principle" Turing complete language that is only held in check by hacks (which haven't even been implemented properly).

You guys need to stop what you are doing and really understand Bitcoin. In particular you should make a proper specification of the existing scripting language, ideally by creating a formal model of the scripting language. *Prove* upper bound on the space and time usage of scripts. Decide what bounds you want to maintain, and only then start defining OP_EVAL, proving that it preserves whatever properties you want your scripting system to have. OP_IF, OP_CODESEPARATOR, OP_EVAL all have the possibility of interacting complicated ways and you can't just hack the scripting language arbitrarily.