diff options
author | obscuren <geffobscura@gmail.com> | 2014-10-28 20:22:04 +0800 |
---|---|---|
committer | obscuren <geffobscura@gmail.com> | 2014-10-28 20:22:04 +0800 |
commit | 7849b7e97873ea443b480f45aa4fe6ffbb41cdb0 (patch) | |
tree | 712ca431b606bc72e6b829d64eb491f092040e78 | |
parent | 5920aa7be6fb973c7cbae34c9d4af03665933c51 (diff) | |
download | go-tangerine-7849b7e97873ea443b480f45aa4fe6ffbb41cdb0.tar go-tangerine-7849b7e97873ea443b480f45aa4fe6ffbb41cdb0.tar.gz go-tangerine-7849b7e97873ea443b480f45aa4fe6ffbb41cdb0.tar.bz2 go-tangerine-7849b7e97873ea443b480f45aa4fe6ffbb41cdb0.tar.lz go-tangerine-7849b7e97873ea443b480f45aa4fe6ffbb41cdb0.tar.xz go-tangerine-7849b7e97873ea443b480f45aa4fe6ffbb41cdb0.tar.zst go-tangerine-7849b7e97873ea443b480f45aa4fe6ffbb41cdb0.zip |
Refund SSTORE properly
-rw-r--r-- | ethstate/state.go | 26 | ||||
-rw-r--r-- | vm/vm_debug.go | 3 |
2 files changed, 27 insertions, 2 deletions
diff --git a/ethstate/state.go b/ethstate/state.go index c23dab330..97958cc0a 100644 --- a/ethstate/state.go +++ b/ethstate/state.go @@ -22,11 +22,13 @@ type State struct { stateObjects map[string]*StateObject manifest *Manifest + + refund map[string]*big.Int } // Create a new state from a given trie func New(trie *ethtrie.Trie) *State { - return &State{Trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest()} + return &State{Trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string]*big.Int)} } // Retrieve the balance from the given address or 0 if object not found @@ -39,6 +41,16 @@ func (self *State) GetBalance(addr []byte) *big.Int { return ethutil.Big0 } +func (self *State) Refund(addr []byte, gas, price *big.Int) { + amount := new(big.Int).Mul(gas, price) + + if self.refund[string(addr)] == nil { + self.refund[string(addr)] = new(big.Int) + } + + self.refund[string(addr)] = new(big.Int).Add(self.refund[string(addr)], amount) +} + func (self *State) AddBalance(addr []byte, amount *big.Int) { stateObject := self.GetStateObject(addr) if stateObject != nil { @@ -186,6 +198,10 @@ func (self *State) Copy() *State { state.stateObjects[k] = stateObject.Copy() } + for addr, refund := range self.refund { + state.refund[addr] = refund + } + return state } @@ -199,6 +215,7 @@ func (self *State) Set(state *State) { self.Trie = state.Trie self.stateObjects = state.stateObjects + self.refund = state.refund } func (s *State) Root() interface{} { @@ -240,10 +257,17 @@ func (s *State) Sync() { func (self *State) Empty() { self.stateObjects = make(map[string]*StateObject) + self.refund = make(map[string]*big.Int) } func (self *State) Update() { var deleted bool + + // Refund any gas that's left + for addr, amount := range self.refund { + self.GetStateObject([]byte(addr)).AddBalance(amount) + } + for _, stateObject := range self.stateObjects { if stateObject.remove { self.DeleteStateObject(stateObject) diff --git a/vm/vm_debug.go b/vm/vm_debug.go index 13446d6c0..d38373411 100644 --- a/vm/vm_debug.go +++ b/vm/vm_debug.go @@ -179,7 +179,8 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { // 0 => non 0 mult = ethutil.Big3 } else if val.BigInt().Cmp(ethutil.Big0) != 0 && len(y.Bytes()) == 0 { - //state.AddBalance(closure.caller.Address(), new(big.Int).Mul(big.NewInt(100), closure.Price)) + state.Refund(closure.caller.Address(), big.NewInt(100), closure.Price) + mult = ethutil.Big0 } else { // non 0 => non 0 |