Fixed VM and added static analysis for EVM jumps

This commit is contained in:
obscuren 2014-11-04 18:18:57 +01:00
parent 8cfbf1836d
commit 1b1fa049fa
5 changed files with 45 additions and 34 deletions

View File

@ -348,7 +348,6 @@ func (self *ChainManager) TestChain(chain *BlockChain) (td *big.Int, err error)
return
}
l.td = td
i++
}
if td.Cmp(self.TD) <= 0 {

View File

@ -123,6 +123,6 @@ func (self *TDError) Error() string {
return fmt.Sprintf("incoming chain has a lower or equal TD (%v <= %v)", self.a, self.b)
}
func IsTDError(e error) bool {
_, ok := err.(*TDError)
_, ok := e.(*TDError)
return ok
}

View File

@ -88,11 +88,14 @@ func TestVMArithmetic(t *testing.T) {
RunVmTest(fn, t)
}
/*
deleted?
func TestVMSystemOperation(t *testing.T) {
//helper.Logger.SetLogLevel(5)
helper.Logger.SetLogLevel(5)
const fn = "../files/vmtests/vmSystemOperationsTest.json"
RunVmTest(fn, t)
}
*/
func TestBitwiseLogicOperation(t *testing.T) {
const fn = "../files/vmtests/vmBitwiseLogicOperationTest.json"
@ -110,6 +113,7 @@ func TestEnvironmentalInfo(t *testing.T) {
}
func TestFlowOperation(t *testing.T) {
// helper.Logger.SetLogLevel(5)
const fn = "../files/vmtests/vmIOandFlowOperationsTest.json"
RunVmTest(fn, t)
}

View File

@ -173,22 +173,23 @@ const (
// Since the opcodes aren't all in order we can't use a regular slice
var opCodeToString = map[OpCode]string{
// 0x0 range - arithmetic ops
STOP: "STOP",
ADD: "ADD",
MUL: "MUL",
SUB: "SUB",
DIV: "DIV",
SDIV: "SDIV",
MOD: "MOD",
SMOD: "SMOD",
EXP: "EXP",
NOT: "NOT",
LT: "LT",
GT: "GT",
SLT: "SLT",
SGT: "SGT",
EQ: "EQ",
ISZERO: "ISZERO",
STOP: "STOP",
ADD: "ADD",
MUL: "MUL",
SUB: "SUB",
DIV: "DIV",
SDIV: "SDIV",
MOD: "MOD",
SMOD: "SMOD",
EXP: "EXP",
NOT: "NOT",
LT: "LT",
GT: "GT",
SLT: "SLT",
SGT: "SGT",
EQ: "EQ",
ISZERO: "ISZERO",
SIGNEXTEND: "SIGNEXTEND",
// 0x10 range - bit ops
AND: "AND",

View File

@ -59,32 +59,34 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
var (
op OpCode
mem = &Memory{}
stack = NewStack()
pc = big.NewInt(0)
step = 0
prevStep = 0
statedb = self.env.State()
require = func(m int) {
destinations = analyseJumpDests(closure.Code)
mem = &Memory{}
stack = NewStack()
pc = big.NewInt(0)
step = 0
prevStep = 0
statedb = self.env.State()
require = func(m int) {
if stack.Len() < m {
panic(fmt.Sprintf("%04v (%v) stack err size = %d, required = %d", pc, op, stack.Len(), m))
}
}
jump = func(pos *big.Int) {
p := int(pos.Int64())
jump = func(from, to *big.Int) {
p := int(to.Int64())
self.Printf(" ~> %v", pos)
self.Printf(" ~> %v", to)
// Return to start
if p == 0 {
pc = big.NewInt(0)
} else {
nop := OpCode(closure.GetOp(p - 1))
if nop != JUMPDEST {
nop := OpCode(closure.GetOp(p))
if !(nop == JUMPDEST || destinations[from.Int64()] != nil) {
panic(fmt.Sprintf("JUMP missed JUMPDEST (%v) %v", nop, p))
}
pc = pos
pc = to
}
self.Endl()
@ -406,6 +408,11 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
} else {
num.And(num, mask)
}
num = U256(num)
self.Printf(" = %v", num)
stack.Push(num)
}
case NOT:
@ -765,14 +772,14 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
case JUMP:
jump(stack.Pop())
jump(pc, stack.Pop())
continue
case JUMPI:
cond, pos := stack.Popn()
if cond.Cmp(ethutil.BigTrue) >= 0 {
jump(pos)
jump(pc, pos)
continue
}