Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce blobbasefee #14755

Merged
merged 1 commit into from
Jan 12, 2024
Merged
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
2 changes: 2 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
### 0.8.24 (unreleased)

Language Features:
* Introduce global ``block.blobbasefee`` for retrieving the blob base fee of the current block.
* Yul: Introduce builtin ``blobbasefee()`` for retrieving the blob base fee of the current block.
nikola-matic marked this conversation as resolved.
Show resolved Hide resolved


Compiler Features:
Expand Down
3 changes: 2 additions & 1 deletion docs/cheatsheet.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,15 @@ Members of ``address``
returns ``false`` on failure
- ``<address payable>.transfer(uint256 amount)``: send given amount of Wei to :ref:`address`, throws on failure

.. index:: blockhash, block, block;basefree, block;chainid, block;coinbase, block;difficulty, block;gaslimit, block;number, block;prevrandao, block;timestamp
.. index:: blockhash, block, block;basefee, block;blobbasefee, block;chainid, block;coinbase, block;difficulty, block;gaslimit, block;number, block;prevrandao, block;timestamp
.. index:: gasleft, msg;data, msg;sender, msg;sig, msg;value, tx;gasprice, tx;origin

Block and Transaction Properties
================================

- ``blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent blocks
- ``block.basefee`` (``uint``): current block's base fee (`EIP-3198 <https://eips.ethereum.org/EIPS/eip-3198>`_ and `EIP-1559 <https://eips.ethereum.org/EIPS/eip-1559>`_)
- ``block.blobbasefee`` (``uint``): current block's blob base fee (`EIP-7516 <https://eips.ethereum.org/EIPS/eip-7516>`_ and `EIP-4844 <https://eips.ethereum.org/EIPS/eip-4844>`_)
r0qs marked this conversation as resolved.
Show resolved Hide resolved
- ``block.chainid`` (``uint``): current chain id
- ``block.coinbase`` (``address payable``): current block miner's address
- ``block.difficulty`` (``uint``): current block difficulty (``EVM < Paris``). For other EVM versions it behaves as a deprecated alias for ``block.prevrandao`` that will be removed in the next breaking release
Expand Down
2 changes: 1 addition & 1 deletion docs/grammar/SolidityLexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ YulEVMBuiltin:
| 'delegatecall' | 'staticcall' | 'return' | 'revert' | 'selfdestruct' | 'invalid'
| 'log0' | 'log1' | 'log2' | 'log3' | 'log4' | 'chainid' | 'origin' | 'gasprice'
| 'blockhash' | 'coinbase' | 'timestamp' | 'number' | 'difficulty' | 'prevrandao'
| 'gaslimit' | 'basefee';
| 'gaslimit' | 'basefee' | 'blobbasefee';

YulLBrace: '{' -> pushMode(YulMode);
YulRBrace: '}' -> popMode;
Expand Down
3 changes: 2 additions & 1 deletion docs/units-and-global-variables.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,15 @@ There are special variables and functions which always exist in the global
namespace and are mainly used to provide information about the blockchain
or are general-use utility functions.

.. index:: abi, block, coinbase, difficulty, prevrandao, encode, number, block;number, timestamp, block;timestamp, msg, data, gas, sender, value, gas price, origin
.. index:: abi, block, coinbase, difficulty, prevrandao, encode, number, block;number, timestamp, block;timestamp, block;basefee, block;blobbasefee, msg, data, gas, sender, value, gas price, origin


Block and Transaction Properties
--------------------------------

- ``blockhash(uint blockNumber) returns (bytes32)``: hash of the given block when ``blocknumber`` is one of the 256 most recent blocks; otherwise returns zero
- ``block.basefee`` (``uint``): current block's base fee (`EIP-3198 <https://eips.ethereum.org/EIPS/eip-3198>`_ and `EIP-1559 <https://eips.ethereum.org/EIPS/eip-1559>`_)
- ``block.blobbasefee`` (``uint``): current block's blob base fee (`EIP-7516 <https://eips.ethereum.org/EIPS/eip-7516>`_ and `EIP-4844 <https://eips.ethereum.org/EIPS/eip-4844>`_)
nikola-matic marked this conversation as resolved.
Show resolved Hide resolved
- ``block.chainid`` (``uint``): current chain id
- ``block.coinbase`` (``address payable``): current block miner's address
- ``block.difficulty`` (``uint``): current block difficulty (``EVM < Paris``). For other EVM versions it behaves as a deprecated alias for ``block.prevrandao`` (`EIP-4399 <https://eips.ethereum.org/EIPS/eip-4399>`_ )
Expand Down
2 changes: 2 additions & 0 deletions docs/using-the-compiler.rst
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ at each version. Backward compatibility is not guaranteed between each version.
- Introduces ``prevrandao()`` and ``block.prevrandao``, and changes the semantics of the now deprecated ``block.difficulty``, disallowing ``difficulty()`` in inline assembly (see `EIP-4399 <https://eips.ethereum.org/EIPS/eip-4399>`_).
- ``shanghai`` (**default**)
- Smaller code size and gas savings due to the introduction of ``push0`` (see `EIP-3855 <https://eips.ethereum.org/EIPS/eip-3855>`_).
- ``cancun``
- The block's blob base fee (`EIP-7516 <https://eips.ethereum.org/EIPS/eip-7516>`_ and `EIP-4844 <https://eips.ethereum.org/EIPS/eip-4844>`_) can be accessed via the global ``block.blobbasefee`` or ``blobbasefee()`` in inline assembly.

.. index:: ! standard JSON, ! --standard-json
.. _compiler-api:
Expand Down
6 changes: 4 additions & 2 deletions docs/yul.rst
Original file line number Diff line number Diff line change
Expand Up @@ -752,8 +752,8 @@ This document does not want to be a full description of the Ethereum virtual mac
Please refer to a different document if you are interested in the precise semantics.

Opcodes marked with ``-`` do not return a result and all others return exactly one value.
Opcodes marked with ``F``, ``H``, ``B``, ``C``, ``I``, ``L`` and ``P`` are present since Frontier,
Homestead, Byzantium, Constantinople, Istanbul, London or Paris respectively.
Opcodes marked with ``F``, ``H``, ``B``, ``C``, ``I``, ``L``, ``P`` and ``N`` are present since Frontier,
Homestead, Byzantium, Constantinople, Istanbul, London, Paris or Cancun respectively.

In the following, ``mem[a...b)`` signifies the bytes of memory starting at position ``a`` up to
but not including position ``b`` and ``storage[p]`` signifies the storage contents at slot ``p``.
Expand Down Expand Up @@ -919,6 +919,8 @@ the ``dup`` and ``swap`` instructions as well as ``jump`` instructions, labels a
+-------------------------+-----+---+-----------------------------------------------------------------+
| basefee() | | L | current block's base fee (EIP-3198 and EIP-1559) |
+-------------------------+-----+---+-----------------------------------------------------------------+
| blobbasefee() | | N | current block's blob base fee (EIP-7516 and EIP-4844) |
+-------------------------+-----+---+-----------------------------------------------------------------+
| origin() | | F | transaction sender |
+-------------------------+-----+---+-----------------------------------------------------------------+
| gasprice() | | F | gas price of the transaction |
Expand Down
2 changes: 2 additions & 0 deletions libevmasm/Instruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ std::map<std::string, Instruction> const solidity::evmasm::c_instructions =
{ "CHAINID", Instruction::CHAINID },
{ "SELFBALANCE", Instruction::SELFBALANCE },
{ "BASEFEE", Instruction::BASEFEE },
{ "BLOBBASEFEE", Instruction::BLOBBASEFEE },
{ "POP", Instruction::POP },
{ "MLOAD", Instruction::MLOAD },
{ "MSTORE", Instruction::MSTORE },
Expand Down Expand Up @@ -230,6 +231,7 @@ static std::map<Instruction, InstructionInfo> const c_instructionInfo =
{ Instruction::CHAINID, { "CHAINID", 0, 0, 1, false, Tier::Base } },
{ Instruction::SELFBALANCE, { "SELFBALANCE", 0, 0, 1, false, Tier::Low } },
{ Instruction::BASEFEE, { "BASEFEE", 0, 0, 1, false, Tier::Base } },
{ Instruction::BLOBBASEFEE, { "BLOBBASEFEE", 0, 0, 1, false, Tier::Base } },
{ Instruction::POP, { "POP", 0, 1, 0, false, Tier::Base } },
{ Instruction::MLOAD, { "MLOAD", 0, 1, 1, true, Tier::VeryLow } },
{ Instruction::MSTORE, { "MSTORE", 0, 2, 0, true, Tier::VeryLow } },
Expand Down
1 change: 1 addition & 0 deletions libevmasm/Instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ enum class Instruction: uint8_t
CHAINID, ///< get the config's chainid param
SELFBALANCE, ///< get balance of the current account
BASEFEE, ///< get the block's basefee
BLOBBASEFEE = 0x4a, ///< get the block's blob basefee

POP = 0x50, ///< remove item from stack
MLOAD, ///< load word from memory
Expand Down
1 change: 1 addition & 0 deletions libevmasm/SemanticInformation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,7 @@ bool SemanticInformation::invalidInPureFunctions(Instruction _instruction)
case Instruction::CALLVALUE:
case Instruction::CHAINID:
case Instruction::BASEFEE:
case Instruction::BLOBBASEFEE:
case Instruction::GAS:
case Instruction::GASPRICE:
case Instruction::EXTCODESIZE:
Expand Down
1 change: 1 addition & 0 deletions libevmasm/SimplificationRule.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ struct EVMBuiltins
static auto constexpr CHAINID = PatternGenerator<Instruction::CHAINID>{};
static auto constexpr SELFBALANCE = PatternGenerator<Instruction::SELFBALANCE>{};
static auto constexpr BASEFEE = PatternGenerator<Instruction::BASEFEE>{};
static auto constexpr BLOBBASEFEE = PatternGenerator<Instruction::BLOBBASEFEE>{};
static auto constexpr POP = PatternGenerator<Instruction::POP>{};
static auto constexpr MLOAD = PatternGenerator<Instruction::MLOAD>{};
static auto constexpr MSTORE = PatternGenerator<Instruction::MSTORE>{};
Expand Down
2 changes: 2 additions & 0 deletions liblangutil/EVMVersion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ bool EVMVersion::hasOpcode(Instruction _opcode) const
return hasSelfBalance();
case Instruction::BASEFEE:
return hasBaseFee();
case Instruction::BLOBBASEFEE:
return hasBlobBaseFee();
default:
return true;
}
Expand Down
1 change: 1 addition & 0 deletions liblangutil/EVMVersion.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ class EVMVersion:
bool hasChainID() const { return *this >= istanbul(); }
bool hasSelfBalance() const { return *this >= istanbul(); }
bool hasBaseFee() const { return *this >= london(); }
bool hasBlobBaseFee() const { return *this >= cancun(); }
bool hasPrevRandao() const { return *this >= paris(); }
bool hasPush0() const { return *this >= shanghai(); }

Expand Down
6 changes: 6 additions & 0 deletions libsolidity/analysis/TypeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3409,6 +3409,12 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
_memberAccess.location(),
"\"basefee\" is not supported by the VM version."
);
else if (memberName == "blobbasefee" && !m_evmVersion.hasBlobBaseFee())
m_errorReporter.typeError(
1006_error,
_memberAccess.location(),
"\"blobbasefee\" is not supported by the VM version."
);
else if (memberName == "prevrandao" && !m_evmVersion.hasPrevRandao())
m_errorReporter.warning(
9432_error,
Expand Down
3 changes: 2 additions & 1 deletion libsolidity/ast/Types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4116,7 +4116,8 @@ MemberList::MemberMap MagicType::nativeMembers(ASTNode const*) const
{"number", TypeProvider::uint256()},
{"gaslimit", TypeProvider::uint256()},
{"chainid", TypeProvider::uint256()},
{"basefee", TypeProvider::uint256()}
{"basefee", TypeProvider::uint256()},
{"blobbasefee", TypeProvider::uint256()}
});
case Kind::Message:
return MemberList::MemberMap({
Expand Down
2 changes: 2 additions & 0 deletions libsolidity/codegen/ExpressionCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1886,6 +1886,8 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
m_context << Instruction::CHAINID;
else if (member == "basefee")
m_context << Instruction::BASEFEE;
else if (member == "blobbasefee")
m_context << Instruction::BLOBBASEFEE;
else if (member == "data")
m_context << u256(0) << Instruction::CALLDATASIZE;
else if (member == "sig")
Expand Down
2 changes: 2 additions & 0 deletions libsolidity/codegen/ir/IRGeneratorForStatements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1895,6 +1895,8 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
define(_memberAccess) << "chainid()\n";
else if (member == "basefee")
define(_memberAccess) << "basefee()\n";
else if (member == "blobbasefee")
define(_memberAccess) << "blobbasefee()\n";
else if (member == "data")
{
IRVariable var(_memberAccess);
Expand Down
2 changes: 2 additions & 0 deletions libyul/AsmAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,8 @@ bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocatio
errorForVM(7721_error, "only available for Istanbul-compatible");
else if (_instr == evmasm::Instruction::BASEFEE && !m_evmVersion.hasBaseFee())
errorForVM(5430_error, "only available for London-compatible");
else if (_instr == evmasm::Instruction::BLOBBASEFEE && !m_evmVersion.hasBlobBaseFee())
errorForVM(6679_error, "only available for Cancun-compatible");
else if (_instr == evmasm::Instruction::PC)
m_errorReporter.error(
2450_error,
Expand Down
13 changes: 12 additions & 1 deletion libyul/backends/evm/EVMDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,13 @@ std::set<YulString> createReservedIdentifiers(langutil::EVMVersion _evmVersion)
return _instr == evmasm::Instruction::BASEFEE && _evmVersion < langutil::EVMVersion::london();
};

// TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name
nikola-matic marked this conversation as resolved.
Show resolved Hide resolved
// blobbasefee for VMs before cancun.
auto blobBaseFeeException = [&](evmasm::Instruction _instr) -> bool
{
return _instr == evmasm::Instruction::BLOBBASEFEE && _evmVersion < langutil::EVMVersion::cancun();
};
nikola-matic marked this conversation as resolved.
Show resolved Hide resolved

// TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name
// prevrandao for VMs before paris.
auto prevRandaoException = [&](std::string const& _instrName) -> bool
Expand All @@ -132,7 +139,11 @@ std::set<YulString> createReservedIdentifiers(langutil::EVMVersion _evmVersion)
for (auto const& instr: evmasm::c_instructions)
{
std::string name = toLower(instr.first);
if (!baseFeeException(instr.second) && !prevRandaoException(name))
if (
!baseFeeException(instr.second) &&
!blobBaseFeeException(instr.second) &&
!prevRandaoException(name)
)
reserved.emplace(name);
}
reserved += std::vector<YulString>{
Expand Down
2 changes: 1 addition & 1 deletion scripts/error_codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False):
"4591", # "There are more than 256 warnings. Ignoring the rest."
# Due to 3805, the warning lists look different for different compiler builds.
"1834", # Unimplemented feature error, as we do not test it anymore via cmdLineTests
"5430", # basefee being used in inline assembly for EVMVersion < london
r0qs marked this conversation as resolved.
Show resolved Hide resolved
"6679", # blobbasefee being used in inline assembly for EVMVersion < cancun
"1180", # SMTChecker, covered by CL tests
"2339", # SMTChecker, covered by CL tests
"2961", # SMTChecker, covered by CL tests
Expand Down
2 changes: 2 additions & 0 deletions scripts/test_antlr_grammar.sh
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ done < <(
grep -v -E 'revertStatement/non_called.sol' |
# Skipping a test with "let basefee := ..."
grep -v -E 'inlineAssembly/basefee_berlin_function.sol' |
# Skipping a test with "let blobbasefee := ..."
grep -v -E 'inlineAssembly/blobbasefee_shanghai_function.sol' |
# Skipping tests with "let prevrandao := ..."
grep -v -E 'inlineAssembly/prevrandao_allowed_function_pre_paris.sol' |
grep -v -E 'inlineAssembly/prevrandao_disallowed_function_post_paris.sol' |
Expand Down
2 changes: 2 additions & 0 deletions test/EVMHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm):
tx_context.chain_id = evmc::uint256be{1};
// The minimum value of basefee
tx_context.block_base_fee = evmc::bytes32{7};
// The minimum value of blobbasefee
tx_context.blob_base_fee = evmc::bytes32{1};

// Reserve space for recording calls.
if (!recorded_calls.capacity())
Expand Down
20 changes: 20 additions & 0 deletions test/libsolidity/ViewPureChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,26 @@ BOOST_AUTO_TEST_CASE(environment_access)
TypeError,
"\"block.blockhash()\" has been deprecated in favor of \"blockhash()\""
);

std::string baseFeeContract = "contract C { function f() view public { block.basefee; } }";
cameel marked this conversation as resolved.
Show resolved Hide resolved
if (!solidity::test::CommonOptions::get().evmVersion().hasBaseFee())
CHECK_ERROR(
baseFeeContract,
TypeError,
"\"basefee\" is not supported by the VM version."
);
else
CHECK_SUCCESS_NO_WARNINGS(baseFeeContract);

std::string blobBaseFeeContract = "contract C { function f() view public { block.blobbasefee; } }";
if (!solidity::test::CommonOptions::get().evmVersion().hasBlobBaseFee())
CHECK_ERROR(
blobBaseFeeContract,
TypeError,
"\"blobbasefee\" is not supported by the VM version."
);
else
CHECK_SUCCESS_NO_WARNINGS(blobBaseFeeContract);
}

BOOST_AUTO_TEST_CASE(address_staticcall)
Expand Down
nikola-matic marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
contract C {
function f() public view returns (uint ret) {
assembly {
let blobbasefee := 999
ret := blobbasefee
}
}
function g() public pure returns (uint ret) {
assembly {
function blobbasefee() -> r {
r := 1000
}
ret := blobbasefee()
}
}
}
// ====
// EVMVersion: <=shanghai
// ----
// f() -> 999
// g() -> 1000
17 changes: 17 additions & 0 deletions test/libsolidity/semanticTests/state/block_blobbasefee.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
contract C {
function f() public view returns (uint) {
return block.blobbasefee;
}
function g() public view returns (uint ret) {
assembly {
ret := blobbasefee()
}
}
}
// ====
// EVMVersion: >=cancun
// ----
// f() -> 1
// g() -> 1
// f() -> 1
// g() -> 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
contract C {
function f() public view returns (uint ret) {
assembly {
let blobbasefee := sload(0)
ret := blobbasefee
}
}
}
// ====
// EVMVersion: >=cancun
// ----
// ParserError 5568: (98-109): Cannot use builtin function name "blobbasefee" as identifier name.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@ contract C {
function f() public view returns (uint) {
return block.basefee;
}
function g() public view returns (uint ret) {
assembly {
ret := basefee()
}
}
}
// ====
// EVMVersion: <=berlin
// EVMVersion: =berlin
// ----
// TypeError 5921: (74-87): "basefee" is not supported by the VM version.
// TypeError 5430: (183-190): The "basefee" instruction is only available for London-compatible VMs (you are currently compiling for "berlin").
// DeclarationError 8678: (176-192): Variable count for assignment to "ret" does not match number of values (1 vs. 0)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
contract C {
function f() public view returns (uint) {
return block.blobbasefee;
}
function g() public view returns (uint ret) {
assembly {
ret := blobbasefee()
}
}
}
// ====
// EVMVersion: >=cancun
// ----
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
contract C {
function f() public view returns (uint) {
return block.blobbasefee;
}
function g() public view returns (uint ret) {
assembly {
ret := blobbasefee()
}
}
}
// ====
// EVMVersion: =shanghai
// ----
// TypeError 1006: (74-91): "blobbasefee" is not supported by the VM version.
// DeclarationError 4619: (187-198): Function "blobbasefee" not found.
// DeclarationError 8678: (180-200): Variable count for assignment to "ret" does not match number of values (1 vs. 0)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
contract C {
function f() public pure {
assembly { pop(blobbasefee()) }
}
function g() public pure returns (uint) {
return block.blobbasefee;
}
}
// ====
// EVMVersion: >=cancun
// ----
// TypeError 2527: (67-80): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view".
// TypeError 2527: (151-168): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view".
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
contract C {
function f() public view {
assembly {
pop(blobbasefee())
}
}
}
// ====
// EVMVersion: >=cancun
// ----
Loading