|
|
@@ -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() {
|