cmd, core, params: dynamic gas ceiling on heavy blocks

This commit is contained in:
Péter Szilágyi 2016-09-22 19:25:57 +03:00
parent 437c3863f1
commit d7e8ec61f0
7 changed files with 71 additions and 8 deletions

View file

@ -150,6 +150,7 @@ participating.
utils.MiningGPUFlag,
utils.AutoDAGFlag,
utils.TargetGasLimitFlag,
utils.BlockTimeLimitFlag,
utils.NATFlag,
utils.NatspecEnabledFlag,
utils.NoDiscoverFlag,

View file

@ -126,6 +126,7 @@ var AppHelpFlagGroups = []flagGroup{
utils.AutoDAGFlag,
utils.EtherbaseFlag,
utils.TargetGasLimitFlag,
utils.BlockTimeLimitFlag,
utils.GasPriceFlag,
utils.ExtraDataFlag,
},

View file

@ -180,9 +180,14 @@ var (
}
TargetGasLimitFlag = cli.StringFlag{
Name: "targetgaslimit",
Usage: "Target gas limit sets the artificial target gas floor for the blocks to mine",
Usage: "Sets the artificial target gas floor for the blocks to mine",
Value: params.GenesisGasLimit.String(),
}
BlockTimeLimitFlag = cli.IntFlag{
Name: "blocktimelimit",
Usage: "Time limit for processing a block after which to halve the hard gas limit",
Value: 5,
}
AutoDAGFlag = cli.BoolFlag{
Name: "autodag",
Usage: "Enable automatic DAG pregeneration",
@ -746,6 +751,8 @@ func SetupNetwork(ctx *cli.Context) {
core.ExpDiffPeriod = big.NewInt(math.MaxInt64)
}
params.TargetGasLimit = common.String2Big(ctx.GlobalString(TargetGasLimitFlag.Name))
params.CurrentGasCeil.Set(params.TargetGasLimit)
params.BlockTimeLimit = time.Duration(ctx.GlobalInt(BlockTimeLimitFlag.Name)) * time.Second
}
// MustMakeChainConfig reads the chain configuration from the database in ctx.Datadir.

View file

@ -364,7 +364,6 @@ func CalcGasLimit(parent *types.Block) *big.Int {
*/
gl := new(big.Int).Sub(parent.GasLimit(), decay)
gl = gl.Add(gl, contrib)
gl.Set(common.BigMax(gl, params.MinGasLimit))
// however, if we're now below the target (TargetGasLimit) we increase the
// limit as much as we can (parentGasLimit / 1024 -1)
@ -372,5 +371,15 @@ func CalcGasLimit(parent *types.Block) *big.Int {
gl.Add(parent.GasLimit(), decay)
gl.Set(common.BigMin(gl, params.TargetGasLimit))
}
// If the gas limit performance ceiling is exceeded, mandatorilly decrease
params.CurrentGasCeilLock.Lock()
if gl.Cmp(params.CurrentGasCeil) > 0 {
gl.Sub(parent.GasLimit(), decay)
gl.Set(common.BigMax(gl, params.CurrentGasCeil))
}
params.CurrentGasCeilLock.Unlock()
// Make sure we never go below the minimum gas limit
gl.Set(common.BigMax(gl, params.MinGasLimit))
return gl
}

View file

@ -38,6 +38,7 @@ import (
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/pow"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
@ -977,12 +978,24 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
events = append(events, ChainSplitEvent{block, logs})
}
stats.processed++
// Update the current gas limit (mining only) based on import times
params.CurrentGasCeilLock.Lock()
if time.Since(bstart) > params.BlockTimeLimit {
ceil := new(big.Int).Div(params.CurrentGasCeil, params.CurrentGasCeilCutDiv)
params.CurrentGasCeil.Set(common.BigMax(ceil, params.MinGasLimit))
} else {
ceil := new(big.Int).Add(params.CurrentGasCeil, new(big.Int).Div(params.CurrentGasCeil, params.CurrentGasCeilIncDiv))
limit := new(big.Int).Mul(chain[i].GasLimit(), big.NewInt(2))
params.CurrentGasCeil.Set(common.BigMin(ceil, limit))
}
glog.V(logger.Debug).Infof("block gas ceiling changed to %v", params.CurrentGasCeil)
params.CurrentGasCeilLock.Unlock()
}
if (stats.queued > 0 || stats.processed > 0 || stats.ignored > 0) && bool(glog.V(logger.Info)) {
tend := time.Since(tstart)
start, end := chain[0], chain[len(chain)-1]
glog.Infof("imported %d block(s) (%d queued %d ignored) including %d txs in %v. #%v [%x / %x]\n", stats.processed, stats.queued, stats.ignored, txcount, tend, end.Number(), start.Hash().Bytes()[:4], end.Hash().Bytes()[:4])
glog.Infof("imported %d block(s) (%d queued %d ignored) including %d txs in %v. #%v [%x / %x]\n", stats.processed, stats.queued, stats.ignored, txcount, time.Since(tstart), end.Number(), start.Hash().Bytes()[:4], end.Hash().Bytes()[:4])
}
go self.postChainEvents(events, coalescedLogs)

35
params/miner_strategy.go Normal file
View file

@ -0,0 +1,35 @@
// Copyright 2016 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package params
import (
"math/big"
"sync"
"time"
)
var (
GenesisGasLimit = big.NewInt(4712388) // Gas limit of the Genesis block.
TargetGasLimit = new(big.Int).Set(GenesisGasLimit) // The artificial target
BlockTimeLimit = 5 * time.Second // Block processing time limit to reduce gas after
// Temp hack to get a dynamic gas limit in palace (clean up!!!)
CurrentGasCeil = new(big.Int).Set(GenesisGasLimit)
CurrentGasCeilCutDiv = big.NewInt(2)
CurrentGasCeilIncDiv = new(big.Int).Set(GasLimitBoundDivisor)
CurrentGasCeilLock sync.Mutex
)

View file

@ -39,10 +39,7 @@ var (
CallStipend = big.NewInt(2300) // Free gas given at beginning of call.
EcrecoverGas = big.NewInt(3000) //
Sha256WordGas = big.NewInt(12) //
MinGasLimit = big.NewInt(5000) // Minimum the gas limit may ever be.
GenesisGasLimit = big.NewInt(4712388) // Gas limit of the Genesis block.
TargetGasLimit = new(big.Int).Set(GenesisGasLimit) // The artificial target
MinGasLimit = big.NewInt(5000) // Minimum the gas limit may ever be.
Sha3Gas = big.NewInt(30) // Once per SHA3 operation.
Sha256Gas = big.NewInt(60) //