forked from cerc-io/plugeth
Use the state instead of the state object directly.
If a state gets reset and you still hold a pointer to the previous, incorrect, state object you'll operate on the wrong object. Using the state to set/get objects and attributes you won't have this problem since the state will always have the correct object.
This commit is contained in:
parent
311c6f8a3f
commit
70f7a0be11
@ -48,6 +48,13 @@ func (self *State) GetNonce(addr []byte) uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *State) SetNonce(addr []byte, nonce uint64) {
|
||||
stateObject := self.GetStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.Nonce = nonce
|
||||
}
|
||||
}
|
||||
|
||||
func (self *State) GetCode(addr []byte) []byte {
|
||||
stateObject := self.GetStateObject(addr)
|
||||
if stateObject != nil {
|
||||
@ -66,6 +73,24 @@ func (self *State) GetState(a, b []byte) []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *State) SetState(addr, key []byte, value interface{}) {
|
||||
stateObject := self.GetStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.SetState(key, ethutil.NewValue(value))
|
||||
}
|
||||
}
|
||||
|
||||
func (self *State) Delete(addr []byte) bool {
|
||||
stateObject := self.GetStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.MarkForDeletion()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
//
|
||||
// Setting, updating & deleting state object methods
|
||||
//
|
||||
|
@ -104,6 +104,10 @@ func (self *StateObject) SetStorage(key *big.Int, value *ethutil.Value) {
|
||||
self.SetState(key.Bytes(), value)
|
||||
}
|
||||
|
||||
func (self *StateObject) Storage() map[string]*ethutil.Value {
|
||||
return self.storage
|
||||
}
|
||||
|
||||
func (self *StateObject) GetState(k []byte) *ethutil.Value {
|
||||
key := ethutil.LeftPadBytes(k, 32)
|
||||
|
||||
|
@ -48,6 +48,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
pc = big.NewInt(0)
|
||||
step = 0
|
||||
prevStep = 0
|
||||
state = 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))
|
||||
@ -93,7 +94,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
if self.logTy == LogTyDiff {
|
||||
switch op {
|
||||
case STOP, RETURN, SUICIDE:
|
||||
closure.object.EachStorage(func(key string, value *ethutil.Value) {
|
||||
state.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())
|
||||
})
|
||||
@ -200,7 +201,12 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
self.Printf("(pc) %-3d -o- %-14s", pc, op.String())
|
||||
self.Printf(" (g) %-3v (%v)", gas, closure.Gas)
|
||||
|
||||
if !closure.UseGas(gas) {
|
||||
self.Endl()
|
||||
|
||||
err := fmt.Errorf("Insufficient gas for %v. req %v has %v", op, gas, closure.Gas)
|
||||
|
||||
closure.UseGas(closure.Gas)
|
||||
@ -208,9 +214,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
return closure.Return(nil), err
|
||||
}
|
||||
|
||||
self.Printf("(pc) %-3d -o- %-14s", pc, op.String())
|
||||
self.Printf(" (g) %-3v (%v)", gas, closure.Gas)
|
||||
|
||||
mem.Resize(newMemSize.Uint64())
|
||||
|
||||
switch op {
|
||||
@ -494,7 +497,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
require(1)
|
||||
|
||||
addr := stack.Pop().Bytes()
|
||||
balance := self.env.State().GetBalance(addr)
|
||||
balance := state.GetBalance(addr)
|
||||
|
||||
stack.Push(balance)
|
||||
|
||||
@ -562,7 +565,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
if op == EXTCODECOPY {
|
||||
addr := stack.Pop().Bytes()
|
||||
|
||||
code = self.env.State().GetCode(addr)
|
||||
code = state.GetCode(addr)
|
||||
} else {
|
||||
code = closure.Code
|
||||
}
|
||||
@ -576,7 +579,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
if op == EXTCODECOPY {
|
||||
addr := stack.Pop().Bytes()
|
||||
|
||||
code = self.env.State().GetCode(addr)
|
||||
code = state.GetCode(addr)
|
||||
} else {
|
||||
code = closure.Code
|
||||
}
|
||||
@ -693,15 +696,14 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
case SLOAD:
|
||||
require(1)
|
||||
loc := stack.Pop()
|
||||
val := closure.GetStorage(loc)
|
||||
|
||||
stack.Push(val.BigInt())
|
||||
val := ethutil.BigD(state.GetState(closure.Address(), loc.Bytes()))
|
||||
stack.Push(val)
|
||||
|
||||
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
|
||||
case SSTORE:
|
||||
require(2)
|
||||
val, loc := stack.Popn()
|
||||
closure.SetStorage(loc, ethutil.NewValue(val))
|
||||
state.SetState(closure.Address(), loc.Bytes(), val)
|
||||
|
||||
// Debug sessions are allowed to run without message
|
||||
if closure.message != nil {
|
||||
@ -712,6 +714,11 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
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()
|
||||
|
||||
@ -723,7 +730,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
pc = pos
|
||||
|
||||
if OpCode(closure.Get(pc).Uint()) != JUMPDEST {
|
||||
return closure.Return(nil), fmt.Errorf("JUMP missed JUMPDEST %v", pc)
|
||||
panic(fmt.Sprintf("JUMP missed JUMPDEST %v", pc))
|
||||
}
|
||||
|
||||
continue
|
||||
@ -755,8 +762,9 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
)
|
||||
|
||||
// Generate a new address
|
||||
addr := ethcrypto.CreateAddress(closure.Address(), closure.object.Nonce)
|
||||
closure.object.Nonce++
|
||||
n := state.GetNonce(closure.Address())
|
||||
addr := ethcrypto.CreateAddress(closure.Address(), n)
|
||||
state.SetNonce(closure.Address(), n+1)
|
||||
|
||||
self.Printf(" (*) %x", addr).Endl()
|
||||
|
||||
@ -799,8 +807,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
// Get the arguments from the memory
|
||||
args := mem.Get(inOffset.Int64(), inSize.Int64())
|
||||
|
||||
//snapshot := self.env.State().Copy()
|
||||
|
||||
var executeAddr []byte
|
||||
if op == CALLCODE {
|
||||
executeAddr = closure.Address()
|
||||
@ -813,12 +819,13 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
if err != nil {
|
||||
stack.Push(ethutil.BigFalse)
|
||||
|
||||
//self.env.State().Set(snapshot)
|
||||
vmlogger.Debugln(err)
|
||||
} else {
|
||||
stack.Push(ethutil.BigTrue)
|
||||
|
||||
mem.Set(retOffset.Int64(), retSize.Int64(), ret)
|
||||
}
|
||||
self.Printf("resume %x", closure.Address())
|
||||
|
||||
// Debug hook
|
||||
if self.Dbg != nil {
|
||||
@ -836,11 +843,10 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
case SUICIDE:
|
||||
require(1)
|
||||
|
||||
receiver := self.env.State().GetOrNewStateObject(stack.Pop().Bytes())
|
||||
receiver := state.GetOrNewStateObject(stack.Pop().Bytes())
|
||||
|
||||
receiver.AddAmount(closure.object.Balance)
|
||||
|
||||
closure.object.MarkForDeletion()
|
||||
receiver.AddAmount(state.GetBalance(closure.Address()))
|
||||
state.Delete(closure.Address())
|
||||
|
||||
fallthrough
|
||||
case STOP: // Stop the closure
|
||||
@ -864,11 +870,11 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
||||
if pc.Cmp(big.NewInt(instrNo)) == 0 {
|
||||
self.Stepping = true
|
||||
|
||||
if !self.Dbg.BreakHook(prevStep, op, mem, stack, closure.Object()) {
|
||||
if !self.Dbg.BreakHook(prevStep, op, mem, stack, state.GetStateObject(closure.Address())) {
|
||||
return nil, nil
|
||||
}
|
||||
} else if self.Stepping {
|
||||
if !self.Dbg.StepHook(prevStep, op, mem, stack, closure.Object()) {
|
||||
if !self.Dbg.StepHook(prevStep, op, mem, stack, state.GetStateObject(closure.Address())) {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user