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 return
} }
l.td = td l.td = td
i++
} }
if td.Cmp(self.TD) <= 0 { 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) return fmt.Sprintf("incoming chain has a lower or equal TD (%v <= %v)", self.a, self.b)
} }
func IsTDError(e error) bool { func IsTDError(e error) bool {
_, ok := err.(*TDError) _, ok := e.(*TDError)
return ok return ok
} }

View File

@ -88,11 +88,14 @@ func TestVMArithmetic(t *testing.T) {
RunVmTest(fn, t) RunVmTest(fn, t)
} }
/*
deleted?
func TestVMSystemOperation(t *testing.T) { func TestVMSystemOperation(t *testing.T) {
//helper.Logger.SetLogLevel(5) helper.Logger.SetLogLevel(5)
const fn = "../files/vmtests/vmSystemOperationsTest.json" const fn = "../files/vmtests/vmSystemOperationsTest.json"
RunVmTest(fn, t) RunVmTest(fn, t)
} }
*/
func TestBitwiseLogicOperation(t *testing.T) { func TestBitwiseLogicOperation(t *testing.T) {
const fn = "../files/vmtests/vmBitwiseLogicOperationTest.json" const fn = "../files/vmtests/vmBitwiseLogicOperationTest.json"
@ -110,6 +113,7 @@ func TestEnvironmentalInfo(t *testing.T) {
} }
func TestFlowOperation(t *testing.T) { func TestFlowOperation(t *testing.T) {
// helper.Logger.SetLogLevel(5)
const fn = "../files/vmtests/vmIOandFlowOperationsTest.json" const fn = "../files/vmtests/vmIOandFlowOperationsTest.json"
RunVmTest(fn, t) 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 // Since the opcodes aren't all in order we can't use a regular slice
var opCodeToString = map[OpCode]string{ var opCodeToString = map[OpCode]string{
// 0x0 range - arithmetic ops // 0x0 range - arithmetic ops
STOP: "STOP", STOP: "STOP",
ADD: "ADD", ADD: "ADD",
MUL: "MUL", MUL: "MUL",
SUB: "SUB", SUB: "SUB",
DIV: "DIV", DIV: "DIV",
SDIV: "SDIV", SDIV: "SDIV",
MOD: "MOD", MOD: "MOD",
SMOD: "SMOD", SMOD: "SMOD",
EXP: "EXP", EXP: "EXP",
NOT: "NOT", NOT: "NOT",
LT: "LT", LT: "LT",
GT: "GT", GT: "GT",
SLT: "SLT", SLT: "SLT",
SGT: "SGT", SGT: "SGT",
EQ: "EQ", EQ: "EQ",
ISZERO: "ISZERO", ISZERO: "ISZERO",
SIGNEXTEND: "SIGNEXTEND",
// 0x10 range - bit ops // 0x10 range - bit ops
AND: "AND", AND: "AND",

View File

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