Fixed VM and added static analysis for EVM jumps
This commit is contained in:
parent
8cfbf1836d
commit
1b1fa049fa
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
33
vm/types.go
33
vm/types.go
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue