diff options
author | obscuren <geffobscura@gmail.com> | 2014-10-17 00:27:05 +0800 |
---|---|---|
committer | obscuren <geffobscura@gmail.com> | 2014-10-17 00:27:05 +0800 |
commit | 93fcabd25189b447cc5c52523134cca2fa1d794e (patch) | |
tree | 152b24831fbb2d547bc2189b0b92a2b18c8f64b7 /ethvm | |
parent | bb5038699ef7e08054ef154107e359dce2e3b106 (diff) | |
download | go-tangerine-93fcabd25189b447cc5c52523134cca2fa1d794e.tar.gz go-tangerine-93fcabd25189b447cc5c52523134cca2fa1d794e.tar.zst go-tangerine-93fcabd25189b447cc5c52523134cca2fa1d794e.zip |
Fixed most of the tests
Diffstat (limited to 'ethvm')
-rw-r--r-- | ethvm/environment.go | 1 | ||||
-rw-r--r-- | ethvm/execution.go | 38 | ||||
-rw-r--r-- | ethvm/vm_debug.go | 58 |
3 files changed, 60 insertions, 37 deletions
diff --git a/ethvm/environment.go b/ethvm/environment.go index 38dbc6499..b04fa332e 100644 --- a/ethvm/environment.go +++ b/ethvm/environment.go @@ -17,6 +17,7 @@ type Environment interface { Time() int64 Difficulty() *big.Int BlockHash() []byte + GasLimit() *big.Int } type Object interface { diff --git a/ethvm/execution.go b/ethvm/execution.go index ce90ade15..f5f1ce70d 100644 --- a/ethvm/execution.go +++ b/ethvm/execution.go @@ -10,21 +10,27 @@ import ( type Execution struct { vm VirtualMachine - closure *Closure address, input []byte - gas, price, value *big.Int + Gas, price, value *big.Int object *ethstate.StateObject } func NewExecution(vm VirtualMachine, address, input []byte, gas, gasPrice, value *big.Int) *Execution { - return &Execution{vm: vm, address: address, input: input, gas: gas, price: gasPrice, value: value} + return &Execution{vm: vm, address: address, input: input, Gas: gas, price: gasPrice, value: value} } func (self *Execution) Addr() []byte { return self.address } -func (self *Execution) Exec(codeAddr []byte, caller ClosureRef) (ret []byte, err error) { +func (self *Execution) Exec(codeAddr []byte, caller ClosureRef) ([]byte, error) { + // Retrieve the executing code + code := self.vm.Env().State().GetCode(codeAddr) + + return self.exec(code, codeAddr, caller) +} + +func (self *Execution) exec(code, caddr []byte, caller ClosureRef) (ret []byte, err error) { env := self.vm.Env() snapshot := env.State().Copy() @@ -44,7 +50,7 @@ func (self *Execution) Exec(codeAddr []byte, caller ClosureRef) (ret []byte, err object := caller.Object() if object.Balance.Cmp(self.value) < 0 { - caller.ReturnGas(self.gas, self.price) + caller.ReturnGas(self.Gas, self.price) err = fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, object.Balance) } else { @@ -55,23 +61,23 @@ func (self *Execution) Exec(codeAddr []byte, caller ClosureRef) (ret []byte, err stateObject.AddAmount(self.value) // Pre-compiled contracts (address.go) 1, 2 & 3. - naddr := ethutil.BigD(codeAddr).Uint64() + naddr := ethutil.BigD(caddr).Uint64() if p := Precompiled[naddr]; p != nil { - if self.gas.Cmp(p.Gas) >= 0 { + if self.Gas.Cmp(p.Gas) >= 0 { ret = p.Call(self.input) self.vm.Printf("NATIVE_FUNC(%x) => %x", naddr, ret) } } else { + // Create a new callable closure + c := NewClosure(msg, caller, stateObject, code, self.Gas, self.price) + c.exe = self + if self.vm.Depth() == MaxCallDepth { - return nil, fmt.Errorf("Max call depth exceeded (%d)", MaxCallDepth) - } + c.UseGas(c.Gas) - // Retrieve the executing code - code := env.State().GetCode(codeAddr) + return c.Return(nil), fmt.Errorf("Max call depth exceeded (%d)", MaxCallDepth) + } - // Create a new callable closure - c := NewClosure(msg, caller, stateObject, code, self.gas, self.price) - c.exe = self // Executer the closure and get the return value (if any) ret, _, err = c.Call(self.vm, self.input) @@ -81,3 +87,7 @@ func (self *Execution) Exec(codeAddr []byte, caller ClosureRef) (ret []byte, err return } + +func (self *Execution) Create(caller ClosureRef) (ret []byte, err error) { + return self.exec(self.input, nil, caller) +} diff --git a/ethvm/vm_debug.go b/ethvm/vm_debug.go index 6d42c6b1e..da9ad8d59 100644 --- a/ethvm/vm_debug.go +++ b/ethvm/vm_debug.go @@ -54,6 +54,25 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { 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()) + + self.Printf(" ~> %v", pos) + // Return to start + if p == 0 { + pc = big.NewInt(0) + } else { + nop := OpCode(closure.GetOp(p - 1)) + if nop != JUMPDEST { + panic(fmt.Sprintf("JUMP missed JUMPDEST (%v) %v", nop, p)) + } + + pc = pos + } + + self.Endl() + } ) if self.Recoverable { @@ -440,14 +459,18 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { case BYTE: require(2) val, th := stack.Popn() - if th.Cmp(big.NewInt(32)) < 0 && th.Cmp(big.NewInt(int64(len(val.Bytes())))) < 0 { + + if th.Cmp(big.NewInt(32)) < 0 { byt := big.NewInt(int64(ethutil.LeftPadBytes(val.Bytes(), 32)[th.Int64()])) - stack.Push(byt) - self.Printf(" => 0x%x", byt.Bytes()) + base.Set(byt) } else { - stack.Push(ethutil.BigFalse) + base.Set(ethutil.BigFalse) } + + self.Printf(" => 0x%x", base.Bytes()) + + stack.Push(base) case ADDMOD: require(3) @@ -562,7 +585,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { mem.Set(mOff, l, code) case CODESIZE, EXTCODESIZE: var code []byte - if op == EXTCODECOPY { + if op == EXTCODESIZE { addr := stack.Pop().Bytes() code = state.GetCode(addr) @@ -638,8 +661,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { self.Printf(" => 0x%x", difficulty.Bytes()) case GASLIMIT: - // TODO - stack.Push(big.NewInt(0)) + stack.Push(self.env.GasLimit()) // 0x50 range case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32: @@ -713,32 +735,21 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes()) case JUMP: require(1) - pc = stack.Pop() - - if OpCode(closure.Get(pc).Uint()) != JUMPDEST { - panic(fmt.Sprintf("JUMP missed JUMPDEST %v", pc)) - } - // Reduce pc by one because of the increment that's at the end of this for loop - self.Printf(" ~> %v", pc).Endl() + jump(stack.Pop()) continue case JUMPI: require(2) cond, pos := stack.Popn() - if cond.Cmp(ethutil.BigTrue) >= 0 { - pc = pos - if OpCode(closure.Get(pc).Uint()) != JUMPDEST { - panic(fmt.Sprintf("JUMP missed JUMPDEST %v", pc)) - } + if cond.Cmp(ethutil.BigTrue) >= 0 { + jump(pos) continue - } else { - self.Printf(" (f)") } + case JUMPDEST: - self.Printf(" ~> %v (t)", pc).Endl() case PC: stack.Push(pc) case MSIZE: @@ -771,7 +782,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { closure.UseGas(closure.Gas) msg := NewExecution(self, addr, input, gas, closure.Price, value) - ret, err := msg.Exec(addr, closure) + ret, err := msg.Create(closure) if err != nil { stack.Push(ethutil.BigFalse) @@ -857,6 +868,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { vmlogger.Debugf("(pc) %-3v Invalid opcode %x\n", pc, op) //panic(fmt.Sprintf("Invalid opcode %x", op)) + closure.ReturnGas(big.NewInt(1), nil) return closure.Return(nil), fmt.Errorf("Invalid opcode %x", op) } |