Skip to content
This repository has been archived by the owner on Oct 4, 2019. It is now read-only.

Commit

Permalink
Merge pull request #59 from ethereumproject/ecip/1015
Browse files Browse the repository at this point in the history
ECIP-1015 GasReprice fork
  • Loading branch information
ericsomdahl authored Oct 15, 2016
2 parents b6320f7 + 1a97543 commit d76ad4e
Show file tree
Hide file tree
Showing 47 changed files with 76,809 additions and 75 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.0.0
3.0.0
2 changes: 1 addition & 1 deletion cmd/ethtest/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func runTestWithReader(test string, r io.Reader) error {
var err error
switch strings.ToLower(test) {
case "bk", "block", "blocktest", "blockchaintest", "blocktests", "blockchaintests":
err = tests.RunBlockTestWithReader(params.MainNetHomesteadBlock, r, skipTests)
err = tests.RunBlockTestWithReader(params.MainNetHomesteadBlock, nil, r, skipTests)
case "st", "state", "statetest", "statetests":
rs := tests.RuleSet{HomesteadBlock: params.MainNetHomesteadBlock}
err = tests.RunStateTestWithReader(rs, r, skipTests)
Expand Down
4 changes: 4 additions & 0 deletions cmd/evm/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"github.com/ethereumproject/go-ethereum/crypto"
"github.com/ethereumproject/go-ethereum/ethdb"
"github.com/ethereumproject/go-ethereum/logger/glog"
"github.com/ethereumproject/go-ethereum/params"
"gopkg.in/urfave/cli.v1"
)

Expand Down Expand Up @@ -222,6 +223,9 @@ func NewEnv(state *state.StateDB, transactor common.Address, value *big.Int, cfg
type ruleSet struct{}

func (ruleSet) IsHomestead(*big.Int) bool { return true }
func (ruleSet) GasTable(*big.Int) params.GasTable {
return params.GasTableHomesteadGasRepriceFork
}

func (self *VMEnv) RuleSet() vm.RuleSet { return ruleSet{} }
func (self *VMEnv) Vm() vm.Vm { return self.evm }
Expand Down
2 changes: 1 addition & 1 deletion cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import (

const (
clientIdentifier = "Geth" // Client identifier to advertise over the network
versionMajor = 2 // Major version component of the current release
versionMajor = 3 // Major version component of the current release
versionMinor = 0 // Minor version component of the current release
versionPatch = 0 // Patch version component of the current release
versionMeta = "stable" // Version metadata to append to the version string
Expand Down
7 changes: 7 additions & 0 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,13 @@ func MustMakeChainConfigFromDb(ctx *cli.Context, db ethdb.Database) *core.ChainC
c.Forks[i].Block = params.MainNetHomesteadBlock
}
}
if c.Forks[i].Name == "GasReprice" {
if ctx.GlobalBool(TestNetFlag.Name) {
c.Forks[i].Block = params.TestNetHomesteadGasRepriceBlock
} else {
c.Forks[i].Block = params.MainNetHomesteadGasRepriceBlock
}
}
if c.Forks[i].Name == "Diehard" {
c.Forks[i].Block = params.DiehardBlock
c.Forks[i].Length = big.NewInt(0).Sub(params.ExplosionBlock, params.DiehardBlock)
Expand Down
6 changes: 4 additions & 2 deletions core/block_validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,17 @@ import (
"github.com/ethereumproject/go-ethereum/core/vm"
"github.com/ethereumproject/go-ethereum/ethdb"
"github.com/ethereumproject/go-ethereum/event"
"github.com/ethereumproject/go-ethereum/params"
"github.com/ethereumproject/go-ethereum/pow/ezp"
)

func testChainConfig() *ChainConfig {
return &ChainConfig{
Forks: []*Fork{
&Fork{
Name: "Homestead",
Block: big.NewInt(0),
Name: "Homestead",
Block: big.NewInt(0),
GasTable: &params.GasTableHomestead,
},
},
}
Expand Down
17 changes: 17 additions & 0 deletions core/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"math/big"

"github.com/ethereumproject/go-ethereum/core/vm"
"github.com/ethereumproject/go-ethereum/params"
)

var (
Expand Down Expand Up @@ -84,3 +85,19 @@ func (c *ChainConfig) Fork(name string) *Fork {
func (c *ChainConfig) LoadForkConfig() {
c.Forks = LoadForks()
}

// GasTable returns the gas table corresponding to the current fork
// The returned GasTable's fields shouldn't, under any circumstances, be changed.
func (c *ChainConfig) GasTable(num *big.Int) params.GasTable {
var gasTable = params.GasTableHomestead
//TODO avoid loop, remember current fork
for i := range c.Forks {
fork := c.Forks[i]
if fork.Block.Cmp(num) <= 0 {
if fork.GasTable != nil {
gasTable = *fork.GasTable
}
}
}
return gasTable
}
11 changes: 11 additions & 0 deletions core/fork.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/ethereumproject/go-ethereum/core/types"
"github.com/ethereumproject/go-ethereum/logger"
"github.com/ethereumproject/go-ethereum/logger/glog"
"github.com/ethereumproject/go-ethereum/params"
)

type Fork struct {
Expand All @@ -29,6 +30,8 @@ type Fork struct {
// ForkExtraRange is the number of consecutive blocks from the fork point
// to override the extra-data in to prevent no-fork attacks.
ExtraRange *big.Int
// Gas Price table
GasTable *params.GasTable
// TODO Derive Oracle contracts from fork struct (Version, Registrar, Release)
}

Expand Down Expand Up @@ -66,6 +69,7 @@ func LoadForks() []*Fork {
Block: big.NewInt(1150000),
NetworkSplit: false,
Support: true,
GasTable: &params.GasTableHomestead,
},
&Fork{
Name: "ETF",
Expand All @@ -79,6 +83,13 @@ func LoadForks() []*Fork {
// ETF Block+1
ForkSplitHash: "4985f5ca3d2afbec36529aa96f74de3cc10a2a4a6c44f2157a57d2c6059a11bb",
},
&Fork{
Name: "GasReprice",
Block: big.NewInt(2500000),
NetworkSplit: false,
Support: true,
GasTable: &params.GasTableHomesteadGasRepriceFork,
},
&Fork{
Name: "Diehard",
Block: big.NewInt(3000000),
Expand Down
4 changes: 2 additions & 2 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ func (self *StateDB) GetState(a common.Address, b common.Hash) common.Hash {
return common.Hash{}
}

func (self *StateDB) IsDeleted(addr common.Address) bool {
func (self *StateDB) HasSuicided(addr common.Address) bool {
stateObject := self.GetStateObject(addr)
if stateObject != nil {
return stateObject.remove
Expand Down Expand Up @@ -303,7 +303,7 @@ func (self *StateDB) SetState(addr common.Address, key common.Hash, value common
}
}

func (self *StateDB) Delete(addr common.Address) bool {
func (self *StateDB) Suicide(addr common.Address) bool {
stateObject := self.GetStateObject(addr)
if stateObject != nil {
stateObject.MarkForDeletion()
Expand Down
11 changes: 9 additions & 2 deletions core/vm/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,16 @@ import (
"math/big"

"github.com/ethereumproject/go-ethereum/common"
"github.com/ethereumproject/go-ethereum/params"
)

// RuleSet is an interface that defines the current rule set during the
// execution of the EVM instructions (e.g. whether it's homestead)
type RuleSet interface {
IsHomestead(*big.Int) bool
// GasTable returns the gas prices for this phase, which is based on
// block number passed in.
GasTable(*big.Int) params.GasTable
}

// Environment is an EVM requirement and helper which allows access to outside
Expand Down Expand Up @@ -105,9 +109,12 @@ type Database interface {
GetState(common.Address, common.Hash) common.Hash
SetState(common.Address, common.Hash, common.Hash)

Delete(common.Address) bool
Suicide(common.Address) bool
HasSuicided(common.Address) bool

// Exist reports whether the given account exists in state.
// Notably this should also return true for suicided accounts.
Exist(common.Address) bool
IsDeleted(common.Address) bool
}

// Account represents a contract or basic ethereum account.
Expand Down
34 changes: 27 additions & 7 deletions core/vm/gas.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,27 @@ var (
GasStop = big.NewInt(0)

GasContractByte = big.NewInt(200)

n64 = big.NewInt(64)
)

// calcGas returns the actual gas cost of the call.
//
// The cost of gas was changed during the homestead price change HF. To allow for EIP150
// to be implemented. The returned gas is gas - base * 63 / 64.
func callGas(gasTable params.GasTable, availableGas, base, callCost *big.Int) *big.Int {
if gasTable.CreateBySuicide != nil {
availableGas = new(big.Int).Sub(availableGas, base)
g := new(big.Int).Div(availableGas, n64)
g.Sub(availableGas, g)

if g.Cmp(callCost) < 0 {
return g
}
}
return callCost
}

// baseCheck checks for any stack error underflows
func baseCheck(op OpCode, stack *stack, gas *big.Int) error {
// PUSH and DUP are a bit special. They all cost the same but we do want to have checking on stack push limit
Expand Down Expand Up @@ -127,18 +146,19 @@ var _baseCheck = map[OpCode]req{
MSIZE: {0, GasQuickStep, 1},
GAS: {0, GasQuickStep, 1},
BLOCKHASH: {1, GasExtStep, 1},
BALANCE: {1, GasExtStep, 1},
EXTCODESIZE: {1, GasExtStep, 1},
EXTCODECOPY: {4, GasExtStep, 0},
BALANCE: {1, Zero, 1},
EXTCODESIZE: {1, Zero, 1},
EXTCODECOPY: {4, Zero, 0},
SLOAD: {1, params.SloadGas, 1},
SSTORE: {2, Zero, 0},
SHA3: {2, params.Sha3Gas, 1},
CREATE: {3, params.CreateGas, 1},
CALL: {7, params.CallGas, 1},
CALLCODE: {7, params.CallGas, 1},
DELEGATECALL: {6, params.CallGas, 1},
JUMPDEST: {0, params.JumpdestGas, 0},
// Zero is calculated in the gasSwitch
CALL: {7, Zero, 1},
CALLCODE: {7, Zero, 1},
DELEGATECALL: {6, Zero, 1},
SUICIDE: {1, Zero, 0},
JUMPDEST: {0, params.JumpdestGas, 0},
RETURN: {2, Zero, 0},
PUSH1: {0, GasFastestStep, 1},
DUP1: {0, Zero, 1},
Expand Down
9 changes: 7 additions & 2 deletions core/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,12 @@ func opCreate(instr instruction, pc *uint64, env Environment, contract *Contract
input = memory.Get(offset.Int64(), size.Int64())
gas = new(big.Int).Set(contract.Gas)
)
contract.UseGas(contract.Gas)
if env.RuleSet().GasTable(env.BlockNumber()).CreateBySuicide != nil {
gas.Div(gas, n64)
gas = gas.Sub(contract.Gas, gas)
}

contract.UseGas(gas)
_, addr, suberr := env.Create(contract, input, gas, contract.Price, value)
// Push item on the stack based on the returned error. If the ruleset is
// homestead we must check for CodeStoreOutOfGasError (homestead only
Expand Down Expand Up @@ -614,7 +619,7 @@ func opSuicide(instr instruction, pc *uint64, env Environment, contract *Contrac
balance := env.Db().GetBalance(contract.Address())
env.Db().AddBalance(common.BigToAddress(stack.pop()), balance)

env.Db().Delete(contract.Address())
env.Db().Suicide(contract.Address())
}

// following functions are used by the instruction jump table
Expand Down
2 changes: 1 addition & 1 deletion core/vm/jit.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ func jitCalculateGasAndSize(env Environment, contract *Contract, instr instructi
}
gas.Set(g)
case SUICIDE:
if !statedb.IsDeleted(contract.Address()) {
if !statedb.HasSuicided(contract.Address()) {
statedb.AddRefund(params.SuicideRefundGas)
}
case MLOAD:
Expand Down
4 changes: 4 additions & 0 deletions core/vm/runtime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,16 @@ import (
"github.com/ethereumproject/go-ethereum/core/vm"
"github.com/ethereumproject/go-ethereum/crypto"
"github.com/ethereumproject/go-ethereum/ethdb"
"github.com/ethereumproject/go-ethereum/params"
)

// The default, always homestead, rule set for the vm env
type ruleSet struct{}

func (ruleSet) IsHomestead(*big.Int) bool { return true }
func (ruleSet) GasTable(*big.Int) params.GasTable {
return params.GasTableHomesteadGasRepriceFork
}

// Config is a basic type specifying certain configuration flags for running
// the EVM.
Expand Down
9 changes: 8 additions & 1 deletion core/vm/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,17 @@

package vm

import "math/big"
import (
"math/big"

"github.com/ethereumproject/go-ethereum/params"
)

type ruleSet struct {
hs *big.Int
}

func (r ruleSet) IsHomestead(n *big.Int) bool { return n.Cmp(r.hs) >= 0 }
func (r ruleSet) GasTable(*big.Int) params.GasTable {
return params.GasTableHomestead
}
Loading

0 comments on commit d76ad4e

Please sign in to comment.