diff options
author | Zsolt Felfoldi <zsfelfoldi@gmail.com> | 2016-10-14 11:47:09 +0800 |
---|---|---|
committer | Felix Lange <fjl@twurst.com> | 2016-11-09 09:12:53 +0800 |
commit | 760fd65487614b7a61443cd9371015925795f40f (patch) | |
tree | a2b122f03b7782e729be85b136f4c5304a164c9e /light/state_object.go | |
parent | 8b1df1a259fe6dc4c15e391e9c0762c9621d9d72 (diff) | |
download | go-tangerine-760fd65487614b7a61443cd9371015925795f40f.tar.gz go-tangerine-760fd65487614b7a61443cd9371015925795f40f.tar.zst go-tangerine-760fd65487614b7a61443cd9371015925795f40f.zip |
light: light chain, VM env and tx pool
Diffstat (limited to 'light/state_object.go')
-rw-r--r-- | light/state_object.go | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/light/state_object.go b/light/state_object.go index 1e9c7f4b1..61c3888fe 100644 --- a/light/state_object.go +++ b/light/state_object.go @@ -40,7 +40,7 @@ func (self Code) String() string { } // Storage is a memory map cache of a contract storage -type Storage map[string]common.Hash +type Storage map[common.Hash]common.Hash // String returns a string representation of the storage cache func (self Storage) String() (str string) { @@ -100,7 +100,7 @@ func NewStateObject(address common.Address, odr OdrBackend) *StateObject { codeHash: emptyCodeHash, storage: make(Storage), } - object.trie = NewLightTrie(common.Hash{}, odr, true) + object.trie = NewLightTrie(&TrieID{}, odr, true) return object } @@ -133,8 +133,7 @@ func (self *StateObject) Storage() Storage { // GetState returns the storage value at the given address from either the cache // or the trie func (self *StateObject) GetState(ctx context.Context, key common.Hash) (common.Hash, error) { - strkey := key.Str() - value, exists := self.storage[strkey] + value, exists := self.storage[key] if !exists { var err error value, err = self.getAddr(ctx, key) @@ -142,7 +141,7 @@ func (self *StateObject) GetState(ctx context.Context, key common.Hash) (common. return common.Hash{}, err } if (value != common.Hash{}) { - self.storage[strkey] = value + self.storage[key] = value } } @@ -151,7 +150,7 @@ func (self *StateObject) GetState(ctx context.Context, key common.Hash) (common. // SetState sets the storage value at the given address func (self *StateObject) SetState(k, value common.Hash) { - self.storage[k.Str()] = value + self.storage[k] = value self.dirty = true } @@ -179,6 +178,9 @@ func (c *StateObject) SetBalance(amount *big.Int) { c.dirty = true } +// ReturnGas returns the gas back to the origin. Used by the Virtual machine or Closures +func (c *StateObject) ReturnGas(gas, price *big.Int) {} + // Copy creates a copy of the state object func (self *StateObject) Copy() *StateObject { stateObject := NewStateObject(self.Address(), self.odr) @@ -215,9 +217,9 @@ func (self *StateObject) Code() []byte { } // SetCode sets the contract code -func (self *StateObject) SetCode(code []byte) { +func (self *StateObject) SetCode(hash common.Hash, code []byte) { self.code = code - self.codeHash = crypto.Keccak256(code) + self.codeHash = hash[:] self.dirty = true } @@ -232,6 +234,23 @@ func (self *StateObject) Nonce() uint64 { return self.nonce } +// ForEachStorage calls a callback function for every key/value pair found +// in the local storage cache. Note that unlike core/state.StateObject, +// light.StateObject only returns cached values and doesn't download the +// entire storage tree. +func (self *StateObject) ForEachStorage(cb func(key, value common.Hash) bool) { + for h, v := range self.storage { + cb(h, v) + } +} + +// Never called, but must be present to allow StateObject to be used +// as a vm.Account interface that also satisfies the vm.ContractRef +// interface. Interfaces are awesome. +func (self *StateObject) Value() *big.Int { + panic("Value on StateObject should never be called") +} + // Encoding type extStateObject struct { @@ -242,7 +261,7 @@ type extStateObject struct { } // DecodeObject decodes an RLP-encoded state object. -func DecodeObject(ctx context.Context, address common.Address, odr OdrBackend, data []byte) (*StateObject, error) { +func DecodeObject(ctx context.Context, stateID *TrieID, address common.Address, odr OdrBackend, data []byte) (*StateObject, error) { var ( obj = &StateObject{address: address, odr: odr, storage: make(Storage)} ext extStateObject @@ -251,9 +270,10 @@ func DecodeObject(ctx context.Context, address common.Address, odr OdrBackend, d if err = rlp.DecodeBytes(data, &ext); err != nil { return nil, err } - obj.trie = NewLightTrie(ext.Root, odr, true) + trieID := StorageTrieID(stateID, address, ext.Root) + obj.trie = NewLightTrie(trieID, odr, true) if !bytes.Equal(ext.CodeHash, emptyCodeHash) { - if obj.code, err = retrieveNodeData(ctx, obj.odr, common.BytesToHash(ext.CodeHash)); err != nil { + if obj.code, err = retrieveContractCode(ctx, obj.odr, trieID, common.BytesToHash(ext.CodeHash)); err != nil { return nil, fmt.Errorf("can't find code for hash %x: %v", ext.CodeHash, err) } } |