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
|
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 {
|
func (self *State) GetCode(addr []byte) []byte {
|
||||||
stateObject := self.GetStateObject(addr)
|
stateObject := self.GetStateObject(addr)
|
||||||
if stateObject != nil {
|
if stateObject != nil {
|
||||||
@ -66,6 +73,24 @@ func (self *State) GetState(a, b []byte) []byte {
|
|||||||
return nil
|
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
|
// 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)
|
self.SetState(key.Bytes(), value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *StateObject) Storage() map[string]*ethutil.Value {
|
||||||
|
return self.storage
|
||||||
|
}
|
||||||
|
|
||||||
func (self *StateObject) GetState(k []byte) *ethutil.Value {
|
func (self *StateObject) GetState(k []byte) *ethutil.Value {
|
||||||
key := ethutil.LeftPadBytes(k, 32)
|
key := ethutil.LeftPadBytes(k, 32)
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
pc = big.NewInt(0)
|
pc = big.NewInt(0)
|
||||||
step = 0
|
step = 0
|
||||||
prevStep = 0
|
prevStep = 0
|
||||||
|
state = self.env.State()
|
||||||
require = func(m int) {
|
require = func(m int) {
|
||||||
if stack.Len() < m {
|
if stack.Len() < m {
|
||||||
panic(fmt.Sprintf("%04v (%v) stack err size = %d, required = %d", pc, op, 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 {
|
if self.logTy == LogTyDiff {
|
||||||
switch op {
|
switch op {
|
||||||
case STOP, RETURN, SUICIDE:
|
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()
|
value.Decode()
|
||||||
fmt.Printf("%x %x\n", new(big.Int).SetBytes([]byte(key)).Bytes(), value.Bytes())
|
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) {
|
if !closure.UseGas(gas) {
|
||||||
|
self.Endl()
|
||||||
|
|
||||||
err := fmt.Errorf("Insufficient gas for %v. req %v has %v", op, gas, closure.Gas)
|
err := fmt.Errorf("Insufficient gas for %v. req %v has %v", op, gas, closure.Gas)
|
||||||
|
|
||||||
closure.UseGas(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
|
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())
|
mem.Resize(newMemSize.Uint64())
|
||||||
|
|
||||||
switch op {
|
switch op {
|
||||||
@ -494,7 +497,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
require(1)
|
require(1)
|
||||||
|
|
||||||
addr := stack.Pop().Bytes()
|
addr := stack.Pop().Bytes()
|
||||||
balance := self.env.State().GetBalance(addr)
|
balance := state.GetBalance(addr)
|
||||||
|
|
||||||
stack.Push(balance)
|
stack.Push(balance)
|
||||||
|
|
||||||
@ -562,7 +565,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
if op == EXTCODECOPY {
|
if op == EXTCODECOPY {
|
||||||
addr := stack.Pop().Bytes()
|
addr := stack.Pop().Bytes()
|
||||||
|
|
||||||
code = self.env.State().GetCode(addr)
|
code = state.GetCode(addr)
|
||||||
} else {
|
} else {
|
||||||
code = closure.Code
|
code = closure.Code
|
||||||
}
|
}
|
||||||
@ -576,7 +579,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
if op == EXTCODECOPY {
|
if op == EXTCODECOPY {
|
||||||
addr := stack.Pop().Bytes()
|
addr := stack.Pop().Bytes()
|
||||||
|
|
||||||
code = self.env.State().GetCode(addr)
|
code = state.GetCode(addr)
|
||||||
} else {
|
} else {
|
||||||
code = closure.Code
|
code = closure.Code
|
||||||
}
|
}
|
||||||
@ -693,15 +696,14 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
case SLOAD:
|
case SLOAD:
|
||||||
require(1)
|
require(1)
|
||||||
loc := stack.Pop()
|
loc := stack.Pop()
|
||||||
val := closure.GetStorage(loc)
|
val := ethutil.BigD(state.GetState(closure.Address(), loc.Bytes()))
|
||||||
|
stack.Push(val)
|
||||||
stack.Push(val.BigInt())
|
|
||||||
|
|
||||||
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
|
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
|
||||||
case SSTORE:
|
case SSTORE:
|
||||||
require(2)
|
require(2)
|
||||||
val, loc := stack.Popn()
|
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
|
// Debug sessions are allowed to run without message
|
||||||
if closure.message != nil {
|
if closure.message != nil {
|
||||||
@ -712,6 +714,11 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
case JUMP:
|
case JUMP:
|
||||||
require(1)
|
require(1)
|
||||||
pc = stack.Pop()
|
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
|
// Reduce pc by one because of the increment that's at the end of this for loop
|
||||||
self.Printf(" ~> %v", pc).Endl()
|
self.Printf(" ~> %v", pc).Endl()
|
||||||
|
|
||||||
@ -723,7 +730,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
pc = pos
|
pc = pos
|
||||||
|
|
||||||
if OpCode(closure.Get(pc).Uint()) != JUMPDEST {
|
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
|
continue
|
||||||
@ -755,8 +762,9 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Generate a new address
|
// Generate a new address
|
||||||
addr := ethcrypto.CreateAddress(closure.Address(), closure.object.Nonce)
|
n := state.GetNonce(closure.Address())
|
||||||
closure.object.Nonce++
|
addr := ethcrypto.CreateAddress(closure.Address(), n)
|
||||||
|
state.SetNonce(closure.Address(), n+1)
|
||||||
|
|
||||||
self.Printf(" (*) %x", addr).Endl()
|
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
|
// Get the arguments from the memory
|
||||||
args := mem.Get(inOffset.Int64(), inSize.Int64())
|
args := mem.Get(inOffset.Int64(), inSize.Int64())
|
||||||
|
|
||||||
//snapshot := self.env.State().Copy()
|
|
||||||
|
|
||||||
var executeAddr []byte
|
var executeAddr []byte
|
||||||
if op == CALLCODE {
|
if op == CALLCODE {
|
||||||
executeAddr = closure.Address()
|
executeAddr = closure.Address()
|
||||||
@ -813,12 +819,13 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
stack.Push(ethutil.BigFalse)
|
stack.Push(ethutil.BigFalse)
|
||||||
|
|
||||||
//self.env.State().Set(snapshot)
|
vmlogger.Debugln(err)
|
||||||
} else {
|
} else {
|
||||||
stack.Push(ethutil.BigTrue)
|
stack.Push(ethutil.BigTrue)
|
||||||
|
|
||||||
mem.Set(retOffset.Int64(), retSize.Int64(), ret)
|
mem.Set(retOffset.Int64(), retSize.Int64(), ret)
|
||||||
}
|
}
|
||||||
|
self.Printf("resume %x", closure.Address())
|
||||||
|
|
||||||
// Debug hook
|
// Debug hook
|
||||||
if self.Dbg != nil {
|
if self.Dbg != nil {
|
||||||
@ -836,11 +843,10 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
case SUICIDE:
|
case SUICIDE:
|
||||||
require(1)
|
require(1)
|
||||||
|
|
||||||
receiver := self.env.State().GetOrNewStateObject(stack.Pop().Bytes())
|
receiver := state.GetOrNewStateObject(stack.Pop().Bytes())
|
||||||
|
|
||||||
receiver.AddAmount(closure.object.Balance)
|
receiver.AddAmount(state.GetBalance(closure.Address()))
|
||||||
|
state.Delete(closure.Address())
|
||||||
closure.object.MarkForDeletion()
|
|
||||||
|
|
||||||
fallthrough
|
fallthrough
|
||||||
case STOP: // Stop the closure
|
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 {
|
if pc.Cmp(big.NewInt(instrNo)) == 0 {
|
||||||
self.Stepping = true
|
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
|
return nil, nil
|
||||||
}
|
}
|
||||||
} else if self.Stepping {
|
} 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
|
return nil, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user