LoginSignup
6
4

More than 5 years have passed since last update.

GasLimitの計算方法をソースコードレベルで理解する ~go-ethereum~

Last updated at Posted at 2017-07-08

背景

  • 最近、急速にGasLimitが上昇しているというニュースを見て、分散ネットワーク上でどのようにGasLimitを変化させているのかが気になった。
  • GasLimitによるcontractの実行制限を排除する方法を知りたいと思った。
    • [解説1] GasLimitとは、contract実行に必要なGas(ether)の上限値である。GasLimitの存在によって、高負荷なプログラムの実行を防止し、無限ループ等によるnode停止を防いでいる。
    • [解説2] contractとは、ethereum上で動作するアプリケーションである。

ソースコード

go-ethereum/core/block_validator.go
// CalcGasLimit computes the gas limit of the next block after parent.
// The result may be modified by the caller.
// This is miner strategy, not consensus protocol.
func CalcGasLimit(parent *types.Block) *big.Int {
    // contrib = (parentGasUsed * 3 / 2) / 1024
    contrib := new(big.Int).Mul(parent.GasUsed(), big.NewInt(3))
    contrib = contrib.Div(contrib, big.NewInt(2))
    contrib = contrib.Div(contrib, params.GasLimitBoundDivisor)

    // decay = parentGasLimit / 1024 -1
    decay := new(big.Int).Div(parent.GasLimit(), params.GasLimitBoundDivisor)
    decay.Sub(decay, big.NewInt(1))

    /*
        strategy: gasLimit of block-to-mine is set based on parent's
        gasUsed value.  if parentGasUsed > parentGasLimit * (2/3) then we
        increase it, otherwise lower it (or leave it unchanged if it's right
        at that usage) the amount increased/decreased depends on how far away
        from parentGasLimit * (2/3) parentGasUsed is.
    */
    gl := new(big.Int).Sub(parent.GasLimit(), decay)
    gl = gl.Add(gl, contrib)
    gl.Set(math.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)
    if gl.Cmp(params.TargetGasLimit) < 0 {
        gl.Add(parent.GasLimit(), decay)
        gl.Set(math.BigMin(gl, params.TargetGasLimit))
    }
    return gl
}

引用元:https://github.com/ethereum/go-ethereum/tree/master/core

パラメータの説明

  • gl: New GasLimit
  • GasLimitBoundDivisor: GasLimitの増減率
    • defined by genesis block
  • contrib: GasLimit増加方向に寄与
    • (parentGasUsed * 3 / 2) / GasLimitBoundDivisor
  • decay: GasLimit減少方向に寄与
    • parentGasLimit / GasLimitBoundDivisor -1

GasLimitの計算方法

  • New GasLimit = parentGasLimit - decay + contrib -> parentGasUsedparentGasLimit * (2/3)の大小関係によって、New GasLimitが増減される
  • MinGasLimit ≦ New GasLimit ≦ TargetGasLimit
    -> MinGasLimitTargetGasLimitの範囲に調整される

GasLimitによるcontract実行制限を解除する

  • MinGasLimitTargetGasLimit(GenesisGasLimit)を十分大きくすれば良い。
  • MinGasLimit,GenesisGasLimitは、genesis.jsonorparams/protocol_params.goで設定する。

まとめ

  • Block生成毎に、GasLimitが再計算される。
  • 前ブロックのGas使用量前ブロックのGasLimit*(2/3)の大小関係によって、New GasLimitが増減される
  • GasLimitによるContractの実行制限を排除したい場合は、MinGasLimitとGenesisGasLimitを十分大きくすれば良い。
  • GasLimitの計算は、consensus protocolではないため、minerが決定することができる。
6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4