diff options
author | obscuren <geffobscura@gmail.com> | 2014-12-19 04:58:26 +0800 |
---|---|---|
committer | obscuren <geffobscura@gmail.com> | 2014-12-19 04:58:26 +0800 |
commit | 198cc69357a0f25ae486a041786e1239c6f5ab0f (patch) | |
tree | 39f4b8c4a8b8360d2fe2fc5583438f948e095524 /core | |
parent | 5ad473d7581b92811c3a3e035274a82fc5568f57 (diff) | |
download | go-tangerine-198cc69357a0f25ae486a041786e1239c6f5ab0f.tar.gz go-tangerine-198cc69357a0f25ae486a041786e1239c6f5ab0f.tar.zst go-tangerine-198cc69357a0f25ae486a041786e1239c6f5ab0f.zip |
Gas corrections and vm fixes
Diffstat (limited to 'core')
-rw-r--r-- | core/block_manager.go | 2 | ||||
-rw-r--r-- | core/state_transition.go | 73 | ||||
-rw-r--r-- | core/types/transaction.go | 9 |
3 files changed, 38 insertions, 46 deletions
diff --git a/core/block_manager.go b/core/block_manager.go index aa845a007..8d319f84e 100644 --- a/core/block_manager.go +++ b/core/block_manager.go @@ -115,7 +115,7 @@ done: cb := state.GetStateObject(coinbase.Address()) st := NewStateTransition(cb, tx, state, block) - err = st.TransitionState() + _, err = st.TransitionState() if err != nil { switch { case IsNonceErr(err): 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) +} diff --git a/core/types/transaction.go b/core/types/transaction.go index 21d455f2e..c64fb69f0 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -46,15 +46,6 @@ func NewTransactionFromValue(val *ethutil.Value) *Transaction { return tx } -func (self *Transaction) GasValue() *big.Int { - return new(big.Int).Mul(self.gas, self.gasPrice) -} - -func (self *Transaction) TotalValue() *big.Int { - v := self.GasValue() - return v.Add(v, self.value) -} - func (tx *Transaction) Hash() []byte { data := []interface{}{tx.Nonce, tx.gasPrice, tx.gas, tx.recipient, tx.Value, tx.Data} |