aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2014-10-28 20:22:04 +0800
committerobscuren <geffobscura@gmail.com>2014-10-28 20:22:04 +0800
commit7849b7e97873ea443b480f45aa4fe6ffbb41cdb0 (patch)
tree712ca431b606bc72e6b829d64eb491f092040e78
parent5920aa7be6fb973c7cbae34c9d4af03665933c51 (diff)
downloaddexon-7849b7e97873ea443b480f45aa4fe6ffbb41cdb0.tar.gz
dexon-7849b7e97873ea443b480f45aa4fe6ffbb41cdb0.tar.zst
dexon-7849b7e97873ea443b480f45aa4fe6ffbb41cdb0.zip
Refund SSTORE properly
-rw-r--r--ethstate/state.go26
-rw-r--r--vm/vm_debug.go3
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