Coverage Summary for Class: GasLimitCalculator (co.rsk.mine)

Class Class, % Method, % Line, %
GasLimitCalculator 0% (0/1) 0% (0/2) 0% (0/31)


1 /* 2  * This file is part of RskJ 3  * Copyright (C) 2017 RSK Labs Ltd. 4  * 5  * This program is free software: you can redistribute it and/or modify 6  * it under the terms of the GNU Lesser General Public License as published by 7  * the Free Software Foundation, either version 3 of the License, or 8  * (at your option) any later version. 9  * 10  * This program is distributed in the hope that it will be useful, 11  * but WITHOUT ANY WARRANTY; without even the implied warranty of 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13  * GNU Lesser General Public License for more details. 14  * 15  * You should have received a copy of the GNU Lesser General Public License 16  * along with this program. If not, see <http://www.gnu.org/licenses/>. 17  */ 18  19 package co.rsk.mine; 20  21 import org.ethereum.config.Constants; 22  23 import java.math.BigInteger; 24  25 /** 26  * Created by Ruben on 23/05/2016. 27  * This class calculates next block gas limit 28  */ 29 public class GasLimitCalculator { 30  31  private final Constants constants; 32  33  public GasLimitCalculator(Constants networkConstants) { 34  constants = networkConstants; 35  } 36  37  // At the end of this algorithm it will increase the gas limit if and only if the previous block gas used 38  // is above 2/3 of the block gas limit, and decrease otherwise, by small amounts 39  // The idea is to increase the gas limit when there are more transactions on the network while reduce it when 40  // there are no or almost no transaction on it 41  public BigInteger calculateBlockGasLimit(BigInteger parentGasLimit, BigInteger parentGasUsed, BigInteger minGasLimit, BigInteger targetGasLimit, boolean forceTarget) { 42  43  BigInteger newGasLimit = parentGasLimit; 44  45  // deltaMax = parentGasLimit / 1024 46  // current Eth implementation substracts parentGasLimit / 1024 - 1 47  // parent - deltaMax or parent + deltaMax are the limits 48  // that should be accepted by consensus rules 49  BigInteger deltaMax = parentGasLimit 50  .divide(BigInteger.valueOf(constants.getGasLimitBoundDivisor())); 51  52  // TODO: we should assert this before reaching this point 53  if (targetGasLimit.compareTo(minGasLimit) < 0) { 54  targetGasLimit = minGasLimit; 55  } 56  57  // In this case we just try to reach the target gasLimit independently of 58  // the gas used 59  if (forceTarget) { 60  if (targetGasLimit.compareTo(parentGasLimit) < 0) { 61  newGasLimit = newGasLimit.subtract(deltaMax); 62  if (targetGasLimit.compareTo(newGasLimit) > 0) { 63  newGasLimit = targetGasLimit; 64  } 65  return newGasLimit; 66  } else { 67  newGasLimit = newGasLimit.add(deltaMax); 68  if (targetGasLimit.compareTo(newGasLimit) < 0) { 69  newGasLimit = targetGasLimit; 70  } 71  return newGasLimit; 72  } 73  } 74  75  // contrib = (parentGasUsed * 3 / 2) / 1024 76  BigInteger contrib = parentGasUsed.multiply(BigInteger.valueOf(3)); 77  contrib = contrib.divide(BigInteger.valueOf(2)); 78  contrib = contrib.divide(BigInteger.valueOf(constants.getGasLimitBoundDivisor())); 79  80  newGasLimit = newGasLimit.subtract(deltaMax); 81  newGasLimit = newGasLimit.add(contrib); 82  83  // Gas limit can never be lesser than a certain threshold 84  if (newGasLimit.compareTo(minGasLimit) < 0) { 85  newGasLimit = minGasLimit; 86  } 87  88  if (newGasLimit.compareTo(targetGasLimit) > 0) { 89  newGasLimit = targetGasLimit; 90  } 91  92  // I've never done enough calculations, but neither of these two should ever happen 93  if (newGasLimit.compareTo(parentGasLimit.subtract(deltaMax)) < 0) { 94  newGasLimit = parentGasLimit; 95  } 96  97  if (newGasLimit.compareTo(parentGasLimit.add(deltaMax)) > 0) { 98  newGasLimit = parentGasLimit; 99  } 100  101  return newGasLimit; 102  } 103 }