diff --git a/docs/constants-and-vars.rst b/docs/constants-and-vars.rst index 62b8b73072..be6393ae37 100644 --- a/docs/constants-and-vars.rst +++ b/docs/constants-and-vars.rst @@ -11,23 +11,26 @@ Environment variables always exist in the namespace and are primarily used to pr Block and Transaction Properties -------------------------------- -==================== ================ ========================================================= -Name Type Value -==================== ================ ========================================================= -``block.coinbase`` ``address`` Current block miner's address -``block.difficulty`` ``uint256`` Current block difficulty -``block.prevrandao`` ``bytes32`` Current randomness beacon provided by the beacon chain -``block.number`` ``uint256`` Current block number -``block.prevhash`` ``bytes32`` Equivalent to ``blockhash(block.number - 1)`` -``block.timestamp`` ``uint256`` Current block epoch timestamp -``chain.id`` ``uint256`` Chain ID -``msg.data`` ``Bytes`` Message data -``msg.gas`` ``uint256`` Remaining gas -``msg.sender`` ``address`` Sender of the message (current call) -``msg.value`` ``uint256`` Number of wei sent with the message -``tx.origin`` ``address`` Sender of the transaction (full call chain) -``tx.gasprice`` ``uint256`` Gas price of current transaction in wei -==================== ================ ========================================================= +===================== ================ ========================================================= +Name Type Value +===================== ================ ========================================================= +``block.coinbase`` ``address`` Current block miner's address +``block.difficulty`` ``uint256`` Current block difficulty +``block.prevrandao`` ``bytes32`` Current randomness beacon provided by the beacon chain +``block.number`` ``uint256`` Current block number +``block.gaslimit`` ``uint256`` Current block's gas limit +``block.basefee`` ``uint256`` Current block's base fee +``block.blobbasefee`` ``uint256`` Current block's blob gas base fee +``block.prevhash`` ``bytes32`` Equivalent to ``blockhash(block.number - 1)`` +``block.timestamp`` ``uint256`` Current block epoch timestamp +``chain.id`` ``uint256`` Chain ID +``msg.data`` ``Bytes`` Message data +``msg.gas`` ``uint256`` Remaining gas +``msg.sender`` ``address`` Sender of the message (current call) +``msg.value`` ``uint256`` Number of wei sent with the message +``tx.origin`` ``address`` Sender of the transaction (full call chain) +``tx.gasprice`` ``uint256`` Gas price of current transaction in wei +===================== ================ ========================================================= .. note:: diff --git a/setup.py b/setup.py index da5654603d..6b02790ad0 100644 --- a/setup.py +++ b/setup.py @@ -13,10 +13,10 @@ "pytest-instafail>=0.4,<1.0", "pytest-xdist>=3.0,<3.4", "pytest-split>=0.7.0,<1.0", - "eth-tester[py-evm]>=0.10.0b4,<0.11", - "eth_abi>=4.0.0,<5.0.0", - "py-evm>=0.10.0b4,<0.11", - "web3==6.0.0", + "eth-tester[py-evm]>=0.11.0b1,<0.12", + "eth_abi>=5.0.0,<6.0.0", + "py-evm>=0.10.1b1,<0.11", + "web3>=7.0.0b4,<8.0", "lark==1.1.9", "hypothesis[lark]>=6.0,<7.0", "eth-stdlib==0.2.7", diff --git a/tests/functional/codegen/environment_variables/test_blobbasefee.py b/tests/functional/codegen/environment_variables/test_blobbasefee.py new file mode 100644 index 0000000000..b92824491c --- /dev/null +++ b/tests/functional/codegen/environment_variables/test_blobbasefee.py @@ -0,0 +1,50 @@ +import pytest +from eth.vm.forks.cancun.constants import BLOB_BASE_FEE_UPDATE_FRACTION, MIN_BLOB_BASE_FEE +from eth.vm.forks.cancun.state import fake_exponential + + +@pytest.mark.requires_evm_version("cancun") +def test_blobbasefee(get_contract_with_gas_estimation, w3): + code = """ +@external +@view +def get_blobbasefee() -> uint256: + return block.blobbasefee +""" + c = get_contract_with_gas_estimation(code) + + assert c.get_blobbasefee() == MIN_BLOB_BASE_FEE + + a0 = w3.eth.account.from_key(f"0x{'00' * 31}01") + + text = b"Vyper is the language of the sneks" + # Blobs contain 4096 32-byte field elements. + blob_data = text.rjust(32 * 4096) + + for _i in range(10): + tx = { + "type": 3, + "chainId": 1337, + "from": a0.address, + "to": "0xb45BEc6eeCA2a09f4689Dd308F550Ad7855051B5", # random address + "value": 0, + "gas": 21000, + "maxFeePerGas": 10**10, + "maxPriorityFeePerGas": 10**10, + "maxFeePerBlobGas": 10**10, + "nonce": w3.eth.get_transaction_count(a0.address), + } + + signed = a0.sign_transaction(tx, blobs=[blob_data] * 6) + w3.eth.send_raw_transaction(signed.rawTransaction) + + block = w3.eth.get_block("latest") + excess_blob_gas = block["excessBlobGas"] + expected_blobbasefee = fake_exponential( + MIN_BLOB_BASE_FEE, excess_blob_gas, BLOB_BASE_FEE_UPDATE_FRACTION + ) + + assert c.get_blobbasefee() == expected_blobbasefee + + # sanity check that blobbasefee has increased above the minimum + assert c.get_blobbasefee() > MIN_BLOB_BASE_FEE diff --git a/tests/functional/syntax/test_block.py b/tests/functional/syntax/test_block.py index 6a90f8f992..c69e7e8657 100644 --- a/tests/functional/syntax/test_block.py +++ b/tests/functional/syntax/test_block.py @@ -153,3 +153,31 @@ def foo() -> uint256: @pytest.mark.parametrize("good_code", valid_list) def test_block_success(good_code): assert compiler.compile_code(good_code) is not None + + +valid_list = [ + """ +@external +def foo() -> uint256: + return block.blobbasefee + """, + """ +@external +def foo() -> uint256: + a: uint256 = 5 + a = block.blobbasefee + return a + """, + """ +@external +def foo() -> uint256: + a: uint256 = block.blobbasefee + return a + """, +] + + +@pytest.mark.requires_evm_version("cancun") +@pytest.mark.parametrize("good_code", valid_list) +def test_block_blob_success(good_code): + assert compiler.compile_code(good_code) is not None diff --git a/vyper/codegen/expr.py b/vyper/codegen/expr.py index 276f261fc8..aca524cd6a 100644 --- a/vyper/codegen/expr.py +++ b/vyper/codegen/expr.py @@ -31,6 +31,7 @@ from vyper.exceptions import ( CodegenPanic, CompilerPanic, + EvmVersionException, StructureException, TypeCheckFailure, TypeMismatch, @@ -286,6 +287,12 @@ def parse_Attribute(self): return IRnode.from_list(["gaslimit"], typ=UINT256_T) elif key == "block.basefee": return IRnode.from_list(["basefee"], typ=UINT256_T) + elif key == "block.blobbasefee": + if not version_check(begin="cancun"): + raise EvmVersionException( + "`block.blobbasefee` is not available pre-cancun", self.expr + ) + return IRnode.from_list(["blobbasefee"], typ=UINT256_T) elif key == "block.prevhash": return IRnode.from_list(["blockhash", ["sub", "number", 1]], typ=BYTES32_T) elif key == "tx.origin": diff --git a/vyper/evm/opcodes.py b/vyper/evm/opcodes.py index 023b3b5fe0..c9b772b760 100644 --- a/vyper/evm/opcodes.py +++ b/vyper/evm/opcodes.py @@ -75,6 +75,7 @@ "CHAINID": (0x46, 0, 1, 2), "SELFBALANCE": (0x47, 0, 1, 5), "BASEFEE": (0x48, 0, 1, 2), + "BLOBBASEFEE": (0x4A, 0, 1, (None, None, None, 2)), "POP": (0x50, 1, 0, 2), "MLOAD": (0x51, 1, 1, 3), "MSTORE": (0x52, 2, 0, 3), diff --git a/vyper/semantics/environment.py b/vyper/semantics/environment.py index 2585521f21..60477ff1c2 100644 --- a/vyper/semantics/environment.py +++ b/vyper/semantics/environment.py @@ -23,6 +23,7 @@ class _Block(_EnvType): "number": UINT256_T, "gaslimit": UINT256_T, "basefee": UINT256_T, + "blobbasefee": UINT256_T, "prevhash": BYTES32_T, "timestamp": UINT256_T, } diff --git a/vyper/venom/ir_node_to_venom.py b/vyper/venom/ir_node_to_venom.py index f610e17f58..7dc6bd2d47 100644 --- a/vyper/venom/ir_node_to_venom.py +++ b/vyper/venom/ir_node_to_venom.py @@ -48,6 +48,7 @@ "signextend", "chainid", "basefee", + "blobbasefee", "timestamp", "blockhash", "caller", @@ -75,7 +76,6 @@ "extcodehash", "balance", "msize", - "basefee", "invalid", "stop", "selfdestruct", diff --git a/vyper/venom/venom_to_assembly.py b/vyper/venom/venom_to_assembly.py index 41fa8888c9..6924628958 100644 --- a/vyper/venom/venom_to_assembly.py +++ b/vyper/venom/venom_to_assembly.py @@ -97,6 +97,7 @@ "delegatecall", "codesize", "basefee", + "blobbasefee", "prevrandao", "difficulty", "invalid",