rework vm
This commit is contained in:
		@@ -5,11 +5,10 @@ import (
 | 
			
		||||
	"math/big"
 | 
			
		||||
 | 
			
		||||
	"github.com/ethereum/go-ethereum/ethutil"
 | 
			
		||||
	"github.com/ethereum/go-ethereum/state"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Environment interface {
 | 
			
		||||
	State() *state.State
 | 
			
		||||
	//State() *state.State
 | 
			
		||||
 | 
			
		||||
	Origin() []byte
 | 
			
		||||
	BlockNumber() *big.Int
 | 
			
		||||
@@ -19,8 +18,16 @@ type Environment interface {
 | 
			
		||||
	Difficulty() *big.Int
 | 
			
		||||
	BlockHash() []byte
 | 
			
		||||
	GasLimit() *big.Int
 | 
			
		||||
 | 
			
		||||
	Transfer(from, to Account, amount *big.Int) error
 | 
			
		||||
	AddLog(*state.Log)
 | 
			
		||||
	AddLog(addr []byte, topics [][]byte, data []byte)
 | 
			
		||||
	DeleteAccount(addr []byte)
 | 
			
		||||
	SetState(addr, key, value []byte)
 | 
			
		||||
	GetState(addr, key []byte) []byte
 | 
			
		||||
	Balance(addr []byte) *big.Int
 | 
			
		||||
	AddBalance(addr []byte, balance *big.Int)
 | 
			
		||||
	GetCode(addr []byte) []byte
 | 
			
		||||
	Refund(addr []byte, gas, price *big.Int)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Object interface {
 | 
			
		||||
@@ -43,9 +50,5 @@ func Transfer(from, to Account, amount *big.Int) error {
 | 
			
		||||
	from.SubBalance(amount)
 | 
			
		||||
	to.AddBalance(amount)
 | 
			
		||||
 | 
			
		||||
	// Add default LOG. Default = big(sender.addr) + 1
 | 
			
		||||
	//addr := ethutil.BigD(receiver.Address())
 | 
			
		||||
	//tx.addLog(vm.Log{sender.Address(), [][]byte{ethutil.U256(addr.Add(addr, ethutil.Big1)).Bytes()}, nil})
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -90,6 +90,6 @@ func (self *Execution) exec(code, caddr []byte, caller ClosureRef) (ret []byte,
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *Execution) Create(caller ClosureRef) (ret []byte, err error) {
 | 
			
		||||
func (self *Execution) Create(caller []byte) (ret []byte, err error) {
 | 
			
		||||
	return self.exec(self.input, nil, caller)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										237
									
								
								vm/vm_debug.go
									
									
									
									
									
								
							
							
						
						
									
										237
									
								
								vm/vm_debug.go
									
									
									
									
									
								
							@@ -6,7 +6,6 @@ import (
 | 
			
		||||
 | 
			
		||||
	"github.com/ethereum/go-ethereum/crypto"
 | 
			
		||||
	"github.com/ethereum/go-ethereum/ethutil"
 | 
			
		||||
	"github.com/ethereum/go-ethereum/state"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type DebugVm struct {
 | 
			
		||||
@@ -29,6 +28,13 @@ type DebugVm struct {
 | 
			
		||||
	depth int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Options struct {
 | 
			
		||||
	Address, Caller   []byte
 | 
			
		||||
	Data              []byte
 | 
			
		||||
	Code              []byte
 | 
			
		||||
	Value, Gas, Price *big.Int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewDebugVm(env Environment) *DebugVm {
 | 
			
		||||
	lt := LogTyPretty
 | 
			
		||||
	if ethutil.Config.Diff {
 | 
			
		||||
@@ -38,7 +44,13 @@ func NewDebugVm(env Environment) *DebugVm {
 | 
			
		||||
	return &DebugVm{env: env, logTy: lt, Recoverable: true}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
//func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
func (self *DebugVm) Run(call Options) (ret []byte, gas *big.Int, err error) {
 | 
			
		||||
	// Don't bother with the execution if there's no code.
 | 
			
		||||
	if len(call.Code) == 0 {
 | 
			
		||||
		return nil, new(big.Int), nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	self.depth++
 | 
			
		||||
 | 
			
		||||
	if self.Recoverable {
 | 
			
		||||
@@ -47,41 +59,49 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
			if r := recover(); r != nil {
 | 
			
		||||
				self.Endl()
 | 
			
		||||
 | 
			
		||||
				closure.UseGas(closure.Gas)
 | 
			
		||||
 | 
			
		||||
				ret = closure.Return(nil)
 | 
			
		||||
 | 
			
		||||
				gas = new(big.Int)
 | 
			
		||||
				err = fmt.Errorf("%v", r)
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
		}()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gas = new(big.Int).Set(opt.Gas)
 | 
			
		||||
	var (
 | 
			
		||||
		op OpCode
 | 
			
		||||
 | 
			
		||||
		destinations = analyseJumpDests(closure.Code)
 | 
			
		||||
		destinations = analyseJumpDests(call.Code)
 | 
			
		||||
		mem          = NewMemory()
 | 
			
		||||
		stack        = NewStack()
 | 
			
		||||
		pc           = big.NewInt(0)
 | 
			
		||||
		step         = 0
 | 
			
		||||
		prevStep     = 0
 | 
			
		||||
		statedb      = self.env.State()
 | 
			
		||||
		//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))
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		useGas = func(amount *big.Int) bool {
 | 
			
		||||
			if amount.Cmp(gas) > 0 {
 | 
			
		||||
				return false
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			gas.Sub(gas, amount)
 | 
			
		||||
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		jump = func(from, to *big.Int) {
 | 
			
		||||
			p := int(to.Int64())
 | 
			
		||||
			p := to.Uint64()
 | 
			
		||||
 | 
			
		||||
			self.Printf(" ~> %v", to)
 | 
			
		||||
			// Return to start
 | 
			
		||||
			if p == 0 {
 | 
			
		||||
				pc = big.NewInt(0)
 | 
			
		||||
			} else {
 | 
			
		||||
				nop := OpCode(closure.GetOp(p))
 | 
			
		||||
				nop := OpCode(call.GetOp(p))
 | 
			
		||||
				if !(nop == JUMPDEST || destinations[from.Int64()] != nil) {
 | 
			
		||||
					panic(fmt.Sprintf("JUMP missed JUMPDEST (%v) %v", nop, p))
 | 
			
		||||
				} else if nop == JUMP || nop == JUMPI {
 | 
			
		||||
@@ -96,17 +116,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
		}
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	// Debug hook
 | 
			
		||||
	if self.Dbg != nil {
 | 
			
		||||
		self.Dbg.SetCode(closure.Code)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Don't bother with the execution if there's no code.
 | 
			
		||||
	if len(closure.Code) == 0 {
 | 
			
		||||
		return closure.Return(nil), nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	vmlogger.Debugf("(%d) %x gas: %v (d) %x\n", self.depth, closure.Address(), closure.Gas, closure.Args)
 | 
			
		||||
	vmlogger.Debugf("(%d) %x gas: %v (d) %x\n", self.depth, call.Address, gas, call.Data)
 | 
			
		||||
 | 
			
		||||
	for {
 | 
			
		||||
		prevStep = step
 | 
			
		||||
@@ -115,10 +125,11 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
 | 
			
		||||
		step++
 | 
			
		||||
		// Get the memory location of pc
 | 
			
		||||
		op = closure.GetOp(int(pc.Uint64()))
 | 
			
		||||
		op = call.GetOp(pc.Uint64())
 | 
			
		||||
 | 
			
		||||
		// XXX Leave this Println intact. Don't change this to the log system.
 | 
			
		||||
		// Used for creating diffs between implementations
 | 
			
		||||
		/*
 | 
			
		||||
			if self.logTy == LogTyDiff {
 | 
			
		||||
				switch op {
 | 
			
		||||
				case STOP, RETURN, SUICIDE:
 | 
			
		||||
@@ -135,11 +146,12 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
 | 
			
		||||
				fmt.Printf("%x %x %x %x\n", closure.Address(), b, []byte{byte(op)}, closure.Gas.Bytes())
 | 
			
		||||
			}
 | 
			
		||||
		*/
 | 
			
		||||
 | 
			
		||||
		gas := new(big.Int)
 | 
			
		||||
		reqGas := new(big.Int)
 | 
			
		||||
		addStepGasUsage := func(amount *big.Int) {
 | 
			
		||||
			if amount.Cmp(ethutil.Big0) >= 0 {
 | 
			
		||||
				gas.Add(gas, amount)
 | 
			
		||||
				reqGas.Add(reqGas, amount)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -166,42 +178,43 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
			require(n + 2)
 | 
			
		||||
 | 
			
		||||
			mSize, mStart := stack.Peekn()
 | 
			
		||||
			gas.Set(GasLog)
 | 
			
		||||
			reqGs.Set(GasLog)
 | 
			
		||||
			addStepGasUsage(new(big.Int).Mul(big.NewInt(int64(n)), GasLog))
 | 
			
		||||
			addStepGasUsage(new(big.Int).Add(mSize, mStart))
 | 
			
		||||
		// Gas only
 | 
			
		||||
		case STOP:
 | 
			
		||||
			gas.Set(ethutil.Big0)
 | 
			
		||||
			reqGas.Set(ethutil.Big0)
 | 
			
		||||
		case SUICIDE:
 | 
			
		||||
			require(1)
 | 
			
		||||
 | 
			
		||||
			gas.Set(ethutil.Big0)
 | 
			
		||||
			reqGas.Set(ethutil.Big0)
 | 
			
		||||
		case SLOAD:
 | 
			
		||||
			require(1)
 | 
			
		||||
 | 
			
		||||
			gas.Set(GasSLoad)
 | 
			
		||||
			reqGas.Set(GasSLoad)
 | 
			
		||||
		// Memory resize & Gas
 | 
			
		||||
		case SSTORE:
 | 
			
		||||
			require(2)
 | 
			
		||||
 | 
			
		||||
			var mult *big.Int
 | 
			
		||||
			y, x := stack.Peekn()
 | 
			
		||||
			val := closure.GetStorage(x)
 | 
			
		||||
			val := ethutil.BigD(self.env.GetState(x.Bytes())) //closure.GetStorage(x)
 | 
			
		||||
			if val.BigInt().Cmp(ethutil.Big0) == 0 && len(y.Bytes()) > 0 {
 | 
			
		||||
				// 0 => non 0
 | 
			
		||||
				mult = ethutil.Big3
 | 
			
		||||
			} else if val.BigInt().Cmp(ethutil.Big0) != 0 && len(y.Bytes()) == 0 {
 | 
			
		||||
				statedb.Refund(closure.caller.Address(), GasSStoreRefund, closure.Price)
 | 
			
		||||
				//statedb.Refund(closure.caller.Address(), GasSStoreRefund, closure.Price)
 | 
			
		||||
				self.env.Refund(call.Caller, GasSStoreRefund, call.Price)
 | 
			
		||||
 | 
			
		||||
				mult = ethutil.Big0
 | 
			
		||||
			} else {
 | 
			
		||||
				// non 0 => non 0
 | 
			
		||||
				mult = ethutil.Big1
 | 
			
		||||
			}
 | 
			
		||||
			gas.Set(new(big.Int).Mul(mult, GasSStore))
 | 
			
		||||
			reqGas.Set(new(big.Int).Mul(mult, GasSStore))
 | 
			
		||||
		case BALANCE:
 | 
			
		||||
			require(1)
 | 
			
		||||
			gas.Set(GasBalance)
 | 
			
		||||
			reqGas.Set(GasBalance)
 | 
			
		||||
		case MSTORE:
 | 
			
		||||
			require(2)
 | 
			
		||||
			newMemSize = calcMemSize(stack.Peek(), u256(32))
 | 
			
		||||
@@ -219,7 +232,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
		case SHA3:
 | 
			
		||||
			require(2)
 | 
			
		||||
 | 
			
		||||
			gas.Set(GasSha)
 | 
			
		||||
			reqGas.Set(GasSha)
 | 
			
		||||
 | 
			
		||||
			newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
 | 
			
		||||
		case CALLDATACOPY:
 | 
			
		||||
@@ -236,7 +249,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
			newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-4])
 | 
			
		||||
		case CALL, CALLCODE:
 | 
			
		||||
			require(7)
 | 
			
		||||
			gas.Set(GasCall)
 | 
			
		||||
			reqGas.Set(GasCall)
 | 
			
		||||
			addStepGasUsage(stack.data[stack.Len()-1])
 | 
			
		||||
 | 
			
		||||
			x := calcMemSize(stack.data[stack.Len()-6], stack.data[stack.Len()-7])
 | 
			
		||||
@@ -245,7 +258,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
			newMemSize = ethutil.BigMax(x, y)
 | 
			
		||||
		case CREATE:
 | 
			
		||||
			require(3)
 | 
			
		||||
			gas.Set(GasCreate)
 | 
			
		||||
			reqGas.Set(GasCreate)
 | 
			
		||||
 | 
			
		||||
			newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-3])
 | 
			
		||||
		}
 | 
			
		||||
@@ -255,6 +268,12 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
			newMemSize.Div(newMemSize, u256(32))
 | 
			
		||||
			newMemSize.Mul(newMemSize, u256(32))
 | 
			
		||||
 | 
			
		||||
			switch op {
 | 
			
		||||
			// Additional gas usage on *CODPY
 | 
			
		||||
			case CALLDATACOPY, CODECOPY, EXTCODECOPY:
 | 
			
		||||
				addStepGasUsage(new(big.Int).Div(newMemSize, u256(32)))
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 {
 | 
			
		||||
				memGasUsage := new(big.Int).Sub(newMemSize, u256(int64(mem.Len())))
 | 
			
		||||
				memGasUsage.Mul(GasMemory, memGasUsage)
 | 
			
		||||
@@ -268,16 +287,12 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		self.Printf("(pc) %-3d -o- %-14s", pc, op.String())
 | 
			
		||||
		self.Printf(" (m) %-4d (s) %-4d (g) %-3v (%v)", mem.Len(), stack.Len(), gas, closure.Gas)
 | 
			
		||||
		self.Printf(" (m) %-4d (s) %-4d (g) %-3v (%v)", mem.Len(), stack.Len(), reqGas, gas)
 | 
			
		||||
 | 
			
		||||
		if !closure.UseGas(gas) {
 | 
			
		||||
		if !useGas(regGas) {
 | 
			
		||||
			self.Endl()
 | 
			
		||||
 | 
			
		||||
			tmp := new(big.Int).Set(closure.Gas)
 | 
			
		||||
 | 
			
		||||
			closure.UseGas(closure.Gas)
 | 
			
		||||
 | 
			
		||||
			return closure.Return(nil), OOG(gas, tmp)
 | 
			
		||||
			return nil, new(big.Int), OOG(reqGas, gas)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		switch op {
 | 
			
		||||
@@ -553,13 +568,15 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
			self.Printf(" => %x", data)
 | 
			
		||||
			// 0x30 range
 | 
			
		||||
		case ADDRESS:
 | 
			
		||||
			stack.Push(ethutil.BigD(closure.Address()))
 | 
			
		||||
			//stack.Push(ethutil.BigD(closure.Address()))
 | 
			
		||||
			stack.Push(ethutil.BigD(call.Address))
 | 
			
		||||
 | 
			
		||||
			self.Printf(" => %x", closure.Address())
 | 
			
		||||
			self.Printf(" => %x", call.Address)
 | 
			
		||||
		case BALANCE:
 | 
			
		||||
 | 
			
		||||
			addr := stack.Pop().Bytes()
 | 
			
		||||
			balance := statedb.GetBalance(addr)
 | 
			
		||||
			//balance := statedb.GetBalance(addr)
 | 
			
		||||
			balance := self.env.GetBalance(addr)
 | 
			
		||||
 | 
			
		||||
			stack.Push(balance)
 | 
			
		||||
 | 
			
		||||
@@ -571,41 +588,42 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
 | 
			
		||||
			self.Printf(" => %x", origin)
 | 
			
		||||
		case CALLER:
 | 
			
		||||
			caller := closure.caller.Address()
 | 
			
		||||
			stack.Push(ethutil.BigD(caller))
 | 
			
		||||
			//caller := closure.caller.Address()
 | 
			
		||||
			//stack.Push(ethutil.BigD(caller))
 | 
			
		||||
			stack.Push(call.Caller)
 | 
			
		||||
 | 
			
		||||
			self.Printf(" => %x", caller)
 | 
			
		||||
			self.Printf(" => %x", call.Caller)
 | 
			
		||||
		case CALLVALUE:
 | 
			
		||||
			value := closure.exe.value
 | 
			
		||||
			//value := closure.exe.value
 | 
			
		||||
 | 
			
		||||
			stack.Push(value)
 | 
			
		||||
			stack.Push(call.Value)
 | 
			
		||||
 | 
			
		||||
			self.Printf(" => %v", value)
 | 
			
		||||
			self.Printf(" => %v", call.Value)
 | 
			
		||||
		case CALLDATALOAD:
 | 
			
		||||
			var (
 | 
			
		||||
				offset  = stack.Pop()
 | 
			
		||||
				data    = make([]byte, 32)
 | 
			
		||||
				lenData = big.NewInt(int64(len(closure.Args)))
 | 
			
		||||
				lenData = big.NewInt(int64(len(call.Data)))
 | 
			
		||||
			)
 | 
			
		||||
 | 
			
		||||
			if lenData.Cmp(offset) >= 0 {
 | 
			
		||||
				length := new(big.Int).Add(offset, ethutil.Big32)
 | 
			
		||||
				length = ethutil.BigMin(length, lenData)
 | 
			
		||||
 | 
			
		||||
				copy(data, closure.Args[offset.Int64():length.Int64()])
 | 
			
		||||
				copy(data, call.Data[offset.Int64():length.Int64()])
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			self.Printf(" => 0x%x", data)
 | 
			
		||||
 | 
			
		||||
			stack.Push(ethutil.BigD(data))
 | 
			
		||||
		case CALLDATASIZE:
 | 
			
		||||
			l := int64(len(closure.Args))
 | 
			
		||||
			l := int64(len(call.Data))
 | 
			
		||||
			stack.Push(big.NewInt(l))
 | 
			
		||||
 | 
			
		||||
			self.Printf(" => %d", l)
 | 
			
		||||
		case CALLDATACOPY:
 | 
			
		||||
			var (
 | 
			
		||||
				size = int64(len(closure.Args))
 | 
			
		||||
				size = int64(len(call.Data))
 | 
			
		||||
				mOff = stack.Pop().Int64()
 | 
			
		||||
				cOff = stack.Pop().Int64()
 | 
			
		||||
				l    = stack.Pop().Int64()
 | 
			
		||||
@@ -618,7 +636,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
				l = 0
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			code := closure.Args[cOff : cOff+l]
 | 
			
		||||
			code := call.Data[cOff : cOff+l]
 | 
			
		||||
 | 
			
		||||
			mem.Set(mOff, l, code)
 | 
			
		||||
 | 
			
		||||
@@ -628,9 +646,9 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
			if op == EXTCODESIZE {
 | 
			
		||||
				addr := stack.Pop().Bytes()
 | 
			
		||||
 | 
			
		||||
				code = statedb.GetCode(addr)
 | 
			
		||||
				self.env.GetCode(addr)
 | 
			
		||||
			} else {
 | 
			
		||||
				code = closure.Code
 | 
			
		||||
				code = call.Code
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			l := big.NewInt(int64(len(code)))
 | 
			
		||||
@@ -642,9 +660,9 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
			if op == EXTCODECOPY {
 | 
			
		||||
				addr := stack.Pop().Bytes()
 | 
			
		||||
 | 
			
		||||
				code = statedb.GetCode(addr)
 | 
			
		||||
				code = self.env.GetCode(addr)
 | 
			
		||||
			} else {
 | 
			
		||||
				code = closure.Code
 | 
			
		||||
				code = call.Code
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			var (
 | 
			
		||||
@@ -667,9 +685,9 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
 | 
			
		||||
			self.Printf(" => [%v, %v, %v] %x", mOff, cOff, l, code[cOff:cOff+l])
 | 
			
		||||
		case GASPRICE:
 | 
			
		||||
			stack.Push(closure.Price)
 | 
			
		||||
			stack.Push(call.Price)
 | 
			
		||||
 | 
			
		||||
			self.Printf(" => %v", closure.Price)
 | 
			
		||||
			self.Printf(" => %v", call.Price)
 | 
			
		||||
 | 
			
		||||
			// 0x40 range
 | 
			
		||||
		case PREVHASH:
 | 
			
		||||
@@ -707,17 +725,17 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
 | 
			
		||||
			// 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:
 | 
			
		||||
			a := big.NewInt(int64(op) - int64(PUSH1) + 1)
 | 
			
		||||
			a := uint64(op) - uint64(PUSH1) + 1
 | 
			
		||||
			pc.Add(pc, ethutil.Big1)
 | 
			
		||||
			data := closure.Gets(pc, a)
 | 
			
		||||
			val := ethutil.BigD(data.Bytes())
 | 
			
		||||
			data := call.Get(pc.Uint64(), a) //closure.Gets(pc, a)
 | 
			
		||||
			val := ethutil.BigD(data)
 | 
			
		||||
			// Push value to stack
 | 
			
		||||
			stack.Push(val)
 | 
			
		||||
			pc.Add(pc, a.Sub(a, big.NewInt(1)))
 | 
			
		||||
			pc.Add(pc, big.NewInt(int64(a)-1))
 | 
			
		||||
 | 
			
		||||
			step += int(op) - int(PUSH1) + 1
 | 
			
		||||
			step += uint64(op) - uint64(PUSH1) + 1
 | 
			
		||||
 | 
			
		||||
			self.Printf(" => 0x%x", data.Bytes())
 | 
			
		||||
			self.Printf(" => 0x%x", data)
 | 
			
		||||
		case POP:
 | 
			
		||||
			stack.Pop()
 | 
			
		||||
		case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16:
 | 
			
		||||
@@ -725,10 +743,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
			v := stack.Dupn(n)
 | 
			
		||||
 | 
			
		||||
			self.Printf(" => [%d] 0x%x", n, stack.Peek().Bytes())
 | 
			
		||||
 | 
			
		||||
			if OpCode(closure.Get(new(big.Int).Add(pc, ethutil.Big1)).Uint()) == POP && OpCode(closure.Get(new(big.Int).Add(pc, big.NewInt(2))).Uint()) == POP {
 | 
			
		||||
				fmt.Println(toValue(v))
 | 
			
		||||
			}
 | 
			
		||||
		case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
 | 
			
		||||
			n := int(op - SWAP1 + 2)
 | 
			
		||||
			x, y := stack.Swapn(n)
 | 
			
		||||
@@ -743,8 +757,8 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
				topics[i] = stack.Pop().Bytes()
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			log := &state.Log{closure.Address(), topics, data}
 | 
			
		||||
			self.env.AddLog(log)
 | 
			
		||||
			//log := &state.Log{closure.Address(), topics, data}
 | 
			
		||||
			self.env.AddLog(call.Address, topics, data)
 | 
			
		||||
 | 
			
		||||
			self.Printf(" => %v", log)
 | 
			
		||||
		case MLOAD:
 | 
			
		||||
@@ -768,18 +782,16 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
			self.Printf(" => [%v] 0x%x", off, val)
 | 
			
		||||
		case SLOAD:
 | 
			
		||||
			loc := stack.Pop()
 | 
			
		||||
			val := ethutil.BigD(statedb.GetState(closure.Address(), loc.Bytes()))
 | 
			
		||||
			val := ethutil.BigD(self.env.GetState(call.Address, loc.Bytes()))
 | 
			
		||||
			stack.Push(val)
 | 
			
		||||
 | 
			
		||||
			self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
 | 
			
		||||
		case SSTORE:
 | 
			
		||||
			val, loc := stack.Popn()
 | 
			
		||||
			statedb.SetState(closure.Address(), loc.Bytes(), val)
 | 
			
		||||
			self.env.SetState(call.Address, loc.Bytes(), val.Bytes())
 | 
			
		||||
			//statedb.SetState(closure.Address(), loc.Bytes(), val)
 | 
			
		||||
 | 
			
		||||
			// Debug sessions are allowed to run without message
 | 
			
		||||
			if closure.message != nil {
 | 
			
		||||
				closure.message.AddStorageChange(loc.Bytes())
 | 
			
		||||
			}
 | 
			
		||||
			//closure.message.AddStorageChange(loc.Bytes())
 | 
			
		||||
 | 
			
		||||
			self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
 | 
			
		||||
		case JUMP:
 | 
			
		||||
@@ -802,7 +814,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
		case MSIZE:
 | 
			
		||||
			stack.Push(big.NewInt(int64(mem.Len())))
 | 
			
		||||
		case GAS:
 | 
			
		||||
			stack.Push(closure.Gas)
 | 
			
		||||
			stack.Push(call.Gas)
 | 
			
		||||
			// 0x60 range
 | 
			
		||||
		case CREATE:
 | 
			
		||||
			var (
 | 
			
		||||
@@ -810,7 +822,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
				value        = stack.Pop()
 | 
			
		||||
				size, offset = stack.Popn()
 | 
			
		||||
				input        = mem.Get(offset.Int64(), size.Int64())
 | 
			
		||||
				gas          = new(big.Int).Set(closure.Gas)
 | 
			
		||||
				gas          = new(big.Int).Set(call.Gas)
 | 
			
		||||
 | 
			
		||||
				// Snapshot the current stack so we are able to
 | 
			
		||||
				// revert back to it later.
 | 
			
		||||
@@ -818,16 +830,19 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
			)
 | 
			
		||||
 | 
			
		||||
			// Generate a new address
 | 
			
		||||
			n := statedb.GetNonce(closure.Address())
 | 
			
		||||
			addr := crypto.CreateAddress(closure.Address(), n)
 | 
			
		||||
			statedb.SetNonce(closure.Address(), n+1)
 | 
			
		||||
			//n := statedb.GetNonce(closure.Address())
 | 
			
		||||
			//addr := crypto.CreateAddress(closure.Address(), n)
 | 
			
		||||
			//statedb.SetNonce(closure.Address(), n+1)
 | 
			
		||||
			n := self.env.GetNonce(call.Address)
 | 
			
		||||
			addr := crypto.CreateAddress(call.Address, n)
 | 
			
		||||
			self.env.SetNonce(call.Address, n+1)
 | 
			
		||||
 | 
			
		||||
			self.Printf(" (*) %x", addr).Endl()
 | 
			
		||||
 | 
			
		||||
			closure.UseGas(closure.Gas)
 | 
			
		||||
			//closure.UseGas(closure.Gas)
 | 
			
		||||
 | 
			
		||||
			msg := NewExecution(self, addr, input, gas, closure.Price, value)
 | 
			
		||||
			ret, err := msg.Create(closure)
 | 
			
		||||
			msg := NewExecution(self, addr, input, gas, call.Price, value)
 | 
			
		||||
			ret, lgas, err := msg.Create(call.Address)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				stack.Push(ethutil.BigFalse)
 | 
			
		||||
 | 
			
		||||
@@ -841,12 +856,9 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
				stack.Push(ethutil.BigD(addr))
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			self.Endl()
 | 
			
		||||
			gas = lgas
 | 
			
		||||
 | 
			
		||||
			// Debug hook
 | 
			
		||||
			if self.Dbg != nil {
 | 
			
		||||
				self.Dbg.SetCode(closure.Code)
 | 
			
		||||
			}
 | 
			
		||||
			self.Endl()
 | 
			
		||||
		case CALL, CALLCODE:
 | 
			
		||||
			self.Endl()
 | 
			
		||||
 | 
			
		||||
@@ -863,12 +875,12 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
 | 
			
		||||
			var executeAddr []byte
 | 
			
		||||
			if op == CALLCODE {
 | 
			
		||||
				executeAddr = closure.Address()
 | 
			
		||||
				executeAddr = call.Address //closure.Address()
 | 
			
		||||
			} else {
 | 
			
		||||
				executeAddr = addr.Bytes()
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			msg := NewExecution(self, executeAddr, args, gas, closure.Price, value)
 | 
			
		||||
			msg := NewExecution(self, executeAddr, args, gas, call.Price, value)
 | 
			
		||||
			ret, err := msg.Exec(addr.Bytes(), closure)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				stack.Push(ethutil.BigFalse)
 | 
			
		||||
@@ -881,24 +893,22 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
			}
 | 
			
		||||
			self.Printf("resume %x", closure.Address())
 | 
			
		||||
 | 
			
		||||
			// Debug hook
 | 
			
		||||
			if self.Dbg != nil {
 | 
			
		||||
				self.Dbg.SetCode(closure.Code)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		case RETURN:
 | 
			
		||||
			size, offset := stack.Popn()
 | 
			
		||||
			ret := mem.Get(offset.Int64(), size.Int64())
 | 
			
		||||
 | 
			
		||||
			self.Printf(" => (%d) 0x%x", len(ret), ret).Endl()
 | 
			
		||||
 | 
			
		||||
			return closure.Return(ret), nil
 | 
			
		||||
			return ret, gas, nil
 | 
			
		||||
 | 
			
		||||
			//return closure.Return(ret), gas, nil
 | 
			
		||||
		case SUICIDE:
 | 
			
		||||
			//receiver := statedb.GetOrNewStateObject(stack.Pop().Bytes())
 | 
			
		||||
			//receiver.AddAmount(statedb.GetBalance(closure.Address()))
 | 
			
		||||
			//statedb.Delete(closure.Address())
 | 
			
		||||
 | 
			
		||||
			receiver := statedb.GetOrNewStateObject(stack.Pop().Bytes())
 | 
			
		||||
 | 
			
		||||
			receiver.AddAmount(statedb.GetBalance(closure.Address()))
 | 
			
		||||
			statedb.Delete(closure.Address())
 | 
			
		||||
			self.env.AddBalance(stack.Pop().Bytes(), self.env.Balance(call.Address))
 | 
			
		||||
			self.env.DeleteAccount(call.Address)
 | 
			
		||||
 | 
			
		||||
			fallthrough
 | 
			
		||||
		case STOP: // Stop the closure
 | 
			
		||||
@@ -917,23 +927,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 | 
			
		||||
		pc.Add(pc, ethutil.Big1)
 | 
			
		||||
 | 
			
		||||
		self.Endl()
 | 
			
		||||
 | 
			
		||||
		if self.Dbg != nil {
 | 
			
		||||
			for _, instrNo := range self.Dbg.BreakPoints() {
 | 
			
		||||
				if pc.Cmp(big.NewInt(instrNo)) == 0 {
 | 
			
		||||
					self.Stepping = true
 | 
			
		||||
 | 
			
		||||
					if !self.Dbg.BreakHook(prevStep, op, mem, stack, statedb.GetStateObject(closure.Address())) {
 | 
			
		||||
						return nil, nil
 | 
			
		||||
					}
 | 
			
		||||
				} else if self.Stepping {
 | 
			
		||||
					if !self.Dbg.StepHook(prevStep, op, mem, stack, statedb.GetStateObject(closure.Address())) {
 | 
			
		||||
						return nil, nil
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user