Skip to content

Commit 4b6dc06

Browse files
committed
bugfix: the gas_limit has to be above or below 1/1024th of the parent
The gas_limit was improperly allowed to be 1/1024th of the parent gas limit. However, this is an exclusive limit that the new gas limit must be inside of, therefore requiring +1 or -1 from the bound as the inclusive, allowable values.
1 parent 7cfe4bb commit 4b6dc06

File tree

5 files changed

+21
-15
lines changed

5 files changed

+21
-15
lines changed

eth/_utils/headers.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,12 @@ def compute_gas_limit_bounds(previous_limit: int) -> Tuple[int, int]:
105105
Compute the boundaries for the block gas limit based on the parent block.
106106
"""
107107
boundary_range = previous_limit // GAS_LIMIT_ADJUSTMENT_FACTOR
108-
upper_bound = min(GAS_LIMIT_MAXIMUM, previous_limit + boundary_range)
109-
lower_bound = max(GAS_LIMIT_MINIMUM, previous_limit - boundary_range)
110-
return lower_bound, upper_bound
108+
109+
# the boundary range is the exclusive limit, therefore the inclusive bounds are
110+
# (boundary_range - 1) and (boundary_range + 1) for upper and lower bounds, respectively
111+
upper_bound_inclusive = min(GAS_LIMIT_MAXIMUM, previous_limit + boundary_range - 1)
112+
lower_bound_inclusive = max(GAS_LIMIT_MINIMUM, previous_limit - boundary_range + 1)
113+
return lower_bound_inclusive, upper_bound_inclusive
111114

112115

113116
def compute_gas_limit(parent_header: BlockHeaderAPI, genesis_gas_limit: int) -> int:
@@ -152,12 +155,14 @@ def compute_gas_limit(parent_header: BlockHeaderAPI, genesis_gas_limit: int) ->
152155

153156
gas_limit = max(
154157
GAS_LIMIT_MINIMUM,
155-
parent_header.gas_limit - decay + usage_increase
158+
# + 1 because the decay is an exclusive limit we have to remain inside of
159+
(parent_header.gas_limit - decay + 1) + usage_increase
156160
)
157161

158162
if gas_limit < GAS_LIMIT_MINIMUM:
159163
return GAS_LIMIT_MINIMUM
160164
elif gas_limit < genesis_gas_limit:
161-
return parent_header.gas_limit + decay
165+
# - 1 because the decay is an exclusive limit we have to remain inside of
166+
return parent_header.gas_limit + decay - 1
162167
else:
163168
return gas_limit

eth/validation.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,11 @@ def validate_vm_configuration(vm_configuration: Tuple[Tuple[int, Type[VirtualMac
230230

231231
def validate_gas_limit(gas_limit: int, parent_gas_limit: int) -> None:
232232
low_bound, high_bound = compute_gas_limit_bounds(parent_gas_limit)
233-
if gas_limit <= low_bound:
233+
if gas_limit < low_bound:
234234
raise ValidationError(
235235
f"The gas limit {gas_limit} is too low. It must be at least {low_bound}"
236236
)
237-
elif gas_limit >= high_bound:
237+
elif gas_limit > high_bound:
238238
raise ValidationError(
239239
f"The gas limit {gas_limit} is too high. It must be at most {high_bound}"
240240
)

eth/vm/base.py

+1
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,7 @@ def validate_uncle(cls,
668668
f"Uncle's gas usage ({uncle.gas_used}) is above "
669669
f"the limit ({uncle.gas_limit})"
670670
)
671+
validate_gas_limit(uncle.gas_limit, uncle_parent.gas_limit)
671672

672673
#
673674
# State

tests/core/vm/test_london.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ def test_state_revert_on_reserved_0xEF_byte_for_create_transaction_post_london(
222222

223223
block_import, _, computations = chain.mine_all(
224224
[create_successful_contract_transaction],
225-
gas_limit=84082,
225+
gas_limit=84081,
226226
)
227227
successful_create_computation = computations[0]
228228
successful_create_computation_state = successful_create_computation.state
@@ -336,7 +336,7 @@ def test_state_does_not_revert_on_reserved_0xEF_byte_for_create_transaction_pre_
336336

337337
block_import, _, computations = chain.mine_all(
338338
[create_contract_txn_0xef_byte],
339-
gas_limit=99903
339+
gas_limit=99904
340340
)
341341

342342
computation = computations[0]

tests/core/vm/test_vm.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ def test_validate_gas_limit_almost_too_low(noproof_consensus_chain):
133133
block1 = noproof_consensus_chain.mine_block()
134134
block2 = noproof_consensus_chain.mine_block()
135135

136-
max_reduction = block1.header.gas_limit // constants.GAS_LIMIT_ADJUSTMENT_FACTOR
136+
max_reduction = block1.header.gas_limit // constants.GAS_LIMIT_ADJUSTMENT_FACTOR - 1
137137
barely_valid_low_gas_limit = block1.header.gas_limit - max_reduction
138138
barely_valid_header = block2.header.copy(gas_limit=barely_valid_low_gas_limit)
139139

@@ -146,8 +146,8 @@ def test_validate_gas_limit_too_low(noproof_consensus_chain):
146146
block1 = noproof_consensus_chain.mine_block()
147147
block2 = noproof_consensus_chain.mine_block()
148148

149-
max_reduction = block1.header.gas_limit // constants.GAS_LIMIT_ADJUSTMENT_FACTOR
150-
invalid_low_gas_limit = block1.header.gas_limit - max_reduction - 1
149+
exclusive_decrease_limit = block1.header.gas_limit // constants.GAS_LIMIT_ADJUSTMENT_FACTOR
150+
invalid_low_gas_limit = block1.header.gas_limit - exclusive_decrease_limit
151151
invalid_header = block2.header.copy(gas_limit=invalid_low_gas_limit)
152152

153153
vm = noproof_consensus_chain.get_vm(block2.header)
@@ -160,7 +160,7 @@ def test_validate_gas_limit_almost_too_high(noproof_consensus_chain):
160160
block1 = noproof_consensus_chain.mine_block()
161161
block2 = noproof_consensus_chain.mine_block()
162162

163-
max_increase = block1.header.gas_limit // constants.GAS_LIMIT_ADJUSTMENT_FACTOR
163+
max_increase = block1.header.gas_limit // constants.GAS_LIMIT_ADJUSTMENT_FACTOR - 1
164164
barely_valid_high_gas_limit = block1.header.gas_limit + max_increase
165165
barely_valid_header = block2.header.copy(gas_limit=barely_valid_high_gas_limit)
166166

@@ -173,8 +173,8 @@ def test_validate_gas_limit_too_high(noproof_consensus_chain):
173173
block1 = noproof_consensus_chain.mine_block()
174174
block2 = noproof_consensus_chain.mine_block()
175175

176-
max_increase = block1.header.gas_limit // constants.GAS_LIMIT_ADJUSTMENT_FACTOR
177-
invalid_high_gas_limit = block1.header.gas_limit + max_increase + 1
176+
exclusive_increase_limit = block1.header.gas_limit // constants.GAS_LIMIT_ADJUSTMENT_FACTOR
177+
invalid_high_gas_limit = block1.header.gas_limit + exclusive_increase_limit
178178
invalid_header = block2.header.copy(gas_limit=invalid_high_gas_limit)
179179

180180
vm = noproof_consensus_chain.get_vm(block2.header)

0 commit comments

Comments
 (0)