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.go56
1 files changed, 37 insertions, 19 deletions
diff --git a/core/state_transition.go b/core/state_transition.go
index 12c3ab3a1..2887f6228 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -27,6 +27,10 @@ import (
"github.com/ethereum/go-ethereum/params"
)
+var (
+ Big0 = big.NewInt(0)
+)
+
/*
The State Transitioning Model
@@ -59,6 +63,7 @@ type StateTransition struct {
// Message represents a message sent to a contract.
type Message interface {
From() (common.Address, error)
+ FromFrontier() (common.Address, error)
To() *common.Address
GasPrice() *big.Int
@@ -75,8 +80,13 @@ func MessageCreatesContract(msg Message) bool {
// IntrinsicGas computes the 'intrinsic gas' for a message
// with the given data.
-func IntrinsicGas(data []byte) *big.Int {
- igas := new(big.Int).Set(params.TxGas)
+func IntrinsicGas(data []byte, contractCreation, homestead bool) *big.Int {
+ igas := new(big.Int)
+ if contractCreation && homestead {
+ igas.Set(params.TxGasContractCreation)
+ } else {
+ igas.Set(params.TxGas)
+ }
if len(data) > 0 {
var nz int64
for _, byt := range data {
@@ -110,7 +120,15 @@ func ApplyMessage(env vm.Environment, msg Message, gp *GasPool) ([]byte, *big.In
}
func (self *StateTransition) from() (vm.Account, error) {
- f, err := self.msg.From()
+ var (
+ f common.Address
+ err error
+ )
+ if params.IsHomestead(self.env.BlockNumber()) {
+ f, err = self.msg.From()
+ } else {
+ f, err = self.msg.FromFrontier()
+ }
if err != nil {
return nil, err
}
@@ -195,35 +213,35 @@ func (self *StateTransition) transitionDb() (ret []byte, usedGas *big.Int, err e
if err = self.preCheck(); err != nil {
return
}
-
msg := self.msg
sender, _ := self.from() // err checked in preCheck
+ homestead := params.IsHomestead(self.env.BlockNumber())
+ contractCreation := MessageCreatesContract(msg)
// Pay intrinsic gas
- if err = self.useGas(IntrinsicGas(self.data)); err != nil {
+ if err = self.useGas(IntrinsicGas(self.data, contractCreation, homestead)); err != nil {
return nil, nil, InvalidTxError(err)
}
vmenv := self.env
- var addr common.Address
- if MessageCreatesContract(msg) {
- ret, addr, err = vmenv.Create(sender, self.data, self.gas, self.gasPrice, self.value)
- if err == nil {
- dataGas := big.NewInt(int64(len(ret)))
- dataGas.Mul(dataGas, params.CreateDataGas)
- if err := self.useGas(dataGas); err == nil {
- self.state.SetCode(addr, ret)
- } else {
- ret = nil // does not affect consensus but useful for StateTests validations
- glog.V(logger.Core).Infoln("Insufficient gas for creating code. Require", dataGas, "and have", self.gas)
- }
+ //var addr common.Address
+ if contractCreation {
+ ret, _, err = vmenv.Create(sender, self.data, self.gas, self.gasPrice, self.value)
+ if homestead && err == vm.CodeStoreOutOfGasError {
+ self.gas = Big0
+ }
+
+ if err != nil {
+ ret = nil
+ glog.V(logger.Core).Infoln("VM create err:", err)
}
- glog.V(logger.Core).Infoln("VM create err:", err)
} else {
// Increment the nonce for the next transaction
self.state.SetNonce(sender.Address(), self.state.GetNonce(sender.Address())+1)
ret, err = vmenv.Call(sender, self.to().Address(), self.data, self.gas, self.gasPrice, self.value)
- glog.V(logger.Core).Infoln("VM call err:", err)
+ if err != nil {
+ glog.V(logger.Core).Infoln("VM call err:", err)
+ }
}
if err != nil && IsValueTransferErr(err) {