TransitionDb will transition the state by applying the current message and returning the result including the the used gas. It returns an error if it failed. An error indicates a consensus issue.
()
| 185 | // returning the result including the the used gas. It returns an error if it |
| 186 | // failed. An error indicates a consensus issue. |
| 187 | func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bool, err error) { |
| 188 | if err = st.preCheck(); err != nil { |
| 189 | return |
| 190 | } |
| 191 | |
| 192 | msg := st.msg |
| 193 | sender := vm.AccountRef(msg.From()) |
| 194 | contractCreation := msg.To() == nil |
| 195 | |
| 196 | // Pay intrinsic gas |
| 197 | gas, err := IntrinsicGas(st.data, contractCreation) |
| 198 | if err != nil { |
| 199 | return nil, 0, false, err |
| 200 | } |
| 201 | if err = st.useGas(gas); err != nil { |
| 202 | return nil, 0, false, err |
| 203 | } |
| 204 | |
| 205 | var ( |
| 206 | evm = st.evm |
| 207 | // vm errors do not effect consensus and are therefor |
| 208 | // not assigned to err, except for insufficient balance |
| 209 | // error. |
| 210 | vmerr error |
| 211 | ) |
| 212 | if contractCreation { |
| 213 | ret, _, st.gas, vmerr = evm.Create(sender, st.data, st.gas, st.value) |
| 214 | } else { |
| 215 | // Increment the nonce for the next transaction |
| 216 | st.state.SetNonce(msg.From(), st.state.GetNonce(sender.Address())+1) |
| 217 | ret, st.gas, vmerr = evm.Call(sender, st.to(), st.data, st.gas, st.value) |
| 218 | } |
| 219 | if vmerr != nil { |
| 220 | log.Debug("VM returned with error", "err", vmerr) |
| 221 | // The only possible consensus-error would be if there wasn't |
| 222 | // sufficient balance to make the transfer happen. The first |
| 223 | // balance transfer may never fail. |
| 224 | if vmerr == vm.ErrInsufficientBalance { |
| 225 | return nil, 0, false, vmerr |
| 226 | } |
| 227 | } |
| 228 | st.refundGas() |
| 229 | st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice)) |
| 230 | |
| 231 | return ret, st.gasUsed(), vmerr != nil, err |
| 232 | } |
| 233 | |
| 234 | func (st *StateTransition) refundGas() { |
| 235 | // Apply refund counter, capped to half of the used gas. |