Read most protocol params from common/params.json
* Add params package with exported variables generated from github.com/ethereum/common/blob/master/params.json * Use params package variables in applicable places * Add check for minimum gas limit in validation of block's gas limit * Remove common/params.json from go-ethereum to avoid outdated version of it
This commit is contained in:
parent
516ec28544
commit
c26c8d3a44
@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/pow"
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"gopkg.in/fatih/set.v0"
|
"gopkg.in/fatih/set.v0"
|
||||||
@ -252,7 +253,7 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (td *big
|
|||||||
// an uncle or anything that isn't on the current block chain.
|
// an uncle or anything that isn't on the current block chain.
|
||||||
// Validation validates easy over difficult (dagger takes longer time = difficult)
|
// Validation validates easy over difficult (dagger takes longer time = difficult)
|
||||||
func (sm *BlockProcessor) ValidateHeader(block, parent *types.Header) error {
|
func (sm *BlockProcessor) ValidateHeader(block, parent *types.Header) error {
|
||||||
if len(block.Extra) > 1024 {
|
if big.NewInt(int64(len(block.Extra))).Cmp(params.MaximumExtraDataSize) == 1 {
|
||||||
return fmt.Errorf("Block extra data too long (%d)", len(block.Extra))
|
return fmt.Errorf("Block extra data too long (%d)", len(block.Extra))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,13 +262,11 @@ func (sm *BlockProcessor) ValidateHeader(block, parent *types.Header) error {
|
|||||||
return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd)
|
return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: use use minGasLimit and gasLimitBoundDivisor from
|
// block.gasLimit - parent.gasLimit <= parent.gasLimit / GasLimitBoundDivisor
|
||||||
// https://github.com/ethereum/common/blob/master/params.json
|
|
||||||
// block.gasLimit - parent.gasLimit <= parent.gasLimit / 1024
|
|
||||||
a := new(big.Int).Sub(block.GasLimit, parent.GasLimit)
|
a := new(big.Int).Sub(block.GasLimit, parent.GasLimit)
|
||||||
a.Abs(a)
|
a.Abs(a)
|
||||||
b := new(big.Int).Div(parent.GasLimit, big.NewInt(1024))
|
b := new(big.Int).Div(parent.GasLimit, params.GasLimitBoundDivisor)
|
||||||
if !(a.Cmp(b) < 0) {
|
if !(a.Cmp(b) < 0) || (block.GasLimit.Cmp(params.MinGasLimit) == -1) {
|
||||||
return fmt.Errorf("GasLimit check failed for block %v (%v > %v)", block.GasLimit, a, b)
|
return fmt.Errorf("GasLimit check failed for block %v (%v > %v)", block.GasLimit, a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -32,18 +33,15 @@ type StateQuery interface {
|
|||||||
func CalcDifficulty(block, parent *types.Header) *big.Int {
|
func CalcDifficulty(block, parent *types.Header) *big.Int {
|
||||||
diff := new(big.Int)
|
diff := new(big.Int)
|
||||||
|
|
||||||
diffBoundDiv := big.NewInt(2048)
|
adjust := new(big.Int).Div(parent.Difficulty, params.DifficultyBoundDivisor)
|
||||||
min := big.NewInt(131072)
|
if big.NewInt(int64(block.Time)-int64(parent.Time)).Cmp(params.DurationLimit) < 0 {
|
||||||
|
|
||||||
adjust := new(big.Int).Div(parent.Difficulty, diffBoundDiv)
|
|
||||||
if (block.Time - parent.Time) < 8 {
|
|
||||||
diff.Add(parent.Difficulty, adjust)
|
diff.Add(parent.Difficulty, adjust)
|
||||||
} else {
|
} else {
|
||||||
diff.Sub(parent.Difficulty, adjust)
|
diff.Sub(parent.Difficulty, adjust)
|
||||||
}
|
}
|
||||||
|
|
||||||
if diff.Cmp(min) < 0 {
|
if diff.Cmp(params.MinimumDifficulty) < 0 {
|
||||||
return min
|
return params.MinimumDifficulty
|
||||||
}
|
}
|
||||||
|
|
||||||
return diff
|
return diff
|
||||||
@ -76,7 +74,7 @@ func CalcGasLimit(parent, block *types.Block) *big.Int {
|
|||||||
result := new(big.Int).Add(previous, curInt)
|
result := new(big.Int).Add(previous, curInt)
|
||||||
result.Div(result, big.NewInt(1024))
|
result.Div(result, big.NewInt(1024))
|
||||||
|
|
||||||
return common.BigMax(GenesisGasLimit, result)
|
return common.BigMax(params.GenesisGasLimit, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChainManager struct {
|
type ChainManager struct {
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Execution struct {
|
type Execution struct {
|
||||||
@ -43,7 +44,7 @@ func (self *Execution) exec(contextAddr *common.Address, code []byte, caller vm.
|
|||||||
|
|
||||||
env := self.env
|
env := self.env
|
||||||
evm := self.evm
|
evm := self.evm
|
||||||
if env.Depth() == vm.MaxCallDepth {
|
if env.Depth() > int(params.CallCreateDepth.Int64()) {
|
||||||
caller.ReturnGas(self.Gas, self.price)
|
caller.ReturnGas(self.Gas, self.price)
|
||||||
|
|
||||||
return nil, vm.DepthError{}
|
return nil, vm.DepthError{}
|
||||||
|
@ -3,12 +3,12 @@ package core
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -18,13 +18,11 @@ import (
|
|||||||
var ZeroHash256 = make([]byte, 32)
|
var ZeroHash256 = make([]byte, 32)
|
||||||
var ZeroHash160 = make([]byte, 20)
|
var ZeroHash160 = make([]byte, 20)
|
||||||
var ZeroHash512 = make([]byte, 64)
|
var ZeroHash512 = make([]byte, 64)
|
||||||
var GenesisDiff = big.NewInt(131072)
|
|
||||||
var GenesisGasLimit = big.NewInt(3141592)
|
|
||||||
|
|
||||||
func GenesisBlock(db common.Database) *types.Block {
|
func GenesisBlock(db common.Database) *types.Block {
|
||||||
genesis := types.NewBlock(common.Hash{}, common.Address{}, common.Hash{}, GenesisDiff, 42, "")
|
genesis := types.NewBlock(common.Hash{}, common.Address{}, common.Hash{}, params.GenesisDifficulty, 42, "")
|
||||||
genesis.Header().Number = common.Big0
|
genesis.Header().Number = common.Big0
|
||||||
genesis.Header().GasLimit = GenesisGasLimit
|
genesis.Header().GasLimit = params.GenesisGasLimit
|
||||||
genesis.Header().GasUsed = common.Big0
|
genesis.Header().GasUsed = common.Big0
|
||||||
genesis.Header().Time = 0
|
genesis.Header().Time = 0
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
const tryJit = false
|
const tryJit = false
|
||||||
@ -178,7 +179,7 @@ func (self *StateTransition) transitionState() (ret []byte, usedGas *big.Int, er
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Transaction gas
|
// Transaction gas
|
||||||
if err = self.UseGas(vm.GasTx); err != nil {
|
if err = self.UseGas(params.TxGas); err != nil {
|
||||||
return nil, nil, InvalidTxError(err)
|
return nil, nil, InvalidTxError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,9 +187,9 @@ func (self *StateTransition) transitionState() (ret []byte, usedGas *big.Int, er
|
|||||||
dgas := new(big.Int)
|
dgas := new(big.Int)
|
||||||
for _, byt := range self.data {
|
for _, byt := range self.data {
|
||||||
if byt != 0 {
|
if byt != 0 {
|
||||||
dgas.Add(dgas, vm.GasTxDataNonzeroByte)
|
dgas.Add(dgas, params.TxDataNonZeroGas)
|
||||||
} else {
|
} else {
|
||||||
dgas.Add(dgas, vm.GasTxDataZeroByte)
|
dgas.Add(dgas, params.TxDataZeroGas)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +203,7 @@ func (self *StateTransition) transitionState() (ret []byte, usedGas *big.Int, er
|
|||||||
ret, err, ref = vmenv.Create(sender, self.msg.Data(), self.gas, self.gasPrice, self.value)
|
ret, err, ref = vmenv.Create(sender, self.msg.Data(), self.gas, self.gasPrice, self.value)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
dataGas := big.NewInt(int64(len(ret)))
|
dataGas := big.NewInt(int64(len(ret)))
|
||||||
dataGas.Mul(dataGas, vm.GasCreateByte)
|
dataGas.Mul(dataGas, params.CreateDataGas)
|
||||||
if err := self.UseGas(dataGas); err == nil {
|
if err := self.UseGas(dataGas); err == nil {
|
||||||
ref.SetCode(ret)
|
ref.SetCode(ret)
|
||||||
} else {
|
} else {
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Address interface {
|
type Address interface {
|
||||||
@ -27,28 +28,28 @@ func PrecompiledContracts() map[string]*PrecompiledAccount {
|
|||||||
return map[string]*PrecompiledAccount{
|
return map[string]*PrecompiledAccount{
|
||||||
// ECRECOVER
|
// ECRECOVER
|
||||||
string(common.LeftPadBytes([]byte{1}, 20)): &PrecompiledAccount{func(l int) *big.Int {
|
string(common.LeftPadBytes([]byte{1}, 20)): &PrecompiledAccount{func(l int) *big.Int {
|
||||||
return GasEcrecover
|
return params.EcrecoverGas
|
||||||
}, ecrecoverFunc},
|
}, ecrecoverFunc},
|
||||||
|
|
||||||
// SHA256
|
// SHA256
|
||||||
string(common.LeftPadBytes([]byte{2}, 20)): &PrecompiledAccount{func(l int) *big.Int {
|
string(common.LeftPadBytes([]byte{2}, 20)): &PrecompiledAccount{func(l int) *big.Int {
|
||||||
n := big.NewInt(int64(l+31) / 32)
|
n := big.NewInt(int64(l+31) / 32)
|
||||||
n.Mul(n, GasSha256Word)
|
n.Mul(n, params.Sha256WordGas)
|
||||||
return n.Add(n, GasSha256Base)
|
return n.Add(n, params.Sha256Gas)
|
||||||
}, sha256Func},
|
}, sha256Func},
|
||||||
|
|
||||||
// RIPEMD160
|
// RIPEMD160
|
||||||
string(common.LeftPadBytes([]byte{3}, 20)): &PrecompiledAccount{func(l int) *big.Int {
|
string(common.LeftPadBytes([]byte{3}, 20)): &PrecompiledAccount{func(l int) *big.Int {
|
||||||
n := big.NewInt(int64(l+31) / 32)
|
n := big.NewInt(int64(l+31) / 32)
|
||||||
n.Mul(n, GasRipemdWord)
|
n.Mul(n, params.Ripemd160WordGas)
|
||||||
return n.Add(n, GasRipemdBase)
|
return n.Add(n, params.Ripemd160Gas)
|
||||||
}, ripemd160Func},
|
}, ripemd160Func},
|
||||||
|
|
||||||
string(common.LeftPadBytes([]byte{4}, 20)): &PrecompiledAccount{func(l int) *big.Int {
|
string(common.LeftPadBytes([]byte{4}, 20)): &PrecompiledAccount{func(l int) *big.Int {
|
||||||
n := big.NewInt(int64(l+31) / 32)
|
n := big.NewInt(int64(l+31) / 32)
|
||||||
n.Mul(n, GasIdentityWord)
|
n.Mul(n, params.IdentityWordGas)
|
||||||
|
|
||||||
return n.Add(n, GasIdentityBase)
|
return n.Add(n, params.IdentityGas)
|
||||||
}, memCpy},
|
}, memCpy},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,6 @@ const (
|
|||||||
JitVmTy
|
JitVmTy
|
||||||
MaxVmTy
|
MaxVmTy
|
||||||
|
|
||||||
MaxCallDepth = 1025
|
|
||||||
|
|
||||||
LogTyPretty byte = 0x1
|
LogTyPretty byte = 0x1
|
||||||
LogTyDiff byte = 0x2
|
LogTyDiff byte = 0x2
|
||||||
)
|
)
|
||||||
|
@ -2,6 +2,7 @@ package vm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"math/big"
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -42,7 +43,7 @@ func IsStack(err error) bool {
|
|||||||
type DepthError struct{}
|
type DepthError struct{}
|
||||||
|
|
||||||
func (self DepthError) Error() string {
|
func (self DepthError) Error() string {
|
||||||
return fmt.Sprintf("Max call depth exceeded (%d)", MaxCallDepth)
|
return fmt.Sprintf("Max call depth exceeded (%d)", params.CallCreateDepth)
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsDepthErr(err error) bool {
|
func IsDepthErr(err error) bool {
|
||||||
|
@ -2,6 +2,7 @@ package vm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"math/big"
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -13,45 +14,10 @@ var (
|
|||||||
GasSlowStep = big.NewInt(10)
|
GasSlowStep = big.NewInt(10)
|
||||||
GasExtStep = big.NewInt(20)
|
GasExtStep = big.NewInt(20)
|
||||||
|
|
||||||
GasStorageGet = big.NewInt(50)
|
GasReturn = big.NewInt(0)
|
||||||
GasStorageAdd = big.NewInt(20000)
|
GasStop = big.NewInt(0)
|
||||||
GasStorageMod = big.NewInt(5000)
|
|
||||||
GasLogBase = big.NewInt(375)
|
|
||||||
GasLogTopic = big.NewInt(375)
|
|
||||||
GasLogByte = big.NewInt(8)
|
|
||||||
GasCreate = big.NewInt(32000)
|
|
||||||
GasCreateByte = big.NewInt(200)
|
|
||||||
GasCall = big.NewInt(40)
|
|
||||||
GasCallValueTransfer = big.NewInt(9000)
|
|
||||||
GasStipend = big.NewInt(2300)
|
|
||||||
GasCallNewAccount = big.NewInt(25000)
|
|
||||||
GasReturn = big.NewInt(0)
|
|
||||||
GasStop = big.NewInt(0)
|
|
||||||
GasJumpDest = big.NewInt(1)
|
|
||||||
|
|
||||||
RefundStorage = big.NewInt(15000)
|
GasContractByte = big.NewInt(200)
|
||||||
RefundSuicide = big.NewInt(24000)
|
|
||||||
|
|
||||||
GasMemWord = big.NewInt(3)
|
|
||||||
GasQuadCoeffDenom = big.NewInt(512)
|
|
||||||
GasContractByte = big.NewInt(200)
|
|
||||||
GasTransaction = big.NewInt(21000)
|
|
||||||
GasTxDataNonzeroByte = big.NewInt(68)
|
|
||||||
GasTxDataZeroByte = big.NewInt(4)
|
|
||||||
GasTx = big.NewInt(21000)
|
|
||||||
GasExp = big.NewInt(10)
|
|
||||||
GasExpByte = big.NewInt(10)
|
|
||||||
|
|
||||||
GasSha3Base = big.NewInt(30)
|
|
||||||
GasSha3Word = big.NewInt(6)
|
|
||||||
GasSha256Base = big.NewInt(60)
|
|
||||||
GasSha256Word = big.NewInt(12)
|
|
||||||
GasRipemdBase = big.NewInt(600)
|
|
||||||
GasRipemdWord = big.NewInt(12)
|
|
||||||
GasEcrecover = big.NewInt(3000)
|
|
||||||
GasIdentityBase = big.NewInt(15)
|
|
||||||
GasIdentityWord = big.NewInt(3)
|
|
||||||
GasCopyWord = big.NewInt(3)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func baseCheck(op OpCode, stack *stack, gas *big.Int) error {
|
func baseCheck(op OpCode, stack *stack, gas *big.Int) error {
|
||||||
@ -71,8 +37,8 @@ func baseCheck(op OpCode, stack *stack, gas *big.Int) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.stackPush && len(stack.data)-r.stackPop+1 > 1024 {
|
if r.stackPush && len(stack.data)-r.stackPop+1 > int(params.StackLimit.Int64()) {
|
||||||
return fmt.Errorf("stack limit reached (%d)", maxStack)
|
return fmt.Errorf("stack limit reached (%d)", params.StackLimit.Int64())
|
||||||
}
|
}
|
||||||
|
|
||||||
gas.Add(gas, r.gas)
|
gas.Add(gas, r.gas)
|
||||||
@ -145,13 +111,13 @@ var _baseCheck = map[OpCode]req{
|
|||||||
BALANCE: {1, GasExtStep, true},
|
BALANCE: {1, GasExtStep, true},
|
||||||
EXTCODESIZE: {1, GasExtStep, true},
|
EXTCODESIZE: {1, GasExtStep, true},
|
||||||
EXTCODECOPY: {4, GasExtStep, false},
|
EXTCODECOPY: {4, GasExtStep, false},
|
||||||
SLOAD: {1, GasStorageGet, true},
|
SLOAD: {1, params.SloadGas, true},
|
||||||
SSTORE: {2, Zero, false},
|
SSTORE: {2, Zero, false},
|
||||||
SHA3: {2, GasSha3Base, true},
|
SHA3: {2, params.Sha3Gas, true},
|
||||||
CREATE: {3, GasCreate, true},
|
CREATE: {3, params.CreateGas, true},
|
||||||
CALL: {7, GasCall, true},
|
CALL: {7, params.CallGas, true},
|
||||||
CALLCODE: {7, GasCall, true},
|
CALLCODE: {7, params.CallGas, true},
|
||||||
JUMPDEST: {0, GasJumpDest, false},
|
JUMPDEST: {0, params.JumpdestGas, false},
|
||||||
SUICIDE: {1, Zero, false},
|
SUICIDE: {1, Zero, false},
|
||||||
RETURN: {2, Zero, false},
|
RETURN: {2, Zero, false},
|
||||||
PUSH1: {0, GasFastestStep, true},
|
PUSH1: {0, GasFastestStep, true},
|
||||||
|
@ -5,8 +5,6 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
const maxStack = 1024
|
|
||||||
|
|
||||||
func newStack() *stack {
|
func newStack() *stack {
|
||||||
return &stack{}
|
return &stack{}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Vm struct {
|
type Vm struct {
|
||||||
@ -640,7 +641,7 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
|
|||||||
} else {
|
} else {
|
||||||
// gas < len(ret) * CreateDataGas == NO_CODE
|
// gas < len(ret) * CreateDataGas == NO_CODE
|
||||||
dataGas := big.NewInt(int64(len(ret)))
|
dataGas := big.NewInt(int64(len(ret)))
|
||||||
dataGas.Mul(dataGas, GasCreateByte)
|
dataGas.Mul(dataGas, params.CreateDataGas)
|
||||||
if context.UseGas(dataGas) {
|
if context.UseGas(dataGas) {
|
||||||
ref.SetCode(ret)
|
ref.SetCode(ret)
|
||||||
}
|
}
|
||||||
@ -667,7 +668,7 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
|
|||||||
args := mem.Get(inOffset.Int64(), inSize.Int64())
|
args := mem.Get(inOffset.Int64(), inSize.Int64())
|
||||||
|
|
||||||
if len(value.Bytes()) > 0 {
|
if len(value.Bytes()) > 0 {
|
||||||
gas.Add(gas, GasStipend)
|
gas.Add(gas, params.CallStipend)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -759,13 +760,13 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo
|
|||||||
|
|
||||||
mSize, mStart := stack.data[stack.len()-2], stack.data[stack.len()-1]
|
mSize, mStart := stack.data[stack.len()-2], stack.data[stack.len()-1]
|
||||||
|
|
||||||
gas.Add(gas, GasLogBase)
|
gas.Add(gas, params.LogGas)
|
||||||
gas.Add(gas, new(big.Int).Mul(big.NewInt(int64(n)), GasLogTopic))
|
gas.Add(gas, new(big.Int).Mul(big.NewInt(int64(n)), params.LogTopicGas))
|
||||||
gas.Add(gas, new(big.Int).Mul(mSize, GasLogByte))
|
gas.Add(gas, new(big.Int).Mul(mSize, params.LogDataGas))
|
||||||
|
|
||||||
newMemSize = calcMemSize(mStart, mSize)
|
newMemSize = calcMemSize(mStart, mSize)
|
||||||
case EXP:
|
case EXP:
|
||||||
gas.Add(gas, new(big.Int).Mul(big.NewInt(int64(len(stack.data[stack.len()-2].Bytes()))), GasExpByte))
|
gas.Add(gas, new(big.Int).Mul(big.NewInt(int64(len(stack.data[stack.len()-2].Bytes()))), params.ExpByteGas))
|
||||||
case SSTORE:
|
case SSTORE:
|
||||||
err := stack.require(2)
|
err := stack.require(2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -777,19 +778,19 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo
|
|||||||
val := statedb.GetState(context.Address(), common.BigToHash(x))
|
val := statedb.GetState(context.Address(), common.BigToHash(x))
|
||||||
if len(val) == 0 && len(y.Bytes()) > 0 {
|
if len(val) == 0 && len(y.Bytes()) > 0 {
|
||||||
// 0 => non 0
|
// 0 => non 0
|
||||||
g = GasStorageAdd
|
g = params.SstoreSetGas
|
||||||
} else if len(val) > 0 && len(y.Bytes()) == 0 {
|
} else if len(val) > 0 && len(y.Bytes()) == 0 {
|
||||||
statedb.Refund(self.env.Origin(), RefundStorage)
|
statedb.Refund(self.env.Origin(), params.SstoreRefundGas)
|
||||||
|
|
||||||
g = GasStorageMod
|
g = params.SstoreClearGas
|
||||||
} else {
|
} else {
|
||||||
// non 0 => non 0 (or 0 => 0)
|
// non 0 => non 0 (or 0 => 0)
|
||||||
g = GasStorageMod
|
g = params.SstoreClearGas
|
||||||
}
|
}
|
||||||
gas.Set(g)
|
gas.Set(g)
|
||||||
case SUICIDE:
|
case SUICIDE:
|
||||||
if !statedb.IsDeleted(context.Address()) {
|
if !statedb.IsDeleted(context.Address()) {
|
||||||
statedb.Refund(self.env.Origin(), RefundSuicide)
|
statedb.Refund(self.env.Origin(), params.SuicideRefundGas)
|
||||||
}
|
}
|
||||||
case MLOAD:
|
case MLOAD:
|
||||||
newMemSize = calcMemSize(stack.peek(), u256(32))
|
newMemSize = calcMemSize(stack.peek(), u256(32))
|
||||||
@ -803,22 +804,22 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo
|
|||||||
newMemSize = calcMemSize(stack.peek(), stack.data[stack.len()-2])
|
newMemSize = calcMemSize(stack.peek(), stack.data[stack.len()-2])
|
||||||
|
|
||||||
words := toWordSize(stack.data[stack.len()-2])
|
words := toWordSize(stack.data[stack.len()-2])
|
||||||
gas.Add(gas, words.Mul(words, GasSha3Word))
|
gas.Add(gas, words.Mul(words, params.Sha3WordGas))
|
||||||
case CALLDATACOPY:
|
case CALLDATACOPY:
|
||||||
newMemSize = calcMemSize(stack.peek(), stack.data[stack.len()-3])
|
newMemSize = calcMemSize(stack.peek(), stack.data[stack.len()-3])
|
||||||
|
|
||||||
words := toWordSize(stack.data[stack.len()-3])
|
words := toWordSize(stack.data[stack.len()-3])
|
||||||
gas.Add(gas, words.Mul(words, GasCopyWord))
|
gas.Add(gas, words.Mul(words, params.CopyGas))
|
||||||
case CODECOPY:
|
case CODECOPY:
|
||||||
newMemSize = calcMemSize(stack.peek(), stack.data[stack.len()-3])
|
newMemSize = calcMemSize(stack.peek(), stack.data[stack.len()-3])
|
||||||
|
|
||||||
words := toWordSize(stack.data[stack.len()-3])
|
words := toWordSize(stack.data[stack.len()-3])
|
||||||
gas.Add(gas, words.Mul(words, GasCopyWord))
|
gas.Add(gas, words.Mul(words, params.CopyGas))
|
||||||
case EXTCODECOPY:
|
case EXTCODECOPY:
|
||||||
newMemSize = calcMemSize(stack.data[stack.len()-2], stack.data[stack.len()-4])
|
newMemSize = calcMemSize(stack.data[stack.len()-2], stack.data[stack.len()-4])
|
||||||
|
|
||||||
words := toWordSize(stack.data[stack.len()-4])
|
words := toWordSize(stack.data[stack.len()-4])
|
||||||
gas.Add(gas, words.Mul(words, GasCopyWord))
|
gas.Add(gas, words.Mul(words, params.CopyGas))
|
||||||
|
|
||||||
case CREATE:
|
case CREATE:
|
||||||
newMemSize = calcMemSize(stack.data[stack.len()-2], stack.data[stack.len()-3])
|
newMemSize = calcMemSize(stack.data[stack.len()-2], stack.data[stack.len()-3])
|
||||||
@ -827,12 +828,12 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo
|
|||||||
|
|
||||||
if op == CALL {
|
if op == CALL {
|
||||||
if self.env.State().GetStateObject(common.BigToAddress(stack.data[stack.len()-2])) == nil {
|
if self.env.State().GetStateObject(common.BigToAddress(stack.data[stack.len()-2])) == nil {
|
||||||
gas.Add(gas, GasCallNewAccount)
|
gas.Add(gas, params.CallNewAccountGas)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(stack.data[stack.len()-3].Bytes()) > 0 {
|
if len(stack.data[stack.len()-3].Bytes()) > 0 {
|
||||||
gas.Add(gas, GasCallValueTransfer)
|
gas.Add(gas, params.CallValueTransferGas)
|
||||||
}
|
}
|
||||||
|
|
||||||
x := calcMemSize(stack.data[stack.len()-6], stack.data[stack.len()-7])
|
x := calcMemSize(stack.data[stack.len()-6], stack.data[stack.len()-7])
|
||||||
@ -848,13 +849,13 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo
|
|||||||
if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 {
|
if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 {
|
||||||
oldSize := toWordSize(big.NewInt(int64(mem.Len())))
|
oldSize := toWordSize(big.NewInt(int64(mem.Len())))
|
||||||
pow := new(big.Int).Exp(oldSize, common.Big2, Zero)
|
pow := new(big.Int).Exp(oldSize, common.Big2, Zero)
|
||||||
linCoef := new(big.Int).Mul(oldSize, GasMemWord)
|
linCoef := new(big.Int).Mul(oldSize, params.MemoryGas)
|
||||||
quadCoef := new(big.Int).Div(pow, GasQuadCoeffDenom)
|
quadCoef := new(big.Int).Div(pow, params.QuadCoeffDiv)
|
||||||
oldTotalFee := new(big.Int).Add(linCoef, quadCoef)
|
oldTotalFee := new(big.Int).Add(linCoef, quadCoef)
|
||||||
|
|
||||||
pow.Exp(newMemSizeWords, common.Big2, Zero)
|
pow.Exp(newMemSizeWords, common.Big2, Zero)
|
||||||
linCoef = new(big.Int).Mul(newMemSizeWords, GasMemWord)
|
linCoef = new(big.Int).Mul(newMemSizeWords, params.MemoryGas)
|
||||||
quadCoef = new(big.Int).Div(pow, GasQuadCoeffDenom)
|
quadCoef = new(big.Int).Div(pow, params.QuadCoeffDiv)
|
||||||
newTotalFee := new(big.Int).Add(linCoef, quadCoef)
|
newTotalFee := new(big.Int).Add(linCoef, quadCoef)
|
||||||
|
|
||||||
fee := new(big.Int).Sub(newTotalFee, oldTotalFee)
|
fee := new(big.Int).Sub(newTotalFee, oldTotalFee)
|
||||||
|
@ -18,8 +18,8 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"math/big"
|
"math/big"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
@ -330,7 +330,7 @@ func env_create(_vm unsafe.Pointer, _gas *int64, _value unsafe.Pointer, initData
|
|||||||
ret, suberr, ref := vm.env.Create(vm.me, nil, initData, gas, vm.price, value)
|
ret, suberr, ref := vm.env.Create(vm.me, nil, initData, gas, vm.price, value)
|
||||||
if suberr == nil {
|
if suberr == nil {
|
||||||
dataGas := big.NewInt(int64(len(ret))) // TODO: Nto the best design. env.Create can do it, it has the reference to gas counter
|
dataGas := big.NewInt(int64(len(ret))) // TODO: Nto the best design. env.Create can do it, it has the reference to gas counter
|
||||||
dataGas.Mul(dataGas, GasCreateByte)
|
dataGas.Mul(dataGas, params.CreateDataGas)
|
||||||
gas.Sub(gas, dataGas)
|
gas.Sub(gas, dataGas)
|
||||||
*result = hash2llvm(ref.Address())
|
*result = hash2llvm(ref.Address())
|
||||||
}
|
}
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
{
|
|
||||||
"genesisGasLimit": { "v": 1000000, "d": "Gas limit of the Genesis block." },
|
|
||||||
"minGasLimit": { "v": 125000, "d": "Minimum the gas limit may ever be." },
|
|
||||||
"gasLimitBoundDivisor": { "v": 1024, "d": "The bound divisor of the gas limit, used in update calculations." },
|
|
||||||
"genesisDifficulty": { "v": 131072, "d": "Difficulty of the Genesis block." },
|
|
||||||
"minimumDifficulty": { "v": 131072, "d": "The minimum that the difficulty may ever be." },
|
|
||||||
"difficultyBoundDivisor": { "v": 2048, "d": "The bound divisor of the difficulty, used in the update calculations." },
|
|
||||||
"durationLimit": { "v": 8, "d": "The decision boundary on the blocktime duration used to determine whether difficulty should go up or not." },
|
|
||||||
"maximumExtraDataSize": { "v": 1024, "d": "Maximum size extra data may be after Genesis." },
|
|
||||||
"epochDuration": { "v": 30000, "d": "Duration between proof-of-work epochs." },
|
|
||||||
"stackLimit": { "v": 1024, "d": "Maximum size of VM stack allowed." },
|
|
||||||
|
|
||||||
"tierStepGas": { "v": [ 0, 2, 3, 5, 8, 10, 20 ], "d": "Once per operation, for a selection of them." },
|
|
||||||
"expGas": { "v": 10, "d": "Once per EXP instuction." },
|
|
||||||
"expByteGas": { "v": 10, "d": "Times ceil(log256(exponent)) for the EXP instruction." },
|
|
||||||
|
|
||||||
"sha3Gas": { "v": 30, "d": "Once per SHA3 operation." },
|
|
||||||
"sha3WordGas": { "v": 6, "d": "Once per word of the SHA3 operation's data." },
|
|
||||||
|
|
||||||
"sloadGas": { "v": 50, "d": "Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added." },
|
|
||||||
"sstoreSetGas": { "v": 20000, "d": "Once per SLOAD operation." },
|
|
||||||
"sstoreResetGas": { "v": 5000, "d": "Once per SSTORE operation if the zeroness changes from zero." },
|
|
||||||
"sstoreClearGas": { "v": 5000, "d": "Once per SSTORE operation if the zeroness doesn't change." },
|
|
||||||
"sstoreRefundGas": { "v": 15000, "d": "Once per SSTORE operation if the zeroness changes to zero." },
|
|
||||||
"jumpdestGas": { "v": 1, "d": "Refunded gas, once per SSTORE operation if the zeroness changes to zero." },
|
|
||||||
|
|
||||||
"logGas": { "v": 375, "d": "Per LOG* operation." },
|
|
||||||
"logDataGas": { "v": 8, "d": "Per byte in a LOG* operation's data." },
|
|
||||||
"logTopicGas": { "v": 375, "d": "Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas." },
|
|
||||||
|
|
||||||
"createGas": { "v": 32000, "d": "Once per CREATE operation & contract-creation transaction." },
|
|
||||||
|
|
||||||
"callGas": { "v": 40, "d": "Once per CALL operation & message call transaction." },
|
|
||||||
"callStipend": { "v": 2300, "d": "Free gas given at beginning of call." },
|
|
||||||
"callValueTransferGas": { "v": 9000, "d": "Paid for CALL when the value transfor is non-zero." },
|
|
||||||
"callNewAccountGas": { "v": 25000, "d": "Paid for CALL when the destination address didn't exist prior." },
|
|
||||||
|
|
||||||
"suicideRefundGas": { "v": 24000, "d": "Refunded following a suicide operation." },
|
|
||||||
"memoryGas": { "v": 3, "d": "Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL." },
|
|
||||||
"quadCoeffDiv": { "v": 512, "d": "Divisor for the quadratic particle of the memory cost equation." },
|
|
||||||
|
|
||||||
"createDataGas": { "v": 200, "d": "" },
|
|
||||||
"txGas": { "v": 21000, "d": "Per transaction. NOTE: Not payable on data of calls between transactions." },
|
|
||||||
"txDataZeroGas": { "v": 4, "d": "Per byte of data attached to a transaction that equals zero. NOTE: Not payable on data of calls between transactions." },
|
|
||||||
"txDataNonZeroGas": { "v": 68, "d": "Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions." },
|
|
||||||
|
|
||||||
"copyGas": { "v": 3, "d": "" },
|
|
||||||
|
|
||||||
"ecrecoverGas": { "v": 3000, "d": "" },
|
|
||||||
"sha256Gas": { "v": 60, "d": "" },
|
|
||||||
"sha256WordGas": { "v": 12, "d": "" },
|
|
||||||
"ripemd160Gas": { "v": 600, "d": "" },
|
|
||||||
"ripemd160WordGas": { "v": 120, "d": "" },
|
|
||||||
"identityGas": { "v": 15, "d": "" },
|
|
||||||
"identityWordGas": { "v": 3, "d": ""}
|
|
||||||
}
|
|
@ -35,13 +35,16 @@ func main() {
|
|||||||
m := make(map[string]setting)
|
m := make(map[string]setting)
|
||||||
json.Unmarshal(content, &m)
|
json.Unmarshal(content, &m)
|
||||||
|
|
||||||
filepath := path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "core", os.Args[2])
|
filepath := path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "params", os.Args[2])
|
||||||
output, err := os.OpenFile(filepath, os.O_RDWR|os.O_CREATE, os.ModePerm /*0777*/)
|
output, err := os.OpenFile(filepath, os.O_RDWR|os.O_CREATE, os.ModePerm /*0777*/)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fatal("error opening file for writing %v\n", err)
|
fatal("error opening file for writing %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
output.WriteString(`package core
|
output.WriteString(`// DO NOT EDIT!!!
|
||||||
|
// AUTOGENERATED FROM generators/defaults.go
|
||||||
|
|
||||||
|
package params
|
||||||
|
|
||||||
import "math/big"
|
import "math/big"
|
||||||
|
|
||||||
|
54
params/protocol_params.go
Executable file
54
params/protocol_params.go
Executable file
@ -0,0 +1,54 @@
|
|||||||
|
// DO NOT EDIT!!!
|
||||||
|
// AUTOGENERATED FROM generators/defaults.go
|
||||||
|
|
||||||
|
package params
|
||||||
|
|
||||||
|
import "math/big"
|
||||||
|
|
||||||
|
var (
|
||||||
|
MaximumExtraDataSize = big.NewInt(1024) // Maximum size extra data may be after Genesis.
|
||||||
|
ExpByteGas = big.NewInt(10) // Times ceil(log256(exponent)) for the EXP instruction.
|
||||||
|
SloadGas = big.NewInt(50) // Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added.
|
||||||
|
CallValueTransferGas = big.NewInt(9000) // Paid for CALL when the value transfor is non-zero.
|
||||||
|
CallNewAccountGas = big.NewInt(25000) // Paid for CALL when the destination address didn't exist prior.
|
||||||
|
TxGas = big.NewInt(21000) // Per transaction. NOTE: Not payable on data of calls between transactions.
|
||||||
|
TxDataZeroGas = big.NewInt(4) // Per byte of data attached to a transaction that equals zero. NOTE: Not payable on data of calls between transactions.
|
||||||
|
GenesisGasLimit = big.NewInt(3141592) // Gas limit of the Genesis block.
|
||||||
|
DifficultyBoundDivisor = big.NewInt(2048) // The bound divisor of the difficulty, used in the update calculations.
|
||||||
|
QuadCoeffDiv = big.NewInt(512) // Divisor for the quadratic particle of the memory cost equation.
|
||||||
|
GenesisDifficulty = big.NewInt(131072) // Difficulty of the Genesis block.
|
||||||
|
DurationLimit = big.NewInt(8) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not.
|
||||||
|
SstoreSetGas = big.NewInt(20000) // Once per SLOAD operation.
|
||||||
|
LogDataGas = big.NewInt(8) // Per byte in a LOG* operation's data.
|
||||||
|
CallStipend = big.NewInt(2300) // Free gas given at beginning of call.
|
||||||
|
EcrecoverGas = big.NewInt(3000) //
|
||||||
|
Sha256WordGas = big.NewInt(12) //
|
||||||
|
MinGasLimit = big.NewInt(125000) // Minimum the gas limit may ever be.
|
||||||
|
Sha3Gas = big.NewInt(30) // Once per SHA3 operation.
|
||||||
|
Sha256Gas = big.NewInt(60) //
|
||||||
|
IdentityWordGas = big.NewInt(3) //
|
||||||
|
Sha3WordGas = big.NewInt(6) // Once per word of the SHA3 operation's data.
|
||||||
|
SstoreResetGas = big.NewInt(5000) // Once per SSTORE operation if the zeroness changes from zero.
|
||||||
|
SstoreClearGas = big.NewInt(5000) // Once per SSTORE operation if the zeroness doesn't change.
|
||||||
|
SstoreRefundGas = big.NewInt(15000) // Once per SSTORE operation if the zeroness changes to zero.
|
||||||
|
JumpdestGas = big.NewInt(1) // Refunded gas, once per SSTORE operation if the zeroness changes to zero.
|
||||||
|
IdentityGas = big.NewInt(15) //
|
||||||
|
GasLimitBoundDivisor = big.NewInt(1024) // The bound divisor of the gas limit, used in update calculations.
|
||||||
|
EpochDuration = big.NewInt(30000) // Duration between proof-of-work epochs.
|
||||||
|
CallGas = big.NewInt(40) // Once per CALL operation & message call transaction.
|
||||||
|
CreateDataGas = big.NewInt(200) //
|
||||||
|
Ripemd160Gas = big.NewInt(600) //
|
||||||
|
Ripemd160WordGas = big.NewInt(120) //
|
||||||
|
MinimumDifficulty = big.NewInt(131072) // The minimum that the difficulty may ever be.
|
||||||
|
CallCreateDepth = big.NewInt(1024) // Maximum depth of call/create stack.
|
||||||
|
ExpGas = big.NewInt(10) // Once per EXP instuction.
|
||||||
|
LogGas = big.NewInt(375) // Per LOG* operation.
|
||||||
|
CopyGas = big.NewInt(3) //
|
||||||
|
StackLimit = big.NewInt(1024) // Maximum size of VM stack allowed.
|
||||||
|
TierStepGas = big.NewInt(0) // Once per operation, for a selection of them.
|
||||||
|
LogTopicGas = big.NewInt(375) // Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas.
|
||||||
|
CreateGas = big.NewInt(32000) // Once per CREATE operation & contract-creation transaction.
|
||||||
|
SuicideRefundGas = big.NewInt(24000) // Refunded following a suicide operation.
|
||||||
|
MemoryGas = big.NewInt(3) // Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL.
|
||||||
|
TxDataNonZeroGas = big.NewInt(68) // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions.
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user