aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chain/block_manager.go7
-rw-r--r--miner/miner.go2
-rw-r--r--state/state.go29
3 files changed, 21 insertions, 17 deletions
diff --git a/chain/block_manager.go b/chain/block_manager.go
index efe9e0862..fdb221cc3 100644
--- a/chain/block_manager.go
+++ b/chain/block_manager.go
@@ -154,10 +154,11 @@ done:
}
}
+ txGas.Sub(txGas, st.gas)
+
// Update the state with pending changes
- state.Update()
+ state.Update(txGas)
- txGas.Sub(txGas, st.gas)
cumulative := new(big.Int).Set(totalUsedGas.Add(totalUsedGas, txGas))
receipt := &Receipt{ethutil.CopyBytes(state.Root()), cumulative, nil /*bloom*/, state.Logs()}
receipt.Bloom = CreateBloom(Receipts{receipt})
@@ -245,7 +246,7 @@ func (sm *BlockManager) ProcessWithParent(block, parent *Block) (td *big.Int, me
return
}
- state.Update()
+ state.Update(nil)
if !block.State().Cmp(state) {
err = fmt.Errorf("invalid merkle root. received=%x got=%x", block.Root(), state.Root())
diff --git a/miner/miner.go b/miner/miner.go
index e3435f5a6..9152d532b 100644
--- a/miner/miner.go
+++ b/miner/miner.go
@@ -203,7 +203,7 @@ func (self *Miner) mine() {
// Accumulate the rewards included for this block
blockManager.AccumelateRewards(block.State(), block, parent)
- block.State().Update()
+ block.State().Update(nil)
minerlogger.Infof("Mining on block. Includes %v transactions", len(transactions))
diff --git a/state/state.go b/state/state.go
index 3abf1545b..0a7f717fe 100644
--- a/state/state.go
+++ b/state/state.go
@@ -23,14 +23,14 @@ type State struct {
manifest *Manifest
- refund map[string]*big.Int
+ refund map[string][]refund
logs Logs
}
// Create a new state from a given trie
func New(trie *trie.Trie) *State {
- return &State{Trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string]*big.Int)}
+ return &State{Trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string][]refund)}
}
func (self *State) EmptyLogs() {
@@ -55,14 +55,12 @@ 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)
- }
+type refund struct {
+ gas, price *big.Int
+}
- self.refund[string(addr)].Add(self.refund[string(addr)], amount)
+func (self *State) Refund(addr []byte, gas, price *big.Int) {
+ self.refund[string(addr)] = append(self.refund[string(addr)], refund{gas, price})
}
func (self *State) AddBalance(addr []byte, amount *big.Int) {
@@ -276,15 +274,20 @@ func (s *State) Sync() {
func (self *State) Empty() {
self.stateObjects = make(map[string]*StateObject)
- self.refund = make(map[string]*big.Int)
+ self.refund = make(map[string][]refund)
}
-func (self *State) Update() {
+func (self *State) Update(gasUsed *big.Int) {
var deleted bool
// Refund any gas that's left
- for addr, amount := range self.refund {
- self.GetStateObject([]byte(addr)).AddBalance(amount)
+ uhalf := new(big.Int).Div(gasUsed, ethutil.Big2)
+ for addr, refs := range self.refund {
+ for _, ref := range refs {
+ refund := ethutil.BigMin(uhalf, ref.gas)
+
+ self.GetStateObject([]byte(addr)).AddBalance(refund.Mul(refund, ref.price))
+ }
}
for _, stateObject := range self.stateObjects {