aboutsummaryrefslogtreecommitdiffstats
path: root/core/state_transition.go
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2014-12-19 04:58:26 +0800
committerobscuren <geffobscura@gmail.com>2014-12-19 04:58:26 +0800
commit198cc69357a0f25ae486a041786e1239c6f5ab0f (patch)
tree39f4b8c4a8b8360d2fe2fc5583438f948e095524 /core/state_transition.go
parent5ad473d7581b92811c3a3e035274a82fc5568f57 (diff)
downloaddexon-198cc69357a0f25ae486a041786e1239c6f5ab0f.tar.gz
dexon-198cc69357a0f25ae486a041786e1239c6f5ab0f.tar.zst
dexon-198cc69357a0f25ae486a041786e1239c6f5ab0f.zip
Gas corrections and vm fixes
Diffstat (limited to 'core/state_transition.go')
-rw-r--r--core/state_transition.go73
1 files changed, 37 insertions, 36 deletions
diff --git a/core/state_transition.go b/core/state_transition.go
index 61c9558e3..34d8cca74 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -31,6 +31,7 @@ type StateTransition struct {
coinbase, receiver []byte
msg Message
gas, gasPrice *big.Int
+ initialGas *big.Int
value *big.Int
data []byte
state *state.StateDB
@@ -47,7 +48,6 @@ type Message interface {
From() []byte
To() []byte
- GasValue() *big.Int
GasPrice() *big.Int
Gas() *big.Int
Value() *big.Int
@@ -65,8 +65,12 @@ func MessageCreatesContract(msg Message) bool {
return len(msg.To()) == 0
}
+func MessageGasValue(msg Message) *big.Int {
+ return new(big.Int).Mul(msg.Gas(), msg.GasPrice())
+}
+
func NewStateTransition(coinbase *state.StateObject, msg Message, state *state.StateDB, block *types.Block) *StateTransition {
- return &StateTransition{coinbase.Address(), msg.To(), msg, new(big.Int), new(big.Int).Set(msg.GasPrice()), msg.Value(), msg.Data(), state, block, coinbase, nil, nil, nil}
+ return &StateTransition{coinbase.Address(), msg.To(), msg, new(big.Int), new(big.Int).Set(msg.GasPrice()), new(big.Int), msg.Value(), msg.Data(), state, block, coinbase, nil, nil, nil}
}
func (self *StateTransition) VmEnv() vm.Environment {
@@ -78,33 +82,16 @@ func (self *StateTransition) VmEnv() vm.Environment {
}
func (self *StateTransition) Coinbase() *state.StateObject {
- if self.cb != nil {
- return self.cb
- }
-
- self.cb = self.state.GetOrNewStateObject(self.coinbase)
- return self.cb
+ return self.state.GetOrNewStateObject(self.coinbase)
}
func (self *StateTransition) From() *state.StateObject {
- if self.sen != nil {
- return self.sen
- }
-
- self.sen = self.state.GetOrNewStateObject(self.msg.From())
-
- return self.sen
+ return self.state.GetOrNewStateObject(self.msg.From())
}
func (self *StateTransition) To() *state.StateObject {
if self.msg != nil && MessageCreatesContract(self.msg) {
return nil
}
-
- if self.rec != nil {
- return self.rec
- }
-
- self.rec = self.state.GetOrNewStateObject(self.msg.To())
- return self.rec
+ return self.state.GetOrNewStateObject(self.msg.To())
}
func (self *StateTransition) UseGas(amount *big.Int) error {
@@ -124,8 +111,8 @@ func (self *StateTransition) BuyGas() error {
var err error
sender := self.From()
- if sender.Balance().Cmp(self.msg.GasValue()) < 0 {
- return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.msg.GasValue(), sender.Balance())
+ if sender.Balance().Cmp(MessageGasValue(self.msg)) < 0 {
+ return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", MessageGasValue(self.msg), sender.Balance())
}
coinbase := self.Coinbase()
@@ -135,20 +122,12 @@ func (self *StateTransition) BuyGas() error {
}
self.AddGas(self.msg.Gas())
- sender.SubAmount(self.msg.GasValue())
+ self.initialGas.Set(self.msg.Gas())
+ sender.SubAmount(MessageGasValue(self.msg))
return nil
}
-func (self *StateTransition) RefundGas() {
- coinbase, sender := self.Coinbase(), self.From()
- coinbase.RefundGas(self.gas, self.msg.GasPrice())
-
- // Return remaining gas
- remaining := new(big.Int).Mul(self.gas, self.msg.GasPrice())
- sender.AddAmount(remaining)
-}
-
func (self *StateTransition) preCheck() (err error) {
var (
msg = self.msg
@@ -168,7 +147,7 @@ func (self *StateTransition) preCheck() (err error) {
return nil
}
-func (self *StateTransition) TransitionState() (err error) {
+func (self *StateTransition) TransitionState() (ret []byte, err error) {
statelogger.Debugf("(~) %x\n", self.msg.Hash())
// XXX Transactions after this point are considered valid.
@@ -204,7 +183,6 @@ func (self *StateTransition) TransitionState() (err error) {
return
}
- var ret []byte
vmenv := self.VmEnv()
var ref vm.ClosureRef
if MessageCreatesContract(msg) {
@@ -231,3 +209,26 @@ func MakeContract(msg Message, state *state.StateDB) *state.StateObject {
return contract
}
+
+func (self *StateTransition) RefundGas() {
+ coinbaseSub := new(big.Int).Set(self.gas)
+ uhalf := new(big.Int).Div(self.GasUsed(), ethutil.Big2)
+ for addr, refs := range self.state.Refunds() {
+ for _, ref := range refs {
+ coinbaseSub.Add(self.gas, ref)
+ refund := ethutil.BigMin(uhalf, ref)
+ self.state.AddBalance([]byte(addr), refund.Mul(refund, self.msg.GasPrice()))
+ }
+ }
+
+ coinbase, sender := self.Coinbase(), self.From()
+ coinbase.RefundGas(coinbaseSub, self.msg.GasPrice())
+
+ // Return remaining gas
+ remaining := new(big.Int).Mul(self.gas, self.msg.GasPrice())
+ sender.AddAmount(remaining)
+}
+
+func (self *StateTransition) GasUsed() *big.Int {
+ return new(big.Int).Sub(self.initialGas, self.gas)
+}