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

@ -189,6 +189,7 @@ var opCodeToString = map[OpCode]string{
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,6 +59,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
var ( var (
op OpCode op OpCode
destinations = analyseJumpDests(closure.Code)
mem = &Memory{} mem = &Memory{}
stack = NewStack() stack = NewStack()
pc = big.NewInt(0) pc = big.NewInt(0)
@ -71,20 +72,21 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
} }
} }
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
} }