diff options
Diffstat (limited to 'core/state_transition.go')
-rw-r--r-- | core/state_transition.go | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/core/state_transition.go b/core/state_transition.go index 60ac7d8cb..c8160424b 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -104,8 +104,9 @@ func IntrinsicGas(data []byte, contractCreation, homestead bool) *big.Int { return igas } -func ApplyMessage(env vm.Environment, msg Message, gp *GasPool) ([]byte, *big.Int, error) { - var st = StateTransition{ +// NewStateTransition initialises and returns a new state transition object. +func NewStateTransition(env vm.Environment, msg Message, gp *GasPool) *StateTransition { + return &StateTransition{ gp: gp, env: env, msg: msg, @@ -116,7 +117,20 @@ func ApplyMessage(env vm.Environment, msg Message, gp *GasPool) ([]byte, *big.In data: msg.Data(), state: env.Db(), } - return st.transitionDb() +} + +// ApplyMessage computes the new state by applying the given message +// against the old state within the environment. +// +// ApplyMessage returns the bytes returned by any EVM execution (if it took place), +// the gas used (which includes gas refunds) and an error if it failed. An error always +// indicates a core error meaning that the message would always fail for that particular +// state and would never be accepted within a block. +func ApplyMessage(env vm.Environment, msg Message, gp *GasPool) ([]byte, *big.Int, error) { + st := NewStateTransition(env, msg, gp) + + ret, _, gasUsed, err := st.TransitionDb() + return ret, gasUsed, err } func (self *StateTransition) from() (vm.Account, error) { @@ -209,7 +223,8 @@ func (self *StateTransition) preCheck() (err error) { return nil } -func (self *StateTransition) transitionDb() (ret []byte, usedGas *big.Int, err error) { +// TransitionDb will move the state by applying the message against the given environment. +func (self *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big.Int, err error) { if err = self.preCheck(); err != nil { return } @@ -220,7 +235,7 @@ func (self *StateTransition) transitionDb() (ret []byte, usedGas *big.Int, err e contractCreation := MessageCreatesContract(msg) // Pay intrinsic gas if err = self.useGas(IntrinsicGas(self.data, contractCreation, homestead)); err != nil { - return nil, nil, InvalidTxError(err) + return nil, nil, nil, InvalidTxError(err) } vmenv := self.env @@ -245,7 +260,7 @@ func (self *StateTransition) transitionDb() (ret []byte, usedGas *big.Int, err e } if err != nil && IsValueTransferErr(err) { - return nil, nil, InvalidTxError(err) + return nil, nil, nil, InvalidTxError(err) } // We aren't interested in errors here. Errors returned by the VM are non-consensus errors and therefor shouldn't bubble up @@ -253,10 +268,12 @@ func (self *StateTransition) transitionDb() (ret []byte, usedGas *big.Int, err e err = nil } + requiredGas = new(big.Int).Set(self.gasUsed()) + self.refundGas() self.state.AddBalance(self.env.Coinbase(), new(big.Int).Mul(self.gasUsed(), self.gasPrice)) - return ret, self.gasUsed(), err + return ret, requiredGas, self.gasUsed(), err } func (self *StateTransition) refundGas() { |