rework vm
This commit is contained in:
		
							parent
							
								
									1bce02eff7
								
							
						
					
					
						commit
						616066a598
					
				| @ -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) | ||||
| } | ||||
|  | ||||
							
								
								
									
										269
									
								
								vm/vm_debug.go
									
									
									
									
									
								
							
							
						
						
									
										269
									
								
								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() | ||||
| 		require      = func(m int) { | ||||
| 		//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,31 +125,33 @@ 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: | ||||
| 				statedb.GetStateObject(closure.Address()).EachStorage(func(key string, value *ethutil.Value) { | ||||
| 					value.Decode() | ||||
| 					fmt.Printf("%x %x\n", new(big.Int).SetBytes([]byte(key)).Bytes(), value.Bytes()) | ||||
| 				}) | ||||
| 		/* | ||||
| 			if self.logTy == LogTyDiff { | ||||
| 				switch op { | ||||
| 				case STOP, RETURN, SUICIDE: | ||||
| 					statedb.GetStateObject(closure.Address()).EachStorage(func(key string, value *ethutil.Value) { | ||||
| 						value.Decode() | ||||
| 						fmt.Printf("%x %x\n", new(big.Int).SetBytes([]byte(key)).Bytes(), value.Bytes()) | ||||
| 					}) | ||||
| 				} | ||||
| 
 | ||||
| 				b := pc.Bytes() | ||||
| 				if len(b) == 0 { | ||||
| 					b = []byte{0} | ||||
| 				} | ||||
| 
 | ||||
| 				fmt.Printf("%x %x %x %x\n", closure.Address(), b, []byte{byte(op)}, closure.Gas.Bytes()) | ||||
| 			} | ||||
| 		*/ | ||||
| 
 | ||||
| 			b := pc.Bytes() | ||||
| 			if len(b) == 0 { | ||||
| 				b = []byte{0} | ||||
| 			} | ||||
| 
 | ||||
| 			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 | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user