2021-06-29 07:41:01 +00:00
|
|
|
# Nimbus
|
2024-05-30 12:54:03 +00:00
|
|
|
# Copyright (c) 2018-2024 Status Research & Development GmbH
|
2021-06-29 07:41:01 +00:00
|
|
|
# Licensed under either of
|
|
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0)
|
|
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
|
|
|
|
# http://opensource.org/licenses/MIT)
|
|
|
|
# at your option. This file may not be copied, modified, or distributed except
|
|
|
|
# according to those terms.
|
|
|
|
|
2022-12-02 04:35:41 +00:00
|
|
|
import ../common/common, std/strformat, results, eth/[eip1559]
|
2021-06-29 07:41:01 +00:00
|
|
|
|
2022-08-18 20:41:03 +00:00
|
|
|
export eip1559
|
2022-10-20 02:44:16 +00:00
|
|
|
|
2023-01-30 22:10:23 +00:00
|
|
|
{.push raises: [].}
|
|
|
|
|
2021-06-29 07:41:01 +00:00
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Pre Eip 1559 gas limit validation
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
2023-01-30 22:10:23 +00:00
|
|
|
proc validateGasLimit(header: BlockHeader, limit: GasInt): Result[void, string] =
|
2021-06-29 07:41:01 +00:00
|
|
|
let diff =
|
|
|
|
if limit > header.gasLimit:
|
|
|
|
limit - header.gasLimit
|
|
|
|
else:
|
|
|
|
header.gasLimit - limit
|
|
|
|
|
|
|
|
let upperLimit = limit div GAS_LIMIT_ADJUSTMENT_FACTOR
|
|
|
|
|
|
|
|
if diff >= upperLimit:
|
2021-10-05 23:31:35 +00:00
|
|
|
try:
|
|
|
|
return err(
|
|
|
|
&"invalid gas limit: have {header.gasLimit}, want {limit} +-= {upperLimit-1}"
|
|
|
|
)
|
|
|
|
except ValueError:
|
|
|
|
# TODO deprecate-strformat
|
|
|
|
raiseAssert "strformat cannot fail"
|
2021-06-29 07:41:01 +00:00
|
|
|
if header.gasLimit < GAS_LIMIT_MINIMUM:
|
|
|
|
return err("invalid gas limit below 5000")
|
|
|
|
ok()
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Eip 1559 support
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
# consensus/misc/eip1559.go(55): func CalcBaseFee(config [..]
|
2022-12-02 04:35:41 +00:00
|
|
|
proc calcEip1599BaseFee*(com: CommonRef, parent: BlockHeader): UInt256 =
|
2021-06-29 07:41:01 +00:00
|
|
|
## calculates the basefee of the header.
|
|
|
|
|
|
|
|
# If the current block is the first EIP-1559 block, return the
|
|
|
|
# initial base fee.
|
2024-06-27 05:54:36 +00:00
|
|
|
if com.isLondonOrLater(parent.number):
|
2024-06-14 07:31:08 +00:00
|
|
|
eip1559.calcEip1599BaseFee(
|
|
|
|
parent.gasLimit, parent.gasUsed, parent.baseFeePerGas.get(0.u256)
|
2024-07-19 13:54:25 +00:00
|
|
|
)
|
2021-06-29 07:41:01 +00:00
|
|
|
else:
|
2022-08-18 20:41:03 +00:00
|
|
|
EIP1559_INITIAL_BASE_FEE
|
2021-06-29 07:41:01 +00:00
|
|
|
|
|
|
|
# consensus/misc/eip1559.go(32): func VerifyEip1559Header(config [..]
|
2022-12-02 04:35:41 +00:00
|
|
|
proc verifyEip1559Header(
|
2021-10-05 23:31:35 +00:00
|
|
|
com: CommonRef, parent, header: BlockHeader
|
|
|
|
): Result[void, string] {.raises: [].} =
|
2021-06-29 07:41:01 +00:00
|
|
|
## Verify that the gas limit remains within allowed bounds
|
2024-06-27 05:54:36 +00:00
|
|
|
let limit =
|
|
|
|
if com.isLondonOrLater(parent.number):
|
2021-06-29 07:41:01 +00:00
|
|
|
parent.gasLimit
|
|
|
|
else:
|
|
|
|
parent.gasLimit * EIP1559_ELASTICITY_MULTIPLIER
|
|
|
|
let rc = header.validateGasLimit(limit)
|
|
|
|
if rc.isErr:
|
|
|
|
return rc
|
|
|
|
|
2024-06-14 07:31:08 +00:00
|
|
|
let headerBaseFee = header.baseFeePerGas.get(0.u256)
|
2021-06-29 07:41:01 +00:00
|
|
|
# Verify the header is not malformed
|
|
|
|
if headerBaseFee.isZero:
|
|
|
|
return err("Post EIP-1559 header expected to have base fee")
|
|
|
|
|
|
|
|
# Verify the baseFee is correct based on the parent header.
|
2022-12-02 04:35:41 +00:00
|
|
|
var expectedBaseFee = com.calcEip1599BaseFee(parent)
|
2021-06-29 07:41:01 +00:00
|
|
|
if headerBaseFee != expectedBaseFee:
|
2021-10-05 23:31:35 +00:00
|
|
|
try:
|
|
|
|
return err(
|
|
|
|
&"invalid baseFee: have {expectedBaseFee}, " & &"want {header.baseFeePerGas}, " &
|
2024-06-14 07:31:08 +00:00
|
|
|
&"parent.baseFee {parent.baseFeePerGas}, " & &"parent.gasUsed {parent.gasUsed}"
|
2021-10-05 23:31:35 +00:00
|
|
|
)
|
|
|
|
except ValueError:
|
|
|
|
# TODO deprecate-strformat
|
|
|
|
raiseAssert "strformat cannot fail"
|
2021-06-29 07:41:01 +00:00
|
|
|
|
|
|
|
return ok()
|
|
|
|
|
2022-12-02 04:35:41 +00:00
|
|
|
proc validateGasLimitOrBaseFee*(
|
2023-01-30 22:10:23 +00:00
|
|
|
com: CommonRef, header, parent: BlockHeader
|
|
|
|
): Result[void, string] =
|
2024-06-27 05:54:36 +00:00
|
|
|
if not com.isLondonOrLater(header.number):
|
2021-06-29 07:41:01 +00:00
|
|
|
# Verify BaseFee not present before EIP-1559 fork.
|
2024-06-14 07:31:08 +00:00
|
|
|
let baseFeePerGas = header.baseFeePerGas.get(0.u256)
|
|
|
|
if not baseFeePerGas.isZero:
|
|
|
|
return
|
|
|
|
err("invalid baseFee before London fork: have " & $baseFeePerGas & ", want <0>")
|
2024-06-24 06:40:22 +00:00
|
|
|
?validateGasLimit(header, parent.gasLimit)
|
2021-06-29 07:41:01 +00:00
|
|
|
else:
|
2024-06-24 06:40:22 +00:00
|
|
|
?com.verifyEip1559Header(parent = parent, header = header)
|
2021-06-29 07:41:01 +00:00
|
|
|
|
|
|
|
return ok()
|