diff options
Diffstat (limited to 'core/state_transition.go')
-rw-r--r-- | core/state_transition.go | 56 |
1 files changed, 37 insertions, 19 deletions
diff --git a/core/state_transition.go b/core/state_transition.go index 7ecc01d4c..52a46c63d 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 'intrisic 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) { |