diff options
Diffstat (limited to 'light/state.go')
-rw-r--r-- | light/state.go | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/light/state.go b/light/state.go index 4f2177238..88f60efbb 100644 --- a/light/state.go +++ b/light/state.go @@ -20,6 +20,7 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "golang.org/x/net/context" @@ -33,10 +34,11 @@ var StartingNonce uint64 // state, retrieving unknown parts on-demand from the ODR backend. Changes are // never stored in the local database, only in the memory objects. type LightState struct { - odr OdrBackend - trie *LightTrie - + odr OdrBackend + trie *LightTrie + id *TrieID stateObjects map[string]*StateObject + refund *big.Int } // NewLightState creates a new LightState with the specified root. @@ -44,15 +46,25 @@ type LightState struct { // root is non-existent. In that case, ODR retrieval will always be unsuccessful // and every operation will return with an error or wait for the context to be // cancelled. -func NewLightState(root common.Hash, odr OdrBackend) *LightState { - tr := NewLightTrie(root, odr, true) +func NewLightState(id *TrieID, odr OdrBackend) *LightState { + var tr *LightTrie + if id != nil { + tr = NewLightTrie(id, odr, true) + } return &LightState{ odr: odr, trie: tr, + id: id, stateObjects: make(map[string]*StateObject), + refund: new(big.Int), } } +// AddRefund adds an amount to the refund value collected during a vm execution +func (self *LightState) AddRefund(gas *big.Int) { + self.refund.Add(self.refund, gas) +} + // HasAccount returns true if an account exists at the given address func (self *LightState) HasAccount(ctx context.Context, addr common.Address) (bool, error) { so, err := self.GetStateObject(ctx, addr) @@ -109,9 +121,9 @@ func (self *LightState) GetState(ctx context.Context, a common.Address, b common return common.Hash{}, err } -// IsDeleted returns true if the given account has been marked for deletion +// HasSuicided returns true if the given account has been marked for deletion // or false if the account does not exist -func (self *LightState) IsDeleted(ctx context.Context, addr common.Address) (bool, error) { +func (self *LightState) HasSuicided(ctx context.Context, addr common.Address) (bool, error) { stateObject, err := self.GetStateObject(ctx, addr) if err == nil && stateObject != nil { return stateObject.remove, nil @@ -145,7 +157,7 @@ func (self *LightState) SetNonce(ctx context.Context, addr common.Address, nonce func (self *LightState) SetCode(ctx context.Context, addr common.Address, code []byte) error { stateObject, err := self.GetOrNewStateObject(ctx, addr) if err == nil && stateObject != nil { - stateObject.SetCode(code) + stateObject.SetCode(crypto.Keccak256Hash(code), code) } return err } @@ -160,7 +172,7 @@ func (self *LightState) SetState(ctx context.Context, addr common.Address, key c } // Delete marks an account to be removed and clears its balance -func (self *LightState) Delete(ctx context.Context, addr common.Address) (bool, error) { +func (self *LightState) Suicide(ctx context.Context, addr common.Address) (bool, error) { stateObject, err := self.GetOrNewStateObject(ctx, addr) if err == nil && stateObject != nil { stateObject.MarkForDeletion() @@ -194,7 +206,7 @@ func (self *LightState) GetStateObject(ctx context.Context, addr common.Address) return nil, nil } - stateObject, err = DecodeObject(ctx, addr, self.odr, []byte(data)) + stateObject, err = DecodeObject(ctx, self.id, addr, self.odr, []byte(data)) if err != nil { return nil, err } @@ -258,14 +270,16 @@ func (self *LightState) CreateStateObject(ctx context.Context, addr common.Addre // Copy creates a copy of the state func (self *LightState) Copy() *LightState { // ignore error - we assume state-to-be-copied always exists - state := NewLightState(common.Hash{}, self.odr) + state := NewLightState(nil, self.odr) state.trie = self.trie + state.id = self.id for k, stateObject := range self.stateObjects { if stateObject.dirty { state.stateObjects[k] = stateObject.Copy() } } + state.refund.Set(self.refund) return state } @@ -274,4 +288,10 @@ func (self *LightState) Copy() *LightState { func (self *LightState) Set(state *LightState) { self.trie = state.trie self.stateObjects = state.stateObjects + self.refund = state.refund +} + +// GetRefund returns the refund value collected during a vm execution +func (self *LightState) GetRefund() *big.Int { + return self.refund } |