Closure => Context

This commit is contained in:
obscuren 2015-01-02 16:14:12 +01:00
parent e2d1d832ef
commit 4dc7ee9087
13 changed files with 107 additions and 119 deletions

@ -144,19 +144,19 @@ func (self *VMEnv) vm(addr, data []byte, gas, price, value *big.Int) *core.Execu
return core.NewExecution(self, addr, data, gas, price, value) return core.NewExecution(self, addr, data, gas, price, value)
} }
func (self *VMEnv) Call(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) { func (self *VMEnv) Call(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
exe := self.vm(addr, data, gas, price, value) exe := self.vm(addr, data, gas, price, value)
ret, err := exe.Call(addr, caller) ret, err := exe.Call(addr, caller)
self.Gas = exe.Gas self.Gas = exe.Gas
return ret, err return ret, err
} }
func (self *VMEnv) CallCode(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) { func (self *VMEnv) CallCode(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
exe := self.vm(caller.Address(), data, gas, price, value) exe := self.vm(caller.Address(), data, gas, price, value)
return exe.Call(addr, caller) return exe.Call(addr, caller)
} }
func (self *VMEnv) Create(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ClosureRef) { func (self *VMEnv) Create(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
exe := self.vm(addr, data, gas, price, value) exe := self.vm(addr, data, gas, price, value)
return exe.Create(caller) return exe.Create(caller)
} }

@ -52,19 +52,19 @@ func (self *VMEnv) vm(addr, data []byte, gas, price, value *big.Int) *core.Execu
return core.NewExecution(self, addr, data, gas, price, value) return core.NewExecution(self, addr, data, gas, price, value)
} }
func (self *VMEnv) Call(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) { func (self *VMEnv) Call(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
exe := self.vm(addr, data, gas, price, value) exe := self.vm(addr, data, gas, price, value)
ret, err := exe.Call(addr, caller) ret, err := exe.Call(addr, caller)
self.Gas = exe.Gas self.Gas = exe.Gas
return ret, err return ret, err
} }
func (self *VMEnv) CallCode(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) { func (self *VMEnv) CallCode(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
exe := self.vm(caller.Address(), data, gas, price, value) exe := self.vm(caller.Address(), data, gas, price, value)
return exe.Call(addr, caller) return exe.Call(addr, caller)
} }
func (self *VMEnv) Create(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ClosureRef) { func (self *VMEnv) Create(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
exe := self.vm(addr, data, gas, price, value) exe := self.vm(addr, data, gas, price, value)
return exe.Create(caller) return exe.Create(caller)
} }

@ -20,26 +20,6 @@ type StateQuery interface {
GetAccount(addr []byte) *state.StateObject GetAccount(addr []byte) *state.StateObject
} }
/*
func AddTestNetFunds(block *types.Block) {
for _, addr := range []string{
"51ba59315b3a95761d0863b05ccc7a7f54703d99",
"e4157b34ea9615cfbde6b4fda419828124b70c78",
"b9c015918bdaba24b4ff057a92a3873d6eb201be",
"6c386a4b26f73c802f34673f7248bb118f97424a",
"cd2a3d9f938e13cd947ec05abc7fe734df8dd826",
"2ef47100e0787b915105fd5e3f4ff6752079d5cb",
"e6716f9544a56c530d868e4bfbacb172315bdead",
"1a26338f0d905e295fccb71fa9ea849ffa12aaf4",
} {
codedAddr := ethutil.Hex2Bytes(addr)
account := block.State().GetAccount(codedAddr)
account.SetBalance(ethutil.Big("1606938044258990275541962092341162602522202993782792835301376")) //ethutil.BigPow(2, 200)
block.State().UpdateStateObject(account)
}
}
*/
func CalcDifficulty(block, parent *types.Block) *big.Int { func CalcDifficulty(block, parent *types.Block) *big.Int {
diff := new(big.Int) diff := new(big.Int)

@ -24,14 +24,14 @@ func (self *Execution) Addr() []byte {
return self.address return self.address
} }
func (self *Execution) Call(codeAddr []byte, caller vm.ClosureRef) ([]byte, error) { func (self *Execution) Call(codeAddr []byte, caller vm.ContextRef) ([]byte, error) {
// Retrieve the executing code // Retrieve the executing code
code := self.env.State().GetCode(codeAddr) code := self.env.State().GetCode(codeAddr)
return self.exec(code, codeAddr, caller) return self.exec(code, codeAddr, caller)
} }
func (self *Execution) exec(code, contextAddr []byte, caller vm.ClosureRef) (ret []byte, err error) { func (self *Execution) exec(code, contextAddr []byte, caller vm.ContextRef) (ret []byte, err error) {
env := self.env env := self.env
evm := vm.New(env, vm.DebugVmTy) evm := vm.New(env, vm.DebugVmTy)
@ -63,7 +63,7 @@ func (self *Execution) exec(code, contextAddr []byte, caller vm.ClosureRef) (ret
return return
} }
func (self *Execution) Create(caller vm.ClosureRef) (ret []byte, err error, account *state.StateObject) { func (self *Execution) Create(caller vm.ContextRef) (ret []byte, err error, account *state.StateObject) {
ret, err = self.exec(self.input, nil, caller) ret, err = self.exec(self.input, nil, caller)
account = self.env.State().GetStateObject(self.address) account = self.env.State().GetStateObject(self.address)

@ -184,7 +184,7 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) {
} }
vmenv := self.VmEnv() vmenv := self.VmEnv()
var ref vm.ClosureRef var ref vm.ContextRef
if MessageCreatesContract(msg) { if MessageCreatesContract(msg) {
contract := MakeContract(msg, self.state) contract := MakeContract(msg, self.state)
ret, err, ref = vmenv.Create(sender, contract.Address(), self.msg.Data(), self.gas, self.gasPrice, self.value) ret, err, ref = vmenv.Create(sender, contract.Address(), self.msg.Data(), self.gas, self.gasPrice, self.value)

@ -46,16 +46,16 @@ func (self *VMEnv) vm(addr, data []byte, gas, price, value *big.Int) *Execution
return NewExecution(self, addr, data, gas, price, value) return NewExecution(self, addr, data, gas, price, value)
} }
func (self *VMEnv) Call(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) { func (self *VMEnv) Call(me vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
exe := self.vm(addr, data, gas, price, value) exe := self.vm(addr, data, gas, price, value)
return exe.Call(addr, me) return exe.Call(addr, me)
} }
func (self *VMEnv) CallCode(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) { func (self *VMEnv) CallCode(me vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
exe := self.vm(me.Address(), data, gas, price, value) exe := self.vm(me.Address(), data, gas, price, value)
return exe.Call(addr, me) return exe.Call(addr, me)
} }
func (self *VMEnv) Create(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ClosureRef) { func (self *VMEnv) Create(me vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
exe := self.vm(addr, data, gas, price, value) exe := self.vm(addr, data, gas, price, value)
return exe.Create(me) return exe.Create(me)
} }

@ -74,19 +74,19 @@ func (self *Env) vm(addr, data []byte, gas, price, value *big.Int) *core.Executi
return exec return exec
} }
func (self *Env) Call(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) { func (self *Env) Call(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
exe := self.vm(addr, data, gas, price, value) exe := self.vm(addr, data, gas, price, value)
ret, err := exe.Call(addr, caller) ret, err := exe.Call(addr, caller)
self.Gas = exe.Gas self.Gas = exe.Gas
return ret, err return ret, err
} }
func (self *Env) CallCode(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) { func (self *Env) CallCode(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
exe := self.vm(caller.Address(), data, gas, price, value) exe := self.vm(caller.Address(), data, gas, price, value)
return exe.Call(addr, caller) return exe.Call(addr, caller)
} }
func (self *Env) Create(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ClosureRef) { func (self *Env) Create(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
exe := self.vm(addr, data, gas, price, value) exe := self.vm(addr, data, gas, price, value)
return exe.Create(caller) return exe.Create(caller)
} }

@ -8,15 +8,15 @@ import (
"github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/state"
) )
type ClosureRef interface { type ContextRef interface {
ReturnGas(*big.Int, *big.Int) ReturnGas(*big.Int, *big.Int)
Address() []byte Address() []byte
SetCode([]byte) SetCode([]byte)
} }
type Closure struct { type Context struct {
caller ClosureRef caller ContextRef
object ClosureRef object ContextRef
Code []byte Code []byte
message *state.Message message *state.Message
@ -25,9 +25,9 @@ type Closure struct {
Args []byte Args []byte
} }
// Create a new closure for the given data items // Create a new context for the given data items
func NewClosure(msg *state.Message, caller ClosureRef, object ClosureRef, code []byte, gas, price *big.Int) *Closure { func NewContext(msg *state.Message, caller ContextRef, object ContextRef, code []byte, gas, price *big.Int) *Context {
c := &Closure{message: msg, caller: caller, object: object, Code: code, Args: nil} c := &Context{message: msg, caller: caller, object: object, Code: code, Args: nil}
// Gas should be a pointer so it can safely be reduced through the run // Gas should be a pointer so it can safely be reduced through the run
// This pointer will be off the state transition // This pointer will be off the state transition
@ -40,11 +40,11 @@ func NewClosure(msg *state.Message, caller ClosureRef, object ClosureRef, code [
return c return c
} }
func (c *Closure) GetOp(x uint64) OpCode { func (c *Context) GetOp(x uint64) OpCode {
return OpCode(c.GetByte(x)) return OpCode(c.GetByte(x))
} }
func (c *Closure) GetByte(x uint64) byte { func (c *Context) GetByte(x uint64) byte {
if x < uint64(len(c.Code)) { if x < uint64(len(c.Code)) {
return c.Code[x] return c.Code[x]
} }
@ -52,18 +52,18 @@ func (c *Closure) GetByte(x uint64) byte {
return 0 return 0
} }
func (c *Closure) GetBytes(x, y int) []byte { func (c *Context) GetBytes(x, y int) []byte {
return c.GetRangeValue(uint64(x), uint64(y)) return c.GetRangeValue(uint64(x), uint64(y))
} }
func (c *Closure) GetRangeValue(x, size uint64) []byte { func (c *Context) GetRangeValue(x, size uint64) []byte {
x = uint64(math.Min(float64(x), float64(len(c.Code)))) x = uint64(math.Min(float64(x), float64(len(c.Code))))
y := uint64(math.Min(float64(x+size), float64(len(c.Code)))) y := uint64(math.Min(float64(x+size), float64(len(c.Code))))
return ethutil.LeftPadBytes(c.Code[x:y], int(size)) return ethutil.LeftPadBytes(c.Code[x:y], int(size))
} }
func (c *Closure) Return(ret []byte) []byte { func (c *Context) Return(ret []byte) []byte {
// Return the remaining gas to the caller // Return the remaining gas to the caller
c.caller.ReturnGas(c.Gas, c.Price) c.caller.ReturnGas(c.Gas, c.Price)
@ -73,7 +73,7 @@ func (c *Closure) Return(ret []byte) []byte {
/* /*
* Gas functions * Gas functions
*/ */
func (c *Closure) UseGas(gas *big.Int) bool { func (c *Context) UseGas(gas *big.Int) bool {
if c.Gas.Cmp(gas) < 0 { if c.Gas.Cmp(gas) < 0 {
return false return false
} }
@ -86,8 +86,8 @@ func (c *Closure) UseGas(gas *big.Int) bool {
} }
// Implement the caller interface // Implement the caller interface
func (c *Closure) ReturnGas(gas, price *big.Int) { func (c *Context) ReturnGas(gas, price *big.Int) {
// Return the gas to the closure // Return the gas to the context
c.Gas.Add(c.Gas, gas) c.Gas.Add(c.Gas, gas)
c.UsedGas.Sub(c.UsedGas, gas) c.UsedGas.Sub(c.UsedGas, gas)
} }
@ -95,10 +95,10 @@ func (c *Closure) ReturnGas(gas, price *big.Int) {
/* /*
* Set / Get * Set / Get
*/ */
func (c *Closure) Address() []byte { func (c *Context) Address() []byte {
return c.object.Address() return c.object.Address()
} }
func (self *Closure) SetCode(code []byte) { func (self *Context) SetCode(code []byte) {
self.Code = code self.Code = code
} }

@ -26,9 +26,9 @@ type Environment interface {
Depth() int Depth() int
SetDepth(i int) SetDepth(i int)
Call(me ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) Call(me ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error)
CallCode(me ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) CallCode(me ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error)
Create(me ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, ClosureRef) Create(me ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, ContextRef)
} }
type Object interface { type Object interface {

@ -4,7 +4,7 @@ import "math/big"
type VirtualMachine interface { type VirtualMachine interface {
Env() Environment Env() Environment
Run(me, caller ClosureRef, code []byte, value, gas, price *big.Int, data []byte) ([]byte, error) Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, data []byte) ([]byte, error)
Printf(string, ...interface{}) VirtualMachine Printf(string, ...interface{}) VirtualMachine
Endl() VirtualMachine Endl() VirtualMachine
} }

@ -20,7 +20,7 @@ func New(env Environment, typ Type) VirtualMachine {
} }
} }
func (self *Vm) Run(me, caller ClosureRef, code []byte, value, gas, price *big.Int, data []byte) (ret []byte, err error) { func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, data []byte) (ret []byte, err error) {
panic("not implemented") panic("not implemented")
} }

@ -37,7 +37,7 @@ func NewDebugVm(env Environment) *DebugVm {
return &DebugVm{env: env, logTy: lt, Recoverable: true} return &DebugVm{env: env, logTy: lt, Recoverable: true}
} }
func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) { func (self *DebugVm) Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) {
self.env.SetDepth(self.env.Depth() + 1) self.env.SetDepth(self.env.Depth() + 1)
msg := self.env.State().Manifest().AddMessage(&state.Message{ msg := self.env.State().Manifest().AddMessage(&state.Message{
@ -47,7 +47,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
Block: self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(), Block: self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(),
Value: value, Value: value,
}) })
closure := NewClosure(msg, caller, me, code, gas, price) context := NewContext(msg, caller, me, code, gas, price)
if self.Recoverable { if self.Recoverable {
// Recover from any require exception // Recover from any require exception
@ -55,9 +55,9 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
if r := recover(); r != nil { if r := recover(); r != nil {
self.Printf(" %v", r).Endl() self.Printf(" %v", r).Endl()
closure.UseGas(closure.Gas) context.UseGas(context.Gas)
ret = closure.Return(nil) ret = context.Return(nil)
err = fmt.Errorf("%v", r) err = fmt.Errorf("%v", r)
@ -66,13 +66,13 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
} }
if p := Precompiled[string(me.Address())]; p != nil { if p := Precompiled[string(me.Address())]; p != nil {
return self.RunPrecompiled(p, callData, closure) return self.RunPrecompiled(p, callData, context)
} }
var ( var (
op OpCode op OpCode
destinations = analyseJumpDests(closure.Code) destinations = analyseJumpDests(context.Code)
mem = NewMemory() mem = NewMemory()
stack = NewStack() stack = NewStack()
pc uint64 = 0 pc uint64 = 0
@ -84,11 +84,19 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
p := to.Uint64() p := to.Uint64()
self.Printf(" ~> %v", to) self.Printf(" ~> %v", to)
/* NOTE: new model. Will change soon
nop := OpCode(context.GetOp(p))
if nop != JUMPDEST {
panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p))
}
pc = to.Uint64()
*/
// Return to start // Return to start
if p == 0 { if p == 0 {
pc = 0 pc = 0
} else { } else {
nop := OpCode(closure.GetOp(p)) nop := OpCode(context.GetOp(p))
if !(nop == JUMPDEST || destinations[from] != nil) { if !(nop == JUMPDEST || destinations[from] != nil) {
panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p)) panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p))
} else if nop == JUMP || nop == JUMPI { } else if nop == JUMP || nop == JUMPI {
@ -103,11 +111,11 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
} }
) )
vmlogger.Debugf("(%d) (%x) %x (code=%d) gas: %v (d) %x\n", self.env.Depth(), caller.Address()[:4], closure.Address(), len(code), closure.Gas, callData) vmlogger.Debugf("(%d) (%x) %x (code=%d) gas: %v (d) %x\n", self.env.Depth(), caller.Address()[:4], context.Address(), len(code), context.Gas, callData)
// Don't bother with the execution if there's no code. // Don't bother with the execution if there's no code.
if len(code) == 0 { if len(code) == 0 {
return closure.Return(nil), nil return context.Return(nil), nil
} }
for { for {
@ -117,22 +125,22 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
step++ step++
// Get the memory location of pc // Get the memory location of pc
op = closure.GetOp(pc) op = context.GetOp(pc)
self.Printf("(pc) %-3d -o- %-14s (m) %-4d (s) %-4d ", pc, op.String(), mem.Len(), stack.Len()) self.Printf("(pc) %-3d -o- %-14s (m) %-4d (s) %-4d ", pc, op.String(), mem.Len(), stack.Len())
newMemSize, gas := self.calculateGasAndSize(closure, caller, op, statedb, mem, stack) newMemSize, gas := self.calculateGasAndSize(context, caller, op, statedb, mem, stack)
self.Printf("(g) %-3v (%v)", gas, closure.Gas) self.Printf("(g) %-3v (%v)", gas, context.Gas)
if !closure.UseGas(gas) { if !context.UseGas(gas) {
self.Endl() self.Endl()
tmp := new(big.Int).Set(closure.Gas) tmp := new(big.Int).Set(context.Gas)
closure.UseGas(closure.Gas) context.UseGas(context.Gas)
return closure.Return(nil), OOG(gas, tmp) return context.Return(nil), OOG(gas, tmp)
} }
mem.Resize(newMemSize.Uint64()) mem.Resize(newMemSize.Uint64())
@ -410,9 +418,9 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
self.Printf(" => %x", data) self.Printf(" => %x", data)
// 0x30 range // 0x30 range
case ADDRESS: case ADDRESS:
stack.Push(ethutil.BigD(closure.Address())) stack.Push(ethutil.BigD(context.Address()))
self.Printf(" => %x", closure.Address()) self.Printf(" => %x", context.Address())
case BALANCE: case BALANCE:
addr := stack.Pop().Bytes() addr := stack.Pop().Bytes()
@ -428,7 +436,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
self.Printf(" => %x", origin) self.Printf(" => %x", origin)
case CALLER: case CALLER:
caller := closure.caller.Address() caller := context.caller.Address()
stack.Push(ethutil.BigD(caller)) stack.Push(ethutil.BigD(caller))
self.Printf(" => %x", caller) self.Printf(" => %x", caller)
@ -485,7 +493,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
code = statedb.GetCode(addr) code = statedb.GetCode(addr)
} else { } else {
code = closure.Code code = context.Code
} }
l := big.NewInt(int64(len(code))) l := big.NewInt(int64(len(code)))
@ -497,7 +505,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
if op == EXTCODECOPY { if op == EXTCODECOPY {
code = statedb.GetCode(stack.Pop().Bytes()) code = statedb.GetCode(stack.Pop().Bytes())
} else { } else {
code = closure.Code code = context.Code
} }
var ( var (
@ -519,9 +527,9 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
self.Printf(" => [%v, %v, %v] %x", mOff, cOff, l, codeCopy) self.Printf(" => [%v, %v, %v] %x", mOff, cOff, l, codeCopy)
case GASPRICE: case GASPRICE:
stack.Push(closure.Price) stack.Push(context.Price)
self.Printf(" => %v", closure.Price) self.Printf(" => %v", context.Price)
// 0x40 range // 0x40 range
case PREVHASH: case PREVHASH:
@ -560,7 +568,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
// 0x50 range // 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: 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:
a := uint64(op - PUSH1 + 1) a := uint64(op - PUSH1 + 1)
byts := closure.GetRangeValue(pc+1, a) byts := context.GetRangeValue(pc+1, a)
// Push value to stack // Push value to stack
stack.Push(ethutil.BigD(byts)) stack.Push(ethutil.BigD(byts))
pc += a pc += a
@ -589,7 +597,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
} }
data := mem.Geti(mStart.Int64(), mSize.Int64()) data := mem.Geti(mStart.Int64(), mSize.Int64())
log := &Log{closure.Address(), topics, data} log := &Log{context.Address(), topics, data}
self.env.AddLog(log) self.env.AddLog(log)
self.Printf(" => %v", log) self.Printf(" => %v", log)
@ -614,15 +622,15 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
self.Printf(" => [%v] 0x%x", off, val) self.Printf(" => [%v] 0x%x", off, val)
case SLOAD: case SLOAD:
loc := stack.Pop() loc := stack.Pop()
val := ethutil.BigD(statedb.GetState(closure.Address(), loc.Bytes())) val := ethutil.BigD(statedb.GetState(context.Address(), loc.Bytes()))
stack.Push(val) stack.Push(val)
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes()) self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
case SSTORE: case SSTORE:
val, loc := stack.Popn() val, loc := stack.Popn()
statedb.SetState(closure.Address(), loc.Bytes(), val) statedb.SetState(context.Address(), loc.Bytes(), val)
closure.message.AddStorageChange(loc.Bytes()) context.message.AddStorageChange(loc.Bytes())
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes()) self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
case JUMP: case JUMP:
@ -644,7 +652,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
case MSIZE: case MSIZE:
stack.Push(big.NewInt(int64(mem.Len()))) stack.Push(big.NewInt(int64(mem.Len())))
case GAS: case GAS:
stack.Push(closure.Gas) stack.Push(context.Gas)
// 0x60 range // 0x60 range
case CREATE: case CREATE:
@ -653,7 +661,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
value = stack.Pop() value = stack.Pop()
size, offset = stack.Popn() size, offset = stack.Popn()
input = mem.Get(offset.Int64(), size.Int64()) input = mem.Get(offset.Int64(), size.Int64())
gas = new(big.Int).Set(closure.Gas) gas = new(big.Int).Set(context.Gas)
// Snapshot the current stack so we are able to // Snapshot the current stack so we are able to
// revert back to it later. // revert back to it later.
@ -661,15 +669,15 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
) )
// Generate a new address // Generate a new address
n := statedb.GetNonce(closure.Address()) n := statedb.GetNonce(context.Address())
addr := crypto.CreateAddress(closure.Address(), n) addr := crypto.CreateAddress(context.Address(), n)
statedb.SetNonce(closure.Address(), n+1) statedb.SetNonce(context.Address(), n+1)
self.Printf(" (*) %x", addr).Endl() self.Printf(" (*) %x", addr).Endl()
closure.UseGas(closure.Gas) context.UseGas(context.Gas)
ret, err, ref := self.env.Create(closure, addr, input, gas, price, value) ret, err, ref := self.env.Create(context, addr, input, gas, price, value)
if err != nil { if err != nil {
stack.Push(ethutil.BigFalse) stack.Push(ethutil.BigFalse)
@ -678,7 +686,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
// gas < len(ret) * CreateDataGas == NO_CODE // gas < len(ret) * CreateDataGas == NO_CODE
dataGas := big.NewInt(int64(len(ret))) dataGas := big.NewInt(int64(len(ret)))
dataGas.Mul(dataGas, GasCreateByte) dataGas.Mul(dataGas, GasCreateByte)
if closure.UseGas(dataGas) { if context.UseGas(dataGas) {
ref.SetCode(ret) ref.SetCode(ret)
msg.Output = ret msg.Output = ret
} }
@ -690,7 +698,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
// Debug hook // Debug hook
if self.Dbg != nil { if self.Dbg != nil {
self.Dbg.SetCode(closure.Code) self.Dbg.SetCode(context.Code)
} }
case CALL, CALLCODE: case CALL, CALLCODE:
self.Endl() self.Endl()
@ -711,9 +719,9 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
err error err error
) )
if op == CALLCODE { if op == CALLCODE {
ret, err = self.env.CallCode(closure, addr.Bytes(), args, gas, price, value) ret, err = self.env.CallCode(context, addr.Bytes(), args, gas, price, value)
} else { } else {
ret, err = self.env.Call(closure, addr.Bytes(), args, gas, price, value) ret, err = self.env.Call(context, addr.Bytes(), args, gas, price, value)
} }
if err != nil { if err != nil {
@ -726,11 +734,11 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
mem.Set(retOffset.Uint64(), retSize.Uint64(), ret) mem.Set(retOffset.Uint64(), retSize.Uint64(), ret)
} }
self.Printf("resume %x (%v)", closure.Address(), closure.Gas) self.Printf("resume %x (%v)", context.Address(), context.Gas)
// Debug hook // Debug hook
if self.Dbg != nil { if self.Dbg != nil {
self.Dbg.SetCode(closure.Code) self.Dbg.SetCode(context.Code)
} }
case RETURN: case RETURN:
@ -739,27 +747,27 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
self.Printf(" => [%v, %v] (%d) 0x%x", offset, size, len(ret), ret).Endl() self.Printf(" => [%v, %v] (%d) 0x%x", offset, size, len(ret), ret).Endl()
return closure.Return(ret), nil return context.Return(ret), nil
case SUICIDE: case SUICIDE:
receiver := statedb.GetOrNewStateObject(stack.Pop().Bytes()) receiver := statedb.GetOrNewStateObject(stack.Pop().Bytes())
balance := statedb.GetBalance(closure.Address()) balance := statedb.GetBalance(context.Address())
self.Printf(" => (%x) %v", receiver.Address()[:4], balance) self.Printf(" => (%x) %v", receiver.Address()[:4], balance)
receiver.AddAmount(balance) receiver.AddAmount(balance)
statedb.Delete(closure.Address()) statedb.Delete(context.Address())
fallthrough fallthrough
case STOP: // Stop the closure case STOP: // Stop the context
self.Endl() self.Endl()
return closure.Return(nil), nil return context.Return(nil), nil
default: default:
vmlogger.Debugf("(pc) %-3v Invalid opcode %x\n", pc, op) vmlogger.Debugf("(pc) %-3v Invalid opcode %x\n", pc, op)
closure.ReturnGas(big.NewInt(1), nil) context.ReturnGas(big.NewInt(1), nil)
return closure.Return(nil), fmt.Errorf("Invalid opcode %x", op) return context.Return(nil), fmt.Errorf("Invalid opcode %x", op)
} }
pc++ pc++
@ -771,11 +779,11 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
if pc == uint64(instrNo) { if pc == uint64(instrNo) {
self.Stepping = true self.Stepping = true
if !self.Dbg.BreakHook(prevStep, op, mem, stack, statedb.GetStateObject(closure.Address())) { if !self.Dbg.BreakHook(prevStep, op, mem, stack, statedb.GetStateObject(context.Address())) {
return nil, nil return nil, nil
} }
} else if self.Stepping { } else if self.Stepping {
if !self.Dbg.StepHook(prevStep, op, mem, stack, statedb.GetStateObject(closure.Address())) { if !self.Dbg.StepHook(prevStep, op, mem, stack, statedb.GetStateObject(context.Address())) {
return nil, nil return nil, nil
} }
} }
@ -785,7 +793,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
} }
} }
func (self *DebugVm) calculateGasAndSize(closure *Closure, caller ClosureRef, op OpCode, statedb *state.StateDB, mem *Memory, stack *Stack) (*big.Int, *big.Int) { func (self *DebugVm) calculateGasAndSize(context *Context, caller ContextRef, op OpCode, statedb *state.StateDB, mem *Memory, stack *Stack) (*big.Int, *big.Int) {
gas := new(big.Int) gas := new(big.Int)
addStepGasUsage := func(amount *big.Int) { addStepGasUsage := func(amount *big.Int) {
if amount.Cmp(ethutil.Big0) >= 0 { if amount.Cmp(ethutil.Big0) >= 0 {
@ -844,7 +852,7 @@ func (self *DebugVm) calculateGasAndSize(closure *Closure, caller ClosureRef, op
var mult *big.Int var mult *big.Int
y, x := stack.Peekn() y, x := stack.Peekn()
val := statedb.GetState(closure.Address(), x.Bytes()) val := statedb.GetState(context.Address(), x.Bytes())
if len(val) == 0 && len(y.Bytes()) > 0 { if len(val) == 0 && len(y.Bytes()) > 0 {
// 0 => non 0 // 0 => non 0
mult = ethutil.Big3 mult = ethutil.Big3
@ -940,22 +948,22 @@ func (self *DebugVm) calculateGasAndSize(closure *Closure, caller ClosureRef, op
return newMemSize, gas return newMemSize, gas
} }
func (self *DebugVm) RunPrecompiled(p *PrecompiledAccount, callData []byte, closure *Closure) (ret []byte, err error) { func (self *DebugVm) RunPrecompiled(p *PrecompiledAccount, callData []byte, context *Context) (ret []byte, err error) {
gas := p.Gas(len(callData)) gas := p.Gas(len(callData))
if closure.UseGas(gas) { if context.UseGas(gas) {
ret = p.Call(callData) ret = p.Call(callData)
self.Printf("NATIVE_FUNC => %x", ret) self.Printf("NATIVE_FUNC => %x", ret)
self.Endl() self.Endl()
return closure.Return(ret), nil return context.Return(ret), nil
} else { } else {
self.Endl() self.Endl()
tmp := new(big.Int).Set(closure.Gas) tmp := new(big.Int).Set(context.Gas)
closure.UseGas(closure.Gas) context.UseGas(context.Gas)
return closure.Return(nil), OOG(gas, tmp) return context.Return(nil), OOG(gas, tmp)
} }
} }

@ -50,16 +50,16 @@ func (self *VMEnv) vm(addr, data []byte, gas, price, value *big.Int) *core.Execu
return core.NewExecution(self, addr, data, gas, price, value) return core.NewExecution(self, addr, data, gas, price, value)
} }
func (self *VMEnv) Call(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) { func (self *VMEnv) Call(me vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
exe := self.vm(addr, data, gas, price, value) exe := self.vm(addr, data, gas, price, value)
return exe.Call(addr, me) return exe.Call(addr, me)
} }
func (self *VMEnv) CallCode(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) { func (self *VMEnv) CallCode(me vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
exe := self.vm(me.Address(), data, gas, price, value) exe := self.vm(me.Address(), data, gas, price, value)
return exe.Call(addr, me) return exe.Call(addr, me)
} }
func (self *VMEnv) Create(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ClosureRef) { func (self *VMEnv) Create(me vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
exe := self.vm(addr, data, gas, price, value) exe := self.vm(addr, data, gas, price, value)
return exe.Create(me) return exe.Create(me)
} }