aboutsummaryrefslogtreecommitdiffstats
path: root/ethchain/state.go
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2014-03-03 18:35:35 +0800
committerobscuren <geffobscura@gmail.com>2014-03-03 18:35:35 +0800
commit5b1613d65b0c3471b80990120022b5a745ecab86 (patch)
treeaddbb87cc82cca07e8ac8aa810d810e1de02b2a5 /ethchain/state.go
parentd7c5936ac4ee8ae3156e0bc9813db61b990aa686 (diff)
parentc1d0ea7366f1bad134c985dbe1f272d376e5ec9b (diff)
downloaddexon-5b1613d65b0c3471b80990120022b5a745ecab86.tar
dexon-5b1613d65b0c3471b80990120022b5a745ecab86.tar.gz
dexon-5b1613d65b0c3471b80990120022b5a745ecab86.tar.bz2
dexon-5b1613d65b0c3471b80990120022b5a745ecab86.tar.lz
dexon-5b1613d65b0c3471b80990120022b5a745ecab86.tar.xz
dexon-5b1613d65b0c3471b80990120022b5a745ecab86.tar.zst
dexon-5b1613d65b0c3471b80990120022b5a745ecab86.zip
Merge branch 'master' into develop
Diffstat (limited to 'ethchain/state.go')
-rw-r--r--ethchain/state.go67
1 files changed, 62 insertions, 5 deletions
diff --git a/ethchain/state.go b/ethchain/state.go
index 1a18ea1d7..e6649cf22 100644
--- a/ethchain/state.go
+++ b/ethchain/state.go
@@ -5,12 +5,46 @@ import (
"math/big"
)
+// States within the ethereum protocol are used to store anything
+// within the merkle trie. States take care of caching and storing
+// nested states. It's the general query interface to retrieve:
+// * Contracts
+// * Accounts
type State struct {
+ // The trie for this structure
trie *ethutil.Trie
+ // Nested states
+ states map[string]*State
}
+// Create a new state from a given trie
func NewState(trie *ethutil.Trie) *State {
- return &State{trie: trie}
+ return &State{trie: trie, states: make(map[string]*State)}
+}
+
+// Resets the trie and all siblings
+func (s *State) Reset() {
+ s.trie.Undo()
+
+ // Reset all nested states
+ for _, state := range s.states {
+ state.Reset()
+ }
+}
+
+// Syncs the trie and all siblings
+func (s *State) Sync() {
+ s.trie.Sync()
+
+ // Sync all nested states
+ for _, state := range s.states {
+ state.Sync()
+ }
+}
+
+// Purges the current trie.
+func (s *State) Purge() int {
+ return s.trie.NewIterator().Purge()
}
func (s *State) GetContract(addr []byte) *Contract {
@@ -19,9 +53,28 @@ func (s *State) GetContract(addr []byte) *Contract {
return nil
}
+ // Whet get contract is called the retrieved value might
+ // be an account. The StateManager uses this to check
+ // to see if the address a tx was sent to is a contract
+ // or an account
+ value := ethutil.NewValueFromBytes([]byte(data))
+ if value.Len() == 2 {
+ return nil
+ }
+
+ // build contract
contract := &Contract{}
contract.RlpDecode([]byte(data))
+ // Check if there's a cached state for this contract
+ cachedState := s.states[string(addr)]
+ if cachedState != nil {
+ contract.state = cachedState
+ } else {
+ // If it isn't cached, cache the state
+ s.states[string(addr)] = contract.state
+ }
+
return contract
}
@@ -40,17 +93,21 @@ func Compile(code []string) (script []string) {
return
}
-func (s *State) GetAccount(addr []byte) (account *Address) {
+func (s *State) GetAccount(addr []byte) (account *Account) {
data := s.trie.Get(string(addr))
if data == "" {
- account = NewAddress(big.NewInt(0))
+ account = NewAccount(big.NewInt(0))
} else {
- account = NewAddressFromData([]byte(data))
+ account = NewAccountFromData([]byte(data))
}
return
}
-func (s *State) UpdateAccount(addr []byte, account *Address) {
+func (s *State) UpdateAccount(addr []byte, account *Account) {
s.trie.Update(string(addr), string(account.RlpEncode()))
}
+
+func (s *State) Cmp(other *State) bool {
+ return s.trie.Cmp(other.trie)
+}