aboutsummaryrefslogtreecommitdiffstats
path: root/core/state_transition.go
diff options
context:
space:
mode:
Diffstat (limited to 'core/state_transition.go')
-rw-r--r--core/state_transition.go31
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() {