Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions src/ethereum/prague/blobs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
"""
Blob Gas Calculations
^^^^^^^^^^^^^^^^^^^^^

.. contents:: Table of Contents
:backlinks: none
:local:

Introduction
------------

Blob gas calculations for blocks and transactions.
"""

from ethereum_types.numeric import U64, Uint

from ..utils.numeric import taylor_exponential
from .blocks import Header
from .transactions import BlobTransaction, Transaction

# Blob gas constants
TARGET_BLOB_GAS_PER_BLOCK = U64(786432)
GAS_PER_BLOB = U64(2**17)
MIN_BLOB_GASPRICE = Uint(1)
BLOB_BASE_FEE_UPDATE_FRACTION = Uint(5007716)
MAX_BLOB_GAS_PER_BLOCK = U64(786432)


def calculate_excess_blob_gas(parent_header: Header) -> U64:
"""
Calculated the excess blob gas for the current block based
on the gas used in the parent block.

Parameters
----------
parent_header :
The parent block of the current block.

Returns
-------
excess_blob_gas: `ethereum.base_types.U64`
The excess blob gas for the current block.
"""
# At the fork block, these are defined as zero.
excess_blob_gas = U64(0)
blob_gas_used = U64(0)

if isinstance(parent_header, Header):
# After the fork block, read them from the parent header.
excess_blob_gas = parent_header.excess_blob_gas
blob_gas_used = parent_header.blob_gas_used

parent_blob_gas = excess_blob_gas + blob_gas_used
if parent_blob_gas < TARGET_BLOB_GAS_PER_BLOCK:
return U64(0)
else:
return parent_blob_gas - TARGET_BLOB_GAS_PER_BLOCK


def calculate_total_blob_gas(tx: Transaction) -> U64:
"""
Calculate the total blob gas for a transaction.

Parameters
----------
tx :
The transaction for which the blob gas is to be calculated.

Returns
-------
total_blob_gas: `ethereum.base_types.Uint`
The total blob gas for the transaction.
"""
if isinstance(tx, BlobTransaction):
return GAS_PER_BLOB * U64(len(tx.blob_versioned_hashes))
else:
return U64(0)


def calculate_blob_gas_price(excess_blob_gas: U64) -> Uint:
"""
Calculate the blob gasprice for a block.

Parameters
----------
excess_blob_gas :
The excess blob gas for the block.

Returns
-------
blob_gasprice: `Uint`
The blob gasprice.
"""
return taylor_exponential(
MIN_BLOB_GASPRICE,
Uint(excess_blob_gas),
BLOB_BASE_FEE_UPDATE_FRACTION,
)


def calculate_data_fee(excess_blob_gas: U64, tx: Transaction) -> Uint:
"""
Calculate the blob data fee for a transaction.

Parameters
----------
excess_blob_gas :
The excess_blob_gas for the execution.
tx :
The transaction for which the blob data fee is to be calculated.

Returns
-------
data_fee: `Uint`
The blob data fee.
"""
return Uint(calculate_total_blob_gas(tx)) * calculate_blob_gas_price(
excess_blob_gas
)
14 changes: 7 additions & 7 deletions src/ethereum/prague/fork.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@
)

from . import vm
from .blobs import (
MAX_BLOB_GAS_PER_BLOCK,
calculate_blob_gas_price,
calculate_data_fee,
calculate_excess_blob_gas,
calculate_total_blob_gas,
)
from .blocks import Block, Header, Log, Receipt, Withdrawal, encode_receipt
from .bloom import logs_bloom
from .fork_types import Account, Address, Authorization, VersionedHash
Expand Down Expand Up @@ -66,12 +73,6 @@
from .utils.message import prepare_message
from .vm import Message
from .vm.eoa_delegation import is_valid_delegation
from .vm.gas import (
calculate_blob_gas_price,
calculate_data_fee,
calculate_excess_blob_gas,
calculate_total_blob_gas,
)
from .vm.interpreter import MessageCallOutput, process_message_call

BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8)
Expand All @@ -84,7 +85,6 @@
"0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02"
)
SYSTEM_TRANSACTION_GAS = Uint(30000000)
MAX_BLOB_GAS_PER_BLOCK = U64(1179648)
VERSIONED_HASH_VERSION_KZG = b"\x01"

WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS = hex_to_address(
Expand Down
104 changes: 2 additions & 102 deletions src/ethereum/prague/vm/gas.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@
from dataclasses import dataclass
from typing import List, Tuple

from ethereum_types.numeric import U64, U256, Uint
from ethereum_types.numeric import U256, Uint

from ethereum.trace import GasAndRefund, evm_trace
from ethereum.utils.numeric import ceil32, taylor_exponential
from ethereum.utils.numeric import ceil32

from ..blocks import Header
from ..transactions import BlobTransaction, Transaction
from . import Evm
from .exceptions import OutOfGasError

Expand Down Expand Up @@ -68,11 +66,6 @@
GAS_BLOBHASH_OPCODE = Uint(3)
GAS_POINT_EVALUATION = Uint(50000)

TARGET_BLOB_GAS_PER_BLOCK = U64(786432)
GAS_PER_BLOB = U64(2**17)
MIN_BLOB_GASPRICE = Uint(1)
BLOB_BASE_FEE_UPDATE_FRACTION = Uint(5007716)

GAS_BLS_G1_ADD = Uint(375)
GAS_BLS_G1_MUL = Uint(12000)
GAS_BLS_G1_MAP = Uint(5500)
Expand Down Expand Up @@ -275,96 +268,3 @@ def init_code_cost(init_code_length: Uint) -> Uint:
The gas to be charged for the init code.
"""
return GAS_INIT_CODE_WORD_COST * ceil32(init_code_length) // Uint(32)


def calculate_excess_blob_gas(parent_header: Header) -> U64:
"""
Calculated the excess blob gas for the current block based
on the gas used in the parent block.

Parameters
----------
parent_header :
The parent block of the current block.

Returns
-------
excess_blob_gas: `ethereum.base_types.U64`
The excess blob gas for the current block.
"""
# At the fork block, these are defined as zero.
excess_blob_gas = U64(0)
blob_gas_used = U64(0)

if isinstance(parent_header, Header):
# After the fork block, read them from the parent header.
excess_blob_gas = parent_header.excess_blob_gas
blob_gas_used = parent_header.blob_gas_used

parent_blob_gas = excess_blob_gas + blob_gas_used
if parent_blob_gas < TARGET_BLOB_GAS_PER_BLOCK:
return U64(0)
else:
return parent_blob_gas - TARGET_BLOB_GAS_PER_BLOCK


def calculate_total_blob_gas(tx: Transaction) -> U64:
"""
Calculate the total blob gas for a transaction.

Parameters
----------
tx :
The transaction for which the blob gas is to be calculated.

Returns
-------
total_blob_gas: `ethereum.base_types.Uint`
The total blob gas for the transaction.
"""
if isinstance(tx, BlobTransaction):
return GAS_PER_BLOB * U64(len(tx.blob_versioned_hashes))
else:
return U64(0)


def calculate_blob_gas_price(excess_blob_gas: U64) -> Uint:
"""
Calculate the blob gasprice for a block.

Parameters
----------
excess_blob_gas :
The excess blob gas for the block.

Returns
-------
blob_gasprice: `Uint`
The blob gasprice.
"""
return taylor_exponential(
MIN_BLOB_GASPRICE,
Uint(excess_blob_gas),
BLOB_BASE_FEE_UPDATE_FRACTION,
)


def calculate_data_fee(excess_blob_gas: U64, tx: Transaction) -> Uint:
"""
Calculate the blob data fee for a transaction.

Parameters
----------
excess_blob_gas :
The excess_blob_gas for the execution.
tx :
The transaction for which the blob data fee is to be calculated.

Returns
-------
data_fee: `Uint`
The blob data fee.
"""
return Uint(calculate_total_blob_gas(tx)) * calculate_blob_gas_price(
excess_blob_gas
)
4 changes: 2 additions & 2 deletions src/ethereum/prague/vm/instructions/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from ethereum.crypto.hash import keccak256
from ethereum.utils.numeric import ceil32

from ...blobs import calculate_blob_gas_price
from ...fork_types import EMPTY_ACCOUNT
from ...state import get_account
from ...utils.address import to_address
Expand All @@ -33,7 +34,6 @@
GAS_RETURN_DATA_COPY,
GAS_VERY_LOW,
GAS_WARM_ACCESS,
calculate_blob_gas_price,
calculate_gas_extend_memory,
charge_gas,
)
Expand Down Expand Up @@ -460,7 +460,7 @@ def returndatacopy(evm: Evm) -> None:

def extcodehash(evm: Evm) -> None:
"""
Returns the keccak256 hash of a contract’s bytecode
Returns the keccak256 hash of a contracts bytecode
Parameters
----------
evm :
Expand Down
Loading