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 }