aboutsummaryrefslogtreecommitdiffstats
path: root/ethchain/state.go
diff options
context:
space:
mode:
Diffstat (limited to 'ethchain/state.go')
-rw-r--r--ethchain/state.go163
1 files changed, 105 insertions, 58 deletions
diff --git a/ethchain/state.go b/ethchain/state.go
index 20af94fe8..8df79dcef 100644
--- a/ethchain/state.go
+++ b/ethchain/state.go
@@ -1,6 +1,7 @@
package ethchain
import (
+ "fmt"
"github.com/ethereum/eth-go/ethcrypto"
"github.com/ethereum/eth-go/ethtrie"
"github.com/ethereum/eth-go/ethutil"
@@ -26,70 +27,36 @@ func NewState(trie *ethtrie.Trie) *State {
return &State{trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest()}
}
-// Resets the trie and all siblings
-func (s *State) Reset() {
- s.trie.Undo()
-
- // Reset all nested states
- for _, stateObject := range s.stateObjects {
- if stateObject.state == nil {
- continue
- }
-
- stateObject.state.Reset()
- }
-
- s.Empty()
+// Iterate over each storage address and yield callback
+func (s *State) EachStorage(cb ethtrie.EachCallback) {
+ it := s.trie.NewIterator()
+ it.Each(cb)
}
-// Syncs the trie and all siblings
-func (s *State) Sync() {
- // Sync all nested states
- for _, stateObject := range s.stateObjects {
- s.UpdateStateObject(stateObject)
-
- if stateObject.state == nil {
- continue
- }
-
- stateObject.state.Sync()
+// Retrieve the balance from the given address or 0 if object not found
+func (self *State) GetBalance(addr []byte) *big.Int {
+ stateObject := self.GetStateObject(addr)
+ if stateObject != nil {
+ return stateObject.Amount
}
- s.trie.Sync()
-
- s.Empty()
-}
-
-func (self *State) Empty() {
- self.stateObjects = make(map[string]*StateObject)
+ return ethutil.Big0
}
-func (self *State) Update() {
- for _, stateObject := range self.stateObjects {
- if stateObject.remove {
- self.trie.Delete(string(stateObject.Address()))
- } else {
- self.UpdateStateObject(stateObject)
- }
+func (self *State) GetNonce(addr []byte) uint64 {
+ stateObject := self.GetStateObject(addr)
+ if stateObject != nil {
+ return stateObject.Nonce
}
-}
-// Purges the current trie.
-func (s *State) Purge() int {
- return s.trie.NewIterator().Purge()
+ return 0
}
-func (s *State) EachStorage(cb ethtrie.EachCallback) {
- it := s.trie.NewIterator()
- it.Each(cb)
-}
-
-func (self *State) ResetStateObject(stateObject *StateObject) {
- delete(self.stateObjects, string(stateObject.Address()))
-
- stateObject.state.Reset()
-}
+//
+// Setting, updating & deleting state object methods
+//
+// Update the given state object and apply it to state trie
func (self *State) UpdateStateObject(stateObject *StateObject) {
addr := stateObject.Address()
@@ -100,6 +67,14 @@ func (self *State) UpdateStateObject(stateObject *StateObject) {
self.manifest.AddObjectChange(stateObject)
}
+// Delete the given state object and delete it from the state trie
+func (self *State) DeleteStateObject(stateObject *StateObject) {
+ self.trie.Delete(string(stateObject.Address()))
+
+ delete(self.stateObjects, string(stateObject.Address()))
+}
+
+// Retrieve a state object given my the address. Nil if not found
func (self *State) GetStateObject(addr []byte) *StateObject {
stateObject := self.stateObjects[string(addr)]
if stateObject != nil {
@@ -117,6 +92,7 @@ func (self *State) GetStateObject(addr []byte) *StateObject {
return stateObject
}
+// Retrieve a state object or create a new state object if nil
func (self *State) GetOrNewStateObject(addr []byte) *StateObject {
stateObject := self.GetStateObject(addr)
if stateObject == nil {
@@ -126,6 +102,7 @@ func (self *State) GetOrNewStateObject(addr []byte) *StateObject {
return stateObject
}
+// Create a state object whether it exist in the trie or not
func (self *State) NewStateObject(addr []byte) *StateObject {
statelogger.Infof("(+) %x\n", addr)
@@ -135,10 +112,15 @@ func (self *State) NewStateObject(addr []byte) *StateObject {
return stateObject
}
+// Deprecated
func (self *State) GetAccount(addr []byte) *StateObject {
return self.GetOrNewStateObject(addr)
}
+//
+// Setting, copying of the state methods
+//
+
func (s *State) Cmp(other *State) bool {
return s.trie.Cmp(other.trie)
}
@@ -161,17 +143,82 @@ func (self *State) Set(state *State) {
panic("Tried setting 'state' to nil through 'Set'")
}
- *self = *state
-}
-
-func (s *State) Put(key, object []byte) {
- s.trie.Update(string(key), string(object))
+ self.trie = state.trie
+ self.stateObjects = state.stateObjects
+ //*self = *state
}
func (s *State) Root() interface{} {
return s.trie.Root
}
+// Resets the trie and all siblings
+func (s *State) Reset() {
+ s.trie.Undo()
+
+ // Reset all nested states
+ for _, stateObject := range s.stateObjects {
+ if stateObject.state == nil {
+ continue
+ }
+
+ //stateObject.state.Reset()
+ stateObject.Reset()
+ }
+
+ s.Empty()
+}
+
+// Syncs the trie and all siblings
+func (s *State) Sync() {
+ // Sync all nested states
+ for _, stateObject := range s.stateObjects {
+ s.UpdateStateObject(stateObject)
+
+ if stateObject.state == nil {
+ continue
+ }
+
+ stateObject.state.Sync()
+ }
+
+ s.trie.Sync()
+
+ s.Empty()
+}
+
+func (self *State) Empty() {
+ self.stateObjects = make(map[string]*StateObject)
+}
+
+func (self *State) Update() {
+ for _, stateObject := range self.stateObjects {
+ if stateObject.remove {
+ self.DeleteStateObject(stateObject)
+ } else {
+ stateObject.Sync()
+
+ self.UpdateStateObject(stateObject)
+ }
+ }
+
+ // FIXME trie delete is broken
+ valid, t2 := ethtrie.ParanoiaCheck(self.trie)
+ if !valid {
+ self.trie = t2
+ }
+}
+
+// Debug stuff
+func (self *State) CreateOutputForDiff() {
+ for addr, stateObject := range self.stateObjects {
+ fmt.Printf("0x%x 0x%x 0x%x 0x%x\n", addr, stateObject.state.Root(), stateObject.Amount.Bytes(), stateObject.Nonce)
+ stateObject.state.EachStorage(func(addr string, value *ethutil.Value) {
+ fmt.Printf("0x%x 0x%x\n", addr, value.Bytes())
+ })
+ }
+}
+
// Object manifest
//
// The object manifest is used to keep changes to the state so we can keep track of the changes